diff --git a/Cargo.lock b/Cargo.lock index 5d378531ba..c540d2a4b1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4922,7 +4922,6 @@ dependencies = [ "thiserror", "tokio", "toml 0.8.8", - "topological-sort", "walkdir", ] @@ -5189,9 +5188,9 @@ dependencies = [ [[package]] name = "omicron-zone-package" -version = "0.9.1" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "620c53207d39a385f298444337d575690e0d9e793561d471ba7a614dc213e372" +checksum = "cdfd257b7067e7a6aa9fba896a89b0f625bac7660213bb830db36e543bd3cdb8" dependencies = [ "anyhow", "async-trait", @@ -5210,6 +5209,7 @@ dependencies = [ "thiserror", "tokio", "toml 0.7.8", + "topological-sort", "walkdir", ] diff --git a/Cargo.toml b/Cargo.toml index 5cd13cc04b..29c29f9633 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -259,7 +259,7 @@ omicron-package = { path = "package" } omicron-rpaths = { path = "rpaths" } omicron-sled-agent = { path = "sled-agent" } omicron-test-utils = { path = "test-utils" } -omicron-zone-package = "0.9.1" +omicron-zone-package = "0.10.1" oxide-client = { path = "clients/oxide-client" } oxide-vpc = { git = "https://github.com/oxidecomputer/opte", rev = "4e6e6ab6379fa4bc40f5d0c7340b9f35c45ad6e4", features = [ "api", "std" ] } once_cell = "1.19.0" @@ -378,7 +378,6 @@ tokio-tungstenite = "0.20" tokio-util = { version = "0.7.10", features = ["io", "io-util"] } toml = "0.8.8" toml_edit = "0.21.0" -topological-sort = "0.2.2" tough = { version = "0.16.0", features = [ "http" ] } trust-dns-client = "0.22" trust-dns-proto = "0.22" diff --git a/package/Cargo.toml b/package/Cargo.toml index 6cc0e343db..0dc86ceb8c 100644 --- a/package/Cargo.toml +++ b/package/Cargo.toml @@ -30,7 +30,6 @@ tar.workspace = true thiserror.workspace = true tokio = { workspace = true, features = [ "full" ] } toml.workspace = true -topological-sort.workspace = true walkdir.workspace = true omicron-workspace-hack.workspace = true diff --git a/package/src/bin/omicron-package.rs b/package/src/bin/omicron-package.rs index 357a217fe5..59c5c6ffe6 100644 --- a/package/src/bin/omicron-package.rs +++ b/package/src/bin/omicron-package.rs @@ -145,6 +145,7 @@ async fn do_for_all_rust_packages( let (release_pkgs, debug_pkgs): (Vec<_>, _) = config .package_config .packages_to_build(&config.target) + .0 .into_iter() .filter_map(|(name, pkg)| match &pkg.source { PackageSource::Local { rust: Some(rust_pkg), .. } => { @@ -463,8 +464,6 @@ async fn get_package( } async fn do_package(config: &Config, output_directory: &Path) -> Result<()> { - use topological_sort::TopologicalSort; - create_dir_all(&output_directory) .map_err(|err| anyhow!("Cannot create output directory: {}", err))?; @@ -472,54 +471,12 @@ async fn do_package(config: &Config, output_directory: &Path) -> Result<()> { do_build(&config).await?; - let mut all_packages = config - .package_config - .packages_to_build(&config.target) - .into_iter() - .map(|(package_name, package)| { - (package.get_output_file(package_name), (package_name, package)) - }) - .collect::>(); - - let mut outputs = TopologicalSort::::new(); - for (package_output, (_, package)) in &all_packages { - match &package.source { - PackageSource::Local { .. } - | PackageSource::Prebuilt { .. } - | PackageSource::Manual => { - // Skip intermediate leaf packages; if necessary they'll be - // added to the dependency graph by whatever composite package - // actually depends on them. - if !matches!( - package.output, - PackageOutput::Zone { intermediate_only: true } - ) { - outputs.insert(package_output); - } - } - PackageSource::Composite { packages: deps } => { - for dep in deps { - outputs.add_dependency(dep, package_output); - } - } - } - } - - while !outputs.is_empty() { - let batch = outputs.pop_all(); - assert!( - !batch.is_empty() || outputs.is_empty(), - "cyclic dependency in package manifest!" - ); - - let packages = batch.into_iter().map(|output| { - all_packages - .remove(&output) - .expect("package should've already been handled.") - }); + let packages = config.package_config.packages_to_build(&config.target); - let ui_refs = vec![ui.clone(); packages.len()]; - let pkg_stream = stream::iter(packages) + let package_iter = packages.build_order(); + for batch in package_iter { + let ui_refs = vec![ui.clone(); batch.len()]; + let pkg_stream = stream::iter(batch) .zip(stream::iter(ui_refs)) .map(Ok::<_, anyhow::Error>) .try_for_each_concurrent( @@ -553,6 +510,7 @@ async fn do_stamp( let (_name, package) = config .package_config .packages_to_deploy(&config.target) + .0 .into_iter() .find(|(name, _pkg)| name.as_str() == package_name) .ok_or_else(|| anyhow!("Package {package_name} not found"))?; @@ -574,7 +532,7 @@ async fn do_unpack( })?; // Copy all packages to the install location in parallel. - let packages = config.package_config.packages_to_deploy(&config.target); + let packages = config.package_config.packages_to_deploy(&config.target).0; packages.par_iter().try_for_each( |(package_name, package)| -> Result<()> { @@ -704,6 +662,7 @@ fn uninstall_all_packages(config: &Config) { for (_, package) in config .package_config .packages_to_deploy(&config.target) + .0 .into_iter() .filter(|(_, package)| matches!(package.output, PackageOutput::Tarball)) {