Skip to content

Conversation

@webern
Copy link
Contributor

@webern webern commented Apr 13, 2024

Issue number:

Closes #185

Description of changes:

For kit builds we are going to need to understand the dependency graph in buildsys build-kit. We may need it for other operations as well.

This PR changes buildsys so that it requires a cargo-metadata json file which is uses to understand the dependency graph and send the list of package dependencies and kit dependencies to the Dockerfile in build args.

This implementation requires that Twoliter projects be organized as in a single workspace with all packages, kits and variants in the same Cargo.toml (which feels like an improvement overall).

Testing done:

  • unit-testing on the in-tree test project local-kit
  • Build Bottlerocket (with changes to make it into one workspace): webern/bottlerocket@8933289...webern:bottlerocket:workspace
  • Build an AMI
  • Rebuild the image to check incremental compilation (only os , release and the variant should be rebuilt) - (aws-iam-authenticator was also rebuilt, but that doesn't seem show-stopping)

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.

@webern
Copy link
Contributor Author

webern commented May 1, 2024

@webern
Copy link
Contributor Author

webern commented May 2, 2024

@webern webern force-pushed the dep-walk branch 4 times, most recently from c128614 to 596002d Compare May 3, 2024 23:46
@webern
Copy link
Contributor Author

webern commented May 4, 2024

Current status: encountered during a Bottlerocket build at the filesystem package:

  --- stderr
  Unable to instantiate the builder: Failed to create build arguments due to a dependency error: Expected to find one of build-package, build-kit, or build-variant in package.metadata.

Turns out that Cargo.toml doesn't have build-package in it. I will fix it and continue on Monday

[package]
name = "filesystem"
version = "0.1.0"
edition = "2021"
publish = false
build = "../build.rs"

[lib]
path = "../packages.rs"

@webern
Copy link
Contributor Author

webern commented May 5, 2024

Over the weekend I made some changes to the Bottlerocket diff and the testing passed. This is ready for review.

@webern webern requested a review from bcressey May 5, 2024 22:03
@webern webern marked this pull request as ready for review May 5, 2024 22:04
@webern webern mentioned this pull request May 7, 2024
5 tasks
@webern
Copy link
Contributor Author

webern commented May 8, 2024

https://github.com/bottlerocket-os/twoliter/compare/596002d362144e6b941596234301c927ad38f061..e5ee4e19e43c322a92613c73fd1cfe7e8bf54d40

Improvement to the algorithm. For package build, for the top-level manifest, we should only consider build-dependencies. When lower in the tree/graph, we should consider both build-dependencies and dev-dependencies.

Comment on lines -11 to -14
included-packages = [
"pkg-b",
"pkg-d",
]
Copy link
Contributor

Choose a reason for hiding this comment

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

Are we not doing included-packages for kits any more?

It might be more natural to support an optional excluded-packages instead, if the default should be that all packages go into the kit.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

An included-packages would be sort of gnarly to implement since it would need to inform the graph algorithm. When we talked about it we were thinking we would just go with Cargo dependencies defining the package list. excluded-packages could be a feature add fairly easily if anyone ends up needing that.

Comment on lines +215 to +217
assert!(BuildFlags::Package.includes(PACKAGE | VARIANT));
assert!(BuildFlags::Variant.includes(VARIANT));
assert!(BuildFlags::Variant.includes(VARIANT | PACKAGE));
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we need kits to include the same build flags that packages do, except we should rebuild on a change to BUILDSYS_KITS_DIR vs BUILDSYS_PACKAGES_DIR.

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 think we need kits to include the same build flags that packages do, except we should rebuild on a change to BUILDSYS_KITS_DIR vs BUILDSYS_PACKAGES_DIR.

True! I'll get it in the next one when adding the build-kit command and getting it to work.

Comment on lines +519 to +529
/// Lists include the "top-level manifest", i.e. the thing that `buildsys` is being asked to build.
/// We do not want this, we want only a list of things that it depends on. Here we convert
/// `PackageMetadata` objects to the `String` name, and filter out the "top-level manifest".
fn filter_map_to_name(top_manifest_name: &str, pkg_metadata: &PackageMetadata) -> Option<String> {
if pkg_metadata.name() == top_manifest_name {
None
} else {
// Return the package override name, if it exists, or else the Cargo manifest name.
Some(get_buildsys_package_name(pkg_metadata))
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Are we guaranteed that the first entry in the traversal is the node we started from? Naively, that's what I would expect from a graph iterator. If so, we could just skip the first element from the iterator.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Are we guaranteed that the first entry in the traversal is the node we started from? Naively, that's what I would expect from a graph iterator. If so, we could just skip the first element from the iterator.

The documentation is silent on order of returned results. Seems safer and cheap to not make the assumption.

Comment on lines +336 to +338
// Sort so that this function has consistent, dependable output regardless of graph internals.
packages.sort();
Ok(packages)
Copy link
Contributor

Choose a reason for hiding this comment

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

Does this make a difference? Seems like we'd already be getting topologically-sorted output, which should be reasonable consistent. This final sort ends up throwing away the ordering information.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Does this make a difference? Seems like we'd already be getting topologically-sorted output, which should be reasonable consistent. This final sort ends up throwing away the ordering information.

The documentation is silent on order of returned results (though topo-sort seems likely). My most common interaction with this list is "is the package I care about in the list?", whereby alphabetical is more convenient.

@webern webern added the kits Work relating to kits. label May 13, 2024
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

#[arg(long, env = "BUILDSYS_ARCH")]
pub(crate) arch: SupportedArch,

#[arg(long, env = "BUILDSYS_CARGO_METADATA_PATH")]
Copy link
Contributor

Choose a reason for hiding this comment

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

does this need to be added to the rebuild vars?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

does this need to be added to the rebuild vars?

I think we're covered by the fact that the package/variant dirs are being watched for changes, and the cargo metadata output should be the same unless something has changed about those packages. In other words, I think if anything important changes, we will be rebuilding anyway.

For kit builds, Buildsys will need to understand the cargo dependency
graph. This requires a call to cargo metadata which, for efficiency
sake, we do only once before calling cargo build. This commit updates
Makefile.toml to provide that information to Buildsys.

Additionally, we want to have one workspace at the top-level of the
Twoliter project which includes all packages, kits and variants.
This commit also includes changes to the Makefile.toml to support a
single workspace.
@webern
Copy link
Contributor Author

webern commented May 13, 2024

@webern webern merged commit 958b544 into bottlerocket-os:develop May 13, 2024
@webern webern deleted the dep-walk branch May 13, 2024 23:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kits Work relating to kits.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

kits: implement recursive dependency search

4 participants