Unverified Commit 3499c11b authored by John DiSanti's avatar John DiSanti Committed by GitHub
Browse files

Fix Lambda bundle naming for the SDK canary (#2135)

* Add release tag and Rust version to canary bundle file name
  Update canary CDK dependencies
  Update Lambda name in logging permissions
parent 51915bed
Loading
Loading
Loading
Loading
+100 −5
Original line number Diff line number Diff line
@@ -74,6 +74,10 @@ pub struct BuildBundleArgs {
    #[clap(long)]
    pub canary_path: Option<PathBuf>,

    /// Rust version
    #[clap(long)]
    pub rust_version: Option<String>,

    /// SDK release tag to use for crate version numbers
    #[clap(
        long,
@@ -182,17 +186,42 @@ fn sha1_file(path: &Path) -> Result<String> {
    Ok(hex::encode(hasher.finalize()))
}

fn name_bundle(
    bin_path: &Path,
    rust_version: Option<&str>,
    sdk_release_tag: Option<&ReleaseTag>,
) -> Result<String> {
    name_hashed_bundle(&sha1_file(bin_path)?, rust_version, sdk_release_tag)
}

fn name_hashed_bundle(
    bin_hash: &str,
    rust_version: Option<&str>,
    sdk_release_tag: Option<&ReleaseTag>,
) -> Result<String> {
    // The Lambda name must be less than 64 characters, so truncate the hash a bit
    let bin_hash = &bin_hash[..24];
    // Lambda function names can't have periods in them
    let rust_version = rust_version.map(|s| s.replace('.', ""));
    let rust_version = rust_version.as_deref().unwrap_or("unknown");
    let sdk_release_tag = sdk_release_tag.map(|s| s.to_string().replace('-', ""));
    let sdk_release_tag = sdk_release_tag.as_deref().unwrap_or("untagged");
    Ok(format!(
        "canary-{sdk_release_tag}-{rust_version}-{bin_hash}.zip"
    ))
}

pub async fn build_bundle(opt: BuildBundleArgs) -> Result<Option<PathBuf>> {
    let canary_path = opt
        .canary_path
        .unwrap_or_else(|| std::env::current_dir().expect("current dir"));

    // Determine the SDK crate source from CLI args
    let crate_source = match (opt.sdk_path, opt.sdk_release_tag) {
    let crate_source = match (opt.sdk_path, &opt.sdk_release_tag) {
        (Some(sdk_path), None) => CrateSource::Path(sdk_path),
        (None, Some(release_tag)) => CrateSource::VersionsManifest {
            versions: VersionsManifest::from_github_tag(&release_tag).await?,
            release_tag,
            versions: VersionsManifest::from_github_tag(release_tag).await?,
            release_tag: release_tag.clone(),
        },
        _ => unreachable!("clap should have validated against this"),
    };
@@ -225,8 +254,11 @@ pub async fn build_bundle(opt: BuildBundleArgs) -> Result<Option<PathBuf>> {
            path.join("release")
        };
        let bin_path = target_path.join("bootstrap");
        let bin_hash = sha1_file(&bin_path)?;
        let bundle_path = target_path.join(format!("canary-lambda-{bin_hash}.zip"));
        let bundle_path = target_path.join(&name_bundle(
            &bin_path,
            opt.rust_version.as_deref(),
            opt.sdk_release_tag.as_ref(),
        )?);

        let zip_file = fs::File::create(&bundle_path).context(here!())?;
        let mut zip = zip::ZipWriter::new(zip_file);
@@ -280,6 +312,7 @@ mod tests {
        assert_eq!(
            Args::BuildBundle(BuildBundleArgs {
                canary_path: None,
                rust_version: None,
                sdk_release_tag: Some(ReleaseTag::from_str("release-2022-07-26").unwrap()),
                sdk_path: None,
                musl: false,
@@ -297,6 +330,7 @@ mod tests {
        assert_eq!(
            Args::BuildBundle(BuildBundleArgs {
                canary_path: Some("some-canary-path".into()),
                rust_version: None,
                sdk_release_tag: None,
                sdk_path: Some("some-sdk-path".into()),
                musl: false,
@@ -316,6 +350,7 @@ mod tests {
        assert_eq!(
            Args::BuildBundle(BuildBundleArgs {
                canary_path: None,
                rust_version: None,
                sdk_release_tag: Some(ReleaseTag::from_str("release-2022-07-26").unwrap()),
                sdk_path: None,
                musl: true,
@@ -332,6 +367,28 @@ mod tests {
            .ok()
            .expect("valid args")
        );
        assert_eq!(
            Args::BuildBundle(BuildBundleArgs {
                canary_path: Some("some-canary-path".into()),
                rust_version: Some("stable".into()),
                sdk_release_tag: None,
                sdk_path: Some("some-sdk-path".into()),
                musl: false,
                manifest_only: false,
            }),
            Args::try_parse_from([
                "./canary-runner",
                "build-bundle",
                "--rust-version",
                "stable",
                "--sdk-path",
                "some-sdk-path",
                "--canary-path",
                "some-canary-path"
            ])
            .ok()
            .expect("valid args")
        );
    }

    #[test]
@@ -462,4 +519,42 @@ default = ["v0.4.1"]
            .expect("success")
        );
    }

    #[test]
    fn test_name_hashed_bundle() {
        fn check(expected: &str, actual: &str) {
            assert!(
                expected.len() < 64,
                "Lambda function name must be less than 64 characters"
            );
            assert_eq!(expected, actual);
        }
        check(
            "canary-release20221216-1621-7ae6085d2105d5d1e13b10f8.zip",
            &name_hashed_bundle(
                "7ae6085d2105d5d1e13b10f882c6cb072ff5bbf8",
                Some("1.62.1"),
                Some(&ReleaseTag::from_str("release-2022-12-16").unwrap()),
            )
            .unwrap(),
        );
        check(
            "canary-untagged-1621-7ae6085d2105d5d1e13b10f8.zip",
            &name_hashed_bundle(
                "7ae6085d2105d5d1e13b10f882c6cb072ff5bbf8",
                Some("1.62.1"),
                None,
            )
            .unwrap(),
        );
        check(
            "canary-release20221216-unknown-7ae6085d2105d5d1e13b10f8.zip",
            &name_hashed_bundle(
                "7ae6085d2105d5d1e13b10f882c6cb072ff5bbf8",
                None,
                Some(&ReleaseTag::from_str("release-2022-12-16").unwrap()),
            )
            .unwrap(),
        );
    }
}
+2 −0
Original line number Diff line number Diff line
@@ -17,6 +17,8 @@ const KNOWN_YANKED_RELEASE_TAGS: &[&str] = &[
    "release-2022-07-04",
    // Add release tags here to get the canary passing after yanking a release
    "release-2022-10-13",
    "release-2022-12-15", // Failed release
    "release-2022-12-16", // Failed release
];

#[derive(Debug, Parser, Eq, PartialEq)]
+15 −4
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ use crate::build_bundle::BuildBundleArgs;
use aws_sdk_cloudwatch as cloudwatch;
use aws_sdk_lambda as lambda;
use aws_sdk_s3 as s3;

lazy_static::lazy_static! {
    // Occasionally, a breaking change introduced in smithy-rs will cause the canary to fail
    // for older versions of the SDK since the canary is in the smithy-rs repository and will
@@ -58,6 +59,10 @@ lazy_static::lazy_static! {

#[derive(Debug, Parser, Eq, PartialEq)]
pub struct RunArgs {
    /// Rust version
    #[clap(long)]
    pub rust_version: Option<String>,

    /// Version of the SDK to compile the canary against
    #[clap(
        long,
@@ -98,6 +103,7 @@ pub struct RunArgs {

#[derive(Debug)]
struct Options {
    rust_version: Option<String>,
    sdk_release_tag: Option<ReleaseTag>,
    sdk_path: Option<PathBuf>,
    musl: bool,
@@ -129,6 +135,7 @@ impl Options {
            )
            .context("read cdk output")?;
            Ok(Options {
                rust_version: run_opt.rust_version,
                sdk_release_tag: run_opt.sdk_release_tag,
                sdk_path: run_opt.sdk_path,
                musl: run_opt.musl,
@@ -138,6 +145,7 @@ impl Options {
            })
        } else {
            Ok(Options {
                rust_version: run_opt.rust_version,
                sdk_release_tag: run_opt.sdk_release_tag,
                sdk_path: run_opt.sdk_path,
                musl: run_opt.musl,
@@ -276,13 +284,16 @@ fn use_correct_revision(smithy_rs: &dyn Git, sdk_release_tag: &ReleaseTag) -> Re

/// Returns the path to the compiled bundle zip file
async fn build_bundle(options: &Options) -> Result<PathBuf> {
    Ok(crate::build_bundle::build_bundle(BuildBundleArgs {
    let build_args = BuildBundleArgs {
        canary_path: None,
        rust_version: options.rust_version.clone(),
        sdk_release_tag: options.sdk_release_tag.clone(),
        sdk_path: options.sdk_path.clone(),
        musl: options.musl,
        manifest_only: false,
    })
    };
    info!("Compiling the canary bundle for Lambda with {build_args:?}. This may take a few minutes...");
    Ok(crate::build_bundle::build_bundle(build_args)
        .await?
        .expect("manifest_only set to false, so there must be a bundle path"))
}
+1 −1
Original line number Diff line number Diff line
@@ -136,7 +136,7 @@ export class CanaryStack extends Stack {
            new PolicyStatement({
                actions: ["logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents"],
                effect: Effect.ALLOW,
                resources: ["arn:aws:logs:*:*:/aws/lambda/canary-lambda-*:*"],
                resources: ["arn:aws:logs:*:*:/aws/lambda/canary-*:*"],
            }),
        );

+1478 −1056

File changed.

Preview size limit exceeded, changes collapsed.