Skip to content

Conversation

@piyush-jena
Copy link
Contributor

@piyush-jena piyush-jena commented Nov 26, 2025

Description of changes:
Add check-advisories task

How it works?
We implement a advisory-checker rust crate that takes 2 arguments - The rpmspec file and advisories directory. The binary is called during build by the upper level build.Dockerfile. Since, its already in the sdk context and the rpm macros are loaded, we can use rpmspec and rpm --eval macros to extract package name and versions. We deserialize the advisory files to extract the expected version and then compare using rpm.vercmp to evaluate if we are in a newer version.

Testing done:
Cropping output for brevity.

Testing it on bottlerocket-core-kit. I introduced 2 errors to test different cases. I created a sub-package BRSA with wrong epoch which got flagged. A different package with wrong version also got flagged.

[fedora@ip-172-31-57-102 bottlerocket-core-kit]$ PACKAGE="amazon-ssm-agent" make twoliter build-package
Found Twoliter v0.13.0 installed.
Skipping installation.
[2025-12-11T22:26:32Z INFO  twoliter::project::lock] Resolving project references to check against lock file
[2025-12-11T22:26:32Z INFO  twoliter::project::lock::image] Resolving dependency image dependency 
 **********************************************
[cargo-make] INFO - Running Task: validate-kits
[cargo-make] INFO - Running Task: build-package
   Compiling amazon-ssm-agent v0.1.0 (/home/fedora/Repositories/myrepos/bottlerocket-core-kit/packages/amazon-ssm-agent)
error: failed to run custom build command for `amazon-ssm-agent v0.1.0 (/home/fedora/Repositories/myrepos/bottlerocket-core-kit/packages/amazon-ssm-agent)`
***********************************************
  #11 [rpmbuild 5/7] RUN --mount=source=advisories,target=/home/builder/advisories     --mount=target=/host     /host/build/tools/advisory-checker --spec-file rpmbuild/SPECS/amazon-ssm-agent.spec --advisories-dir /home/builder/advisories/
  #11 0.337 Error: 1 Advisory violations found.
  #11 0.337 
  #11 0.337 Advisory violations found: 
  #11 0.337  BRSA ID: BRSA-hc1ikaaaqfgw
  #11 0.337  package name: amazon-ssm-agent-plugin
  #11 0.337  package version: 0:3.3.3185.0
  #11 0.337  min expected version: 1:3.3.2746.0
  #11 ERROR: process "/bin/sh -c /host/build/tools/advisory-checker --spec-file rpmbuild/SPECS/${PACKAGE}.spec --advisories-dir /home/builder/advisories/" did not complete successfully: exit code: 1
  ------
   > [rpmbuild 5/7] RUN --mount=source=advisories,target=/home/builder/advisories     --mount=target=/host     /host/build/tools/advisory-checker --spec-file rpmbuild/SPECS/amazon-ssm-agent.spec --advisories-dir /home/builder/advisories/:
  0.337 Error: 1 Advisory violations found.
  0.337 
  0.337 Advisory violations found: 
  0.337  BRSA ID: BRSA-hc1ikaaaqfgw
  0.337  package name: amazon-ssm-agent-plugin
  0.337  package version: 0:3.3.3185.0
  0.337  min expected version: 1:3.3.2746.0
 **********************************************
  --- stderr
  Failed to execute command: 'docker build /home/fedora/Repositories/myrepos/bottlerocket-core-kit --target package --tag buildsys-pkg-iputils-x86_64-d06f4eb4ccb3 --network host --file /home/fedora/Repositories/myrepos/bottlerocket-core-kit/build/tools/build.Dockerfile --no-cache-filter rpmbuild,kitbuild,repobuild,imgbuild,migrationbuild,kmodkitbuild,imgrepack --build-arg BYPASS_SOCKET=buildsys-pkg-iputils-x86_64-d06f4eb4ccb3-bypass --build-arg BUILDER_UID=1000 --build-arg KIT_DEPENDENCIES= --build-arg EXTERNAL_KIT_DEPENDENCIES= --build-arg PACKAGE=iputils --build-arg PACKAGE_DEPENDENCIES=glibc libattr libcap --build-arg BUILD_ID=9b3a8b3a-dirty --build-arg BUILD_ID_TIMESTAMP=1764962845 --build-arg ARCH=x86_64 --build-arg GOARCH=amd64 --build-arg SDK=public.ecr.aws/bottlerocket/bottlerocket-sdk:v0.65.1 --build-arg NOCACHE=257869799141623177217469531688013417160 --build-arg TOKEN=d06f4eb4ccb3 --build-arg OUTPUT_SOCKET=buildsys-output-d06f4eb4ccb3-257869799141623177217469531688013417160 --build-arg BUILDKIT_DOCKERFILE_CHECK=skip=InvalidDefaultArgInFrom,SecretsUsedInArgOrEnv'
Error while executing command, exit code: 101
Error: Command was unsuccessful, exit code 105
make: *** [Makefile:65: twoliter] Error 1

Testing it on bottlerocket-kernel-kit.

[fedora@ip-172-31-57-102 bottlerocket-kernel-kit]$ make ARCH=x86_64
 **********************************************
[cargo-make] INFO - Running Task: validate-kits
[cargo-make] INFO - Running Task: build-kit
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.04s
[cargo-make] INFO - Build Done in 0.83 seconds.

Terms of contribution:

By submitting this pull request, I agree that this contribution is dual-licensed under the terms of both the Apache License, version 2.0, and the MIT license.

@piyush-jena piyush-jena force-pushed the check-advisories branch 5 times, most recently from ba9f677 to 1eb07a3 Compare December 1, 2025 20:46
Copy link
Contributor

@jmt-lab jmt-lab left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@piyush-jena piyush-jena force-pushed the check-advisories branch 5 times, most recently from ed9e89a to 9b86a6b Compare December 4, 2025 00:25
@piyush-jena
Copy link
Contributor Author

Fixed some of the comments above.

@piyush-jena piyush-jena force-pushed the check-advisories branch 3 times, most recently from 34db683 to a78f0ec Compare December 4, 2025 03:18
@piyush-jena
Copy link
Contributor Author

Resolved all comments.

@piyush-jena piyush-jena force-pushed the check-advisories branch 3 times, most recently from 6179367 to 8a85572 Compare December 4, 2025 19:28
Copy link
Contributor

@cbgbt cbgbt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had to fix the advisories in the earlier versions because they didn't have patched-epoch field. We can plan on either defaulting to 0 here or add those fields in the advisories.

Zero as a default should be OK. RPM treats unspecified as 0.

I noticed that bottlerocket-core-kit/advisories/2.1.0/BRSA-1j0o73qa.toml has an odd patched version:

patched-version = "kernel-5.15.160-104.158.amzn2"

I suppose this just shows up as a warning? What should happen here?

@piyush-jena
Copy link
Contributor Author

piyush-jena commented Dec 5, 2025

I had to fix the advisories in the earlier versions because they didn't have patched-epoch field. We can plan on either defaulting to 0 here or add those fields in the advisories.

Zero as a default should be OK. RPM treats unspecified as 0.

I noticed that bottlerocket-core-kit/advisories/2.1.0/BRSA-1j0o73qa.toml has an odd patched version:

patched-version = "kernel-5.15.160-104.158.amzn2"

I suppose this just shows up as a warning? What should happen here?

@cbgbt

  1. Yeah I used default so that I don't have to fix the old advisories.

  2. Because the corresponding package is not present, we just emit a warning like this

Checking advisory: advisories/2.1.0/BRSA-1j0o73qa.toml
  WARNING: Package kernel-5.15 could not be found.

@piyush-jena piyush-jena force-pushed the check-advisories branch 3 times, most recently from 8d45429 to f064191 Compare December 5, 2025 09:25
@piyush-jena
Copy link
Contributor Author

Fixed all comments.

@piyush-jena piyush-jena force-pushed the check-advisories branch 2 times, most recently from e24be77 to d3f188d Compare December 5, 2025 10:02
@piyush-jena piyush-jena force-pushed the check-advisories branch 4 times, most recently from 0d1536d to 5ef22a5 Compare December 11, 2025 22:28
Copy link
Contributor

@cbgbt cbgbt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we still need changes to Makefile.toml to ensure that these get run during a kit build? Maybe I missed it, but I'm not seeing how this gets invoked.

@piyush-jena
Copy link
Contributor Author

@cbgbt

Do we still need changes to Makefile.toml to ensure that these get run during a kit build? Maybe I missed it, but I'm not seeing how this gets invoked.

This runs as part of the make twoliter build-package so we don't need to make any changes. A bad advisory would show up as build failure with error messages like shown above in the Description.

Comment on lines 111 to 113
RUN --mount=source=advisories,target=/home/builder/advisories \
--mount=target=/host \
/host/build/tools/advisory-checker rpmbuild/SPECS/${PACKAGE}.spec /home/builder/advisories/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better to run this before the package build.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I placed it before the rpmbuild but after we put the sources and macros in the right place. Should I move this before that and add the line for copying macros into this?

@piyush-jena piyush-jena force-pushed the check-advisories branch 3 times, most recently from dc3a561 to 8802745 Compare December 17, 2025 02:02
@piyush-jena piyush-jena force-pushed the check-advisories branch 2 times, most recently from 0e976b4 to ebf88db Compare December 19, 2025 08:20
@piyush-jena
Copy link
Contributor Author

rebased ^

@piyush-jena piyush-jena force-pushed the check-advisories branch 5 times, most recently from 83241ec to 7592ad1 Compare December 19, 2025 09:46
assert!(output.status.success());
let stdout = String::from_utf8_lossy(&output.stdout);

let output_pattern = r"Advisories directory .* not found, skipping";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm glad that this behavior is documented but it has me wondering if we need to consider how to protect against cases where we accidentally point the checker at the wrong directory. Should the script fail if the directory doesn't exist? That seems like maybe a choice that would reduce the chance of making a mistake.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was the behaviour I implemented initially but switched to this because of this comment - #604 (comment). There may be kit users who get rid of the advisories directory and we don't want to break the build for them.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if the "right way" is to make it so that we don't invoke the tool when there are no advisories present, but the invocation of the tool implies the presence of advisories.

parse_rpm_metadata(pkg_prefix, output)
}

fn parse_rpm_metadata(pkg_prefix: String, output: String) -> Result<HashMap<String, String>> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function does some kind of string processing, but it's actually hard to tell just by looking at the function signature what. At the very least, it needs a docstring.

The "Rust way" would lean more heavily on using a composite type instead of a HashMap though -- You could alter the return type to be Result<HashMap<PackageName, EVR>> where PackageName and EVR were newtypes or type aliases. Alternatively you could return Result<PackageVersionManifest> or some kind of composite type that documented what was being processed.

With the existing code "parse_rpm_metadata" could mean any kind of information from the RPM, and the function signature doesn't really tell you what. The only way to know what the code is doing is to read all of it.

Signed-off-by: Piyush Jena <jepiyush@amazon.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants