diff --git a/.github/buildomat/jobs/deploy.sh b/.github/buildomat/jobs/deploy.sh index 5e43ff7f7c..c16d523b03 100755 --- a/.github/buildomat/jobs/deploy.sh +++ b/.github/buildomat/jobs/deploy.sh @@ -161,7 +161,7 @@ cd /opt/oxide/work ptime -m tar xvzf /input/package/work/package.tar.gz cp /input/package/work/zones/* out/ -mv out/omicron-nexus-single-sled.tar.gz out/omicron-nexus.tar.gz +mv out/nexus-single-sled.tar.gz out/nexus.tar.gz mkdir tests for p in /input/ci-tools/work/end-to-end-tests/*.gz; do ptime -m gunzip < "$p" > "tests/$(basename "${p%.gz}")" diff --git a/.github/buildomat/jobs/package.sh b/.github/buildomat/jobs/package.sh index 13f374779c..dc89bc787b 100755 --- a/.github/buildomat/jobs/package.sh +++ b/.github/buildomat/jobs/package.sh @@ -84,7 +84,7 @@ stamp_packages() { # Keep the single-sled Nexus zone around for the deploy job. (The global zone # build below overwrites the file.) -mv out/omicron-nexus.tar.gz out/omicron-nexus-single-sled.tar.gz +mv out/nexus.tar.gz out/nexus-single-sled.tar.gz # Build necessary for the global zone ptime -m cargo run --locked --release --bin omicron-package -- \ @@ -115,8 +115,8 @@ zones=( out/crucible-zone.tar.gz out/external-dns.tar.gz out/internal-dns.tar.gz - out/omicron-nexus.tar.gz - out/omicron-nexus-single-sled.tar.gz + out/nexus.tar.gz + out/nexus-single-sled.tar.gz out/oximeter.tar.gz out/propolis-server.tar.gz out/switch-*.tar.gz diff --git a/.github/buildomat/jobs/tuf-repo.sh b/.github/buildomat/jobs/tuf-repo.sh index 14c2293f5b..aca43422d9 100644 --- a/.github/buildomat/jobs/tuf-repo.sh +++ b/.github/buildomat/jobs/tuf-repo.sh @@ -93,7 +93,7 @@ target/release/omicron-package -t default target create -i standard -m gimlet -s ln -s /input/package/work/zones/* out/ rm out/switch-softnpu.tar.gz # not used when target switch=asic rm out/omicron-gateway-softnpu.tar.gz # not used when target switch=asic -rm out/omicron-nexus-single-sled.tar.gz # only used for deploy tests +rm out/nexus-single-sled.tar.gz # only used for deploy tests for zone in out/*.tar.gz; do target/release/omicron-package stamp "$(basename "${zone%.tar.gz}")" "$VERSION" done diff --git a/Cargo.lock b/Cargo.lock index 18c783037f..00a8fb0074 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1856,7 +1856,7 @@ dependencies = [ "dns-service-client", "dropshot", "expectorate", - "http 0.2.11", + "http 0.2.12", "omicron-test-utils", "omicron-workspace-hack", "openapi-lint", @@ -1889,7 +1889,7 @@ version = "0.1.0" dependencies = [ "anyhow", "chrono", - "http 0.2.11", + "http 0.2.12", "omicron-workspace-hack", "progenitor", "reqwest", @@ -1941,7 +1941,7 @@ dependencies = [ "anyhow", "chrono", "futures", - "http 0.2.11", + "http 0.2.12", "ipnetwork", "omicron-workspace-hack", "omicron-zone-package", @@ -1976,7 +1976,7 @@ dependencies = [ "form_urlencoded", "futures", "hostname", - "http 0.2.11", + "http 0.2.12", "hyper 0.14.27", "indexmap 2.2.5", "multer", @@ -1985,7 +1985,7 @@ dependencies = [ "percent-encoding", "proc-macro2", "rustls 0.22.2", - "rustls-pemfile 2.1.0", + "rustls-pemfile 2.1.1", "schemars", "serde", "serde_json", @@ -2158,7 +2158,7 @@ dependencies = [ "async-trait", "base64", "chrono", - "http 0.2.11", + "http 0.2.12", "hyper 0.14.27", "omicron-sled-agent", "omicron-test-utils", @@ -2812,7 +2812,7 @@ dependencies = [ "futures-core", "futures-sink", "futures-util", - "http 0.2.11", + "http 0.2.12", "indexmap 2.2.5", "slab", "tokio", @@ -2882,7 +2882,7 @@ dependencies = [ "base64", "bytes", "headers-core", - "http 0.2.11", + "http 0.2.12", "httpdate", "mime", "sha1", @@ -2894,7 +2894,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" dependencies = [ - "http 0.2.11", + "http 0.2.12", ] [[package]] @@ -3011,9 +3011,9 @@ dependencies = [ [[package]] name = "http" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" dependencies = [ "bytes", "fnv", @@ -3038,7 +3038,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" dependencies = [ "bytes", - "http 0.2.11", + "http 0.2.12", "pin-project-lite", ] @@ -3081,7 +3081,7 @@ dependencies = [ "crossbeam-channel", "form_urlencoded", "futures", - "http 0.2.11", + "http 0.2.12", "hyper 0.14.27", "log", "once_cell", @@ -3168,7 +3168,7 @@ dependencies = [ "futures-core", "futures-util", "h2", - "http 0.2.11", + "http 0.2.12", "http-body 0.4.5", "httparse", "httpdate", @@ -3206,7 +3206,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" dependencies = [ "futures-util", - "http 0.2.11", + "http 0.2.12", "hyper 0.14.27", "rustls 0.21.9", "tokio", @@ -3239,7 +3239,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "318ca89e4827e7fe4ddd2824f52337239796ae8ecc761a663324407dc3d8d7e7" dependencies = [ "futures-util", - "http 0.2.11", + "http 0.2.12", "http-range", "httpdate", "hyper 0.14.27", @@ -3469,7 +3469,7 @@ dependencies = [ "futures", "hex", "hex-literal", - "http 0.2.11", + "http 0.2.12", "illumos-utils", "installinator-artifact-client", "installinator-common", @@ -4364,7 +4364,7 @@ dependencies = [ "futures", "gateway-client", "headers", - "http 0.2.11", + "http 0.2.12", "hyper 0.14.27", "hyper-rustls 0.26.0", "illumos-utils", @@ -4555,7 +4555,7 @@ dependencies = [ "gateway-messages", "gateway-test-utils", "headers", - "http 0.2.11", + "http 0.2.12", "hyper 0.14.27", "internal-dns", "nexus-config", @@ -4907,7 +4907,7 @@ dependencies = [ "expectorate", "futures", "hex", - "http 0.2.11", + "http 0.2.12", "ipnetwork", "libc", "macaddr", @@ -4984,7 +4984,7 @@ dependencies = [ "gateway-sp-comms", "gateway-test-utils", "hex", - "http 0.2.11", + "http 0.2.12", "hyper 0.14.27", "illumos-utils", "ipcc", @@ -5044,7 +5044,7 @@ dependencies = [ "gateway-test-utils", "headers", "hex", - "http 0.2.11", + "http 0.2.12", "httptest", "hubtools", "hyper 0.14.27", @@ -5099,7 +5099,7 @@ dependencies = [ "reqwest", "ring 0.17.8", "rustls 0.22.2", - "rustls-pemfile 2.1.0", + "rustls-pemfile 2.1.1", "samael", "schemars", "semver 1.0.22", @@ -5273,7 +5273,7 @@ dependencies = [ "glob", "guppy", "hex", - "http 0.2.11", + "http 0.2.12", "hyper 0.14.27", "hyper-staticfile", "illumos-utils", @@ -5347,7 +5347,7 @@ dependencies = [ "filetime", "headers", "hex", - "http 0.2.11", + "http 0.2.12", "libc", "nexus-config", "omicron-common", @@ -5698,7 +5698,7 @@ dependencies = [ "base64", "chrono", "futures", - "http 0.2.11", + "http 0.2.12", "hyper 0.14.27", "omicron-workspace-hack", "progenitor", @@ -5855,7 +5855,7 @@ dependencies = [ "chrono", "dropshot", "futures", - "http 0.2.11", + "http 0.2.12", "kstat-rs", "omicron-workspace-hack", "oximeter", @@ -6599,7 +6599,7 @@ source = "git+https://github.com/oxidecomputer/progenitor?branch=main#08bbafc251 dependencies = [ "getopts", "heck 0.4.1", - "http 0.2.11", + "http 0.2.12", "indexmap 2.2.5", "openapiv3", "proc-macro2", @@ -7094,7 +7094,7 @@ dependencies = [ "futures-core", "futures-util", "h2", - "http 0.2.11", + "http 0.2.12", "http-body 0.4.5", "hyper 0.14.27", "hyper-rustls 0.24.2", @@ -7449,7 +7449,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f1fb85efa936c42c6d5fc28d2629bb51e4b2f4b8a5211e297d599cc5a093792" dependencies = [ "openssl-probe", - "rustls-pemfile 2.1.0", + "rustls-pemfile 2.1.1", "rustls-pki-types", "schannel", "security-framework", @@ -7466,9 +7466,9 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c333bb734fcdedcea57de1602543590f545f127dc8b533324318fd492c5c70b" +checksum = "f48172685e6ff52a556baa527774f61fcaa884f59daf3375c62a3f1cd2549dab" dependencies = [ "base64", "rustls-pki-types", @@ -9675,7 +9675,7 @@ dependencies = [ "byteorder", "bytes", "data-encoding", - "http 0.2.11", + "http 0.2.12", "httparse", "log", "rand 0.8.5", @@ -10401,7 +10401,7 @@ dependencies = [ "gateway-messages", "gateway-test-utils", "hex", - "http 0.2.11", + "http 0.2.12", "hubtools", "hyper 0.14.27", "illumos-utils", diff --git a/Cargo.toml b/Cargo.toml index 474739a932..534c33e713 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -225,7 +225,7 @@ hex = "0.4.3" hex-literal = "0.4.1" highway = "1.1.0" hkdf = "0.12.4" -http = "0.2.11" +http = "0.2.12" httptest = "0.15.5" hubtools = { git = "https://github.com/oxidecomputer/hubtools.git", branch = "main" } humantime = "2.1.0" @@ -336,7 +336,7 @@ rpassword = "7.3.1" rstest = "0.18.2" rustfmt-wrapper = "0.2" rustls = "0.22.2" -rustls-pemfile = "2.1.0" +rustls-pemfile = "2.1.1" rustyline = "13.0.0" samael = { version = "0.0.14", features = ["xmlsec"] } schemars = "0.8.16" diff --git a/illumos-utils/src/running_zone.rs b/illumos-utils/src/running_zone.rs index d86a27e3f7..02302347cd 100644 --- a/illumos-utils/src/running_zone.rs +++ b/illumos-utils/src/running_zone.rs @@ -404,7 +404,7 @@ impl RunningZone { /// Returns the filesystem path to the zone's root in the GZ. pub fn root(&self) -> Utf8PathBuf { - self.inner.zonepath.join(Self::ROOT_FS_PATH) + self.inner.root() } pub fn control_interface(&self) -> AddrObject { @@ -1094,6 +1094,9 @@ pub struct InstalledZone { } impl InstalledZone { + /// The path to the zone's root filesystem (i.e., `/`), within zonepath. + pub const ROOT_FS_PATH: &'static str = "root"; + /// Returns the name of a zone, based on the base zone name plus any unique /// identifying info. /// @@ -1135,6 +1138,11 @@ impl InstalledZone { pub fn opte_ports(&self) -> impl Iterator { self.opte_ports.iter().map(|(port, _)| port) } + + /// Returns the filesystem path to the zone's root in the GZ. + pub fn root(&self) -> Utf8PathBuf { + self.zonepath.join(Self::ROOT_FS_PATH) + } } #[derive(Clone)] diff --git a/nexus/db-queries/src/db/datastore/deployment.rs b/nexus/db-queries/src/db/datastore/deployment.rs index 020916928d..a00318c9dc 100644 --- a/nexus/db-queries/src/db/datastore/deployment.rs +++ b/nexus/db-queries/src/db/datastore/deployment.rs @@ -1349,6 +1349,7 @@ mod tests { // different DNS version to test that that works. let new_dns_version = blueprint1.internal_dns_version.next(); let mut builder = BlueprintBuilder::new_based_on( + &logctx.log, &blueprint1, new_dns_version, &policy, @@ -1500,6 +1501,7 @@ mod tests { ) .unwrap(); let blueprint2 = BlueprintBuilder::new_based_on( + &logctx.log, &blueprint1, Generation::new(), &EMPTY_POLICY, @@ -1508,6 +1510,7 @@ mod tests { .expect("failed to create builder") .build(); let blueprint3 = BlueprintBuilder::new_based_on( + &logctx.log, &blueprint1, Generation::new(), &EMPTY_POLICY, @@ -1604,6 +1607,7 @@ mod tests { // Create a child of blueprint3, and ensure when we set it as the target // with enabled=false, that status is serialized. let blueprint4 = BlueprintBuilder::new_based_on( + &logctx.log, &blueprint3, Generation::new(), &EMPTY_POLICY, diff --git a/nexus/reconfigurator/planning/src/blueprint_builder.rs b/nexus/reconfigurator/planning/src/blueprint_builder.rs index d58d798770..ebb64c36f9 100644 --- a/nexus/reconfigurator/planning/src/blueprint_builder.rs +++ b/nexus/reconfigurator/planning/src/blueprint_builder.rs @@ -35,6 +35,8 @@ use omicron_common::api::external::Generation; use omicron_common::api::external::IpNet; use omicron_common::api::external::MacAddr; use omicron_common::api::external::Vni; +use slog::o; +use slog::Logger; use std::collections::BTreeMap; use std::collections::BTreeSet; use std::collections::HashSet; @@ -98,6 +100,9 @@ pub enum EnsureMultiple { /// However, the new blueprint can only be made the system's target if its /// parent is the current target. pub struct BlueprintBuilder<'a> { + #[allow(dead_code)] + log: Logger, + /// previous blueprint, on which this one will be based parent_blueprint: &'a Blueprint, internal_dns_version: Generation, @@ -186,11 +191,17 @@ impl<'a> BlueprintBuilder<'a> { /// Construct a new `BlueprintBuilder` based on a previous blueprint, /// starting with no changes from that state pub fn new_based_on( + log: &Logger, parent_blueprint: &'a Blueprint, internal_dns_version: Generation, policy: &'a Policy, creator: &str, ) -> anyhow::Result> { + let log = log.new(o!( + "component" => "BlueprintBuilder", + "parent_id" => parent_blueprint.id.to_string(), + )); + // Scan through the parent blueprint and build several sets of "used // resources". When adding new control plane zones to a sled, we may // need to allocate new resources to that zone. However, allocation at @@ -287,6 +298,7 @@ impl<'a> BlueprintBuilder<'a> { ); Ok(BlueprintBuilder { + log, parent_blueprint, internal_dns_version, policy, @@ -731,6 +743,7 @@ pub mod test { use omicron_common::address::Ipv6Subnet; use omicron_common::address::SLED_PREFIX; use omicron_common::api::external::ByteCount; + use omicron_test_utils::dev::test_setup_log; use sled_agent_client::types::{ Baseboard, Inventory, OmicronZoneConfig, OmicronZoneDataset, OmicronZoneType, OmicronZonesConfig, SledRole, @@ -945,6 +958,7 @@ pub mod test { fn test_initial() { // Test creating a blueprint from a collection and verifying that it // describes no changes. + let logctx = test_setup_log("blueprint_builder_test_initial"); let (collection, policy) = example(DEFAULT_N_SLEDS); let blueprint_initial = BlueprintBuilder::build_initial_from_collection( @@ -971,6 +985,7 @@ pub mod test { // Test a no-op blueprint. let builder = BlueprintBuilder::new_based_on( + &logctx.log, &blueprint_initial, Generation::new(), &policy, @@ -987,10 +1002,13 @@ pub mod test { assert_eq!(diff.sleds_added().count(), 0); assert_eq!(diff.sleds_removed().count(), 0); assert_eq!(diff.sleds_changed().count(), 0); + + logctx.cleanup_successful(); } #[test] fn test_basic() { + let logctx = test_setup_log("blueprint_builder_test_basic"); let (collection, mut policy) = example(DEFAULT_N_SLEDS); let blueprint1 = BlueprintBuilder::build_initial_from_collection( &collection, @@ -1002,6 +1020,7 @@ pub mod test { verify_blueprint(&blueprint1); let mut builder = BlueprintBuilder::new_based_on( + &logctx.log, &blueprint1, Generation::new(), &policy, @@ -1036,6 +1055,7 @@ pub mod test { let new_sled_id = Uuid::new_v4(); let _ = policy_add_sled(&mut policy, new_sled_id); let mut builder = BlueprintBuilder::new_based_on( + &logctx.log, &blueprint2, Generation::new(), &policy, @@ -1106,10 +1126,15 @@ pub mod test { }) .collect::>(); assert_eq!(crucible_pool_names, new_sled_resources.zpools); + + logctx.cleanup_successful(); } #[test] fn test_add_nexus_with_no_existing_nexus_zones() { + let logctx = test_setup_log( + "blueprint_builder_test_add_nexus_with_no_existing_nexus_zones", + ); let (mut collection, policy) = example(DEFAULT_N_SLEDS); // We don't care about the internal DNS version here. @@ -1134,6 +1159,7 @@ pub mod test { .expect("failed to create initial blueprint"); let mut builder = BlueprintBuilder::new_based_on( + &logctx.log, &parent, internal_dns_version, &policy, @@ -1157,10 +1183,14 @@ pub mod test { matches!(err, Error::NoNexusZonesInParentBlueprint), "unexpected error {err}" ); + + logctx.cleanup_successful(); } #[test] fn test_add_nexus_error_cases() { + let logctx = + test_setup_log("blueprint_builder_test_add_nexus_error_cases"); let (mut collection, policy) = example(DEFAULT_N_SLEDS); // We don't care about the internal DNS version here. @@ -1196,6 +1226,7 @@ pub mod test { // Attempting to add Nexus to the sled we removed it from (with no // other changes to the environment) should succeed. let mut builder = BlueprintBuilder::new_based_on( + &logctx.log, &parent, internal_dns_version, &policy, @@ -1214,6 +1245,7 @@ pub mod test { // from (with no other changes to the environment) should also // succeed. let mut builder = BlueprintBuilder::new_based_on( + &logctx.log, &parent, internal_dns_version, &policy, @@ -1246,6 +1278,7 @@ pub mod test { policy.service_ip_pool_ranges = used_ip_ranges; let mut builder = BlueprintBuilder::new_based_on( + &logctx.log, &parent, internal_dns_version, &policy, @@ -1269,10 +1302,16 @@ pub mod test { // `NEXUS_OPTE_*_SUBNET`. We could hack around that by creating the // `BlueprintBuilder` and mucking with its internals, but that doesn't // seem like a particularly useful test either. + + logctx.cleanup_successful(); } #[test] fn test_invalid_parent_blueprint_two_zones_with_same_external_ip() { + let logctx = test_setup_log( + "blueprint_builder_test_invalid_parent_blueprint_\ + two_zones_with_same_external_ip", + ); let (mut collection, policy) = example(DEFAULT_N_SLEDS); // We should fail if the parent blueprint claims to contain two @@ -1309,6 +1348,7 @@ pub mod test { .unwrap(); match BlueprintBuilder::new_based_on( + &logctx.log, &parent, Generation::new(), &policy, @@ -1320,10 +1360,16 @@ pub mod test { "unexpected error: {err:#}" ), }; + + logctx.cleanup_successful(); } #[test] fn test_invalid_parent_blueprint_two_nexus_zones_with_same_nic_ip() { + let logctx = test_setup_log( + "blueprint_builder_test_invalid_parent_blueprint_\ + two_nexus_zones_with_same_nic_ip", + ); let (mut collection, policy) = example(DEFAULT_N_SLEDS); // We should fail if the parent blueprint claims to contain two @@ -1358,6 +1404,7 @@ pub mod test { .unwrap(); match BlueprintBuilder::new_based_on( + &logctx.log, &parent, Generation::new(), &policy, @@ -1369,10 +1416,16 @@ pub mod test { "unexpected error: {err:#}" ), }; + + logctx.cleanup_successful(); } #[test] fn test_invalid_parent_blueprint_two_zones_with_same_vnic_mac() { + let logctx = test_setup_log( + "blueprint_builder_test_invalid_parent_blueprint_\ + two_zones_with_same_vnic_mac", + ); let (mut collection, policy) = example(DEFAULT_N_SLEDS); // We should fail if the parent blueprint claims to contain two @@ -1407,6 +1460,7 @@ pub mod test { .unwrap(); match BlueprintBuilder::new_based_on( + &logctx.log, &parent, Generation::new(), &policy, @@ -1418,5 +1472,7 @@ pub mod test { "unexpected error: {err:#}" ), }; + + logctx.cleanup_successful(); } } diff --git a/nexus/reconfigurator/planning/src/planner.rs b/nexus/reconfigurator/planning/src/planner.rs index 0773fec2bf..9f4b653507 100644 --- a/nexus/reconfigurator/planning/src/planner.rs +++ b/nexus/reconfigurator/planning/src/planner.rs @@ -48,6 +48,7 @@ impl<'a> Planner<'a> { inventory: &'a Collection, ) -> anyhow::Result> { let blueprint = BlueprintBuilder::new_based_on( + &log, parent_blueprint, internal_dns_version, policy, diff --git a/package-manifest.toml b/package-manifest.toml index f858338f86..c6f39d2ecd 100644 --- a/package-manifest.toml +++ b/package-manifest.toml @@ -97,9 +97,21 @@ source.paths = [ output.type = "zone" output.intermediate_only = true -[package.omicron-nexus] +[package.nexus] service_name = "nexus" only_for_targets.image = "standard" +source.type = "composite" +source.packages = [ + "omicron-nexus.tar.gz", + "zone-network-setup.tar.gz", + "zone-network-install.tar.gz", + "opte-interface-setup.tar.gz" +] +output.type = "zone" + +[package.omicron-nexus] +service_name = "omicron-nexus" +only_for_targets.image = "standard" source.type = "local" source.rust.binary_names = ["nexus", "schema-updater"] source.rust.release = true @@ -115,6 +127,7 @@ setup_hint = """ - Run `./tools/ci_download_console` to download the web console assets - Run `pkg install library/postgresql-13` to download Postgres libraries """ +output.intermediate_only = true [package.oximeter] service_name = "oximeter" @@ -502,7 +515,7 @@ source.repo = "maghemite" # `tools/maghemite_openapi_version`. Failing to do so will cause a failure when # building `ddm-admin-client` (which will instruct you to update # `tools/maghemite_openapi_version`). -source.commit = "4b0e584eec455a43c36af08ae207086965cef833" +source.commit = "ee0896f5cf9ba0799f155dd8c95f6e1dabaf80ba" # The SHA256 digest is automatically posted to: # https://buildomat.eng.oxide.computer/public/file/oxidecomputer/maghemite/image//maghemite.sha256.txt source.sha256 = "f1407cb9aac188d6493d2b0f948c75aad2c36668ddf4ae2a1ed80e9dd395b35d" @@ -518,7 +531,7 @@ source.repo = "maghemite" # `tools/maghemite_openapi_version`. Failing to do so will cause a failure when # building `ddm-admin-client` (which will instruct you to update # `tools/maghemite_openapi_version`). -source.commit = "4b0e584eec455a43c36af08ae207086965cef833" +source.commit = "ee0896f5cf9ba0799f155dd8c95f6e1dabaf80ba" # The SHA256 digest is automatically posted to: # https://buildomat.eng.oxide.computer/public/file/oxidecomputer/maghemite/image//mg-ddm.sha256.txt source.sha256 = "fae53cb39536dc92d97cb9610de65b0acbce285e685d7167b719ea6311844fec" @@ -533,10 +546,10 @@ source.repo = "maghemite" # `tools/maghemite_openapi_version`. Failing to do so will cause a failure when # building `ddm-admin-client` (which will instruct you to update # `tools/maghemite_openapi_version`). -source.commit = "4b0e584eec455a43c36af08ae207086965cef833" +source.commit = "ee0896f5cf9ba0799f155dd8c95f6e1dabaf80ba" # The SHA256 digest is automatically posted to: # https://buildomat.eng.oxide.computer/public/file/oxidecomputer/maghemite/image//mg-ddm.sha256.txt -source.sha256 = "22996a6f3353296b848be729f14e78a42e7d3d6e62a4a918a5c2358ae011c8eb" +source.sha256 = "151aeb26414989cad571b3886786efbeeafd91c41a93a747c784cdc654d5876d" output.type = "zone" output.intermediate_only = true diff --git a/sled-agent/src/services.rs b/sled-agent/src/services.rs index 0338c37bfd..4adcb77774 100644 --- a/sled-agent/src/services.rs +++ b/sled-agent/src/services.rs @@ -2118,6 +2118,153 @@ impl ServiceManager { })?; return Ok(RunningZone::boot(installed_zone).await?); } + ZoneArgs::Omicron(OmicronZoneConfigLocal { + zone: + OmicronZoneConfig { + zone_type: + OmicronZoneType::Nexus { + internal_address, + external_tls, + external_dns_servers, + .. + }, + underlay_address, + id, + }, + .. + }) => { + let Some(info) = self.inner.sled_info.get() else { + return Err(Error::SledAgentNotReady); + }; + + let static_addr = underlay_address.to_string(); + + let nw_setup_service = Self::zone_network_setup_install( + &info, + &installed_zone, + &static_addr.clone(), + )?; + + // While Nexus will be reachable via `external_ip`, it + // communicates atop an OPTE port which operates on a + // VPC private IP. OPTE will map the private IP to the + // external IP automatically. + let opte_interface_setup = + Self::opte_interface_set_up_install(&installed_zone)?; + + let port_idx = 0; + let port = installed_zone + .opte_ports() + .nth(port_idx) + .ok_or_else(|| { + Error::ZoneEnsureAddress( + EnsureAddressError::MissingOptePort { + zone: String::from(installed_zone.name()), + port_idx, + }, + ) + })?; + let opte_ip = port.ip(); + + // Nexus takes a separate config file for parameters + // which cannot be known at packaging time. + let nexus_port = if *external_tls { 443 } else { 80 }; + let deployment_config = DeploymentConfig { + id: *id, + rack_id: info.rack_id, + techport_external_server_port: NEXUS_TECHPORT_EXTERNAL_PORT, + + dropshot_external: ConfigDropshotWithTls { + tls: *external_tls, + dropshot: dropshot::ConfigDropshot { + bind_address: SocketAddr::new(*opte_ip, nexus_port), + // This has to be large enough to support: + // - bulk writes to disks + request_body_max_bytes: 8192 * 1024, + default_handler_task_mode: + HandlerTaskMode::Detached, + }, + }, + dropshot_internal: dropshot::ConfigDropshot { + bind_address: (*internal_address).into(), + // This has to be large enough to support, among + // other things, the initial list of TLS + // certificates provided by the customer during + // rack setup. + request_body_max_bytes: 10 * 1024 * 1024, + default_handler_task_mode: HandlerTaskMode::Detached, + }, + internal_dns: nexus_config::InternalDns::FromSubnet { + subnet: Ipv6Subnet::::new( + info.underlay_address, + ), + }, + database: nexus_config::Database::FromDns, + external_dns_servers: external_dns_servers.clone(), + }; + + // Copy the partial config file to the expected + // location. + let config_dir = Utf8PathBuf::from(format!( + "{}/var/svc/manifest/site/nexus", + installed_zone.root() + )); + // The filename of a half-completed config, in need of + // parameters supplied at runtime. + const PARTIAL_LEDGER_FILENAME: &str = "config-partial.toml"; + // The filename of a completed config, merging the + // partial config with additional appended parameters + // known at runtime. + const COMPLETE_LEDGER_FILENAME: &str = "config.toml"; + let partial_config_path = + config_dir.join(PARTIAL_LEDGER_FILENAME); + let config_path = config_dir.join(COMPLETE_LEDGER_FILENAME); + tokio::fs::copy(partial_config_path, &config_path) + .await + .map_err(|err| Error::io_path(&config_path, err))?; + + // Serialize the configuration and append it into the + // file. + let serialized_cfg = toml::Value::try_from(&deployment_config) + .expect("Cannot serialize config"); + let mut map = toml::map::Map::new(); + map.insert("deployment".to_string(), serialized_cfg); + let config_str = toml::to_string(&map).map_err(|err| { + Error::TomlSerialize { path: config_path.clone(), err } + })?; + let mut file = tokio::fs::OpenOptions::new() + .append(true) + .open(&config_path) + .await + .map_err(|err| Error::io_path(&config_path, err))?; + file.write_all(b"\n\n") + .await + .map_err(|err| Error::io_path(&config_path, err))?; + file.write_all(config_str.as_bytes()) + .await + .map_err(|err| Error::io_path(&config_path, err))?; + + let nexus_config = PropertyGroupBuilder::new("config"); + let nexus_service = ServiceBuilder::new("oxide/nexus") + .add_instance( + ServiceInstanceBuilder::new("default") + .add_property_group(nexus_config), + ); + + let profile = ProfileBuilder::new("omicron") + .add_service(nw_setup_service) + .add_service(opte_interface_setup) + .add_service(disabled_ssh_service) + .add_service(nexus_service) + .add_service(disabled_dns_client_service); + profile + .add_to_zone(&self.inner.log, &installed_zone) + .await + .map_err(|err| { + Error::io("Failed to setup Nexus profile", err) + })?; + return Ok(RunningZone::boot(installed_zone).await?); + } _ => {} } @@ -2235,129 +2382,7 @@ impl ServiceManager { match &request { ZoneArgs::Omicron(zone_config) => { - // TODO: Related to - // https://github.com/oxidecomputer/omicron/pull/1124 , should we - // avoid importing this manifest? - debug!(self.inner.log, "importing manifest"); - - let smfh = - SmfHelper::new(&running_zone, &zone_config.zone.zone_type); - smfh.import_manifest()?; - match &zone_config.zone.zone_type { - OmicronZoneType::Nexus { - internal_address, - external_tls, - external_dns_servers, - .. - } => { - info!(self.inner.log, "Setting up Nexus service"); - - let sled_info = self - .inner - .sled_info - .get() - .ok_or(Error::SledAgentNotReady)?; - - // While Nexus will be reachable via `external_ip`, it - // communicates atop an OPTE port which operates on a - // VPC private IP. OPTE will map the private IP to the - // external IP automatically. - let port_ip = running_zone - .ensure_address_for_port("public", 0) - .await? - .ip(); - - // Nexus takes a separate config file for parameters - // which cannot be known at packaging time. - let nexus_port = if *external_tls { 443 } else { 80 }; - let deployment_config = DeploymentConfig { - id: zone_config.zone.id, - rack_id: sled_info.rack_id, - techport_external_server_port: - NEXUS_TECHPORT_EXTERNAL_PORT, - - dropshot_external: ConfigDropshotWithTls { - tls: *external_tls, - dropshot: dropshot::ConfigDropshot { - bind_address: SocketAddr::new( - port_ip, nexus_port, - ), - // This has to be large enough to support: - // - bulk writes to disks - request_body_max_bytes: 8192 * 1024, - default_handler_task_mode: - HandlerTaskMode::Detached, - }, - }, - dropshot_internal: dropshot::ConfigDropshot { - bind_address: (*internal_address).into(), - // This has to be large enough to support, among - // other things, the initial list of TLS - // certificates provided by the customer during - // rack setup. - request_body_max_bytes: 10 * 1024 * 1024, - default_handler_task_mode: - HandlerTaskMode::Detached, - }, - internal_dns: - nexus_config::InternalDns::FromSubnet { - subnet: Ipv6Subnet::::new( - sled_info.underlay_address, - ), - }, - database: nexus_config::Database::FromDns, - external_dns_servers: external_dns_servers.clone(), - }; - - // Copy the partial config file to the expected - // location. - let config_dir = Utf8PathBuf::from(format!( - "{}/var/svc/manifest/site/nexus", - running_zone.root() - )); - // The filename of a half-completed config, in need of - // parameters supplied at runtime. - const PARTIAL_LEDGER_FILENAME: &str = - "config-partial.toml"; - // The filename of a completed config, merging the - // partial config with additional appended parameters - // known at runtime. - const COMPLETE_LEDGER_FILENAME: &str = "config.toml"; - let partial_config_path = - config_dir.join(PARTIAL_LEDGER_FILENAME); - let config_path = - config_dir.join(COMPLETE_LEDGER_FILENAME); - tokio::fs::copy(partial_config_path, &config_path) - .await - .map_err(|err| Error::io_path(&config_path, err))?; - - // Serialize the configuration and append it into the - // file. - let serialized_cfg = - toml::Value::try_from(&deployment_config) - .expect("Cannot serialize config"); - let mut map = toml::map::Map::new(); - map.insert("deployment".to_string(), serialized_cfg); - let config_str = - toml::to_string(&map).map_err(|err| { - Error::TomlSerialize { - path: config_path.clone(), - err, - } - })?; - let mut file = tokio::fs::OpenOptions::new() - .append(true) - .open(&config_path) - .await - .map_err(|err| Error::io_path(&config_path, err))?; - file.write_all(b"\n\n") - .await - .map_err(|err| Error::io_path(&config_path, err))?; - file.write_all(config_str.as_bytes()) - .await - .map_err(|err| Error::io_path(&config_path, err))?; - } OmicronZoneType::BoundaryNtp { .. } | OmicronZoneType::Clickhouse { .. } | OmicronZoneType::ClickhouseKeeper { .. } @@ -2367,6 +2392,7 @@ impl ServiceManager { | OmicronZoneType::ExternalDns { .. } | OmicronZoneType::InternalDns { .. } | OmicronZoneType::InternalNtp { .. } + | OmicronZoneType::Nexus { .. } | OmicronZoneType::Oximeter { .. } => { panic!( "{} is a service which exists as part of a \ @@ -2375,9 +2401,6 @@ impl ServiceManager { ) } }; - - debug!(self.inner.log, "enabling service"); - smfh.enable()?; } ZoneArgs::Switch(request) => { for service in &request.zone.services { diff --git a/smf/nexus/manifest.xml b/smf/nexus/manifest.xml index 5a72df8a22..7f1a3e76ff 100644 --- a/smf/nexus/manifest.xml +++ b/smf/nexus/manifest.xml @@ -4,28 +4,41 @@ - + + + + + + + + + + + + diff --git a/tools/maghemite_ddm_openapi_version b/tools/maghemite_ddm_openapi_version index d161091fa8..14ff749506 100644 --- a/tools/maghemite_ddm_openapi_version +++ b/tools/maghemite_ddm_openapi_version @@ -1,2 +1,2 @@ -COMMIT="4b0e584eec455a43c36af08ae207086965cef833" +COMMIT="ee0896f5cf9ba0799f155dd8c95f6e1dabaf80ba" SHA2="0b0dbc2f8bbc5d2d9be92d64c4865f8f9335355aae62f7de9f67f81dfb3f1803" diff --git a/tools/maghemite_mg_openapi_version b/tools/maghemite_mg_openapi_version index 475d273f4a..a2becb4efc 100644 --- a/tools/maghemite_mg_openapi_version +++ b/tools/maghemite_mg_openapi_version @@ -1,2 +1,2 @@ -COMMIT="4b0e584eec455a43c36af08ae207086965cef833" +COMMIT="ee0896f5cf9ba0799f155dd8c95f6e1dabaf80ba" SHA2="0ac038bbaa54d0ae0ac5ccaeff48f03070618372cca26c9d09b716b909bf9355" diff --git a/tools/maghemite_mgd_checksums b/tools/maghemite_mgd_checksums index ab84fafc01..2f58a88808 100644 --- a/tools/maghemite_mgd_checksums +++ b/tools/maghemite_mgd_checksums @@ -1,2 +1,2 @@ -CIDL_SHA256="22996a6f3353296b848be729f14e78a42e7d3d6e62a4a918a5c2358ae011c8eb" +CIDL_SHA256="151aeb26414989cad571b3886786efbeeafd91c41a93a747c784cdc654d5876d" MGD_LINUX_SHA256="943b0a52d279bde55a419e2cdb24873acc32703bc97bd599376117ee0edc1511" \ No newline at end of file diff --git a/tufaceous/README.adoc b/tufaceous/README.adoc index 973a37aa90..86e4cfc4e5 100644 --- a/tufaceous/README.adoc +++ b/tufaceous/README.adoc @@ -31,6 +31,6 @@ tuftool [-r PATH/TO/REPO] add-zone [--name NAME] ZONE_TAR_GZ VERSION Example: ---- -$ tuftool add-zone out/omicron-nexus.tar.gz 0.0.0 -added zone omicron-nexus, version 0.0.0 +$ tuftool add-zone out/nexus.tar.gz 0.0.0 +added zone nexus, version 0.0.0 ---- diff --git a/tufaceous/tests/integration-tests/command_tests.rs b/tufaceous/tests/integration-tests/command_tests.rs index 72c3a1a13a..20c6a06d66 100644 --- a/tufaceous/tests/integration-tests/command_tests.rs +++ b/tufaceous/tests/integration-tests/command_tests.rs @@ -25,7 +25,7 @@ async fn test_init_and_add() -> Result<()> { cmd.assert().success(); // Create a couple of stub files on disk. - let nexus_path = tempdir.path().join("omicron-nexus.tar.gz"); + let nexus_path = tempdir.path().join("nexus.tar.gz"); fs_err::write(&nexus_path, "test")?; let unknown_path = tempdir.path().join("my-unknown-kind.tar.gz"); fs_err::write(&unknown_path, "unknown test")?; @@ -65,7 +65,7 @@ async fn test_init_and_add() -> Result<()> { let mut artifacts_iter = artifacts.artifacts.into_iter(); let artifact = artifacts_iter.next().unwrap(); - assert_eq!(artifact.name, "omicron-nexus", "artifact name"); + assert_eq!(artifact.name, "nexus", "artifact name"); assert_eq!(artifact.version, "42.0.0".parse().unwrap(), "artifact version"); assert_eq!( artifact.kind, @@ -73,7 +73,7 @@ async fn test_init_and_add() -> Result<()> { "artifact kind" ); assert_eq!( - artifact.target, "gimlet_sp-omicron-nexus-42.0.0.tar.gz", + artifact.target, "gimlet_sp-nexus-42.0.0.tar.gz", "artifact target" );