1use lazy_static::lazy_static;
2
3use std::collections::HashMap;
4
5use crate::common::{NitroCliErrorEnum, NitroCliFailure};
6
7lazy_static! {
8 pub static ref ERROR_CODES: HashMap<NitroCliErrorEnum, &'static str> =
10 [
11 (NitroCliErrorEnum::UnspecifiedError, "E00"),
12 (NitroCliErrorEnum::MissingArgument, "E01"),
13 (NitroCliErrorEnum::ConflictingArgument, "E02"),
14 (NitroCliErrorEnum::InvalidArgument, "E03"),
15 (NitroCliErrorEnum::SocketPairCreationFailure, "E04"),
16 (NitroCliErrorEnum::ProcessSpawnFailure, "E05"),
17 (NitroCliErrorEnum::DaemonizeProcessFailure, "E06"),
18 (NitroCliErrorEnum::ReadFromDiskFailure, "E07"),
19 (NitroCliErrorEnum::UnusableConnectionError, "E08"),
20 (NitroCliErrorEnum::SocketCloseError, "E09"),
21 (NitroCliErrorEnum::SocketConnectTimeoutError, "E10"),
22 (NitroCliErrorEnum::SocketError, "E11"),
23 (NitroCliErrorEnum::EpollError, "E12"),
24 (NitroCliErrorEnum::InotifyError, "E13"),
25 (NitroCliErrorEnum::InvalidCommand, "E14"),
26 (NitroCliErrorEnum::LockAcquireFailure, "E15"),
27 (NitroCliErrorEnum::ThreadJoinFailure, "E16"),
28 (NitroCliErrorEnum::SerdeError, "E17"),
29 (NitroCliErrorEnum::FilePermissionsError, "E18"),
30 (NitroCliErrorEnum::FileOperationFailure, "E19"),
31 (NitroCliErrorEnum::InvalidCpuConfiguration, "E20"),
32 (NitroCliErrorEnum::NoSuchCpuAvailableInPool, "E21"),
33 (NitroCliErrorEnum::InsufficientCpus, "E22"),
34 (NitroCliErrorEnum::MalformedCpuId, "E23"),
35 (NitroCliErrorEnum::CpuError, "E24"),
36 (NitroCliErrorEnum::NoSuchHugepageFlag, "E25"),
37 (NitroCliErrorEnum::InsufficientMemoryRequested, "E26"),
38 (NitroCliErrorEnum::InsufficientMemoryAvailable, "E27"),
39 (NitroCliErrorEnum::InvalidEnclaveFd, "E28"),
40 (NitroCliErrorEnum::IoctlFailure, "E29"),
41 (NitroCliErrorEnum::IoctlImageLoadInfoFailure, "E30"),
42 (NitroCliErrorEnum::IoctlSetMemoryRegionFailure, "E31"),
43 (NitroCliErrorEnum::IoctlAddVcpuFailure, "E32"),
44 (NitroCliErrorEnum::IoctlEnclaveStartFailure, "E33"),
45 (NitroCliErrorEnum::MemoryOverflow, "E34"),
46 (NitroCliErrorEnum::EifParsingError, "E35"),
47 (NitroCliErrorEnum::EnclaveBootFailure, "E36"),
48 (NitroCliErrorEnum::EnclaveEventWaitError, "E37"),
49 (NitroCliErrorEnum::EnclaveProcessCommandNotExecuted, "E38"),
50 (NitroCliErrorEnum::EnclaveProcessConnectionFailure, "E39"),
51 (NitroCliErrorEnum::SocketPathNotFound, "E40"),
52 (NitroCliErrorEnum::EnclaveProcessSendReplyFailure, "E41"),
53 (NitroCliErrorEnum::EnclaveMmapError, "E42"),
54 (NitroCliErrorEnum::EnclaveMunmapError, "E43"),
55 (NitroCliErrorEnum::EnclaveConsoleConnectionFailure, "E44"),
56 (NitroCliErrorEnum::EnclaveConsoleReadError, "E45"),
57 (NitroCliErrorEnum::EnclaveConsoleWriteOutputError, "E46"),
58 (NitroCliErrorEnum::IntegerParsingError, "E47"),
59 (NitroCliErrorEnum::EifBuildingError, "E48"),
60 (NitroCliErrorEnum::DockerImageBuildError, "E49"),
61 (NitroCliErrorEnum::DockerImagePullError, "E50"),
62 (NitroCliErrorEnum::ArtifactsPathNotSet, "E51"),
63 (NitroCliErrorEnum::BlobsPathNotSet, "E52"),
64 (NitroCliErrorEnum::ClockSkewError, "E53"),
65 (NitroCliErrorEnum::SignalMaskingError, "E54"),
66 (NitroCliErrorEnum::SignalUnmaskingError, "E55"),
67 (NitroCliErrorEnum::LoggerError, "E56"),
68 (NitroCliErrorEnum::HasherError, "E57"),
69 (NitroCliErrorEnum::EnclaveNamingError, "E58"),
70 (NitroCliErrorEnum::EIFSignatureCheckerError, "E59"),
71 (NitroCliErrorEnum::EIFSigningError, "E60"),
72 ].iter().cloned().collect();
73}
74
75pub fn get_detailed_info(error_code_str: String, additional_info: &[String]) -> String {
77 let mut ret = format!("[ {error_code_str} ] ");
78 let info_placeholder = "MISSING_INFO".to_string();
79
80 match error_code_str.as_str() {
81 "E00" => {
82 ret.push_str("Unspecified error. This is used as a catch-all error and should not be used in the code.");
83 }
84 "E01" => {
85 ret.push_str(
86 format!(
87 "Missing mandatory argument. User did not provide the `{}` argument.",
88 additional_info.first().unwrap_or(&info_placeholder)
89 )
90 .as_str(),
91 );
92 }
93 "E02" => {
94 ret.push_str(
95 format!(
96 "Conflicting arguments. User provided both `{}` and `{}`.",
97 additional_info.first().unwrap_or(&info_placeholder),
98 additional_info.get(1).unwrap_or(&info_placeholder)
99 )
100 .as_str(),
101 );
102 }
103 "E03" => {
104 ret.push_str(
105 format!(
106 "Invalid argument provided. The parameter `{}` is not a valid integer (`{}`)",
107 additional_info.first().unwrap_or(&info_placeholder),
108 additional_info.get(1).unwrap_or(&info_placeholder)
109 )
110 .as_str(),
111 );
112 }
113 "E04" => {
114 ret.push_str("Socket pair creation failure. Such error appears when the Nitro CLI process attempts to open a stream pair in order to send a command to the enclave process but the stream initialization fails.");
115 }
116 "E05" => {
117 ret.push_str("Process spawn failure. Such error appears when the main Nitro CLI process fails to spawn the enclave process, in order to complete a `run-enclave` command.");
118 }
119 "E06" => {
120 ret.push_str("Daemonize process failure. Such error appears when the system fails to daemonize a newly spawned enclave process.");
121 }
122 "E07" => {
123 ret.push_str("Read from disk failure. Such error appears when the Nitro CLI process fails to read the content of the enclave sockets directory (usually '/run/nitro_enclaves/') in order to perform a `describe-enclave` operation. Check that the directory exists and it has proper permissions, or run the Nitro Enclaves configuration script in order to (re)configure the environment.");
124 }
125 "E08" => {
126 ret.push_str("Unusable connection error. Such error appears when the Nitro CLI process attempts to open a connection to a non-existing or previously closed enclave descriptor");
127 }
128 "E09" => {
129 ret.push_str("Socket close error. Such error appears when the system fails to successfully close a communication channel.");
130 }
131 "E10" => {
132 ret.push_str("Socket connect set timeout error. Such error appears when the system fails to configure a specific timeout for a given socket. May arise when trying to connect to an enclave's console.");
133 }
134 "E11" => {
135 ret.push_str("Socket error. This is used as an error for catching any other socket operation errors not covered by previous custom errors.");
136 }
137 "E12" => {
138 ret.push_str("Epoll error. Such error appears, for instance, when the system fails to register a specific enclave descriptor with epoll in order to monitor events for it.");
139 }
140 "E13" => {
141 ret.push_str("Inotify error. Such error appears when the system fails to configure a socket for monitorization.");
142 }
143 "E14" => {
144 ret.push_str("Invalid command. Such error appears when an unknown command and / or unknown arguments are sent through a socket.");
145 }
146 "E15" => {
147 ret.push_str("Lock acquire failure. Such error appears when the system fails to obtain the lock for an object with concurrent access, such as a structure containing information about a running enclave.");
148 }
149 "E16" => {
150 ret.push_str("Thread join failure. Such error appears when the system fails to successfully join a thread, after it finished executing.");
151 }
152 "E17" => {
153 ret.push_str("Serde error. Such error appears when serializing / deserializing a command or response fails.");
154 }
155 "E18" => {
156 ret.push_str("File permissions error. Such error appears when a user other than the owner of the logging file (usually '/var/log/nitro_enclaves/nitro_enclaves.log') attempts to change the file permissions");
157 }
158 "E19" => {
159 ret.push_str("File operation failure. Such error appears when the system fails to perform the requested file operations, such as opening the EIF file when launching an enclave, or seeking to a specific offset in the EIF file, or writing to the log file.");
160 if additional_info.len() >= 2 {
161 ret.push_str(
162 format!(
163 "\nFile: '{}', failing operation: '{}'.",
164 additional_info.first().unwrap_or(&info_placeholder),
165 additional_info.get(1).unwrap_or(&info_placeholder),
166 )
167 .as_str(),
168 );
169 }
170 }
171 "E20" => {
172 ret.push_str(
173 format!(
174 "Invalid CPU configuration. User provided `{}` contains same CPU(s) (CPU(s) {}) multiple times.",
175 additional_info.first().unwrap_or(&info_placeholder),
176 additional_info.get(1).unwrap_or(&info_placeholder),
177 )
178 .as_str(),
179 );
180 }
181 "E21" => {
182 ret.push_str(
183 format!(
184 "No such CPU available in the pool. User provided `{}` contains CPU {}, which is not available in the pool.\nYou can add a specific CPU to the CPU pool by editing the `cpu_pool` value from '/etc/nitro_enclaves/allocator.yaml' and then enable the nitro-enclaves-allocator.service.",
185 additional_info.first().unwrap_or(&info_placeholder),
186 additional_info.get(1).unwrap_or(&info_placeholder),
187 ).as_str(),
188 );
189 }
190 "E22" => {
191 ret.push_str(
192 format!(
193 "Insufficient CPUs available in the pool. User provided `{}` is {}, which is more than the configured CPU pool size.\nYou can increase the CPU pool size by editing the `cpu_count` value from '/etc/nitro_enclaves/allocator.yaml' and then enable the nitro-enclaves-allocator.service.",
194 additional_info.first().unwrap_or(&info_placeholder),
195 additional_info.get(1).unwrap_or(&info_placeholder),
196 ).as_str(),
197 );
198 }
199 "E23" => {
200 ret.push_str("Malformed CPU ID error. Such error appears when a `lscpu` line is malformed and reports an invalid online CPUs list.");
201 }
202 "E24" => {
203 ret.push_str("CPU error. Such error appears when a CPU line interval is invalid (for instance, 0-3-7)");
204 }
205 "E25" => {
206 ret.push_str("No such hugepage flag error. Such error appears when the enclave process attempts to use an invalid hugepage size (size other than the known hugepage sizes) for initializing the enclave memory.");
207 }
208 "E26" => {
209 if additional_info.len() >= 3 {
210 ret.push_str(
211 format!(
212 "Insufficient memory requested. User provided `{}` is {} MB, but based on the EIF file size, the minimum memory should be {} MB",
213 additional_info.first().unwrap_or(&info_placeholder),
214 additional_info.get(1).unwrap_or(&info_placeholder),
215 additional_info.get(2).unwrap_or(&info_placeholder)
216 ).as_str(),
217 );
218 } else {
219 ret.push_str(
220 format!(
221 "Insufficient memory requested. User provided `{}` is {} MB, and memory should be greater than 0 MB.",
222 additional_info.first().unwrap_or(&info_placeholder),
223 additional_info.get(1).unwrap_or(&info_placeholder)
224 ).as_str(),
225 );
226 }
227 }
228 "E27" => {
229 ret.push_str(
230 format!(
231 "Insufficient memory available. User provided `{}` is {} MB, which is more than the available hugepage memory.\nYou can increase the available memory by editing the `memory_mib` value from '/etc/nitro_enclaves/allocator.yaml' and then restart the nitro-enclaves-allocator.service.",
232 additional_info.first().unwrap_or(&info_placeholder),
233 additional_info.get(1).unwrap_or(&info_placeholder)
234 ).as_str(),
235 );
236 }
237 "E28" => {
238 ret.push_str("Invalid enclave descriptor. Such error appears when the NE_CREATE_VM ioctl returns with an error.");
239 }
240 "E29" => {
241 ret.push_str("Ioctl failure. Such error is used as a general ioctl error and appears whenever an ioctl fails. In this case, the error backtrace provides detailed information on what specifically failed during the ioctl.");
242 }
243 "E30" => {
244 ret.push_str("Ioctl image get load info failure. Such error appears when the ioctl used for getting the memory load information fails. In this case, the error backtrace provides detailed information on what specifically failed during the ioctl.");
245 }
246 "E31" => {
247 ret.push_str("Ioctl set memory region failure. Such error appears when the ioctl used for setting a given memory region fails. In this case, the error backtrace provides detailed information on what specifically failed during the ioctl.");
248 }
249 "E32" => {
250 ret.push_str("Ioctl add vCPU failure. Such error appears when the ioctl used for adding a vCPU fails. In this case, the error backtrace provides detailed information on what specifically failed during the ioctl.");
251 }
252 "E33" => {
253 ret.push_str("Ioctl start enclave failure. Such error appears when the ioctl used for starting an enclave fails. In this case, the error backtrace provides details information on what specifically failed during the ioctl.");
254 }
255 "E34" => {
256 ret.push_str("Memory overflow. Such error may appear during loading the EIF in the memory regions which will be conceded to the future enclave, if the regions offset plus the EIF file size exceeds the maximum address of the target platform.");
257 }
258 "E35" => {
259 ret.push_str("EIF file parsing error. Such errors appear when attempting to fill a memory region with a section of the EIF file, but reading the entire section fails. This might indicate that the required hugepages are not available.");
260 }
261 "E36" => {
262 ret.push_str("Enclave boot failure. Such error appears when attempting to receive the `ready` signal from a freshly booted enclave. It arises in several contexts, for instance, when the enclave is booted from an invalid EIF file and the enclave process immediately exits, failing to submit the `ready` signal. In this case, the error backtrace provides detailed information on what specifically failed during the enclave boot process.");
263 }
264 "E37" => {
265 ret.push_str("Enclave event wait error. Such error appears when monitoring an enclave descriptor for events fails.");
266 }
267 "E38" => {
268 ret.push_str("Enclave process command not executed error. Such error appears when at least one enclave fails to provide the description information.");
269 }
270 "E39" => {
271 ret.push_str("Enclave process connection failure. Such error appears when the enclave manager fails to connect to at least one enclave process for retrieving the description information.");
272 }
273 "E40" => {
274 ret.push_str("Socket path not found. Such error appears when the Nitro CLI process fails to build the corresponding socket path starting from a given enclave ID.");
275 }
276 "E41" => {
277 ret.push_str("Enclave process send reply failure. Such error appears when the enclave process fails to submit the status code to the Nitro CLI process after performing a run / describe / terminate command.");
278 }
279 "E42" => {
280 ret.push_str(
281 "Enclave mmap error. Such error appears when allocating the enclave memory fails.",
282 );
283 }
284 "E43" => {
285 ret.push_str(
286 "Enclave munmap error. Such error appears when unmapping the enclave memory fails.",
287 );
288 }
289 "E44" => {
290 ret.push_str("Enclave console connection failure. Such error appears when the Nitro CLI process fails to establish a connection to a running enclave's console.");
291 }
292 "E45" => {
293 ret.push_str("Enclave console read error. Such error appears when reading from a running enclave's console fails.");
294 }
295 "E46" => {
296 ret.push_str("Enclave console write output error. Such error appears when writing the information retrieved from a running enclave's console (to a given stream) fails.");
297 }
298 "E47" => {
299 ret.push_str("Integer parsing error. Such error appears when trying to connect to a running enclave's console, but the enclave CID cannot be parsed correctly.");
300 }
301 "E48" => {
302 ret.push_str("EIF building error. Such error appears when trying to build an EIF file. In this case, the error backtrace provides detailed information on the failure reason.");
303 }
304 "E49" => {
305 ret.push_str("Docker image build error. Such error appears when trying to build and EIF file, but building the corresponding docker image fails. In this case, the error backtrace provides detailed information on the failure reason.");
306 }
307 "E50" => {
308 ret.push_str("Docker image pull error. Such error appears when trying to build an EIF file, but pulling the corresponding docker image fails. In this case, the error backtrace provides detailed informatino on the failure reason.");
309 }
310 "E51" => {
311 ret.push_str("Artifacts path environment variable not set. Such error appears when trying to build an EIF file, but the artifacts path environment variable is not set.");
312 }
313 "E52" => {
314 ret.push_str("Blobs path environment variable not set. Such error appears when trying to build an EIF file, but the blobs path environment variable is not set.");
315 }
316 "E53" => {
317 ret.push_str("Clock skew error. Such error appears when continuously reading from a running enclave's console, but measuring the time elapsed between consecutive reads failed.");
318 }
319 "E54" => {
320 ret.push_str("Signal masking error. Such error appears if attempting to mask specific signals before creating an enclave process fails.");
321 }
322 "E55" => {
323 ret.push_str("Signal unmasking error. Such error appears if attempting to unmask specific signals after creating an enclave process fails.");
324 }
325 "E56" => {
326 ret.push_str("Logger error. Such error appears when attempting to initialize the underlying logging system fails.");
327 }
328 "E57" => {
329 ret.push_str("Hasher error. Such error appears when trying to initialize a hasher or write bytes to it, resulting in a IO error.");
330 }
331 "E58" => {
332 ret.push_str("Naming error. Such error appears when trying to perform an enclave operation using the enclave name and the name is invalid.");
333 }
334 "E59" => {
335 ret.push_str("EIF signature checker error. Such error appears when validation of the signing certificate fails.");
336 }
337 "E60" => {
338 ret.push_str("Signing error. Such error appears if incorrect key or certificate paths are provided, or when AWS credenrials need to be refreshed to use a KMS key.");
339 }
340 _ => {
341 ret.push_str(format!("No such error code {error_code_str}").as_str());
342 }
343 }
344
345 ret
346}
347
348pub fn construct_help_link(error_code_str: String) -> String {
350 format!("https://docs.aws.amazon.com/enclaves/latest/user/cli-errors.html#{error_code_str}")
351}
352
353pub fn construct_backtrace(failure_info: &NitroCliFailure) -> String {
355 let version = env!("CARGO_PKG_VERSION").to_string();
356
357 format!(" Action: {}\n Subactions:{}\n Root error file: {}\n Root error line: {}\n Version: {}",
358 failure_info.action,
359 failure_info.subactions.iter().rev().fold("".to_string(), |acc, x| {
360 format!("{acc}\n {x}")
361 }),
362 failure_info.file,
363 failure_info.line,
364 version)
365}
366
367pub fn explain_error(error_code_str: String) {
369 match error_code_str.as_str() {
370 "E00" => {
371 eprintln!("Unspecified error. This is used as a catch-all error and should not be used in the code.");
372 }
373 "E01" => {
374 eprintln!("Missing mandatory argument. Such error appears when the Nitro CLI is requested to perform an operation, but not all of the mandatory arguments were supplied.\n\tExample: `nitro-cli run-enclave --cpu-count 2 --eif-path /path/to/my/eif`. Note that in this case, the mandatory parameter `--memory` is missing a value.");
375 }
376 "E02" => {
377 eprintln!("CLI conflicting arguments. Such error appears when the Nitro CLI is supplied two contradicting arguments at the same time, such as `--cpu-count` and `--cpu-ids`.\nIn this case, only one of the parameters should be supplied.");
378 }
379 "E03" => {
380 eprintln!("Invalid argument provided. Such error appears when the type of at least one of the arguments provided to the Nitro CLI does not match the expected type of that parameter.\n\tExample: `nitro-cli run-enclave --cpu-count 1z --memory 80 --eif-path /path/to/my/eif`. In this case, `cpu-count` is not a valid integer value." );
381 }
382 "E04" => {
383 eprintln!("Socket pair creation failure. Such error apears when the Nitro CLI process attempts to open a stream pair in order to send a command to the enclave process, but the stream initialization fails.");
384 }
385 "E05" => {
386 eprintln!("Process spawn failure. Such error appears when the main Nitro CLI process failed to spawn the enclave process, in order to complete a `run-enclave` command.");
387 }
388 "E06" => {
389 eprintln!("Daemonize process failure. Such error appears when the system fails to daemonize the newly spawned enclave process.")
390 }
391 "E07" => {
392 eprintln!("Read from disk failure. Such error appears when the Nitro CLI process fails to read the content of the enclave sockets directory (usually '/run/nitro_enclaves/') in order to perform a `describe-enclave` operation. Check that the directory exists and it has proper permissions, or run the Nitro Enclaves configuration script in order to (re)configure the environment.");
393 }
394 "E08" => {
395 eprintln!("Unusable connection error. Such error appears when the Nitro CLI process attempts to open a connection to a non-existing or previously closed enclave descriptor");
396 }
397 "E09" => {
398 eprintln!("Socket close error. Such error appears when the system fails to successfully close a communication channel.");
399 }
400 "E10" => {
401 eprintln!("Socket connect set timeout error. Such error appears when the system fails to configure a specific timeout for a given socket. May arise when trying to connect to an enclave's console.");
402 }
403 "E11" => {
404 eprintln!("Socket error. This is used as an error for catching any other socket operation errors not covered by previous custom errors.");
405 }
406 "E12" => {
407 eprintln!("Epoll error. Such error appears, for instance, when the system fails to register a specific enclave descriptor with epoll in order to monitor events for it.");
408 }
409 "E13" => {
410 eprintln!("Inotify error. Such error appears when the system fails to configure a socket for monitorization.");
411 }
412 "E14" => {
413 eprintln!("Invalid command. Such error appears when an unknown command and / or unknown arguments are sent through a socket.");
414 }
415 "E15" => {
416 eprintln!("Lock acquire failure. Such error appears when the system fails to obtain the lock for an object with concurrent access, such as a structure containing information about a running enclave.");
417 }
418 "E16" => {
419 eprintln!("Thread join failure. Such error appears when the system fails to successfully join a thread, after it finished executing.");
420 }
421 "E17" => {
422 eprintln!("Serde error. Such error appears when serializing / deserializing a command or response fails.");
423 }
424 "E18" => {
425 eprintln!("File permissions error. Such error appears when a user other than the owner of the logging file (usually '/var/log/nitro_enclaves/nitro_enclaves.log') attempts to change the file permissions");
426 }
427 "E19" => {
428 eprintln!("File operation failure. Such error appears when the system fails to perform the requested file operations, such as opening the EIF file when launching an enclave, or seeking to a specific offset in the EIF file, or writing to the log file.");
429 }
430 "E20" => {
431 eprintln!("Invalid CPU configuration. Such error appears when the user supplies the same CPU ID multiple times.\n\tExample: `nitro-cli run-enclave --cpu-ids 1 1 --memory 80 --eif-path /path/to/my/eif`. In this case, CPU ID `1` has been selected twice.");
432 }
433 "E21" => {
434 eprintln!("No such CPU available in the pool. Such error appears when the user requests to run an enclave with at least one CPU ID which does not exist in the CPU pool.\n\tExample: (configured CPU pool: [1,9]) `nitro-cli run-enclave --cpu-ids 1 2 --memory 80 --eif-path /path/to/my/eif`. In this case, CPU 2 is not in the configured CPU pool.");
435 }
436 "E22" => {
437 eprintln!("Insufficient CPUs available in the pool. Such error appears when the user requests to run an enclave with more CPUs that available in the CPU pool.\n\tExample: (configured CPU pool: [1,9]) `nitro-cli run-enclave --cpu-count 4 --memory 80 --eif-path /path/to/my/eif`. In this case, the user requested 4 CPUs, but the CPU pool contains only 2.");
438 }
439 "E23" => {
440 eprintln!("Malformed CPU ID error. Such error appears when a `lscpu` line is malformed and reports an invalid online CPUs list.");
441 }
442 "E24" => {
443 eprintln!(
444 "CPU error. Such error appears when a CPU line interval is invalid (as in 0-3-7)"
445 );
446 }
447 "E25" => {
448 eprintln!("No such hugepage flag error. Such error appears when the enclave process attempts to use an invalid hugepage size (size other than the known hugepage sizes) for initializing the enclave memory.");
449 }
450 "E26" => {
451 eprintln!("Insufficient memory requested. Such error appears when the user requests to launch an enclave with not enough memory. The enclave memory should be at least equal to the size of the EIF file used for launching the enclave.\n\tExample: (EIF file size: 11MB) `nitro-cli run-enclave --cpu-count 2 --memory 5 --eif-path /path/to/my/eif`. In this case, the user requested to run an enclave with only 5MB of memory, whereas the EIF file alone requires 11MB.");
452 }
453 "E27" => {
454 eprintln!("Insufficient memory available. Such error appears when the user requests to launch an enclave with more memory than available. The enclave memory should be at most equal to the size of the configured hugepage memory.\n\tExample: (previously configured 80MB of hugepage memory) `nitro-cli run-enclave --cpu-count 2 --memory 100 --eif-path /path/to/my/eif`. In this case, the user requested to run an enclave with 100MB of memory, whereas the system has only 80MB available for enclaves. As a solution, (re)configure the Nitro Enclaves environment, specifying a higher value for the available memory.");
455 }
456 "E28" => {
457 eprintln!("Invalid enclave descriptor. Such error appears when the NE_CREATE_VM ioctl returns with an error.");
458 }
459 "E29" => {
460 eprintln!("Ioctl failure. Such error is used as a general ioctl error and appears whenever an ioctl fails. In this case, the error backtrace provides detailed information on what specifically failed during the ioctl.");
461 }
462 "E30" => {
463 eprintln!("Ioctl image get load info failure. Such error appears when the ioctl used for getting the memory load information fails. In this case, the error backtrace provides detailed information on what specifically failed during the ioctl.");
464 }
465 "E31" => {
466 eprintln!("Ioctl set memory region failure. Such error appears when the ioctl used for setting a given memory region fails. In this case, the error backtrace provides detailed information on what specifically failed during the ioctl.");
467 }
468 "E32" => {
469 eprintln!("Ioctl add vCPU failure. Such error appears when the ioctl used for adding a vCPU fails. In this case, the error backtrace provides detailed information on what specifically failed during the ioctl.");
470 }
471 "E33" => {
472 eprintln!("Ioctl start enclave failure. Such error appears when the ioctl used for starting an enclave fails. In this case, the error backtrace provides details information on what specifically failed during the ioctl.");
473 }
474 "E34" => {
475 eprintln!("Memory overflow. Such error may appear during loading the EIF in the memory regions which will be conceded to the future enclave, if the regions offset plus the EIF file size exceeds the maximum address of the target platform.");
476 }
477 "E35" => {
478 eprintln!("EIF file parsing error. Such errors appear when attempting to fill a memory region with a section of the EIF file, but reading the entire section fails. This might indicate that the required hugepages are not available.");
479 }
480 "E36" => {
481 eprintln!("Enclave boot failure. Such error appears when attempting to receive the `ready` signal from a freshly booted enclave. It arises in several contexts, for instance, when the enclave is booted from an invalid EIF file and the enclave process immediately exits, failing to submit the `ready` signal. In this case, the error backtrace provides detailed information on what specifically failed during the enclave boot process.");
482 }
483 "E37" => {
484 eprintln!("Enclave event wait error. Such error appears when monitoring an enclave descriptor for events fails.");
485 }
486 "E38" => {
487 eprintln!("Enclave process command not executed error. Such error appears when at least one enclave fails to provide the description information.");
488 }
489 "E39" => {
490 eprintln!("Enclave process connection failure. Such error appears when the enclave manager fails to connect to at least one enclave process for retrieving the description information.");
491 }
492 "E40" => {
493 eprintln!("Socket path not found. Such error appears when the Nitro CLI process fails to build the corresponding socket path starting from a given enclave ID.");
494 }
495 "E41" => {
496 eprintln!("Enclave process send reply failure. Such error appears when the enclave process fails to submit the status code to the Nitro CLI process after performing a run / describe / terminate command.");
497 }
498 "E42" => {
499 eprintln!(
500 "Enclave mmap error. Such error appears when allocating the enclave memory fails."
501 );
502 }
503 "E43" => {
504 eprintln!(
505 "Enclave munmap error. Such error appears when unmapping the enclave memory fails."
506 );
507 }
508 "E44" => {
509 eprintln!("Enclave console connection failure. Such error appears when the Nitro CLI process fails to establish a connection to a running enclave's console.");
510 }
511 "E45" => {
512 eprintln!("Enclave console read error. Such error appears when reading from a running enclave's console fails.");
513 }
514 "E46" => {
515 eprintln!("Enclave console write output error. Such error appears when writing the information retrieved from a running enclave's console (to a given stream) fails.");
516 }
517 "E47" => {
518 eprintln!("Integer parsing error. Such error appears when trying to connect to a running enclave's console, but the enclave CID cannot be parsed correctly.");
519 }
520 "E48" => {
521 eprintln!("EIF building error. Such error appears when trying to build an EIF file. In this case, the error backtrace provides detailed information on the failure reason.");
522 }
523 "E49" => {
524 eprintln!("Docker image build error. Such error appears when trying to build and EIF file, but building the corresponding docker image fails. In this case, the error backtrace provides detailed information on the failure reason.");
525 }
526 "E50" => {
527 eprintln!("Docker image pull error. Such error appears when trying to build an EIF file, but pulling the corresponding docker image fails. In this case, the error backtrace provides detailed informatino on the failure reason.");
528 }
529 "E51" => {
530 eprintln!("Artifacts path environment variable not set. Such error appears when trying to build an EIF file, but the artifacts path environment variable is not set.");
531 }
532 "E52" => {
533 eprintln!("Blobs path environment variable not set. Such error appears when trying to build an EIF file, but the blobs path environment variable is not set.");
534 }
535 "E53" => {
536 eprintln!("Clock skew error. Such error appears when continuously reading from a running enclave's console, but measuring the time elapsed between consecutive reads failed.");
537 }
538 "E54" => {
539 eprintln!("Signal masking error. Such error appears if attempting to mask specific signals before creating an enclave process fails.");
540 }
541 "E55" => {
542 eprintln!("Signal unmasking error. Such error appears if attempting to unmask specific signals after creating an enclave process fails.");
543 }
544 "E56" => {
545 eprintln!("Logger error. Such error appears when attempting to initialize the underlying logging system fails.");
546 }
547 "E60" => {
548 eprintln!("Signing error. Such error appears if incorrect key or certificate paths are provided, or when AWS credenrials need to be refreshed to use a KMS key.");
549 }
550 _ => {
551 eprintln!("No such error code {error_code_str}");
552 }
553 }
554}
555
556#[cfg(test)]
557mod tests {
558 use super::NitroCliFailure;
559 use crate::common::document_errors::construct_backtrace;
560
561 #[test]
562 fn test_construct_backtrace() {
563 let failure = NitroCliFailure::new()
564 .set_action(String::from("ABCD"))
565 .add_subaction(String::from("EFGH"))
566 .add_subaction(String::from("IJKL"))
567 .set_file_and_line("/path/file.txt", 1234);
568 let expected = format!(" Action: ABCD\n Subactions:\n IJKL\n EFGH\n Root error file: /path/file.txt\n Root error line: 1234\n Version: {}",
576 env!("CARGO_PKG_VERSION"));
577 assert_eq!(expected, construct_backtrace(&failure));
578 }
579}