diff --git a/README.md b/README.md index 17e5c13..4a8c32f 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,28 @@ It can be used to simplify snapshot handling in an automated pipeline. ## Usage +### Credentials + +Coldsnap uses the same credential mechanisms as the `aws cli`. +For example, if you have credentials in `~/.aws/credentials`, these will be used. +You can specify the name of the profile to be used by adding `--profile profile-name`. + +You can also define environment variables, for example: + +``` +$ export AWS_ACCESS_KEY_ID=EXAMPLEAKIAIOSFODNN7 +$ export AWS_SECRET_ACCESS_KEY=EXAMPLEKEYwJalrXUtnFEMI/K7MDENG/bPxRfiCY +$ export AWS_DEFAULT_REGION=us-west-2 +``` + +If the name of a profile is provided, then it will be used. +If not, then the default behavior of the AWS Rust SDK credential provider will be used. +[Here] is the description of the default behavior. + +[Here]: https://docs.rs/aws-config/latest/aws_config/default_provider/credentials/struct.DefaultCredentialsChain.html + +### Upload + Upload a local file into an EBS snapshot: ``` @@ -26,6 +48,8 @@ Alternately, you can use `coldsnap wait`, which offers more flexibility in terms $ coldsnap wait snap-1234 ``` +### Download + Download an EBS snapshot into a local file: ``` diff --git a/src/download.rs b/src/download.rs index fc313c0..e16aabc 100644 --- a/src/download.rs +++ b/src/download.rs @@ -619,7 +619,7 @@ mod error { #[snafu(display("Missing temporary file"))] MissingTempFile {}, - #[snafu(display("Failed to list snapshot blocks '{}': {}", snapshot_id, source))] + #[snafu(display("Failed to list snapshot blocks '{snapshot_id}': {source}", source = crate::error_stack(source, 2)))] ListSnapshotBlocks { snapshot_id: String, source: aws_sdk_ebs::error::SdkError, diff --git a/src/lib.rs b/src/lib.rs index cdc5e82..80de95a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -69,3 +69,21 @@ pub use upload::SnapshotUploader; pub use wait::Error as WaitError; pub use wait::{SnapshotWaiter, WaitParams}; + +/// Errors from the AWS Rust SDK crate often swallow relevant information when they are printed +/// using `Display`. This leads to errors that do not have enough information for the user to know +/// what went wrong. This function `Display` prints an error and recursively adds up to n levels of +/// underlying errors to that printed message. +pub(crate) fn error_stack(e: &dyn std::error::Error, n: u16) -> String { + let mut current_error = e; + let mut s = format!("{}", e); + + for _ in 0..n { + current_error = match current_error.source() { + None => return s, + Some(next_error) => next_error, + }; + s += &format!(": {}", current_error) + } + s +} diff --git a/src/upload.rs b/src/upload.rs index 564eddd..d0a1946 100644 --- a/src/upload.rs +++ b/src/upload.rs @@ -470,7 +470,7 @@ mod error { source: std::io::Error, }, - #[snafu(display("Failed to start snapshot: {}", source))] + #[snafu(display("Failed to start snapshot: {source}", source = crate::error_stack(&source, 2)))] StartSnapshot { source: aws_sdk_ebs::error::SdkError, },