From d1122c8ce2f108a7abfd74d4ad6d2cc57e77406b Mon Sep 17 00:00:00 2001 From: John Gallagher Date: Thu, 18 Dec 2025 14:49:23 -0500 Subject: [PATCH 1/7] first draft of not-as-painful sled config ledger versioning --- Cargo.lock | 1 + Cargo.toml | 1 + oximeter/db/Cargo.toml | 2 +- sled-agent/config-reconciler/Cargo.toml | 1 + sled-agent/config-reconciler/src/ledger.rs | 29 +- .../src/ledger/legacy_configs.rs | 449 +++++++----------- .../inventory.rs | 18 + .../inventory.rs | 18 + .../types/versions/src/impls/inventory.rs | 14 - 9 files changed, 228 insertions(+), 305 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f9fc092188d..64723e94866 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -12969,6 +12969,7 @@ version = "0.1.0" dependencies = [ "anyhow", "assert_matches", + "async-recursion", "async-trait", "bytes", "camino", diff --git a/Cargo.toml b/Cargo.toml index ef463c10878..be41892696a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -382,6 +382,7 @@ approx = "0.5.1" assert_matches = "1.5.0" assert_cmd = "2.0.17" async-bb8-diesel = "0.2" +async-recursion = "1.1.1" async-trait = "0.1.89" attest-mock = { git = "https://github.com/oxidecomputer/dice-util", rev = "10952e8d9599b735b85d480af3560a11700e5b64" } atomicwrites = "0.4.4" diff --git a/oximeter/db/Cargo.toml b/oximeter/db/Cargo.toml index 8bb185195ba..986eb4167be 100644 --- a/oximeter/db/Cargo.toml +++ b/oximeter/db/Cargo.toml @@ -10,7 +10,7 @@ workspace = true [dependencies] anyhow.workspace = true -async-recursion = "1.1.1" +async-recursion.workspace = true async-trait.workspace = true bcs.workspace = true camino.workspace = true diff --git a/sled-agent/config-reconciler/Cargo.toml b/sled-agent/config-reconciler/Cargo.toml index d66d9cfcef2..0c628a83989 100644 --- a/sled-agent/config-reconciler/Cargo.toml +++ b/sled-agent/config-reconciler/Cargo.toml @@ -9,6 +9,7 @@ workspace = true [dependencies] anyhow.workspace = true +async-recursion.workspace = true async-trait.workspace = true bytes.workspace = true camino.workspace = true diff --git a/sled-agent/config-reconciler/src/ledger.rs b/sled-agent/config-reconciler/src/ledger.rs index f47e7d01081..a520401fe0d 100644 --- a/sled-agent/config-reconciler/src/ledger.rs +++ b/sled-agent/config-reconciler/src/ledger.rs @@ -6,7 +6,6 @@ use camino::Utf8PathBuf; use dropshot::HttpError; -use legacy_configs::convert_legacy_ledgers; use omicron_common::api::external::Generation; use omicron_common::ledger; use omicron_common::ledger::Ledger; @@ -30,7 +29,7 @@ use tufaceous_artifact::ArtifactHash; use crate::InternalDisksReceiver; use crate::SledAgentArtifactStore; -use crate::ledger::legacy_configs::try_convert_v4_sled_config; +use crate::ledger::legacy_configs::try_convert_old_ledgered_config_versions; mod legacy_configs; @@ -644,28 +643,22 @@ async fn load_sled_config( return CurrentSledConfig::Ledgered(Box::new(config.into_inner())); } - // If we have no ledgered config, see if we can convert from the previous - // version of the format. - if let Some(config) = try_convert_v4_sled_config(log, paths).await { + // If we can't successfully read a ledgered config, see if we can convert + // from one of the previous versions of the format. + if let Some(config) = + try_convert_old_ledgered_config_versions(log, paths).await + { info!( log, - "Ledger of sled config exists, but it was formatted as \ - version 6, with single-stack NICs. It has been rewritten \ - to the current version", + "Ledger of sled config exists, but it was formatted as a previous \ + version. It has been rewritten to the current version", ); return CurrentSledConfig::Ledgered(Box::new(config)); } - // If we have no ledgered config, see if we can convert from the even - // more-previous triple of legacy ledgers. - if let Some(config) = convert_legacy_ledgers(&config_datasets, log).await { - info!(log, "Converted legacy triple of ledgers into new sled config"); - return CurrentSledConfig::Ledgered(Box::new(config)); - } - - // We have no ledger and didn't find legacy ledgers to convert; we must be - // waiting for RSS (if we're pre-rack-setup) or for Nexus to send us a - // config (if we're a sled being added to an existing rack). + // We have no ledger; we must be waiting for RSS (if we're pre-rack-setup) + // or for Nexus to send us a config (if we're a sled being added to an + // existing rack). info!(log, "No sled config ledger exists"); CurrentSledConfig::WaitingForInitialConfig } diff --git a/sled-agent/config-reconciler/src/ledger/legacy_configs.rs b/sled-agent/config-reconciler/src/ledger/legacy_configs.rs index e6f348e6f02..b9ab0ec0d32 100644 --- a/sled-agent/config-reconciler/src/ledger/legacy_configs.rs +++ b/sled-agent/config-reconciler/src/ledger/legacy_configs.rs @@ -5,345 +5,250 @@ //! Module for converting older formats of the sled configuration files. use camino::Utf8PathBuf; -use omicron_common::api::external::Generation; -use omicron_common::disk::DatasetsConfig; -use omicron_common::disk::OmicronPhysicalDisksConfig; +use omicron_common::api::external; use omicron_common::ledger::Ledger; use omicron_common::ledger::Ledgerable; use serde::Deserialize; use serde::Serialize; -use sled_agent_types::inventory::HostPhase2DesiredSlots; use sled_agent_types::inventory::OmicronSledConfig; -use sled_agent_types_versions::v4::inventory::OmicronSledConfig as OmicronSledConfigV4; -use sled_agent_types_versions::v4::inventory::OmicronZoneConfig as OmicronZoneConfigV4; -use sled_agent_types_versions::v10::inventory::OmicronSledConfig as OmicronSledConfigV10; +use sled_agent_types_versions::v4; +use sled_agent_types_versions::v10; use slog::Logger; -use slog::error; +use slog::info; use slog::warn; use slog_error_chain::InlineErrorChain; +use std::error::Error as StdError; -use super::CONFIG_LEDGER_FILENAME; +/// Trait describing an ordered sequence of `OmicronSledConfig` versions, each +/// of which can be converted from its previous version. +/// +/// When adding a new [`OmicronSledConfig`] version, do the following: +/// +/// 1. Implement [`VersionConversionChain`] for your new version. Its associated +/// `Previous` type should point to the prior version (what was the current +/// version before your change). +/// 2. Update the [`CurrentMinusOneSledConfigVersion`] type alias; this points +/// to the first version that [`try_convert_old_ledgered_config_versions`] +/// will attempt to read. +trait VersionConversionChain: Ledgerable { + /// A description of the version. This shows up in logs. + const DESCRIPTION: &str; + + /// Special terminal state; this must be `false` for all implementors except + /// [`VersionConversionChainTerminal`]. + /// [`try_convert_old_ledgered_config_versions_chain()] uses this to know + /// when to stop recursing. + const IS_TERMINAL: bool = false; + + /// The previous [`OmicronSledConfig`] version, which must be convertible + /// into this version. + type Previous: VersionConversionChain + TryInto; +} + +type CurrentMinusOneSledConfigVersion = v10::inventory::OmicronSledConfig; + +impl VersionConversionChain for v10::inventory::OmicronSledConfig { + const DESCRIPTION: &str = "v10::inventory::OmicronSledConfig"; -const LEGACY_DISKS_LEDGER_FILENAME: &str = "omicron-physical-disks.json"; -const LEGACY_DATASETS_LEDGER_FILENAME: &str = "omicron-datasets.json"; -const LEGACY_ZONES_LEDGER_FILENAME: &str = "omicron-zones.json"; + type Previous = OmicronSledConfigLocal; +} + +impl VersionConversionChain for OmicronSledConfigLocal { + const DESCRIPTION: &str = "OmicronSledConfigLocal"; -/// Convert from version 4 of the sled-configuration to the current, if -/// possible. The later version includes dual-stack private IP configuration in -/// our internal network interface types. + type Previous = VersionConversionChainTerminal; +} + +/// Convert from an earlier version of the sled configuration to the current, if +/// possible. /// /// # Panics /// -/// This panics if the conversion fails. That might happen if we somehow -/// serialized a NIC with an IPv4 address, but on an IPv6 subnet. That should -/// not be possible, but we have no way of recovering into the current format if -/// we do encounter that. Returning `None` is not correct, since that would +/// This panics if we're able to read a config (of any known older version) but +/// fail to convert it to the latest version. Most sled config conversions are +/// infallible, but occasionally we have fallible ones that only fail if we've +/// done something that ought to be impossible; e.g., in the dual-stack +/// networking work, there's a fallible conversion if we somehow +/// serialized a NIC with an IPv4 address, but on an IPv6 subnet. In such a +/// situation, we have no way of converting to the current format, which means +/// we have no way to proceed. Returning `None` is not correct, since that would /// incorrectly indicate that we have no config at all. We _must_ panic and rely /// on support correcting this (believed-to-be-impossible) situation. -pub(super) async fn try_convert_v4_sled_config( +pub(super) async fn try_convert_old_ledgered_config_versions( log: &Logger, datasets: Vec, ) -> Option { - let old = - Ledger::::new(log, datasets.clone()).await?; - let new_config = OmicronSledConfigV10::try_from(old.into_inner().0).unwrap_or_else(|e| { - panic!( - "Failed to convert OmicronSledConfigV4 to OmicronSledConfigV10: {e}" - ) - }); - let new_config = new_config.try_into().unwrap_or_else(|e| { + // Try to read the config as the previous version; if we have an older + // version on disk, this will recurse until we get to it, but then convert + // it up throw `CurrentMinusOneSledConfigVersion` before returning. + let prev_version = try_convert_old_ledgered_config_versions_chain::< + CurrentMinusOneSledConfigVersion, + >(log, datasets.clone()) + .await?; + + let current_version = prev_version.try_into().unwrap_or_else(|e| { panic!( - "Failed to convert OmicronSledConfigV10 to the current version: {e}" - ) + "failed to convert {} to the current version: {}", + CurrentMinusOneSledConfigVersion::DESCRIPTION, + InlineErrorChain::new(&e) + ); }); - write_converted_ledger( - log, - datasets, - new_config, - LegacyKind::SingleStackNic, - ) - .await + + Some(write_converted_ledger(log, datasets, current_version).await) } -/// Convert the legacy triple of sled config files (disks, datasets, and zones) -/// into the current unified [`OmicronSledConfig`]. -pub(super) async fn convert_legacy_ledgers( - config_datasets: &[Utf8PathBuf], +/// Reading old ledgers from disk in the face of multiple version changes is +/// tricky. Imagine we have this sequence in the versioning change: +/// +/// * v4 (the oldest supported version) +/// * v10 +/// * v11 +/// * v12 (current) +/// +/// Our caller must have already attempted to read the ledgered disk as v12 and +/// failed, if it's trying to convert from an old version. To support the prior +/// three versions, we must: +/// +/// * Attempt to read the ledger as v11. If that succeeds, convert it to v12 and +/// we're done. +/// * If that failed, attempt to read the ledger as v10. If that succeeds, +/// convert it to v11 then v12 and we're done. +/// * If that failed, attempt to read the ledger as v4. If that succeeds, +/// convert it to v10 then v11 then v12 and we're done. +/// +/// This method handles that process by recursing. In this example, we start +/// with `T` being the v11 sled config type. We'll try to read the ledger; if +/// that succeeds, we return it (and our caller will convert to v12). If that +/// fails, we'll recurse and call ourselves with `T::Previous` (i.e., v10). If +/// v10 returns successfully (after possibly recursing itself!), we'll convert +/// v10 to v11 and return to our caller. +/// +/// The recursion depth here is capped at the number of versions we support, +/// which we should be able to keep managable. Technically we can drop any +/// versions older than what was "current" as of the previously shipped release +/// (since we forbid updates from skipping releases). For extra paranoia, we can +/// keep versions covering the oldest deployed rack around. +#[async_recursion::async_recursion] +async fn try_convert_old_ledgered_config_versions_chain( log: &Logger, -) -> Option { - let disk_paths = config_datasets - .iter() - .map(|p| p.join(LEGACY_DISKS_LEDGER_FILENAME)) - .collect::>(); - let dataset_paths = config_datasets - .iter() - .map(|p| p.join(LEGACY_DATASETS_LEDGER_FILENAME)) - .collect::>(); - let zone_paths = config_datasets - .iter() - .map(|p| p.join(LEGACY_ZONES_LEDGER_FILENAME)) - .collect::>(); - - let loaded_ledgers = futures::join!( - Ledger::::new(log, disk_paths.clone()), - Ledger::::new(log, dataset_paths.clone()), - Ledger::::new(log, zone_paths.clone()), - ); + datasets: Vec, +) -> Option +where + T: VersionConversionChain, +{ + if T::IS_TERMINAL { + return None; + } - let (disks, datasets, zones) = match loaded_ledgers { - // If we have all three, proceed below to our conversion. - (Some(disks), Some(datasets), Some(zones)) => { - (disks.into_inner(), datasets.into_inner(), zones.into_inner()) - } + if let Some(config) = Ledger::::new(log, datasets.clone()).await { + return Some(config.into_inner()); + } - // If none of them exist, we have no conversion to do. - (None, None, None) => return None, - - // Any other combo is terrible: we have one or two legacy ledgers, but - // are missing the other two or one. This should only be possible if we - // were interrupted mid-rack-setup, which already requires - // clean-slate'ing (which should remove these config files!). Panic if - // we hit this case: it is not safe to continue with sled-agent startup - // if we are partially configured. - (disks, datasets, zones) => { - error!( - log, - "Found partial legacy ledgers; unsafe to proceed"; - "found-legacy-disks" => disks.is_some(), - "legacy-disk-paths" => ?disk_paths, - "found-legacy-datasets" => datasets.is_some(), - "legacy-dataset-paths" => ?dataset_paths, - "found-legacy-zones" => zones.is_some(), - "legacy-zone-paths" => ?zone_paths, - ); - panic!( - "Found partial legacy ledgers; unsafe to proceed (\ - found-legacy-disks: {}, \ - legacy-disk-paths: {disk_paths:?}, \ - found-legacy-datasets: {}, \ - legacy-dataset-paths: {dataset_paths:?}, \ - found-legacy-zones: {}, \ - legacy-zone-paths: {zone_paths:?} \ - )", - disks.is_some(), - datasets.is_some(), - zones.is_some(), - ); - } - }; - - // Perform the actual merge; this is infallible. - let sled_config = merge_old_configs(disks, datasets, zones); - - // At this point, we've converted from the old, 3-config world into the - // 1-config world, but we've also converted into an older version of the - // configuration type itself. The 3-file format predates support for - // dual-stack network interfaces. - // - // Convert the merged configuration into this new format, and write that out - // instead. This conversion _is_ fallible. Unfortunately, if it fails, - // there's nothing we can do. That conversion is determinstic, so doing it - // again won't change the result. - let sled_config = OmicronSledConfigV10::try_from(sled_config) - .unwrap_or_else(|e| panic!( - "Failed to convert OmicronSledConfigV4 to OmicronSledConfigV10: {e}" - )); - let sled_config = OmicronSledConfig::try_from(sled_config) - .unwrap_or_else(|e| panic!( - "Failed to convert OmicronSledConfigV10 to the current version: {e}" - )); - - // Write the newly-merged config to disk. - let new_config_paths = config_datasets - .iter() - .map(|p| p.join(CONFIG_LEDGER_FILENAME)) - .collect::>(); - let new_ledger = write_converted_ledger( - log, - new_config_paths, - sled_config, - LegacyKind::ThreeLedgerFormat, - ) + let old_config = try_convert_old_ledgered_config_versions_chain::< + T::Previous, + >(log, datasets) .await?; - // We've successfully written and reread our new combined config; remove the - // old legacy ledgers. - for old_ledger_path in - disk_paths.iter().chain(dataset_paths.iter()).chain(zone_paths.iter()) - { - if let Err(err) = tokio::fs::remove_file(old_ledger_path).await { - // There isn't really anything we can do other than warn here; - // future attempts to read the ledger will find the combined config - // we wrote above, so we'll just leak the legacy configs here and - // rely on support procedures to confirm we don't hit this during - // the transition period. - warn!( - log, - "Failed to remove legacy ledger"; - "path" => %old_ledger_path, + info!( + log, + "Successfully read ledgered config as old version {}; \ + will now convert to latest version", + T::DESCRIPTION, + ); + + match old_config.try_into() { + Ok(config) => Some(config), + Err(err) => { + panic!( + "failed to convert legered config \ + of version {} to version {}: {}", + T::Previous::DESCRIPTION, + T::DESCRIPTION, InlineErrorChain::new(&err), ); } } - - Some(new_ledger) -} - -#[derive(Debug)] -enum LegacyKind { - ThreeLedgerFormat, - SingleStackNic, } async fn write_converted_ledger( log: &Logger, paths: Vec, sled_config: OmicronSledConfig, - kind: LegacyKind, -) -> Option { +) -> OmicronSledConfig { let mut config_ledger = Ledger::new_with(log, paths.clone(), sled_config); match config_ledger.commit().await { Ok(()) => (), Err(err) => { // We weren't able to write the new ledger, but we were still able - // to _read_ it (via the old ones). Log this failure but return the - // config we read; we'll try converting again the next time we run. + // to _read_ it (via converting an old version). Log this failure + // but return the config we read; we'll try converting again the + // next time we run. warn!( log, - "Failed to write new sled config ledger built \ - from legacy ledgers"; - "legacy_kind" => ?kind, + "Failed to write new sled config converted from \ + from older version"; InlineErrorChain::new(&err), ); - return Some(config_ledger.into_inner()); } } - // Be paranoid before removing the legacy ledgers: confirm we can read back - // the new combined config. - match Ledger::new(log, paths.clone()).await { - Some(reread_config) => { - // Check that the contents we wrote match the contents we read. No - // one should be modifying this file concurrently, so a failure here - // means we've ledgered incorrect data, which could be disastrous. - // Log an error and at least try remove the ledgers we just wrote, - // then use the config we cobbled together from the legacy ledgers. - if config_ledger.data() != reread_config.data() { - error!( - log, - "Reading just-ledgered config returns unexpected contents!"; - "legacy_kind" => ?kind, - "written" => ?config_ledger.data(), - "read" => ?reread_config.data(), - ); - for p in &paths { - if let Err(err) = tokio::fs::remove_file(p).await { - // We're in really big trouble now: we've written a - // bogus ledger and can't remove it. We cannot safely - // proceed with startup. - error!( - log, - "Wrote bogus ledger and then failed to remove it!"; - "legacy_kind" => ?kind, - "path" => %p, - InlineErrorChain::new(&err), - ); - panic!( - "Wrote bogus ledger and then failed to remove it; \ - contents of {p} are invalid based on the contents \ - of the legacy configs! (removal error: {})", - InlineErrorChain::new(&err), - ); - } - } - - // This is a pretty weird case, but we're okay to proceed. We - // successfully read and converted old ledgers, then somehow - // wrote bad combined ledgers, but then successfully _removed_ - // those bad ledgers. We're back to the state we were in when we - // started: the three legacy configs are still present, and we - // know what our config should be. Return that config, and next - // time we run we'll try converting again. - return Some(config_ledger.into_inner()); - } - } - None => { - // Not much we can do here - log the failure and return before we - // try to remove the legacy ledgers. - warn!( - log, "Failed to read ledgered config we just wrote!"; - "legacy_kind" => ?kind, - "paths" => ?paths, - ); - return Some(config_ledger.into_inner()); - } + config_ledger.into_inner() +} + +#[derive(Clone, Debug, Deserialize, Serialize)] +#[serde(transparent)] +struct OmicronSledConfigLocal(v4::inventory::OmicronSledConfig); + +impl Ledgerable for OmicronSledConfigLocal { + fn is_newer_than(&self, other: &Self) -> bool { + self.0.generation > other.0.generation } - Some(config_ledger.into_inner()) + fn generation_bump(&mut self) { + self.0.generation = self.0.generation.next() + } } -fn merge_old_configs( - disks: OmicronPhysicalDisksConfig, - datasets: DatasetsConfig, - zones: OmicronZonesConfigLocal, -) -> OmicronSledConfigV4 { - OmicronSledConfigV4 { - // Take the zone generation as the overall config generation; this is - // consistent with Reconfigurator's transition from three configs to - // one. - generation: zones.omicron_generation, - disks: disks.disks.into_iter().collect(), - datasets: datasets.datasets.into_values().collect(), - zones: zones.zones.into_iter().map(|z| z.zone).collect(), - // Old configs are pre-mupdate overrides. - remove_mupdate_override: None, - // Old configs are pre-host-phase-2 knowledge. - host_phase_2: HostPhase2DesiredSlots::current_contents(), +impl TryFrom for v10::inventory::OmicronSledConfig { + type Error = external::Error; + + fn try_from(value: OmicronSledConfigLocal) -> Result { + Self::try_from(value.0) } } -/// Legacy type of the ledgered zone config. -#[derive(Debug, Clone, Deserialize, Serialize)] -#[cfg_attr(test, derive(schemars::JsonSchema))] -struct OmicronZonesConfigLocal { - omicron_generation: Generation, - ledger_generation: Generation, - zones: Vec, +// Terminal type for the [`VersionConversionChain`] above. This type is +// uninhabitable (equivalent to the `Never` / `!` type), and therefore its trait +// implementations can all safely panic (since no instance of it can exist at +// runtime for us to have a `self`). +#[derive(Debug, Serialize, Deserialize)] +enum VersionConversionChainTerminal {} + +impl VersionConversionChain for VersionConversionChainTerminal { + const DESCRIPTION: &str = "NEVER_USED_TERMINAL_STATE"; + const IS_TERMINAL: bool = true; + + type Previous = Self; } -impl Ledgerable for OmicronZonesConfigLocal { - fn is_newer_than(&self, other: &OmicronZonesConfigLocal) -> bool { - self.omicron_generation > other.omicron_generation - || (self.omicron_generation == other.omicron_generation - && self.ledger_generation >= other.ledger_generation) +impl Ledgerable for VersionConversionChainTerminal { + fn is_newer_than(&self, _: &Self) -> bool { + unreachable!("terminal type is uninhabitable") } fn generation_bump(&mut self) { - self.ledger_generation = self.ledger_generation.next(); + unreachable!("terminal type is uninhabitable") } } -#[derive(Debug, Clone, Deserialize, Serialize)] -#[cfg_attr(test, derive(schemars::JsonSchema))] -struct OmicronZoneConfigLocal { - zone: OmicronZoneConfigV4, - #[serde(rename = "root")] - #[cfg_attr(test, schemars(with = "String"))] - _root: Utf8PathBuf, -} +impl TryFrom for OmicronSledConfigLocal { + type Error = std::io::Error; -#[derive(Clone, Debug, Deserialize, Serialize)] -#[serde(transparent)] -struct OmicronSledConfigLocal(OmicronSledConfigV4); - -impl Ledgerable for OmicronSledConfigLocal { - fn is_newer_than(&self, other: &Self) -> bool { - self.0.generation > other.0.generation - } - - fn generation_bump(&mut self) { - self.0.generation = self.0.generation.next() + fn try_from( + _: VersionConversionChainTerminal, + ) -> Result { + unreachable!("terminal type is uninhabitable") } } diff --git a/sled-agent/types/versions/src/add_dual_stack_external_ip_config/inventory.rs b/sled-agent/types/versions/src/add_dual_stack_external_ip_config/inventory.rs index d71fba17315..828405bd27d 100644 --- a/sled-agent/types/versions/src/add_dual_stack_external_ip_config/inventory.rs +++ b/sled-agent/types/versions/src/add_dual_stack_external_ip_config/inventory.rs @@ -10,6 +10,7 @@ use chrono::{DateTime, Utc}; use iddqd::IdOrdItem; use iddqd::IdOrdMap; use iddqd::id_upcast; +use omicron_common::ledger::Ledgerable; use omicron_common::{ api::{ external::{ByteCount, Generation}, @@ -112,6 +113,23 @@ pub struct OmicronSledConfig { pub host_phase_2: HostPhase2DesiredSlots, } +// NOTE: Most trait impls live in the `impls` module of this crate, but we +// ledger sled configs on disk, so have to be able to read them from the ledger +// even for old versions. Therefore, we implement `Ledgerable` on this type +// directly. +impl Ledgerable for OmicronSledConfig { + fn is_newer_than(&self, other: &Self) -> bool { + self.generation > other.generation + } + + fn generation_bump(&mut self) { + // DO NOTHING! + // + // Generation bumps must only ever come from nexus and will be encoded + // in the struct itself + } +} + /// Describes the set of Omicron-managed zones running on a sled #[derive( Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq, Eq, Hash, diff --git a/sled-agent/types/versions/src/add_dual_stack_shared_network_interfaces/inventory.rs b/sled-agent/types/versions/src/add_dual_stack_shared_network_interfaces/inventory.rs index 99b63db54e7..ad2e9c4b6ff 100644 --- a/sled-agent/types/versions/src/add_dual_stack_shared_network_interfaces/inventory.rs +++ b/sled-agent/types/versions/src/add_dual_stack_shared_network_interfaces/inventory.rs @@ -10,6 +10,7 @@ use chrono::{DateTime, Utc}; use iddqd::IdOrdItem; use iddqd::IdOrdMap; use iddqd::id_upcast; +use omicron_common::ledger::Ledgerable; use omicron_common::{ api::{ external::{self, ByteCount, Generation}, @@ -114,6 +115,23 @@ pub struct OmicronSledConfig { pub host_phase_2: HostPhase2DesiredSlots, } +// NOTE: Most trait impls live in the `impls` module of this crate, but we +// ledger sled configs on disk, so have to be able to read them from the ledger +// even for old versions. Therefore, we implement `Ledgerable` on this type +// directly. +impl Ledgerable for OmicronSledConfig { + fn is_newer_than(&self, other: &Self) -> bool { + self.generation > other.generation + } + + fn generation_bump(&mut self) { + // DO NOTHING! + // + // Generation bumps must only ever come from nexus and will be encoded + // in the struct itself + } +} + /// Describes the set of Omicron-managed zones running on a sled #[derive( Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq, Eq, Hash, diff --git a/sled-agent/types/versions/src/impls/inventory.rs b/sled-agent/types/versions/src/impls/inventory.rs index b5a767e09b4..89cbd492854 100644 --- a/sled-agent/types/versions/src/impls/inventory.rs +++ b/sled-agent/types/versions/src/impls/inventory.rs @@ -12,7 +12,6 @@ use indent_write::fmt::IndentWriter; use omicron_common::api::external::Generation; use omicron_common::api::internal::shared::NetworkInterface; use omicron_common::disk::{DatasetKind, DatasetName, M2Slot}; -use omicron_common::ledger::Ledgerable; use omicron_common::update::{ArtifactId, OmicronInstallManifestSource}; use omicron_uuid_kinds::MupdateUuid; use tufaceous_artifact::{ArtifactHash, KnownArtifactKind}; @@ -868,16 +867,3 @@ impl Default for OmicronSledConfig { } } } - -impl Ledgerable for OmicronSledConfig { - fn is_newer_than(&self, other: &Self) -> bool { - self.generation > other.generation - } - - fn generation_bump(&mut self) { - // DO NOTHING! - // - // Generation bumps must only ever come from nexus and will be encoded - // in the struct itself - } -} From bb1aba35416b9e8322e6d091b67f2157aaaa617a Mon Sep 17 00:00:00 2001 From: John Gallagher Date: Thu, 18 Dec 2025 15:13:04 -0500 Subject: [PATCH 2/7] remove need for CurrentMinusOneSledConfigVersion type alias --- sled-agent/config-reconciler/src/ledger.rs | 33 +++---- .../src/ledger/legacy_configs.rs | 86 +++++++++++-------- 2 files changed, 58 insertions(+), 61 deletions(-) diff --git a/sled-agent/config-reconciler/src/ledger.rs b/sled-agent/config-reconciler/src/ledger.rs index a520401fe0d..c6b7a501cfa 100644 --- a/sled-agent/config-reconciler/src/ledger.rs +++ b/sled-agent/config-reconciler/src/ledger.rs @@ -29,7 +29,7 @@ use tufaceous_artifact::ArtifactHash; use crate::InternalDisksReceiver; use crate::SledAgentArtifactStore; -use crate::ledger::legacy_configs::try_convert_old_ledgered_config_versions; +use legacy_configs::read_ledgered_sled_config; mod legacy_configs; @@ -638,29 +638,16 @@ async fn load_sled_config( log, "Attempting to load sled config from ledger"; "paths" => ?paths, ); - if let Some(config) = Ledger::new(log, paths.clone()).await { - info!(log, "Ledger of sled config exists"); - return CurrentSledConfig::Ledgered(Box::new(config.into_inner())); - } - - // If we can't successfully read a ledgered config, see if we can convert - // from one of the previous versions of the format. - if let Some(config) = - try_convert_old_ledgered_config_versions(log, paths).await - { - info!( - log, - "Ledger of sled config exists, but it was formatted as a previous \ - version. It has been rewritten to the current version", - ); - return CurrentSledConfig::Ledgered(Box::new(config)); + match read_ledgered_sled_config(log, paths).await { + Some(config) => CurrentSledConfig::Ledgered(Box::new(config)), + None => { + // We have no ledger; we must be waiting for RSS (if we're + // pre-rack-setup) or for Nexus to send us a config (if we're a sled + // being added to an existing rack). + info!(log, "No sled config ledger exists"); + CurrentSledConfig::WaitingForInitialConfig + } } - - // We have no ledger; we must be waiting for RSS (if we're pre-rack-setup) - // or for Nexus to send us a config (if we're a sled being added to an - // existing rack). - info!(log, "No sled config ledger exists"); - CurrentSledConfig::WaitingForInitialConfig } // `LedgerTask` should not exit in production, but may exit during tests diff --git a/sled-agent/config-reconciler/src/ledger/legacy_configs.rs b/sled-agent/config-reconciler/src/ledger/legacy_configs.rs index b9ab0ec0d32..ad81c4c9fbd 100644 --- a/sled-agent/config-reconciler/src/ledger/legacy_configs.rs +++ b/sled-agent/config-reconciler/src/ledger/legacy_configs.rs @@ -13,6 +13,7 @@ use serde::Serialize; use sled_agent_types::inventory::OmicronSledConfig; use sled_agent_types_versions::v4; use sled_agent_types_versions::v10; +use sled_agent_types_versions::v11; use slog::Logger; use slog::info; use slog::warn; @@ -22,14 +23,12 @@ use std::error::Error as StdError; /// Trait describing an ordered sequence of `OmicronSledConfig` versions, each /// of which can be converted from its previous version. /// -/// When adding a new [`OmicronSledConfig`] version, do the following: -/// -/// 1. Implement [`VersionConversionChain`] for your new version. Its associated -/// `Previous` type should point to the prior version (what was the current -/// version before your change). -/// 2. Update the [`CurrentMinusOneSledConfigVersion`] type alias; this points -/// to the first version that [`try_convert_old_ledgered_config_versions`] -/// will attempt to read. +/// When adding a new [`OmicronSledConfig`] version, implement +/// [`VersionConversionChain`] for your new version. Use its fully-versioned +/// name (e.g., `vN::inventory::OmicronSledConfig`), not the +/// [`OmicronSledConfig`] alias from `latest`. The `Previous` associated type +/// should point to the prior version (what was the current version before your +/// change). trait VersionConversionChain: Ledgerable { /// A description of the version. This shows up in logs. const DESCRIPTION: &str; @@ -45,22 +44,23 @@ trait VersionConversionChain: Ledgerable { type Previous: VersionConversionChain + TryInto; } -type CurrentMinusOneSledConfigVersion = v10::inventory::OmicronSledConfig; +impl VersionConversionChain for v11::inventory::OmicronSledConfig { + const DESCRIPTION: &str = "v11::inventory::OmicronSledConfig"; + type Previous = v10::inventory::OmicronSledConfig; +} impl VersionConversionChain for v10::inventory::OmicronSledConfig { const DESCRIPTION: &str = "v10::inventory::OmicronSledConfig"; - type Previous = OmicronSledConfigLocal; } impl VersionConversionChain for OmicronSledConfigLocal { const DESCRIPTION: &str = "OmicronSledConfigLocal"; - type Previous = VersionConversionChainTerminal; } -/// Convert from an earlier version of the sled configuration to the current, if -/// possible. +/// Read the ledgered [`OmicronSledConfig`], converting from older versions if +/// needed. /// /// # Panics /// @@ -74,31 +74,38 @@ impl VersionConversionChain for OmicronSledConfigLocal { /// we have no way to proceed. Returning `None` is not correct, since that would /// incorrectly indicate that we have no config at all. We _must_ panic and rely /// on support correcting this (believed-to-be-impossible) situation. -pub(super) async fn try_convert_old_ledgered_config_versions( +pub(super) async fn read_ledgered_sled_config( log: &Logger, - datasets: Vec, + paths: Vec, ) -> Option { + // Attempt to read the ledger as the current version; if this succeeds, + // we're done. + if let Some(config) = Ledger::new(log, paths.clone()).await { + info!(log, "Ledger of sled config exists"); + return Some(config.into_inner()); + } + // Try to read the config as the previous version; if we have an older // version on disk, this will recurse until we get to it, but then convert - // it up throw `CurrentMinusOneSledConfigVersion` before returning. - let prev_version = try_convert_old_ledgered_config_versions_chain::< - CurrentMinusOneSledConfigVersion, - >(log, datasets.clone()) + // it up through our previous version before returning. + let prev_version = try_ledgered_config_versions_chain::< + ::Previous, + >(log, paths.clone()) .await?; let current_version = prev_version.try_into().unwrap_or_else(|e| { panic!( "failed to convert {} to the current version: {}", - CurrentMinusOneSledConfigVersion::DESCRIPTION, + ::DESCRIPTION, InlineErrorChain::new(&e) ); }); - Some(write_converted_ledger(log, datasets, current_version).await) + Some(write_converted_ledger(log, paths, current_version).await) } /// Reading old ledgers from disk in the face of multiple version changes is -/// tricky. Imagine we have this sequence in the versioning change: +/// tricky. Imagine we have this sequence in the versioning chain: /// /// * v4 (the oldest supported version) /// * v10 @@ -129,9 +136,9 @@ pub(super) async fn try_convert_old_ledgered_config_versions( /// (since we forbid updates from skipping releases). For extra paranoia, we can /// keep versions covering the oldest deployed rack around. #[async_recursion::async_recursion] -async fn try_convert_old_ledgered_config_versions_chain( +async fn try_ledgered_config_versions_chain( log: &Logger, - datasets: Vec, + paths: Vec, ) -> Option where T: VersionConversionChain, @@ -140,28 +147,31 @@ where return None; } - if let Some(config) = Ledger::::new(log, datasets.clone()).await { + if let Some(config) = Ledger::::new(log, paths.clone()).await { + info!( + log, + "successfully read ledgered config as version {}", + T::DESCRIPTION + ); return Some(config.into_inner()); } - let old_config = try_convert_old_ledgered_config_versions_chain::< - T::Previous, - >(log, datasets) - .await?; - - info!( - log, - "Successfully read ledgered config as old version {}; \ - will now convert to latest version", - T::DESCRIPTION, - ); + let old_config = + try_ledgered_config_versions_chain::(log, paths).await?; match old_config.try_into() { - Ok(config) => Some(config), + Ok(config) => { + info!( + log, + "converted config read from ledger to version {}", + T::DESCRIPTION + ); + Some(config) + } Err(err) => { panic!( "failed to convert legered config \ - of version {} to version {}: {}", + from version {} to version {}: {}", T::Previous::DESCRIPTION, T::DESCRIPTION, InlineErrorChain::new(&err), From aa36a1c832b11bb9d013c08ed4fd80c8d5136d6c Mon Sep 17 00:00:00 2001 From: John Gallagher Date: Thu, 18 Dec 2025 15:17:04 -0500 Subject: [PATCH 3/7] rename module --- sled-agent/config-reconciler/src/ledger.rs | 12 ++++++------ ...configs.rs => ledgered_sled_config_versioning.rs} | 0 2 files changed, 6 insertions(+), 6 deletions(-) rename sled-agent/config-reconciler/src/ledger/{legacy_configs.rs => ledgered_sled_config_versioning.rs} (100%) diff --git a/sled-agent/config-reconciler/src/ledger.rs b/sled-agent/config-reconciler/src/ledger.rs index c6b7a501cfa..2a4816feb8a 100644 --- a/sled-agent/config-reconciler/src/ledger.rs +++ b/sled-agent/config-reconciler/src/ledger.rs @@ -29,9 +29,9 @@ use tufaceous_artifact::ArtifactHash; use crate::InternalDisksReceiver; use crate::SledAgentArtifactStore; -use legacy_configs::read_ledgered_sled_config; +use ledgered_sled_config_versioning::read_ledgered_sled_config; -mod legacy_configs; +mod ledgered_sled_config_versioning; const CONFIG_LEDGER_FILENAME: &str = "omicron-sled-config.json"; @@ -663,12 +663,12 @@ enum LedgerTaskExit { #[cfg(test)] mod tests { - use super::legacy_configs::tests::LEGACY_DATASETS_PATH; - use super::legacy_configs::tests::LEGACY_DISKS_PATH; - use super::legacy_configs::tests::LEGACY_ZONES_PATH; + use super::ledgered_sled_config_versioning::tests::LEGACY_DATASETS_PATH; + use super::ledgered_sled_config_versioning::tests::LEGACY_DISKS_PATH; + use super::ledgered_sled_config_versioning::tests::LEGACY_ZONES_PATH; use super::*; use crate::internal_disks::InternalDiskDetails; - use crate::ledger::legacy_configs::tests::test_data_merged_config; + use crate::ledger::ledgered_sled_config_versioning::tests::test_data_merged_config; use anyhow::anyhow; use camino::Utf8Path; use camino_tempfile::Utf8TempDir; diff --git a/sled-agent/config-reconciler/src/ledger/legacy_configs.rs b/sled-agent/config-reconciler/src/ledger/ledgered_sled_config_versioning.rs similarity index 100% rename from sled-agent/config-reconciler/src/ledger/legacy_configs.rs rename to sled-agent/config-reconciler/src/ledger/ledgered_sled_config_versioning.rs From 6d5644e79137461d8335183ecd4557061cea14e7 Mon Sep 17 00:00:00 2001 From: John Gallagher Date: Thu, 18 Dec 2025 15:22:14 -0500 Subject: [PATCH 4/7] remove OmicronSledConfigLocal wrapper --- .../ledger/ledgered_sled_config_versioning.rs | 33 ++++--------------- .../inventory.rs | 18 ++++++++++ 2 files changed, 24 insertions(+), 27 deletions(-) diff --git a/sled-agent/config-reconciler/src/ledger/ledgered_sled_config_versioning.rs b/sled-agent/config-reconciler/src/ledger/ledgered_sled_config_versioning.rs index ad81c4c9fbd..3d6f91e567f 100644 --- a/sled-agent/config-reconciler/src/ledger/ledgered_sled_config_versioning.rs +++ b/sled-agent/config-reconciler/src/ledger/ledgered_sled_config_versioning.rs @@ -5,7 +5,6 @@ //! Module for converting older formats of the sled configuration files. use camino::Utf8PathBuf; -use omicron_common::api::external; use omicron_common::ledger::Ledger; use omicron_common::ledger::Ledgerable; use serde::Deserialize; @@ -51,11 +50,11 @@ impl VersionConversionChain for v11::inventory::OmicronSledConfig { impl VersionConversionChain for v10::inventory::OmicronSledConfig { const DESCRIPTION: &str = "v10::inventory::OmicronSledConfig"; - type Previous = OmicronSledConfigLocal; + type Previous = v4::inventory::OmicronSledConfig; } -impl VersionConversionChain for OmicronSledConfigLocal { - const DESCRIPTION: &str = "OmicronSledConfigLocal"; +impl VersionConversionChain for v4::inventory::OmicronSledConfig { + const DESCRIPTION: &str = "v4::inventory::OmicronSledConfig"; type Previous = VersionConversionChainTerminal; } @@ -206,28 +205,6 @@ async fn write_converted_ledger( config_ledger.into_inner() } -#[derive(Clone, Debug, Deserialize, Serialize)] -#[serde(transparent)] -struct OmicronSledConfigLocal(v4::inventory::OmicronSledConfig); - -impl Ledgerable for OmicronSledConfigLocal { - fn is_newer_than(&self, other: &Self) -> bool { - self.0.generation > other.0.generation - } - - fn generation_bump(&mut self) { - self.0.generation = self.0.generation.next() - } -} - -impl TryFrom for v10::inventory::OmicronSledConfig { - type Error = external::Error; - - fn try_from(value: OmicronSledConfigLocal) -> Result { - Self::try_from(value.0) - } -} - // Terminal type for the [`VersionConversionChain`] above. This type is // uninhabitable (equivalent to the `Never` / `!` type), and therefore its trait // implementations can all safely panic (since no instance of it can exist at @@ -252,7 +229,9 @@ impl Ledgerable for VersionConversionChainTerminal { } } -impl TryFrom for OmicronSledConfigLocal { +impl TryFrom + for v4::inventory::OmicronSledConfig +{ type Error = std::io::Error; fn try_from( diff --git a/sled-agent/types/versions/src/add_nexus_lockstep_port_to_inventory/inventory.rs b/sled-agent/types/versions/src/add_nexus_lockstep_port_to_inventory/inventory.rs index 140aa92c4b2..e49c58231c9 100644 --- a/sled-agent/types/versions/src/add_nexus_lockstep_port_to_inventory/inventory.rs +++ b/sled-agent/types/versions/src/add_nexus_lockstep_port_to_inventory/inventory.rs @@ -15,6 +15,7 @@ use omicron_common::api::external::{ByteCount, Generation}; use omicron_common::api::internal::shared::external_ip::v1::SourceNatConfig; use omicron_common::api::internal::shared::network_interface::v1::NetworkInterface; use omicron_common::disk::{DatasetConfig, OmicronPhysicalDiskConfig}; +use omicron_common::ledger::Ledgerable; use omicron_common::zpool_name::ZpoolName; use omicron_uuid_kinds::{DatasetUuid, MupdateOverrideUuid, OmicronZoneUuid}; use omicron_uuid_kinds::{PhysicalDiskUuid, SledUuid}; @@ -69,6 +70,23 @@ pub struct OmicronSledConfig { pub host_phase_2: HostPhase2DesiredSlots, } +// NOTE: Most trait impls live in the `impls` module of this crate, but we +// ledger sled configs on disk, so have to be able to read them from the ledger +// even for old versions. Therefore, we implement `Ledgerable` on this type +// directly. +impl Ledgerable for OmicronSledConfig { + fn is_newer_than(&self, other: &Self) -> bool { + self.generation > other.generation + } + + fn generation_bump(&mut self) { + // DO NOTHING! + // + // Generation bumps must only ever come from nexus and will be encoded + // in the struct itself + } +} + /// Describes one Omicron-managed zone running on a sled #[derive( Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq, Eq, Hash, From 2148f44db599416b64d917771cbf4fffbf674a25 Mon Sep 17 00:00:00 2001 From: John Gallagher Date: Thu, 18 Dec 2025 16:35:38 -0500 Subject: [PATCH 5/7] rework tests --- Cargo.lock | 1 + sled-agent/config-reconciler/Cargo.toml | 1 + .../expectorate/v10-sled-config.json | 1005 +++++++++++++++++ .../expectorate/v11-sled-config.json | 1005 +++++++++++++++++ sled-agent/config-reconciler/src/ledger.rs | 54 +- .../ledger/ledgered_sled_config_versioning.rs | 289 ++--- .../config-reconciler/test-data/README.md | 4 - .../expectorate/merged-sled-config.json | 822 -------------- .../test-data/omicron-datasets.json | 543 --------- .../test-data/omicron-physical-disks.json | 95 -- .../test-data/omicron-zones.json | 221 ---- .../test-data/v4-sled-config.json | 993 ++++++++++++++++ 12 files changed, 3107 insertions(+), 1926 deletions(-) create mode 100644 sled-agent/config-reconciler/expectorate/v10-sled-config.json create mode 100644 sled-agent/config-reconciler/expectorate/v11-sled-config.json delete mode 100644 sled-agent/config-reconciler/test-data/README.md delete mode 100644 sled-agent/config-reconciler/test-data/expectorate/merged-sled-config.json delete mode 100644 sled-agent/config-reconciler/test-data/omicron-datasets.json delete mode 100644 sled-agent/config-reconciler/test-data/omicron-physical-disks.json delete mode 100644 sled-agent/config-reconciler/test-data/omicron-zones.json create mode 100644 sled-agent/config-reconciler/test-data/v4-sled-config.json diff --git a/Cargo.lock b/Cargo.lock index 64723e94866..7f23cb31286 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -12974,6 +12974,7 @@ dependencies = [ "bytes", "camino", "camino-tempfile", + "camino-tempfile-ext", "chrono", "debug-ignore", "derive_more 0.99.20", diff --git a/sled-agent/config-reconciler/Cargo.toml b/sled-agent/config-reconciler/Cargo.toml index 0c628a83989..832329c5a9a 100644 --- a/sled-agent/config-reconciler/Cargo.toml +++ b/sled-agent/config-reconciler/Cargo.toml @@ -47,6 +47,7 @@ omicron-workspace-hack.workspace = true [dev-dependencies] assert_matches.workspace = true +camino-tempfile-ext.workspace = true expectorate.workspace = true illumos-utils = { workspace = true, features = ["testing"] } omicron-common = { workspace = true, features = ["testing"] } diff --git a/sled-agent/config-reconciler/expectorate/v10-sled-config.json b/sled-agent/config-reconciler/expectorate/v10-sled-config.json new file mode 100644 index 00000000000..b3e01ed0cab --- /dev/null +++ b/sled-agent/config-reconciler/expectorate/v10-sled-config.json @@ -0,0 +1,1005 @@ +{ + "generation": 351, + "disks": { + "10fec275-f937-40f7-9c25-616079ef3816": { + "identity": { + "vendor": "1b96", + "model": "WUS4C6432DSP3X3", + "serial": "A084A5E3" + }, + "id": "10fec275-f937-40f7-9c25-616079ef3816", + "pool_id": "6340805e-c5af-418d-8bd1-fc0085667f33" + }, + "883b970b-2b70-4771-bb0e-aed2765c3e6a": { + "identity": { + "vendor": "1b96", + "model": "WUS4C6432DSP3X3", + "serial": "A084A79D" + }, + "id": "883b970b-2b70-4771-bb0e-aed2765c3e6a", + "pool_id": "414e235b-55c3-4dc1-a568-8adf4ea1a052" + }, + "9272fa96-eef8-43ed-8658-12ccf722bec2": { + "identity": { + "vendor": "1b96", + "model": "WUS4C6432DSP3X3", + "serial": "A084A61D" + }, + "id": "9272fa96-eef8-43ed-8658-12ccf722bec2", + "pool_id": "7b24095a-72df-45e3-984f-2b795e052ac7" + }, + "b20f225f-fef6-4ef5-a474-bd818013fceb": { + "identity": { + "vendor": "1b96", + "model": "WUS4C6432DSP3X3", + "serial": "A084A7EE" + }, + "id": "b20f225f-fef6-4ef5-a474-bd818013fceb", + "pool_id": "b93f880e-c55b-4d6c-9a16-939d84b628fc" + }, + "b483c693-700f-4630-92bb-9659e735648b": { + "identity": { + "vendor": "1b96", + "model": "WUS4C6432DSP3X3", + "serial": "A084A67C" + }, + "id": "b483c693-700f-4630-92bb-9659e735648b", + "pool_id": "cf940e15-dbc5-481b-866a-4de4b018898e" + }, + "c9bd1b35-c87a-4acf-bf52-06ed624e3be0": { + "identity": { + "vendor": "1b96", + "model": "WUS4C6432DSP3X3", + "serial": "A084A6F3" + }, + "id": "c9bd1b35-c87a-4acf-bf52-06ed624e3be0", + "pool_id": "8a199f12-4f5c-483a-8aca-f97856658a35" + }, + "d45fb895-f500-473f-9bdb-3d1f15464055": { + "identity": { + "vendor": "1b96", + "model": "WUS4C6432DSP3X3", + "serial": "A084A5C3" + }, + "id": "d45fb895-f500-473f-9bdb-3d1f15464055", + "pool_id": "26e698bb-006d-4208-94b9-d1bc279111fa" + }, + "d9fb1545-4051-4710-bcfd-8d33115bb022": { + "identity": { + "vendor": "1b96", + "model": "WUS4C6432DSP3X3", + "serial": "A084A7BE" + }, + "id": "d9fb1545-4051-4710-bcfd-8d33115bb022", + "pool_id": "e126ddcc-8bee-46ba-8199-2a74df0ba040" + }, + "e1bfe0a7-e848-4907-9068-22e02bad03ca": { + "identity": { + "vendor": "1b96", + "model": "WUS4C6432DSP3X3", + "serial": "A084A7DA" + }, + "id": "e1bfe0a7-e848-4907-9068-22e02bad03ca", + "pool_id": "2115b084-be0f-4fba-941b-33a659798a9e" + }, + "f6d26664-f32e-46c4-a3f3-74d55dae7fac": { + "identity": { + "vendor": "1b96", + "model": "WUS4C6432DSP3X3", + "serial": "A084A75D" + }, + "id": "f6d26664-f32e-46c4-a3f3-74d55dae7fac", + "pool_id": "bf428719-1b16-4503-99f4-ad95846d916f" + } + }, + "datasets": { + "01f93020-7e7d-4185-93fb-6ca234056c82": { + "id": "01f93020-7e7d-4185-93fb-6ca234056c82", + "name": { + "pool_name": "oxp_7b24095a-72df-45e3-984f-2b795e052ac7", + "kind": "crucible" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "01ffd316-ea25-4287-95aa-01bf6b036a16": { + "id": "01ffd316-ea25-4287-95aa-01bf6b036a16", + "name": { + "pool_name": "oxp_7b24095a-72df-45e3-984f-2b795e052ac7", + "kind": "zone/oxz_crucible_01f93020-7e7d-4185-93fb-6ca234056c82" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "02a5be47-df19-4159-b793-98a888603200": { + "id": "02a5be47-df19-4159-b793-98a888603200", + "name": { + "pool_name": "oxp_cf940e15-dbc5-481b-866a-4de4b018898e", + "kind": "debug" + }, + "compression": { + "type": "gzip_n", + "level": 9 + }, + "quota": 107374182400, + "reservation": null + }, + "072fdae8-2adf-4fd2-94ce-e9b0663b91e7": { + "id": "072fdae8-2adf-4fd2-94ce-e9b0663b91e7", + "name": { + "pool_name": "oxp_26e698bb-006d-4208-94b9-d1bc279111fa", + "kind": "crucible" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "088ff0e3-9b7e-4798-901c-fe88cf7aca52": { + "id": "088ff0e3-9b7e-4798-901c-fe88cf7aca52", + "name": { + "pool_name": "oxp_bf428719-1b16-4503-99f4-ad95846d916f", + "kind": "zone" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "0b41c560-3b20-42f4-82ad-92f5bb575d6b": { + "id": "0b41c560-3b20-42f4-82ad-92f5bb575d6b", + "name": { + "pool_name": "oxp_b93f880e-c55b-4d6c-9a16-939d84b628fc", + "kind": "crucible" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "0ccf27c0-e32d-4b52-a2c5-6db0c64a26f9": { + "id": "0ccf27c0-e32d-4b52-a2c5-6db0c64a26f9", + "name": { + "pool_name": "oxp_2115b084-be0f-4fba-941b-33a659798a9e", + "kind": "crucible" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "14b70f75-89e1-4ded-a7c4-dcf49ebd87ba": { + "id": "14b70f75-89e1-4ded-a7c4-dcf49ebd87ba", + "name": { + "pool_name": "oxp_b93f880e-c55b-4d6c-9a16-939d84b628fc", + "kind": "zone/oxz_crucible_0b41c560-3b20-42f4-82ad-92f5bb575d6b" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "1a00597c-8225-4324-9530-aaad3d7a9138": { + "id": "1a00597c-8225-4324-9530-aaad3d7a9138", + "name": { + "pool_name": "oxp_414e235b-55c3-4dc1-a568-8adf4ea1a052", + "kind": "zone/oxz_crucible_7d44ba36-4a69-490a-bc40-f6f90a4208d4" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "257d5c91-5bd5-4a13-802b-0995f76df671": { + "id": "257d5c91-5bd5-4a13-802b-0995f76df671", + "name": { + "pool_name": "oxp_2115b084-be0f-4fba-941b-33a659798a9e", + "kind": "zone/oxz_nexus_470fbf4d-0178-45ee-a422-136fa5f4a158" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "27bb57f7-abc6-4550-b1c6-5a18c7356748": { + "id": "27bb57f7-abc6-4550-b1c6-5a18c7356748", + "name": { + "pool_name": "oxp_26e698bb-006d-4208-94b9-d1bc279111fa", + "kind": "debug" + }, + "compression": { + "type": "gzip_n", + "level": 9 + }, + "quota": 107374182400, + "reservation": null + }, + "2bd226bd-edce-488c-bbe8-e0b301664de0": { + "id": "2bd226bd-edce-488c-bbe8-e0b301664de0", + "name": { + "pool_name": "oxp_2115b084-be0f-4fba-941b-33a659798a9e", + "kind": "local_storage" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "2c260613-a7bc-401e-ab73-cde4069ef09a": { + "id": "2c260613-a7bc-401e-ab73-cde4069ef09a", + "name": { + "pool_name": "oxp_7b24095a-72df-45e3-984f-2b795e052ac7", + "kind": "debug" + }, + "compression": { + "type": "gzip_n", + "level": 9 + }, + "quota": 107374182400, + "reservation": null + }, + "2fa20fca-7b61-4e56-8dbf-f56171bf35e1": { + "id": "2fa20fca-7b61-4e56-8dbf-f56171bf35e1", + "name": { + "pool_name": "oxp_2115b084-be0f-4fba-941b-33a659798a9e", + "kind": "debug" + }, + "compression": { + "type": "gzip_n", + "level": 9 + }, + "quota": 107374182400, + "reservation": null + }, + "34007214-81f0-4768-804d-d090695f1f09": { + "id": "34007214-81f0-4768-804d-d090695f1f09", + "name": { + "pool_name": "oxp_2115b084-be0f-4fba-941b-33a659798a9e", + "kind": "external_dns" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "46596dcd-4bea-4878-b498-1b9da4437aff": { + "id": "46596dcd-4bea-4878-b498-1b9da4437aff", + "name": { + "pool_name": "oxp_8a199f12-4f5c-483a-8aca-f97856658a35", + "kind": "debug" + }, + "compression": { + "type": "gzip_n", + "level": 9 + }, + "quota": 107374182400, + "reservation": null + }, + "468152ab-b771-4caf-9ca2-8abbd6fc5bec": { + "id": "468152ab-b771-4caf-9ca2-8abbd6fc5bec", + "name": { + "pool_name": "oxp_e126ddcc-8bee-46ba-8199-2a74df0ba040", + "kind": "debug" + }, + "compression": { + "type": "gzip_n", + "level": 9 + }, + "quota": 107374182400, + "reservation": null + }, + "46c13daf-0808-496a-b0f8-9eca75fcfa84": { + "id": "46c13daf-0808-496a-b0f8-9eca75fcfa84", + "name": { + "pool_name": "oxp_6340805e-c5af-418d-8bd1-fc0085667f33", + "kind": "debug" + }, + "compression": { + "type": "gzip_n", + "level": 9 + }, + "quota": 107374182400, + "reservation": null + }, + "4b771fc2-312a-4abf-9eef-ae9ff3853a13": { + "id": "4b771fc2-312a-4abf-9eef-ae9ff3853a13", + "name": { + "pool_name": "oxp_2115b084-be0f-4fba-941b-33a659798a9e", + "kind": "zone" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "4e3b3938-ad72-4443-9d96-4d6ba8ab19fb": { + "id": "4e3b3938-ad72-4443-9d96-4d6ba8ab19fb", + "name": { + "pool_name": "oxp_6340805e-c5af-418d-8bd1-fc0085667f33", + "kind": "zone/oxz_crucible_585cd8c5-c41e-4be4-beb8-bfbef9b53856" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "50b12371-0120-4210-89c7-2ecd58bea4d3": { + "id": "50b12371-0120-4210-89c7-2ecd58bea4d3", + "name": { + "pool_name": "oxp_b93f880e-c55b-4d6c-9a16-939d84b628fc", + "kind": "local_storage" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "5171b6ba-b282-4e71-917e-f253c7b2eb22": { + "id": "5171b6ba-b282-4e71-917e-f253c7b2eb22", + "name": { + "pool_name": "oxp_7b24095a-72df-45e3-984f-2b795e052ac7", + "kind": "zone" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "5625f171-927d-4e4a-b009-be250ac92bc3": { + "id": "5625f171-927d-4e4a-b009-be250ac92bc3", + "name": { + "pool_name": "oxp_8a199f12-4f5c-483a-8aca-f97856658a35", + "kind": "local_storage" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "56b0119a-f49d-45d7-a93e-d4a4e1d76559": { + "id": "56b0119a-f49d-45d7-a93e-d4a4e1d76559", + "name": { + "pool_name": "oxp_e126ddcc-8bee-46ba-8199-2a74df0ba040", + "kind": "zone" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "585cd8c5-c41e-4be4-beb8-bfbef9b53856": { + "id": "585cd8c5-c41e-4be4-beb8-bfbef9b53856", + "name": { + "pool_name": "oxp_6340805e-c5af-418d-8bd1-fc0085667f33", + "kind": "crucible" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "5b0bc0d3-24c6-4f9c-937b-f38e8ccee03c": { + "id": "5b0bc0d3-24c6-4f9c-937b-f38e8ccee03c", + "name": { + "pool_name": "oxp_26e698bb-006d-4208-94b9-d1bc279111fa", + "kind": "local_storage" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "5c4e9d03-f202-46dd-ba50-179b2b84f849": { + "id": "5c4e9d03-f202-46dd-ba50-179b2b84f849", + "name": { + "pool_name": "oxp_bf428719-1b16-4503-99f4-ad95846d916f", + "kind": "zone/oxz_crucible_7153983f-8fd7-4fb9-92ac-0f07a07798b4" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "69794309-1082-410b-a2a1-8b97588efa16": { + "id": "69794309-1082-410b-a2a1-8b97588efa16", + "name": { + "pool_name": "oxp_b93f880e-c55b-4d6c-9a16-939d84b628fc", + "kind": "zone" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "69a6412f-8438-4a0d-9c6e-a2e766750b2c": { + "id": "69a6412f-8438-4a0d-9c6e-a2e766750b2c", + "name": { + "pool_name": "oxp_2115b084-be0f-4fba-941b-33a659798a9e", + "kind": "zone/oxz_external_dns_5c97418b-8318-4427-8f65-14f3e3362d13" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "7153983f-8fd7-4fb9-92ac-0f07a07798b4": { + "id": "7153983f-8fd7-4fb9-92ac-0f07a07798b4", + "name": { + "pool_name": "oxp_bf428719-1b16-4503-99f4-ad95846d916f", + "kind": "crucible" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "77906e4e-1bbc-49c9-a7ee-f581de5552c4": { + "id": "77906e4e-1bbc-49c9-a7ee-f581de5552c4", + "name": { + "pool_name": "oxp_e126ddcc-8bee-46ba-8199-2a74df0ba040", + "kind": "zone/oxz_crucible_e238116d-e5cc-43d4-9c8a-6f138ae8a15d" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "7d44ba36-4a69-490a-bc40-f6f90a4208d4": { + "id": "7d44ba36-4a69-490a-bc40-f6f90a4208d4", + "name": { + "pool_name": "oxp_414e235b-55c3-4dc1-a568-8adf4ea1a052", + "kind": "crucible" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "8bce1ea9-5d2f-451a-87fd-db9140e07420": { + "id": "8bce1ea9-5d2f-451a-87fd-db9140e07420", + "name": { + "pool_name": "oxp_8a199f12-4f5c-483a-8aca-f97856658a35", + "kind": "zone/oxz_crucible_a6ba8273-0320-4dab-b801-281f041b0c50" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "8f50c2e8-d091-4440-b9cc-0c6c3e62b8b8": { + "id": "8f50c2e8-d091-4440-b9cc-0c6c3e62b8b8", + "name": { + "pool_name": "oxp_2115b084-be0f-4fba-941b-33a659798a9e", + "kind": "zone/oxz_crucible_0ccf27c0-e32d-4b52-a2c5-6db0c64a26f9" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "9721d822-c80a-4856-a715-02c9c0c89184": { + "id": "9721d822-c80a-4856-a715-02c9c0c89184", + "name": { + "pool_name": "oxp_e126ddcc-8bee-46ba-8199-2a74df0ba040", + "kind": "local_storage" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "978354d3-17cb-40ce-815d-b4edaad79f11": { + "id": "978354d3-17cb-40ce-815d-b4edaad79f11", + "name": { + "pool_name": "oxp_26e698bb-006d-4208-94b9-d1bc279111fa", + "kind": "zone" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "9bf9e7bd-269b-4925-ba99-a0cdb8138fb8": { + "id": "9bf9e7bd-269b-4925-ba99-a0cdb8138fb8", + "name": { + "pool_name": "oxp_cf940e15-dbc5-481b-866a-4de4b018898e", + "kind": "local_storage" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "a2d0f801-bf2d-44a3-b39b-bbfb3b387a4a": { + "id": "a2d0f801-bf2d-44a3-b39b-bbfb3b387a4a", + "name": { + "pool_name": "oxp_bf428719-1b16-4503-99f4-ad95846d916f", + "kind": "debug" + }, + "compression": { + "type": "gzip_n", + "level": 9 + }, + "quota": 107374182400, + "reservation": null + }, + "a6ba8273-0320-4dab-b801-281f041b0c50": { + "id": "a6ba8273-0320-4dab-b801-281f041b0c50", + "name": { + "pool_name": "oxp_8a199f12-4f5c-483a-8aca-f97856658a35", + "kind": "crucible" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "a6cbbb5d-f7b3-4d91-b54e-c3cf55762adc": { + "id": "a6cbbb5d-f7b3-4d91-b54e-c3cf55762adc", + "name": { + "pool_name": "oxp_bf428719-1b16-4503-99f4-ad95846d916f", + "kind": "local_storage" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "a724aab1-2fdc-45aa-8fa2-2f0a272aae62": { + "id": "a724aab1-2fdc-45aa-8fa2-2f0a272aae62", + "name": { + "pool_name": "oxp_414e235b-55c3-4dc1-a568-8adf4ea1a052", + "kind": "local_storage" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "aa44f101-8502-4480-bec8-9c48d3f4106b": { + "id": "aa44f101-8502-4480-bec8-9c48d3f4106b", + "name": { + "pool_name": "oxp_cf940e15-dbc5-481b-866a-4de4b018898e", + "kind": "zone" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "adb8db9b-2cd7-45b7-bb9f-adf094c4ccca": { + "id": "adb8db9b-2cd7-45b7-bb9f-adf094c4ccca", + "name": { + "pool_name": "oxp_414e235b-55c3-4dc1-a568-8adf4ea1a052", + "kind": "debug" + }, + "compression": { + "type": "gzip_n", + "level": 9 + }, + "quota": 107374182400, + "reservation": null + }, + "b156677f-cafa-4d73-9719-6b0d16dad722": { + "id": "b156677f-cafa-4d73-9719-6b0d16dad722", + "name": { + "pool_name": "oxp_8a199f12-4f5c-483a-8aca-f97856658a35", + "kind": "zone" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "b9b7b4c2-284a-4ec1-80ea-75b7a43b71c4": { + "id": "b9b7b4c2-284a-4ec1-80ea-75b7a43b71c4", + "name": { + "pool_name": "oxp_cf940e15-dbc5-481b-866a-4de4b018898e", + "kind": "crucible" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "c5e4bd8a-d323-48ec-a641-5c7dbecf3252": { + "id": "c5e4bd8a-d323-48ec-a641-5c7dbecf3252", + "name": { + "pool_name": "oxp_7b24095a-72df-45e3-984f-2b795e052ac7", + "kind": "local_storage" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "c9c7a527-d432-490d-86b3-658da7b555cc": { + "id": "c9c7a527-d432-490d-86b3-658da7b555cc", + "name": { + "pool_name": "oxp_26e698bb-006d-4208-94b9-d1bc279111fa", + "kind": "zone/oxz_crucible_072fdae8-2adf-4fd2-94ce-e9b0663b91e7" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "d8b3ba09-1267-43af-9734-1fdc3e22b23e": { + "id": "d8b3ba09-1267-43af-9734-1fdc3e22b23e", + "name": { + "pool_name": "oxp_cf940e15-dbc5-481b-866a-4de4b018898e", + "kind": "zone/oxz_crucible_b9b7b4c2-284a-4ec1-80ea-75b7a43b71c4" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "dee3ca8e-c6f5-4e12-aa0d-74ed9a6245a3": { + "id": "dee3ca8e-c6f5-4e12-aa0d-74ed9a6245a3", + "name": { + "pool_name": "oxp_2115b084-be0f-4fba-941b-33a659798a9e", + "kind": "zone/oxz_ntp_a700528f-f600-4908-94ac-9c06442ef6b4" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "e1c7ecae-faed-4d02-b446-2dd3478dc27d": { + "id": "e1c7ecae-faed-4d02-b446-2dd3478dc27d", + "name": { + "pool_name": "oxp_b93f880e-c55b-4d6c-9a16-939d84b628fc", + "kind": "debug" + }, + "compression": { + "type": "gzip_n", + "level": 9 + }, + "quota": 107374182400, + "reservation": null + }, + "e238116d-e5cc-43d4-9c8a-6f138ae8a15d": { + "id": "e238116d-e5cc-43d4-9c8a-6f138ae8a15d", + "name": { + "pool_name": "oxp_e126ddcc-8bee-46ba-8199-2a74df0ba040", + "kind": "crucible" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "e3d07396-5ab6-4008-b590-df8b5794f9e1": { + "id": "e3d07396-5ab6-4008-b590-df8b5794f9e1", + "name": { + "pool_name": "oxp_6340805e-c5af-418d-8bd1-fc0085667f33", + "kind": "local_storage" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "e7d578b0-2c40-4e1f-a1c2-2dc2a6f9f5d8": { + "id": "e7d578b0-2c40-4e1f-a1c2-2dc2a6f9f5d8", + "name": { + "pool_name": "oxp_6340805e-c5af-418d-8bd1-fc0085667f33", + "kind": "zone" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "fb307365-fd47-4112-9a88-519ee5cf6445": { + "id": "fb307365-fd47-4112-9a88-519ee5cf6445", + "name": { + "pool_name": "oxp_414e235b-55c3-4dc1-a568-8adf4ea1a052", + "kind": "zone" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + } + }, + "zones": { + "01f93020-7e7d-4185-93fb-6ca234056c82": { + "id": "01f93020-7e7d-4185-93fb-6ca234056c82", + "filesystem_pool": "oxp_7b24095a-72df-45e3-984f-2b795e052ac7", + "zone_type": { + "type": "crucible", + "address": "[fd00:1122:3344:103::5]:32345", + "dataset": { + "pool_name": "oxp_7b24095a-72df-45e3-984f-2b795e052ac7" + } + }, + "image_source": { + "type": "artifact", + "hash": "988cab6ea184b7912350e5af151bd18152ee2702bad7dc0b977d414eb8062e27" + } + }, + "072fdae8-2adf-4fd2-94ce-e9b0663b91e7": { + "id": "072fdae8-2adf-4fd2-94ce-e9b0663b91e7", + "filesystem_pool": "oxp_26e698bb-006d-4208-94b9-d1bc279111fa", + "zone_type": { + "type": "crucible", + "address": "[fd00:1122:3344:103::b]:32345", + "dataset": { + "pool_name": "oxp_26e698bb-006d-4208-94b9-d1bc279111fa" + } + }, + "image_source": { + "type": "artifact", + "hash": "988cab6ea184b7912350e5af151bd18152ee2702bad7dc0b977d414eb8062e27" + } + }, + "0b41c560-3b20-42f4-82ad-92f5bb575d6b": { + "id": "0b41c560-3b20-42f4-82ad-92f5bb575d6b", + "filesystem_pool": "oxp_b93f880e-c55b-4d6c-9a16-939d84b628fc", + "zone_type": { + "type": "crucible", + "address": "[fd00:1122:3344:103::9]:32345", + "dataset": { + "pool_name": "oxp_b93f880e-c55b-4d6c-9a16-939d84b628fc" + } + }, + "image_source": { + "type": "artifact", + "hash": "988cab6ea184b7912350e5af151bd18152ee2702bad7dc0b977d414eb8062e27" + } + }, + "0ccf27c0-e32d-4b52-a2c5-6db0c64a26f9": { + "id": "0ccf27c0-e32d-4b52-a2c5-6db0c64a26f9", + "filesystem_pool": "oxp_2115b084-be0f-4fba-941b-33a659798a9e", + "zone_type": { + "type": "crucible", + "address": "[fd00:1122:3344:103::d]:32345", + "dataset": { + "pool_name": "oxp_2115b084-be0f-4fba-941b-33a659798a9e" + } + }, + "image_source": { + "type": "artifact", + "hash": "988cab6ea184b7912350e5af151bd18152ee2702bad7dc0b977d414eb8062e27" + } + }, + "470fbf4d-0178-45ee-a422-136fa5f4a158": { + "id": "470fbf4d-0178-45ee-a422-136fa5f4a158", + "filesystem_pool": "oxp_2115b084-be0f-4fba-941b-33a659798a9e", + "zone_type": { + "type": "nexus", + "internal_address": "[fd00:1122:3344:103::47]:12221", + "lockstep_port": 12232, + "external_ip": "172.20.26.8", + "nic": { + "id": "98d2e08e-a3a6-43ed-a2a0-7cf52fd211f8", + "kind": { + "type": "service", + "id": "470fbf4d-0178-45ee-a422-136fa5f4a158" + }, + "name": "nexus-470fbf4d-0178-45ee-a422-136fa5f4a158", + "ip_config": { + "type": "v4", + "value": { + "ip": "172.30.2.9", + "subnet": "172.30.2.0/24", + "transit_ips": [] + } + }, + "mac": "A8:40:25:FF:80:05", + "vni": 100, + "primary": true, + "slot": 0 + }, + "external_tls": true, + "external_dns_servers": [ + "1.1.1.1", + "9.9.9.9" + ] + }, + "image_source": { + "type": "artifact", + "hash": "1ae3b88364f311ce588ac802cb8177c4806b76da0ce42e39aab0b0d8bb04c197" + } + }, + "585cd8c5-c41e-4be4-beb8-bfbef9b53856": { + "id": "585cd8c5-c41e-4be4-beb8-bfbef9b53856", + "filesystem_pool": "oxp_6340805e-c5af-418d-8bd1-fc0085667f33", + "zone_type": { + "type": "crucible", + "address": "[fd00:1122:3344:103::7]:32345", + "dataset": { + "pool_name": "oxp_6340805e-c5af-418d-8bd1-fc0085667f33" + } + }, + "image_source": { + "type": "artifact", + "hash": "988cab6ea184b7912350e5af151bd18152ee2702bad7dc0b977d414eb8062e27" + } + }, + "5c97418b-8318-4427-8f65-14f3e3362d13": { + "id": "5c97418b-8318-4427-8f65-14f3e3362d13", + "filesystem_pool": "oxp_2115b084-be0f-4fba-941b-33a659798a9e", + "zone_type": { + "type": "external_dns", + "dataset": { + "pool_name": "oxp_2115b084-be0f-4fba-941b-33a659798a9e" + }, + "http_address": "[fd00:1122:3344:103::46]:5353", + "dns_address": "172.20.26.2:53", + "nic": { + "id": "9e5b3233-1bb2-4d10-a99a-6884d6ab4d7d", + "kind": { + "type": "service", + "id": "5c97418b-8318-4427-8f65-14f3e3362d13" + }, + "name": "external-dns-5c97418b-8318-4427-8f65-14f3e3362d13", + "ip_config": { + "type": "v4", + "value": { + "ip": "172.30.1.6", + "subnet": "172.30.1.0/24", + "transit_ips": [] + } + }, + "mac": "A8:40:25:FF:80:01", + "vni": 100, + "primary": true, + "slot": 0 + } + }, + "image_source": { + "type": "artifact", + "hash": "389335a28c7bb548e68537df4bf5be5df7f2f54db1fba6b1cba3ad36ad48e625" + } + }, + "7153983f-8fd7-4fb9-92ac-0f07a07798b4": { + "id": "7153983f-8fd7-4fb9-92ac-0f07a07798b4", + "filesystem_pool": "oxp_bf428719-1b16-4503-99f4-ad95846d916f", + "zone_type": { + "type": "crucible", + "address": "[fd00:1122:3344:103::a]:32345", + "dataset": { + "pool_name": "oxp_bf428719-1b16-4503-99f4-ad95846d916f" + } + }, + "image_source": { + "type": "artifact", + "hash": "988cab6ea184b7912350e5af151bd18152ee2702bad7dc0b977d414eb8062e27" + } + }, + "7d44ba36-4a69-490a-bc40-f6f90a4208d4": { + "id": "7d44ba36-4a69-490a-bc40-f6f90a4208d4", + "filesystem_pool": "oxp_414e235b-55c3-4dc1-a568-8adf4ea1a052", + "zone_type": { + "type": "crucible", + "address": "[fd00:1122:3344:103::c]:32345", + "dataset": { + "pool_name": "oxp_414e235b-55c3-4dc1-a568-8adf4ea1a052" + } + }, + "image_source": { + "type": "artifact", + "hash": "988cab6ea184b7912350e5af151bd18152ee2702bad7dc0b977d414eb8062e27" + } + }, + "a6ba8273-0320-4dab-b801-281f041b0c50": { + "id": "a6ba8273-0320-4dab-b801-281f041b0c50", + "filesystem_pool": "oxp_8a199f12-4f5c-483a-8aca-f97856658a35", + "zone_type": { + "type": "crucible", + "address": "[fd00:1122:3344:103::4]:32345", + "dataset": { + "pool_name": "oxp_8a199f12-4f5c-483a-8aca-f97856658a35" + } + }, + "image_source": { + "type": "artifact", + "hash": "988cab6ea184b7912350e5af151bd18152ee2702bad7dc0b977d414eb8062e27" + } + }, + "a700528f-f600-4908-94ac-9c06442ef6b4": { + "id": "a700528f-f600-4908-94ac-9c06442ef6b4", + "filesystem_pool": "oxp_2115b084-be0f-4fba-941b-33a659798a9e", + "zone_type": { + "type": "internal_ntp", + "address": "[fd00:1122:3344:103::45]:123" + }, + "image_source": { + "type": "artifact", + "hash": "2b0988a6122b34391f3310ce1ade733c175316331f408cf1e40329c419318142" + } + }, + "b9b7b4c2-284a-4ec1-80ea-75b7a43b71c4": { + "id": "b9b7b4c2-284a-4ec1-80ea-75b7a43b71c4", + "filesystem_pool": "oxp_cf940e15-dbc5-481b-866a-4de4b018898e", + "zone_type": { + "type": "crucible", + "address": "[fd00:1122:3344:103::8]:32345", + "dataset": { + "pool_name": "oxp_cf940e15-dbc5-481b-866a-4de4b018898e" + } + }, + "image_source": { + "type": "artifact", + "hash": "988cab6ea184b7912350e5af151bd18152ee2702bad7dc0b977d414eb8062e27" + } + }, + "e238116d-e5cc-43d4-9c8a-6f138ae8a15d": { + "id": "e238116d-e5cc-43d4-9c8a-6f138ae8a15d", + "filesystem_pool": "oxp_e126ddcc-8bee-46ba-8199-2a74df0ba040", + "zone_type": { + "type": "crucible", + "address": "[fd00:1122:3344:103::6]:32345", + "dataset": { + "pool_name": "oxp_e126ddcc-8bee-46ba-8199-2a74df0ba040" + } + }, + "image_source": { + "type": "artifact", + "hash": "988cab6ea184b7912350e5af151bd18152ee2702bad7dc0b977d414eb8062e27" + } + } + }, + "remove_mupdate_override": null, + "host_phase_2": { + "slot_a": { + "type": "artifact", + "hash": "8234c10964ef7f62880772caaf96f449234bad8428b2a6a09e623d383550bfdf" + }, + "slot_b": { + "type": "artifact", + "hash": "8234c10964ef7f62880772caaf96f449234bad8428b2a6a09e623d383550bfdf" + } + } +} \ No newline at end of file diff --git a/sled-agent/config-reconciler/expectorate/v11-sled-config.json b/sled-agent/config-reconciler/expectorate/v11-sled-config.json new file mode 100644 index 00000000000..b3e01ed0cab --- /dev/null +++ b/sled-agent/config-reconciler/expectorate/v11-sled-config.json @@ -0,0 +1,1005 @@ +{ + "generation": 351, + "disks": { + "10fec275-f937-40f7-9c25-616079ef3816": { + "identity": { + "vendor": "1b96", + "model": "WUS4C6432DSP3X3", + "serial": "A084A5E3" + }, + "id": "10fec275-f937-40f7-9c25-616079ef3816", + "pool_id": "6340805e-c5af-418d-8bd1-fc0085667f33" + }, + "883b970b-2b70-4771-bb0e-aed2765c3e6a": { + "identity": { + "vendor": "1b96", + "model": "WUS4C6432DSP3X3", + "serial": "A084A79D" + }, + "id": "883b970b-2b70-4771-bb0e-aed2765c3e6a", + "pool_id": "414e235b-55c3-4dc1-a568-8adf4ea1a052" + }, + "9272fa96-eef8-43ed-8658-12ccf722bec2": { + "identity": { + "vendor": "1b96", + "model": "WUS4C6432DSP3X3", + "serial": "A084A61D" + }, + "id": "9272fa96-eef8-43ed-8658-12ccf722bec2", + "pool_id": "7b24095a-72df-45e3-984f-2b795e052ac7" + }, + "b20f225f-fef6-4ef5-a474-bd818013fceb": { + "identity": { + "vendor": "1b96", + "model": "WUS4C6432DSP3X3", + "serial": "A084A7EE" + }, + "id": "b20f225f-fef6-4ef5-a474-bd818013fceb", + "pool_id": "b93f880e-c55b-4d6c-9a16-939d84b628fc" + }, + "b483c693-700f-4630-92bb-9659e735648b": { + "identity": { + "vendor": "1b96", + "model": "WUS4C6432DSP3X3", + "serial": "A084A67C" + }, + "id": "b483c693-700f-4630-92bb-9659e735648b", + "pool_id": "cf940e15-dbc5-481b-866a-4de4b018898e" + }, + "c9bd1b35-c87a-4acf-bf52-06ed624e3be0": { + "identity": { + "vendor": "1b96", + "model": "WUS4C6432DSP3X3", + "serial": "A084A6F3" + }, + "id": "c9bd1b35-c87a-4acf-bf52-06ed624e3be0", + "pool_id": "8a199f12-4f5c-483a-8aca-f97856658a35" + }, + "d45fb895-f500-473f-9bdb-3d1f15464055": { + "identity": { + "vendor": "1b96", + "model": "WUS4C6432DSP3X3", + "serial": "A084A5C3" + }, + "id": "d45fb895-f500-473f-9bdb-3d1f15464055", + "pool_id": "26e698bb-006d-4208-94b9-d1bc279111fa" + }, + "d9fb1545-4051-4710-bcfd-8d33115bb022": { + "identity": { + "vendor": "1b96", + "model": "WUS4C6432DSP3X3", + "serial": "A084A7BE" + }, + "id": "d9fb1545-4051-4710-bcfd-8d33115bb022", + "pool_id": "e126ddcc-8bee-46ba-8199-2a74df0ba040" + }, + "e1bfe0a7-e848-4907-9068-22e02bad03ca": { + "identity": { + "vendor": "1b96", + "model": "WUS4C6432DSP3X3", + "serial": "A084A7DA" + }, + "id": "e1bfe0a7-e848-4907-9068-22e02bad03ca", + "pool_id": "2115b084-be0f-4fba-941b-33a659798a9e" + }, + "f6d26664-f32e-46c4-a3f3-74d55dae7fac": { + "identity": { + "vendor": "1b96", + "model": "WUS4C6432DSP3X3", + "serial": "A084A75D" + }, + "id": "f6d26664-f32e-46c4-a3f3-74d55dae7fac", + "pool_id": "bf428719-1b16-4503-99f4-ad95846d916f" + } + }, + "datasets": { + "01f93020-7e7d-4185-93fb-6ca234056c82": { + "id": "01f93020-7e7d-4185-93fb-6ca234056c82", + "name": { + "pool_name": "oxp_7b24095a-72df-45e3-984f-2b795e052ac7", + "kind": "crucible" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "01ffd316-ea25-4287-95aa-01bf6b036a16": { + "id": "01ffd316-ea25-4287-95aa-01bf6b036a16", + "name": { + "pool_name": "oxp_7b24095a-72df-45e3-984f-2b795e052ac7", + "kind": "zone/oxz_crucible_01f93020-7e7d-4185-93fb-6ca234056c82" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "02a5be47-df19-4159-b793-98a888603200": { + "id": "02a5be47-df19-4159-b793-98a888603200", + "name": { + "pool_name": "oxp_cf940e15-dbc5-481b-866a-4de4b018898e", + "kind": "debug" + }, + "compression": { + "type": "gzip_n", + "level": 9 + }, + "quota": 107374182400, + "reservation": null + }, + "072fdae8-2adf-4fd2-94ce-e9b0663b91e7": { + "id": "072fdae8-2adf-4fd2-94ce-e9b0663b91e7", + "name": { + "pool_name": "oxp_26e698bb-006d-4208-94b9-d1bc279111fa", + "kind": "crucible" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "088ff0e3-9b7e-4798-901c-fe88cf7aca52": { + "id": "088ff0e3-9b7e-4798-901c-fe88cf7aca52", + "name": { + "pool_name": "oxp_bf428719-1b16-4503-99f4-ad95846d916f", + "kind": "zone" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "0b41c560-3b20-42f4-82ad-92f5bb575d6b": { + "id": "0b41c560-3b20-42f4-82ad-92f5bb575d6b", + "name": { + "pool_name": "oxp_b93f880e-c55b-4d6c-9a16-939d84b628fc", + "kind": "crucible" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "0ccf27c0-e32d-4b52-a2c5-6db0c64a26f9": { + "id": "0ccf27c0-e32d-4b52-a2c5-6db0c64a26f9", + "name": { + "pool_name": "oxp_2115b084-be0f-4fba-941b-33a659798a9e", + "kind": "crucible" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "14b70f75-89e1-4ded-a7c4-dcf49ebd87ba": { + "id": "14b70f75-89e1-4ded-a7c4-dcf49ebd87ba", + "name": { + "pool_name": "oxp_b93f880e-c55b-4d6c-9a16-939d84b628fc", + "kind": "zone/oxz_crucible_0b41c560-3b20-42f4-82ad-92f5bb575d6b" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "1a00597c-8225-4324-9530-aaad3d7a9138": { + "id": "1a00597c-8225-4324-9530-aaad3d7a9138", + "name": { + "pool_name": "oxp_414e235b-55c3-4dc1-a568-8adf4ea1a052", + "kind": "zone/oxz_crucible_7d44ba36-4a69-490a-bc40-f6f90a4208d4" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "257d5c91-5bd5-4a13-802b-0995f76df671": { + "id": "257d5c91-5bd5-4a13-802b-0995f76df671", + "name": { + "pool_name": "oxp_2115b084-be0f-4fba-941b-33a659798a9e", + "kind": "zone/oxz_nexus_470fbf4d-0178-45ee-a422-136fa5f4a158" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "27bb57f7-abc6-4550-b1c6-5a18c7356748": { + "id": "27bb57f7-abc6-4550-b1c6-5a18c7356748", + "name": { + "pool_name": "oxp_26e698bb-006d-4208-94b9-d1bc279111fa", + "kind": "debug" + }, + "compression": { + "type": "gzip_n", + "level": 9 + }, + "quota": 107374182400, + "reservation": null + }, + "2bd226bd-edce-488c-bbe8-e0b301664de0": { + "id": "2bd226bd-edce-488c-bbe8-e0b301664de0", + "name": { + "pool_name": "oxp_2115b084-be0f-4fba-941b-33a659798a9e", + "kind": "local_storage" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "2c260613-a7bc-401e-ab73-cde4069ef09a": { + "id": "2c260613-a7bc-401e-ab73-cde4069ef09a", + "name": { + "pool_name": "oxp_7b24095a-72df-45e3-984f-2b795e052ac7", + "kind": "debug" + }, + "compression": { + "type": "gzip_n", + "level": 9 + }, + "quota": 107374182400, + "reservation": null + }, + "2fa20fca-7b61-4e56-8dbf-f56171bf35e1": { + "id": "2fa20fca-7b61-4e56-8dbf-f56171bf35e1", + "name": { + "pool_name": "oxp_2115b084-be0f-4fba-941b-33a659798a9e", + "kind": "debug" + }, + "compression": { + "type": "gzip_n", + "level": 9 + }, + "quota": 107374182400, + "reservation": null + }, + "34007214-81f0-4768-804d-d090695f1f09": { + "id": "34007214-81f0-4768-804d-d090695f1f09", + "name": { + "pool_name": "oxp_2115b084-be0f-4fba-941b-33a659798a9e", + "kind": "external_dns" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "46596dcd-4bea-4878-b498-1b9da4437aff": { + "id": "46596dcd-4bea-4878-b498-1b9da4437aff", + "name": { + "pool_name": "oxp_8a199f12-4f5c-483a-8aca-f97856658a35", + "kind": "debug" + }, + "compression": { + "type": "gzip_n", + "level": 9 + }, + "quota": 107374182400, + "reservation": null + }, + "468152ab-b771-4caf-9ca2-8abbd6fc5bec": { + "id": "468152ab-b771-4caf-9ca2-8abbd6fc5bec", + "name": { + "pool_name": "oxp_e126ddcc-8bee-46ba-8199-2a74df0ba040", + "kind": "debug" + }, + "compression": { + "type": "gzip_n", + "level": 9 + }, + "quota": 107374182400, + "reservation": null + }, + "46c13daf-0808-496a-b0f8-9eca75fcfa84": { + "id": "46c13daf-0808-496a-b0f8-9eca75fcfa84", + "name": { + "pool_name": "oxp_6340805e-c5af-418d-8bd1-fc0085667f33", + "kind": "debug" + }, + "compression": { + "type": "gzip_n", + "level": 9 + }, + "quota": 107374182400, + "reservation": null + }, + "4b771fc2-312a-4abf-9eef-ae9ff3853a13": { + "id": "4b771fc2-312a-4abf-9eef-ae9ff3853a13", + "name": { + "pool_name": "oxp_2115b084-be0f-4fba-941b-33a659798a9e", + "kind": "zone" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "4e3b3938-ad72-4443-9d96-4d6ba8ab19fb": { + "id": "4e3b3938-ad72-4443-9d96-4d6ba8ab19fb", + "name": { + "pool_name": "oxp_6340805e-c5af-418d-8bd1-fc0085667f33", + "kind": "zone/oxz_crucible_585cd8c5-c41e-4be4-beb8-bfbef9b53856" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "50b12371-0120-4210-89c7-2ecd58bea4d3": { + "id": "50b12371-0120-4210-89c7-2ecd58bea4d3", + "name": { + "pool_name": "oxp_b93f880e-c55b-4d6c-9a16-939d84b628fc", + "kind": "local_storage" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "5171b6ba-b282-4e71-917e-f253c7b2eb22": { + "id": "5171b6ba-b282-4e71-917e-f253c7b2eb22", + "name": { + "pool_name": "oxp_7b24095a-72df-45e3-984f-2b795e052ac7", + "kind": "zone" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "5625f171-927d-4e4a-b009-be250ac92bc3": { + "id": "5625f171-927d-4e4a-b009-be250ac92bc3", + "name": { + "pool_name": "oxp_8a199f12-4f5c-483a-8aca-f97856658a35", + "kind": "local_storage" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "56b0119a-f49d-45d7-a93e-d4a4e1d76559": { + "id": "56b0119a-f49d-45d7-a93e-d4a4e1d76559", + "name": { + "pool_name": "oxp_e126ddcc-8bee-46ba-8199-2a74df0ba040", + "kind": "zone" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "585cd8c5-c41e-4be4-beb8-bfbef9b53856": { + "id": "585cd8c5-c41e-4be4-beb8-bfbef9b53856", + "name": { + "pool_name": "oxp_6340805e-c5af-418d-8bd1-fc0085667f33", + "kind": "crucible" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "5b0bc0d3-24c6-4f9c-937b-f38e8ccee03c": { + "id": "5b0bc0d3-24c6-4f9c-937b-f38e8ccee03c", + "name": { + "pool_name": "oxp_26e698bb-006d-4208-94b9-d1bc279111fa", + "kind": "local_storage" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "5c4e9d03-f202-46dd-ba50-179b2b84f849": { + "id": "5c4e9d03-f202-46dd-ba50-179b2b84f849", + "name": { + "pool_name": "oxp_bf428719-1b16-4503-99f4-ad95846d916f", + "kind": "zone/oxz_crucible_7153983f-8fd7-4fb9-92ac-0f07a07798b4" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "69794309-1082-410b-a2a1-8b97588efa16": { + "id": "69794309-1082-410b-a2a1-8b97588efa16", + "name": { + "pool_name": "oxp_b93f880e-c55b-4d6c-9a16-939d84b628fc", + "kind": "zone" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "69a6412f-8438-4a0d-9c6e-a2e766750b2c": { + "id": "69a6412f-8438-4a0d-9c6e-a2e766750b2c", + "name": { + "pool_name": "oxp_2115b084-be0f-4fba-941b-33a659798a9e", + "kind": "zone/oxz_external_dns_5c97418b-8318-4427-8f65-14f3e3362d13" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "7153983f-8fd7-4fb9-92ac-0f07a07798b4": { + "id": "7153983f-8fd7-4fb9-92ac-0f07a07798b4", + "name": { + "pool_name": "oxp_bf428719-1b16-4503-99f4-ad95846d916f", + "kind": "crucible" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "77906e4e-1bbc-49c9-a7ee-f581de5552c4": { + "id": "77906e4e-1bbc-49c9-a7ee-f581de5552c4", + "name": { + "pool_name": "oxp_e126ddcc-8bee-46ba-8199-2a74df0ba040", + "kind": "zone/oxz_crucible_e238116d-e5cc-43d4-9c8a-6f138ae8a15d" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "7d44ba36-4a69-490a-bc40-f6f90a4208d4": { + "id": "7d44ba36-4a69-490a-bc40-f6f90a4208d4", + "name": { + "pool_name": "oxp_414e235b-55c3-4dc1-a568-8adf4ea1a052", + "kind": "crucible" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "8bce1ea9-5d2f-451a-87fd-db9140e07420": { + "id": "8bce1ea9-5d2f-451a-87fd-db9140e07420", + "name": { + "pool_name": "oxp_8a199f12-4f5c-483a-8aca-f97856658a35", + "kind": "zone/oxz_crucible_a6ba8273-0320-4dab-b801-281f041b0c50" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "8f50c2e8-d091-4440-b9cc-0c6c3e62b8b8": { + "id": "8f50c2e8-d091-4440-b9cc-0c6c3e62b8b8", + "name": { + "pool_name": "oxp_2115b084-be0f-4fba-941b-33a659798a9e", + "kind": "zone/oxz_crucible_0ccf27c0-e32d-4b52-a2c5-6db0c64a26f9" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "9721d822-c80a-4856-a715-02c9c0c89184": { + "id": "9721d822-c80a-4856-a715-02c9c0c89184", + "name": { + "pool_name": "oxp_e126ddcc-8bee-46ba-8199-2a74df0ba040", + "kind": "local_storage" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "978354d3-17cb-40ce-815d-b4edaad79f11": { + "id": "978354d3-17cb-40ce-815d-b4edaad79f11", + "name": { + "pool_name": "oxp_26e698bb-006d-4208-94b9-d1bc279111fa", + "kind": "zone" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "9bf9e7bd-269b-4925-ba99-a0cdb8138fb8": { + "id": "9bf9e7bd-269b-4925-ba99-a0cdb8138fb8", + "name": { + "pool_name": "oxp_cf940e15-dbc5-481b-866a-4de4b018898e", + "kind": "local_storage" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "a2d0f801-bf2d-44a3-b39b-bbfb3b387a4a": { + "id": "a2d0f801-bf2d-44a3-b39b-bbfb3b387a4a", + "name": { + "pool_name": "oxp_bf428719-1b16-4503-99f4-ad95846d916f", + "kind": "debug" + }, + "compression": { + "type": "gzip_n", + "level": 9 + }, + "quota": 107374182400, + "reservation": null + }, + "a6ba8273-0320-4dab-b801-281f041b0c50": { + "id": "a6ba8273-0320-4dab-b801-281f041b0c50", + "name": { + "pool_name": "oxp_8a199f12-4f5c-483a-8aca-f97856658a35", + "kind": "crucible" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "a6cbbb5d-f7b3-4d91-b54e-c3cf55762adc": { + "id": "a6cbbb5d-f7b3-4d91-b54e-c3cf55762adc", + "name": { + "pool_name": "oxp_bf428719-1b16-4503-99f4-ad95846d916f", + "kind": "local_storage" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "a724aab1-2fdc-45aa-8fa2-2f0a272aae62": { + "id": "a724aab1-2fdc-45aa-8fa2-2f0a272aae62", + "name": { + "pool_name": "oxp_414e235b-55c3-4dc1-a568-8adf4ea1a052", + "kind": "local_storage" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "aa44f101-8502-4480-bec8-9c48d3f4106b": { + "id": "aa44f101-8502-4480-bec8-9c48d3f4106b", + "name": { + "pool_name": "oxp_cf940e15-dbc5-481b-866a-4de4b018898e", + "kind": "zone" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "adb8db9b-2cd7-45b7-bb9f-adf094c4ccca": { + "id": "adb8db9b-2cd7-45b7-bb9f-adf094c4ccca", + "name": { + "pool_name": "oxp_414e235b-55c3-4dc1-a568-8adf4ea1a052", + "kind": "debug" + }, + "compression": { + "type": "gzip_n", + "level": 9 + }, + "quota": 107374182400, + "reservation": null + }, + "b156677f-cafa-4d73-9719-6b0d16dad722": { + "id": "b156677f-cafa-4d73-9719-6b0d16dad722", + "name": { + "pool_name": "oxp_8a199f12-4f5c-483a-8aca-f97856658a35", + "kind": "zone" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "b9b7b4c2-284a-4ec1-80ea-75b7a43b71c4": { + "id": "b9b7b4c2-284a-4ec1-80ea-75b7a43b71c4", + "name": { + "pool_name": "oxp_cf940e15-dbc5-481b-866a-4de4b018898e", + "kind": "crucible" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "c5e4bd8a-d323-48ec-a641-5c7dbecf3252": { + "id": "c5e4bd8a-d323-48ec-a641-5c7dbecf3252", + "name": { + "pool_name": "oxp_7b24095a-72df-45e3-984f-2b795e052ac7", + "kind": "local_storage" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "c9c7a527-d432-490d-86b3-658da7b555cc": { + "id": "c9c7a527-d432-490d-86b3-658da7b555cc", + "name": { + "pool_name": "oxp_26e698bb-006d-4208-94b9-d1bc279111fa", + "kind": "zone/oxz_crucible_072fdae8-2adf-4fd2-94ce-e9b0663b91e7" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "d8b3ba09-1267-43af-9734-1fdc3e22b23e": { + "id": "d8b3ba09-1267-43af-9734-1fdc3e22b23e", + "name": { + "pool_name": "oxp_cf940e15-dbc5-481b-866a-4de4b018898e", + "kind": "zone/oxz_crucible_b9b7b4c2-284a-4ec1-80ea-75b7a43b71c4" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "dee3ca8e-c6f5-4e12-aa0d-74ed9a6245a3": { + "id": "dee3ca8e-c6f5-4e12-aa0d-74ed9a6245a3", + "name": { + "pool_name": "oxp_2115b084-be0f-4fba-941b-33a659798a9e", + "kind": "zone/oxz_ntp_a700528f-f600-4908-94ac-9c06442ef6b4" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "e1c7ecae-faed-4d02-b446-2dd3478dc27d": { + "id": "e1c7ecae-faed-4d02-b446-2dd3478dc27d", + "name": { + "pool_name": "oxp_b93f880e-c55b-4d6c-9a16-939d84b628fc", + "kind": "debug" + }, + "compression": { + "type": "gzip_n", + "level": 9 + }, + "quota": 107374182400, + "reservation": null + }, + "e238116d-e5cc-43d4-9c8a-6f138ae8a15d": { + "id": "e238116d-e5cc-43d4-9c8a-6f138ae8a15d", + "name": { + "pool_name": "oxp_e126ddcc-8bee-46ba-8199-2a74df0ba040", + "kind": "crucible" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "e3d07396-5ab6-4008-b590-df8b5794f9e1": { + "id": "e3d07396-5ab6-4008-b590-df8b5794f9e1", + "name": { + "pool_name": "oxp_6340805e-c5af-418d-8bd1-fc0085667f33", + "kind": "local_storage" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "e7d578b0-2c40-4e1f-a1c2-2dc2a6f9f5d8": { + "id": "e7d578b0-2c40-4e1f-a1c2-2dc2a6f9f5d8", + "name": { + "pool_name": "oxp_6340805e-c5af-418d-8bd1-fc0085667f33", + "kind": "zone" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "fb307365-fd47-4112-9a88-519ee5cf6445": { + "id": "fb307365-fd47-4112-9a88-519ee5cf6445", + "name": { + "pool_name": "oxp_414e235b-55c3-4dc1-a568-8adf4ea1a052", + "kind": "zone" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + } + }, + "zones": { + "01f93020-7e7d-4185-93fb-6ca234056c82": { + "id": "01f93020-7e7d-4185-93fb-6ca234056c82", + "filesystem_pool": "oxp_7b24095a-72df-45e3-984f-2b795e052ac7", + "zone_type": { + "type": "crucible", + "address": "[fd00:1122:3344:103::5]:32345", + "dataset": { + "pool_name": "oxp_7b24095a-72df-45e3-984f-2b795e052ac7" + } + }, + "image_source": { + "type": "artifact", + "hash": "988cab6ea184b7912350e5af151bd18152ee2702bad7dc0b977d414eb8062e27" + } + }, + "072fdae8-2adf-4fd2-94ce-e9b0663b91e7": { + "id": "072fdae8-2adf-4fd2-94ce-e9b0663b91e7", + "filesystem_pool": "oxp_26e698bb-006d-4208-94b9-d1bc279111fa", + "zone_type": { + "type": "crucible", + "address": "[fd00:1122:3344:103::b]:32345", + "dataset": { + "pool_name": "oxp_26e698bb-006d-4208-94b9-d1bc279111fa" + } + }, + "image_source": { + "type": "artifact", + "hash": "988cab6ea184b7912350e5af151bd18152ee2702bad7dc0b977d414eb8062e27" + } + }, + "0b41c560-3b20-42f4-82ad-92f5bb575d6b": { + "id": "0b41c560-3b20-42f4-82ad-92f5bb575d6b", + "filesystem_pool": "oxp_b93f880e-c55b-4d6c-9a16-939d84b628fc", + "zone_type": { + "type": "crucible", + "address": "[fd00:1122:3344:103::9]:32345", + "dataset": { + "pool_name": "oxp_b93f880e-c55b-4d6c-9a16-939d84b628fc" + } + }, + "image_source": { + "type": "artifact", + "hash": "988cab6ea184b7912350e5af151bd18152ee2702bad7dc0b977d414eb8062e27" + } + }, + "0ccf27c0-e32d-4b52-a2c5-6db0c64a26f9": { + "id": "0ccf27c0-e32d-4b52-a2c5-6db0c64a26f9", + "filesystem_pool": "oxp_2115b084-be0f-4fba-941b-33a659798a9e", + "zone_type": { + "type": "crucible", + "address": "[fd00:1122:3344:103::d]:32345", + "dataset": { + "pool_name": "oxp_2115b084-be0f-4fba-941b-33a659798a9e" + } + }, + "image_source": { + "type": "artifact", + "hash": "988cab6ea184b7912350e5af151bd18152ee2702bad7dc0b977d414eb8062e27" + } + }, + "470fbf4d-0178-45ee-a422-136fa5f4a158": { + "id": "470fbf4d-0178-45ee-a422-136fa5f4a158", + "filesystem_pool": "oxp_2115b084-be0f-4fba-941b-33a659798a9e", + "zone_type": { + "type": "nexus", + "internal_address": "[fd00:1122:3344:103::47]:12221", + "lockstep_port": 12232, + "external_ip": "172.20.26.8", + "nic": { + "id": "98d2e08e-a3a6-43ed-a2a0-7cf52fd211f8", + "kind": { + "type": "service", + "id": "470fbf4d-0178-45ee-a422-136fa5f4a158" + }, + "name": "nexus-470fbf4d-0178-45ee-a422-136fa5f4a158", + "ip_config": { + "type": "v4", + "value": { + "ip": "172.30.2.9", + "subnet": "172.30.2.0/24", + "transit_ips": [] + } + }, + "mac": "A8:40:25:FF:80:05", + "vni": 100, + "primary": true, + "slot": 0 + }, + "external_tls": true, + "external_dns_servers": [ + "1.1.1.1", + "9.9.9.9" + ] + }, + "image_source": { + "type": "artifact", + "hash": "1ae3b88364f311ce588ac802cb8177c4806b76da0ce42e39aab0b0d8bb04c197" + } + }, + "585cd8c5-c41e-4be4-beb8-bfbef9b53856": { + "id": "585cd8c5-c41e-4be4-beb8-bfbef9b53856", + "filesystem_pool": "oxp_6340805e-c5af-418d-8bd1-fc0085667f33", + "zone_type": { + "type": "crucible", + "address": "[fd00:1122:3344:103::7]:32345", + "dataset": { + "pool_name": "oxp_6340805e-c5af-418d-8bd1-fc0085667f33" + } + }, + "image_source": { + "type": "artifact", + "hash": "988cab6ea184b7912350e5af151bd18152ee2702bad7dc0b977d414eb8062e27" + } + }, + "5c97418b-8318-4427-8f65-14f3e3362d13": { + "id": "5c97418b-8318-4427-8f65-14f3e3362d13", + "filesystem_pool": "oxp_2115b084-be0f-4fba-941b-33a659798a9e", + "zone_type": { + "type": "external_dns", + "dataset": { + "pool_name": "oxp_2115b084-be0f-4fba-941b-33a659798a9e" + }, + "http_address": "[fd00:1122:3344:103::46]:5353", + "dns_address": "172.20.26.2:53", + "nic": { + "id": "9e5b3233-1bb2-4d10-a99a-6884d6ab4d7d", + "kind": { + "type": "service", + "id": "5c97418b-8318-4427-8f65-14f3e3362d13" + }, + "name": "external-dns-5c97418b-8318-4427-8f65-14f3e3362d13", + "ip_config": { + "type": "v4", + "value": { + "ip": "172.30.1.6", + "subnet": "172.30.1.0/24", + "transit_ips": [] + } + }, + "mac": "A8:40:25:FF:80:01", + "vni": 100, + "primary": true, + "slot": 0 + } + }, + "image_source": { + "type": "artifact", + "hash": "389335a28c7bb548e68537df4bf5be5df7f2f54db1fba6b1cba3ad36ad48e625" + } + }, + "7153983f-8fd7-4fb9-92ac-0f07a07798b4": { + "id": "7153983f-8fd7-4fb9-92ac-0f07a07798b4", + "filesystem_pool": "oxp_bf428719-1b16-4503-99f4-ad95846d916f", + "zone_type": { + "type": "crucible", + "address": "[fd00:1122:3344:103::a]:32345", + "dataset": { + "pool_name": "oxp_bf428719-1b16-4503-99f4-ad95846d916f" + } + }, + "image_source": { + "type": "artifact", + "hash": "988cab6ea184b7912350e5af151bd18152ee2702bad7dc0b977d414eb8062e27" + } + }, + "7d44ba36-4a69-490a-bc40-f6f90a4208d4": { + "id": "7d44ba36-4a69-490a-bc40-f6f90a4208d4", + "filesystem_pool": "oxp_414e235b-55c3-4dc1-a568-8adf4ea1a052", + "zone_type": { + "type": "crucible", + "address": "[fd00:1122:3344:103::c]:32345", + "dataset": { + "pool_name": "oxp_414e235b-55c3-4dc1-a568-8adf4ea1a052" + } + }, + "image_source": { + "type": "artifact", + "hash": "988cab6ea184b7912350e5af151bd18152ee2702bad7dc0b977d414eb8062e27" + } + }, + "a6ba8273-0320-4dab-b801-281f041b0c50": { + "id": "a6ba8273-0320-4dab-b801-281f041b0c50", + "filesystem_pool": "oxp_8a199f12-4f5c-483a-8aca-f97856658a35", + "zone_type": { + "type": "crucible", + "address": "[fd00:1122:3344:103::4]:32345", + "dataset": { + "pool_name": "oxp_8a199f12-4f5c-483a-8aca-f97856658a35" + } + }, + "image_source": { + "type": "artifact", + "hash": "988cab6ea184b7912350e5af151bd18152ee2702bad7dc0b977d414eb8062e27" + } + }, + "a700528f-f600-4908-94ac-9c06442ef6b4": { + "id": "a700528f-f600-4908-94ac-9c06442ef6b4", + "filesystem_pool": "oxp_2115b084-be0f-4fba-941b-33a659798a9e", + "zone_type": { + "type": "internal_ntp", + "address": "[fd00:1122:3344:103::45]:123" + }, + "image_source": { + "type": "artifact", + "hash": "2b0988a6122b34391f3310ce1ade733c175316331f408cf1e40329c419318142" + } + }, + "b9b7b4c2-284a-4ec1-80ea-75b7a43b71c4": { + "id": "b9b7b4c2-284a-4ec1-80ea-75b7a43b71c4", + "filesystem_pool": "oxp_cf940e15-dbc5-481b-866a-4de4b018898e", + "zone_type": { + "type": "crucible", + "address": "[fd00:1122:3344:103::8]:32345", + "dataset": { + "pool_name": "oxp_cf940e15-dbc5-481b-866a-4de4b018898e" + } + }, + "image_source": { + "type": "artifact", + "hash": "988cab6ea184b7912350e5af151bd18152ee2702bad7dc0b977d414eb8062e27" + } + }, + "e238116d-e5cc-43d4-9c8a-6f138ae8a15d": { + "id": "e238116d-e5cc-43d4-9c8a-6f138ae8a15d", + "filesystem_pool": "oxp_e126ddcc-8bee-46ba-8199-2a74df0ba040", + "zone_type": { + "type": "crucible", + "address": "[fd00:1122:3344:103::6]:32345", + "dataset": { + "pool_name": "oxp_e126ddcc-8bee-46ba-8199-2a74df0ba040" + } + }, + "image_source": { + "type": "artifact", + "hash": "988cab6ea184b7912350e5af151bd18152ee2702bad7dc0b977d414eb8062e27" + } + } + }, + "remove_mupdate_override": null, + "host_phase_2": { + "slot_a": { + "type": "artifact", + "hash": "8234c10964ef7f62880772caaf96f449234bad8428b2a6a09e623d383550bfdf" + }, + "slot_b": { + "type": "artifact", + "hash": "8234c10964ef7f62880772caaf96f449234bad8428b2a6a09e623d383550bfdf" + } + } +} \ No newline at end of file diff --git a/sled-agent/config-reconciler/src/ledger.rs b/sled-agent/config-reconciler/src/ledger.rs index 2a4816feb8a..dedd3f63e56 100644 --- a/sled-agent/config-reconciler/src/ledger.rs +++ b/sled-agent/config-reconciler/src/ledger.rs @@ -663,14 +663,9 @@ enum LedgerTaskExit { #[cfg(test)] mod tests { - use super::ledgered_sled_config_versioning::tests::LEGACY_DATASETS_PATH; - use super::ledgered_sled_config_versioning::tests::LEGACY_DISKS_PATH; - use super::ledgered_sled_config_versioning::tests::LEGACY_ZONES_PATH; use super::*; use crate::internal_disks::InternalDiskDetails; - use crate::ledger::ledgered_sled_config_versioning::tests::test_data_merged_config; use anyhow::anyhow; - use camino::Utf8Path; use camino_tempfile::Utf8TempDir; use camino_tempfile::tempfile; use iddqd::IdOrdMap; @@ -748,7 +743,7 @@ mod tests { impl TestHarness { async fn new(log: Logger) -> Self { - Self::build(log, FakeArtifactStore::default(), None, false).await + Self::build(log, FakeArtifactStore::default(), None).await } async fn with_fake_artifacts( @@ -759,7 +754,6 @@ mod tests { log, FakeArtifactStore { artifacts: Some(artifacts.collect()) }, None, - false, ) .await } @@ -768,23 +762,15 @@ mod tests { log: Logger, config: &OmicronSledConfig, ) -> Self { - Self::build(log, FakeArtifactStore::default(), Some(config), false) - .await - } - - async fn with_legacy_ledgers(log: Logger) -> Self { - Self::build(log, FakeArtifactStore::default(), None, true).await + Self::build(log, FakeArtifactStore::default(), Some(config)).await } // If `sled_config` is `Some(_)`, that config will be written to the // tempdir's config dataset before the ledger task is spawned. - // Otherwise, if `copy_legacy_ledgers` is true, we'll copy our test data - // legacy ledgers into the tempdir's config dataset. async fn build( log: Logger, fake_artifact_store: FakeArtifactStore, sled_config: Option<&OmicronSledConfig>, - copy_legacy_ledgers: bool, ) -> Self { // Create the tempdir. let tempdir = Utf8TempDir::new().expect("created temp directory"); @@ -810,19 +796,6 @@ mod tests { .expect("created config file"); serde_json::to_writer(file, &sled_config) .expect("wrote config to file"); - } else if copy_legacy_ledgers { - for src in [ - LEGACY_DISKS_PATH, - LEGACY_DATASETS_PATH, - LEGACY_ZONES_PATH, - ] { - let src = Utf8Path::new(src); - let dst = path.join(src.file_name().unwrap()); - - tokio::fs::copy(src, dst) - .await - .expect("staged file in tempdir"); - } } } @@ -844,11 +817,11 @@ mod tests { Err(CondCheckError::<()>::NotYet) } CurrentSledConfig::WaitingForInitialConfig => { - assert!(sled_config.is_none() && !copy_legacy_ledgers); + assert!(sled_config.is_none()); Ok(()) } CurrentSledConfig::Ledgered(_) => { - assert!(sled_config.is_some() || copy_legacy_ledgers); + assert!(sled_config.is_some()); Ok(()) } }, @@ -1340,23 +1313,4 @@ mod tests { logctx.cleanup_successful(); } - - // Basic test that we convert the legacy triple of config ledgers if they're - // present. The `legacy_configs` submodule has more extensive tests of this - // functionality. - #[tokio::test] - async fn convert_legacy_ledgers_if_present() { - let logctx = dev::test_setup_log("convert_legacy_ledgers_if_present"); - - let test_harness = - TestHarness::with_legacy_ledgers(logctx.log.clone()).await; - - // It should have combined the legacy ledgers. - assert_eq!( - *test_harness.current_config_rx.borrow(), - CurrentSledConfig::Ledgered(Box::new(test_data_merged_config())), - ); - - logctx.cleanup_successful(); - } } diff --git a/sled-agent/config-reconciler/src/ledger/ledgered_sled_config_versioning.rs b/sled-agent/config-reconciler/src/ledger/ledgered_sled_config_versioning.rs index 3d6f91e567f..a6eaaf9602b 100644 --- a/sled-agent/config-reconciler/src/ledger/ledgered_sled_config_versioning.rs +++ b/sled-agent/config-reconciler/src/ledger/ledgered_sled_config_versioning.rs @@ -28,6 +28,9 @@ use std::error::Error as StdError; /// [`OmicronSledConfig`] alias from `latest`. The `Previous` associated type /// should point to the prior version (what was the current version before your /// change). +/// +/// Also update the unit tests at the bottom of this file to cover your new +/// version as well. trait VersionConversionChain: Ledgerable { /// A description of the version. This shows up in logs. const DESCRIPTION: &str; @@ -243,220 +246,124 @@ impl TryFrom #[cfg(test)] pub(super) mod tests { - use crate::ledger::CONFIG_LEDGER_FILENAME; - use super::*; - use camino::Utf8Path; use camino_tempfile::Utf8TempDir; + use camino_tempfile_ext::prelude::*; use omicron_test_utils::dev; - // Legacy configs collected from a test system. - pub(crate) const LEGACY_DISKS_PATH: &str = - "test-data/omicron-physical-disks.json"; - pub(crate) const LEGACY_DATASETS_PATH: &str = - "test-data/omicron-datasets.json"; - pub(crate) const LEGACY_ZONES_PATH: &str = "test-data/omicron-zones.json"; - - // The merged legacy configs above. We assert that it matches in - // test_merge_old_configs below. - const MERGED_CONFIG_PATH: &str = - "test-data/expectorate/merged-sled-config.json"; - - #[test] - fn test_old_config_schema() { - let schema = schemars::schema_for!(OmicronZonesConfigLocal); - expectorate::assert_contents( - "../../schema/all-zones-requests.json", - &serde_json::to_string_pretty(&schema).unwrap(), - ); - } + // v4 config collected from a test system. + const V4_CONFIG_PATH: &str = "test-data/v4-sled-config.json"; - #[tokio::test] - async fn can_convert_v9_config_version() { - let logctx = dev::test_setup_log("can_convert_v9_config_version"); - let tempdir = Utf8TempDir::new().expect("created tempdir"); - - // Copy version 6 into a tempdir. - println!("logging to {}", tempdir.path()); - let dst_file_name = Utf8PathBuf::from( - Utf8PathBuf::from(MERGED_CONFIG_PATH).file_name().unwrap(), - ); - let dst_file = tempdir.path().join(&dst_file_name); - tokio::fs::copy(MERGED_CONFIG_PATH, &dst_file) - .await - .expect("Copy old config into tempdir"); - println!("copied {} => {}", MERGED_CONFIG_PATH, dst_file); + // paths for expectorate checks + const EXPECTORATE_V10_CONFIG_PATH: &str = + "expectorate/v10-sled-config.json"; + const EXPECTORATE_V11_CONFIG_PATH: &str = + "expectorate/v11-sled-config.json"; - // Convert, which will rewrite the config as well. - let converted = - try_convert_v4_sled_config(&logctx.log, vec![dst_file.clone()]) - .await - .expect("Should have found and converted v9 config"); + // This is solely an expectorate test to guarantee: + // + // * the conversions for various versions function (at least starting from + // the v4 config we've committed) + // * we have input files at intermediate versions we can use in other tests + #[tokio::test] + async fn can_convert_v4_to_newer_versions() { + let logctx = dev::test_setup_log("can_convert_v4_to_newer_versions"); + let log = &logctx.log; - // And make sure it matches the new, directly loaded and converted from - // disk. - let new_as_v4: OmicronSledConfigV4 = serde_json::from_str( - tokio::fs::read_to_string(dst_file).await.unwrap().as_str(), + let v4 = Ledger::::new( + log, + vec![V4_CONFIG_PATH.into()], ) - .expect("successfully converted config"); - let new_as_v10 = OmicronSledConfigV10::try_from(new_as_v4) - .expect("successfully converted v4 config to v10"); - let new = OmicronSledConfig::try_from(new_as_v10) - .expect("successfully converted v10 config to current"); - assert_eq!(new, converted); - logctx.cleanup_successful(); - } + .await + .expect("read v4 from test-data") + .into_inner(); - #[test] - fn test_merge_old_configs() { - let disks: OmicronPhysicalDisksConfig = { - let mut f = std::fs::File::open(LEGACY_DISKS_PATH) - .expect("opened disks test data"); - serde_json::from_reader(&mut f).expect("parsed disks test data") - }; - let datasets: DatasetsConfig = { - let mut f = std::fs::File::open(LEGACY_DATASETS_PATH) - .expect("opened datasets test data"); - serde_json::from_reader(&mut f).expect("parsed datasets test data") - }; - let zones: OmicronZonesConfigLocal = { - let mut f = std::fs::File::open(LEGACY_ZONES_PATH) - .expect("opened zones test data"); - serde_json::from_reader(&mut f).expect("parsed zones test data") - }; - - let merged_config = - merge_old_configs(disks.clone(), datasets.clone(), zones.clone()); - - assert_eq!(merged_config.generation, zones.omicron_generation); - assert_eq!(merged_config.disks.len(), disks.disks.len()); - assert_eq!(merged_config.datasets.len(), datasets.datasets.len()); - assert_eq!(merged_config.zones.len(), zones.zones.len()); - - for disk in disks.disks { - assert_eq!(merged_config.disks.get(&disk.id), Some(&disk)); - } - for dataset in datasets.datasets.into_values() { - assert_eq!(merged_config.datasets.get(&dataset.id), Some(&dataset)); - } - for zone in zones.zones.into_iter().map(|z| z.zone) { - assert_eq!(merged_config.zones.get(&zone.id), Some(&zone)); - } + // For each version after the oldest, confirm we can convert and then + // assert the expectorate contents. - let serialized_merged_config = - serde_json::to_string_pretty(&merged_config) - .expect("config always serializes"); + let v10 = v10::inventory::OmicronSledConfig::try_from(v4) + .expect("converted from v4"); + let v11 = v11::inventory::OmicronSledConfig::try_from(v10.clone()) + .expect("converted from v10"); expectorate::assert_contents( - MERGED_CONFIG_PATH, - &serialized_merged_config, + EXPECTORATE_V10_CONFIG_PATH, + &serde_json::to_string_pretty(&v10).unwrap(), + ); + expectorate::assert_contents( + EXPECTORATE_V11_CONFIG_PATH, + &serde_json::to_string_pretty(&v11).unwrap(), ); - } - // Helper to read the expected sled config from our combined test data. - pub(crate) fn test_data_merged_config() -> OmicronSledConfig { - let mut f = std::fs::File::open(MERGED_CONFIG_PATH) - .expect("opened merged sled config test data"); - serde_json::from_reader(&mut f).expect("parsed sled config") + logctx.cleanup_successful(); } #[tokio::test] - async fn convert_legacy_ledgers_merges_old_configs() { - let logctx = - dev::test_setup_log("convert_legacy_ledgers_merges_old_configs"); - let tempdir = Utf8TempDir::new().expect("created tempdir"); - - // Copy the legacy configs into this directory. - for src in [LEGACY_DISKS_PATH, LEGACY_DATASETS_PATH, LEGACY_ZONES_PATH] - { - let src = Utf8Path::new(src); - let dst = tempdir.path().join(src.file_name().unwrap()); - - tokio::fs::copy(src, dst).await.expect("staged file in tempdir"); - } - - // We should get back the merged config. - let config = match convert_legacy_ledgers( - &[tempdir.path().to_owned()], - &logctx.log, + async fn read_config_converts_from_older_versions() { + let logctx = dev::test_setup_log("can_convert_v4_to_newer_versions"); + let log = &logctx.log; + + // All our configs should match the latest version. We use an explicit + // type here instead of the generic `OmicronSledConfig` so we get a + // compilation error if the latest version changes. Bump the + // version here and add the new version's path to the array of ledger + // paths below. + let latest_version_path = EXPECTORATE_V11_CONFIG_PATH; + let expected_config = v11::inventory::OmicronSledConfig::read_from( + log, + latest_version_path.into(), ) .await - { - Some(config) => { - assert_eq!(config, test_data_merged_config()); - config - } - None => panic!("convert_legacy_ledgers didn't merge configs"), - }; + .expect("read v11 config"); + + // Reading old configs should rewrite the file to match the newest + // version. + let expected_rewritten = + serde_json::to_string(&expected_config).expect("serialized config"); + + // If no conversion was necessary, we should keep the same contents. + // This is semantically equivalent to `expected_rewritten` but may be + // formatted differently (e.g., our expectorate files are written + // pretty-printed, but ledgered files generally aren't). + let expected_unchanged = tokio::fs::read_to_string(latest_version_path) + .await + .expect("read latest version"); + + let tempdir = Utf8TempDir::new().unwrap(); + + // For each older version, confirm we can read a ledger of that version + // and that it's converted to the current version. + for src_ledger_path in [ + V4_CONFIG_PATH, + EXPECTORATE_V10_CONFIG_PATH, + EXPECTORATE_V11_CONFIG_PATH, + ] { + // Copy the ledger into `my-ledger.json` + let dst_ledger_path = tempdir.child("my-ledger.json"); + dst_ledger_path.write_file(src_ledger_path.into()).unwrap(); + + // Attempt to read `my-ledger.json`; this should give us back a + // current-version `OmicronSledConfig` and also have rewritten the + // config. + let converted_config = read_ledgered_sled_config( + log, + vec![dst_ledger_path.to_path_buf()], + ) + .await + .expect("read and converted ledger"); + assert_eq!(expected_config, converted_config); - // The merged config should also have been written to the "dataset"... - let merged = - tokio::fs::read(tempdir.path().join(CONFIG_LEDGER_FILENAME)) + // We should only rewrite the file if we converted it. + let data = tokio::fs::read_to_string(&dst_ledger_path) .await - .expect("merged config written"); - assert_eq!( - config, - serde_json::from_slice::(&merged) - .expect("parsed merged config") - ); - - // ... and the legacy configs should have been removed. - // Copy the legacy configs into this directory. - for p in [LEGACY_DISKS_PATH, LEGACY_DATASETS_PATH, LEGACY_ZONES_PATH] { - let p = Utf8Path::new(p); - let old = tempdir.path().join(p.file_name().unwrap()); - assert!(!old.exists(), "legacy file wasn't removed: {old}"); - } - - logctx.cleanup_successful(); - } - - #[tokio::test] - async fn convert_legacy_ledgers_returns_none_if_no_legacy_configs() { - let logctx = dev::test_setup_log( - "convert_legacy_ledgers_returns_none_if_no_legacy_configs", - ); - let tempdir = Utf8TempDir::new().expect("created tempdir"); - - match convert_legacy_ledgers(&[tempdir.path().to_owned()], &logctx.log) - .await - { - Some(config) => panic!("unexpected config: {config:?}"), - None => (), + .expect("read tempdir ledger"); + if data != expected_unchanged { + // The data changed - we must have done a conversion. Assert it + // matches what we expect. + assert_eq!(data, expected_rewritten); + } } logctx.cleanup_successful(); } - - #[tokio::test] - #[should_panic( - expected = "Found partial legacy ledgers; unsafe to proceed" - )] - async fn convert_legacy_ledgers_panics_if_partial_legacy_configs() { - // This test intends to panic, but we still want to cleanup the logctx - // on that panic. Stuff it into a scopeguard to do so. - let logctx = - dev::test_setup_log("convert_legacy_ledgers_merges_old_configs"); - let logctx = scopeguard::guard(logctx, |logctx| { - logctx.cleanup_successful(); - }); - - // Copy just the disk and zones legacy configs; omit datasets. (This - // test would work equally well if we copied any 1 or 2 of the legacy - // files; we just pick one such combo.) - let tempdir = Utf8TempDir::new().expect("created tempdir"); - for src in [LEGACY_DISKS_PATH, LEGACY_ZONES_PATH] { - let src = Utf8Path::new(src); - let dst = tempdir.path().join(src.file_name().unwrap()); - - tokio::fs::copy(src, dst).await.expect("staged file in tempdir"); - } - - // This call should panic: it's not safe to proceed with startup if we - // have some but not all three legacy configs. - _ = convert_legacy_ledgers(&[tempdir.path().to_owned()], &logctx.log) - .await; - - unreachable!("convert_legacy_ledgers should have panicked"); - } } diff --git a/sled-agent/config-reconciler/test-data/README.md b/sled-agent/config-reconciler/test-data/README.md deleted file mode 100644 index 2200040c01b..00000000000 --- a/sled-agent/config-reconciler/test-data/README.md +++ /dev/null @@ -1,4 +0,0 @@ -The JSON files in this directory were collected from a sled on the dogfood rack -on May 1, 2025, and should not be modified; they're used for testing the -"convert from the legacy triple of configs into a unified config" code of this -crate. diff --git a/sled-agent/config-reconciler/test-data/expectorate/merged-sled-config.json b/sled-agent/config-reconciler/test-data/expectorate/merged-sled-config.json deleted file mode 100644 index c985a09af81..00000000000 --- a/sled-agent/config-reconciler/test-data/expectorate/merged-sled-config.json +++ /dev/null @@ -1,822 +0,0 @@ -{ - "generation": 5, - "disks": { - "1201b2d5-5491-4e96-aa9d-efd7afed0612": { - "identity": { - "vendor": "1b96", - "model": "WUS4C6432DSP3X3", - "serial": "A084A795" - }, - "id": "1201b2d5-5491-4e96-aa9d-efd7afed0612", - "pool_id": "b358fb1e-f52a-4a63-9aab-170225509b37" - }, - "25a61844-be5a-4b6d-bd3d-e6c7906ee52a": { - "identity": { - "vendor": "1b96", - "model": "WUS4C6432DSP3X3", - "serial": "A084A7C0" - }, - "id": "25a61844-be5a-4b6d-bd3d-e6c7906ee52a", - "pool_id": "4eb2e4eb-41d8-496c-9a5a-687d7e004aa4" - }, - "2fd7c854-5c0e-408e-8e4d-4b36ae42725d": { - "identity": { - "vendor": "1b96", - "model": "WUS4C6432DSP3X3", - "serial": "A084A5E5" - }, - "id": "2fd7c854-5c0e-408e-8e4d-4b36ae42725d", - "pool_id": "f8b11629-ced6-412a-9c3f-d169b99ee996" - }, - "6a19ddca-447e-4579-90b3-6826fa3f7950": { - "identity": { - "vendor": "1b96", - "model": "WUS4C6432DSP3X3", - "serial": "A084A6EF" - }, - "id": "6a19ddca-447e-4579-90b3-6826fa3f7950", - "pool_id": "d1cb6b7d-2b92-4b7d-8a4d-551987f0277e" - }, - "6ad551bd-487e-48fd-bf7a-fc80da2a027c": { - "identity": { - "vendor": "1b96", - "model": "WUS4C6432DSP3X3", - "serial": "A084A7F3" - }, - "id": "6ad551bd-487e-48fd-bf7a-fc80da2a027c", - "pool_id": "eb1234a5-fdf7-4977-94d5-2eef25ce56a1" - }, - "735d639f-f9c9-438d-a286-12190ce419db": { - "identity": { - "vendor": "1b96", - "model": "WUS4C6432DSP3X3", - "serial": "A084A606" - }, - "id": "735d639f-f9c9-438d-a286-12190ce419db", - "pool_id": "4358f47f-f21e-4cc8-829e-0c7fc2400a59" - }, - "76e4d7bf-c908-4843-bd41-ecd62bb42bd1": { - "identity": { - "vendor": "1b96", - "model": "WUS4C6432DSP3X3", - "serial": "A084A6CB" - }, - "id": "76e4d7bf-c908-4843-bd41-ecd62bb42bd1", - "pool_id": "0ae29053-29a2-489e-a1e6-6aec0ecd05f8" - }, - "c463143f-9a4e-4ac0-8c9f-49bd07f0f7f4": { - "identity": { - "vendor": "1b96", - "model": "WUS4C6432DSP3X3", - "serial": "A084A60D" - }, - "id": "c463143f-9a4e-4ac0-8c9f-49bd07f0f7f4", - "pool_id": "aadf48eb-6ff0-40b5-a092-1fdd06c03e11" - }, - "e63d3ba9-7a02-4171-bdab-9ccca465b08a": { - "identity": { - "vendor": "1b96", - "model": "WUS4C6432DSP3X3", - "serial": "A084A703" - }, - "id": "e63d3ba9-7a02-4171-bdab-9ccca465b08a", - "pool_id": "57650e05-36ff-4de8-865f-b9562bdb67f5" - }, - "e67a2c76-22dc-4f99-8b5b-c8c633fcf000": { - "identity": { - "vendor": "1b96", - "model": "WUS4C6432DSP3X3", - "serial": "A084A63C" - }, - "id": "e67a2c76-22dc-4f99-8b5b-c8c633fcf000", - "pool_id": "17eff217-f0b1-4353-b133-0f68bbd5ceaa" - } - }, - "datasets": { - "010e5295-84de-4820-b7ae-c68c6fd5fbba": { - "id": "010e5295-84de-4820-b7ae-c68c6fd5fbba", - "name": { - "pool_name": "oxp_0ae29053-29a2-489e-a1e6-6aec0ecd05f8", - "kind": "debug" - }, - "compression": { - "type": "gzip_n", - "level": 9 - }, - "quota": 107374182400, - "reservation": null - }, - "056fd7c9-56ab-4c27-93ed-c7ae716567e1": { - "id": "056fd7c9-56ab-4c27-93ed-c7ae716567e1", - "name": { - "pool_name": "oxp_d1cb6b7d-2b92-4b7d-8a4d-551987f0277e", - "kind": "zone" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "18ffa6fb-99f7-49fd-a192-bf10499c5654": { - "id": "18ffa6fb-99f7-49fd-a192-bf10499c5654", - "name": { - "pool_name": "oxp_57650e05-36ff-4de8-865f-b9562bdb67f5", - "kind": "debug" - }, - "compression": { - "type": "gzip_n", - "level": 9 - }, - "quota": 107374182400, - "reservation": null - }, - "239245eb-2917-4be3-94ea-f38adb70ed9a": { - "id": "239245eb-2917-4be3-94ea-f38adb70ed9a", - "name": { - "pool_name": "oxp_4358f47f-f21e-4cc8-829e-0c7fc2400a59", - "kind": "zone" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "23dca27d-c79b-4930-a817-392e8aeaa4c1": { - "id": "23dca27d-c79b-4930-a817-392e8aeaa4c1", - "name": { - "pool_name": "oxp_57650e05-36ff-4de8-865f-b9562bdb67f5", - "kind": "crucible" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "240f0791-4b3c-4506-a2ff-43f567095b87": { - "id": "240f0791-4b3c-4506-a2ff-43f567095b87", - "name": { - "pool_name": "oxp_0ae29053-29a2-489e-a1e6-6aec0ecd05f8", - "kind": "zone/oxz_crucible_pantry_375296e5-0a23-466c-b605-4204080f8103" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "25368942-b0a1-4063-8a54-f929d694f49e": { - "id": "25368942-b0a1-4063-8a54-f929d694f49e", - "name": { - "pool_name": "oxp_57650e05-36ff-4de8-865f-b9562bdb67f5", - "kind": "zone/oxz_crucible_23dca27d-c79b-4930-a817-392e8aeaa4c1" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "36a1bb9a-5985-43ab-ac3c-cfe168431fa9": { - "id": "36a1bb9a-5985-43ab-ac3c-cfe168431fa9", - "name": { - "pool_name": "oxp_d1cb6b7d-2b92-4b7d-8a4d-551987f0277e", - "kind": "debug" - }, - "compression": { - "type": "gzip_n", - "level": 9 - }, - "quota": 107374182400, - "reservation": null - }, - "3aaed2d8-7581-427f-9b0c-9b3d316b33a0": { - "id": "3aaed2d8-7581-427f-9b0c-9b3d316b33a0", - "name": { - "pool_name": "oxp_17eff217-f0b1-4353-b133-0f68bbd5ceaa", - "kind": "zone/oxz_crucible_9470ea7d-1920-4b4b-8fca-e7659a1ef733" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "3c14b954-e3b4-4cdd-bc02-b597b133e564": { - "id": "3c14b954-e3b4-4cdd-bc02-b597b133e564", - "name": { - "pool_name": "oxp_b358fb1e-f52a-4a63-9aab-170225509b37", - "kind": "zone/oxz_crucible_912346a2-d7e6-427e-b373-e8dcbe4fcea9" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "3d420dff-c616-4c7d-bab1-0f9c2b5396bf": { - "id": "3d420dff-c616-4c7d-bab1-0f9c2b5396bf", - "name": { - "pool_name": "oxp_4eb2e4eb-41d8-496c-9a5a-687d7e004aa4", - "kind": "crucible" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "3e26445a-b225-4432-b947-445139e29815": { - "id": "3e26445a-b225-4432-b947-445139e29815", - "name": { - "pool_name": "oxp_d1cb6b7d-2b92-4b7d-8a4d-551987f0277e", - "kind": "zone/oxz_crucible_f9c1deca-1898-429e-8c93-254c7aa7bae6" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "4090f4ca-89d5-403e-a8fb-8e2dcb9c5229": { - "id": "4090f4ca-89d5-403e-a8fb-8e2dcb9c5229", - "name": { - "pool_name": "oxp_57650e05-36ff-4de8-865f-b9562bdb67f5", - "kind": "zone/oxz_ntp_76b79b96-eaa2-4341-9aba-e77cfc92e0a9" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "419b3c50-17d0-438e-a456-b94acc9aee0d": { - "id": "419b3c50-17d0-438e-a456-b94acc9aee0d", - "name": { - "pool_name": "oxp_4eb2e4eb-41d8-496c-9a5a-687d7e004aa4", - "kind": "zone/oxz_crucible_3d420dff-c616-4c7d-bab1-0f9c2b5396bf" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "4c3ef132-ec83-4b1b-9574-7c7d3035f9e9": { - "id": "4c3ef132-ec83-4b1b-9574-7c7d3035f9e9", - "name": { - "pool_name": "oxp_b358fb1e-f52a-4a63-9aab-170225509b37", - "kind": "cockroachdb" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "4e83fc2f-4a80-4049-bcbb-a53cf017540c": { - "id": "4e83fc2f-4a80-4049-bcbb-a53cf017540c", - "name": { - "pool_name": "oxp_eb1234a5-fdf7-4977-94d5-2eef25ce56a1", - "kind": "zone" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "5c35e44c-0c03-4f9c-9387-59f5bee29e84": { - "id": "5c35e44c-0c03-4f9c-9387-59f5bee29e84", - "name": { - "pool_name": "oxp_4358f47f-f21e-4cc8-829e-0c7fc2400a59", - "kind": "zone/oxz_crucible_ce8563f3-4a93-45ff-b727-cbfbee6aa413" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "5e08effd-c18a-48da-857d-c90f48564281": { - "id": "5e08effd-c18a-48da-857d-c90f48564281", - "name": { - "pool_name": "oxp_aadf48eb-6ff0-40b5-a092-1fdd06c03e11", - "kind": "zone/oxz_crucible_9c5d88c9-8ff1-4f23-9438-7b81322eaf68" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "6b195654-0073-407d-a49a-e2bbfde71f9e": { - "id": "6b195654-0073-407d-a49a-e2bbfde71f9e", - "name": { - "pool_name": "oxp_b358fb1e-f52a-4a63-9aab-170225509b37", - "kind": "zone" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "731613cc-081e-4f7c-ae64-8d4345b6389e": { - "id": "731613cc-081e-4f7c-ae64-8d4345b6389e", - "name": { - "pool_name": "oxp_aadf48eb-6ff0-40b5-a092-1fdd06c03e11", - "kind": "zone" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "777aca07-5b08-451f-8f86-a41943941922": { - "id": "777aca07-5b08-451f-8f86-a41943941922", - "name": { - "pool_name": "oxp_17eff217-f0b1-4353-b133-0f68bbd5ceaa", - "kind": "zone" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "7dc65f64-984b-4aef-87cd-3d3596023b0e": { - "id": "7dc65f64-984b-4aef-87cd-3d3596023b0e", - "name": { - "pool_name": "oxp_b358fb1e-f52a-4a63-9aab-170225509b37", - "kind": "zone/oxz_cockroachdb_4c3ef132-ec83-4b1b-9574-7c7d3035f9e9" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "8c5473f1-3168-4ce6-b680-ad9159fa729d": { - "id": "8c5473f1-3168-4ce6-b680-ad9159fa729d", - "name": { - "pool_name": "oxp_17eff217-f0b1-4353-b133-0f68bbd5ceaa", - "kind": "debug" - }, - "compression": { - "type": "gzip_n", - "level": 9 - }, - "quota": 107374182400, - "reservation": null - }, - "8d7214d8-168c-42de-9ab6-8c4480f3ca88": { - "id": "8d7214d8-168c-42de-9ab6-8c4480f3ca88", - "name": { - "pool_name": "oxp_aadf48eb-6ff0-40b5-a092-1fdd06c03e11", - "kind": "debug" - }, - "compression": { - "type": "gzip_n", - "level": 9 - }, - "quota": 107374182400, - "reservation": null - }, - "912346a2-d7e6-427e-b373-e8dcbe4fcea9": { - "id": "912346a2-d7e6-427e-b373-e8dcbe4fcea9", - "name": { - "pool_name": "oxp_b358fb1e-f52a-4a63-9aab-170225509b37", - "kind": "crucible" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "92d3e4e9-0768-4772-83c1-23cce52190e9": { - "id": "92d3e4e9-0768-4772-83c1-23cce52190e9", - "name": { - "pool_name": "oxp_eb1234a5-fdf7-4977-94d5-2eef25ce56a1", - "kind": "crucible" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "9470ea7d-1920-4b4b-8fca-e7659a1ef733": { - "id": "9470ea7d-1920-4b4b-8fca-e7659a1ef733", - "name": { - "pool_name": "oxp_17eff217-f0b1-4353-b133-0f68bbd5ceaa", - "kind": "crucible" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "9c5d88c9-8ff1-4f23-9438-7b81322eaf68": { - "id": "9c5d88c9-8ff1-4f23-9438-7b81322eaf68", - "name": { - "pool_name": "oxp_aadf48eb-6ff0-40b5-a092-1fdd06c03e11", - "kind": "crucible" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "9f20b123-0bfe-4e00-bfe7-4ac45e1c3982": { - "id": "9f20b123-0bfe-4e00-bfe7-4ac45e1c3982", - "name": { - "pool_name": "oxp_f8b11629-ced6-412a-9c3f-d169b99ee996", - "kind": "zone/oxz_crucible_f9940969-b0e8-4e8c-86c7-4bc49cd15a5f" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "a23fbf9f-e215-4624-a472-52935ac43c38": { - "id": "a23fbf9f-e215-4624-a472-52935ac43c38", - "name": { - "pool_name": "oxp_57650e05-36ff-4de8-865f-b9562bdb67f5", - "kind": "zone" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "b3e9fee2-24d2-44e7-8539-a6918e85cf2b": { - "id": "b3e9fee2-24d2-44e7-8539-a6918e85cf2b", - "name": { - "pool_name": "oxp_0ae29053-29a2-489e-a1e6-6aec0ecd05f8", - "kind": "crucible" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "bc9ed1d3-6f10-40d5-b7b2-ad93495e3052": { - "id": "bc9ed1d3-6f10-40d5-b7b2-ad93495e3052", - "name": { - "pool_name": "oxp_b358fb1e-f52a-4a63-9aab-170225509b37", - "kind": "debug" - }, - "compression": { - "type": "gzip_n", - "level": 9 - }, - "quota": 107374182400, - "reservation": null - }, - "be805bfe-01f0-479e-8b9b-869926caaa22": { - "id": "be805bfe-01f0-479e-8b9b-869926caaa22", - "name": { - "pool_name": "oxp_eb1234a5-fdf7-4977-94d5-2eef25ce56a1", - "kind": "debug" - }, - "compression": { - "type": "gzip_n", - "level": 9 - }, - "quota": 107374182400, - "reservation": null - }, - "ce8563f3-4a93-45ff-b727-cbfbee6aa413": { - "id": "ce8563f3-4a93-45ff-b727-cbfbee6aa413", - "name": { - "pool_name": "oxp_4358f47f-f21e-4cc8-829e-0c7fc2400a59", - "kind": "crucible" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "cf636ba2-5214-4c3b-8b8d-fc64a555a0fe": { - "id": "cf636ba2-5214-4c3b-8b8d-fc64a555a0fe", - "name": { - "pool_name": "oxp_f8b11629-ced6-412a-9c3f-d169b99ee996", - "kind": "debug" - }, - "compression": { - "type": "gzip_n", - "level": 9 - }, - "quota": 107374182400, - "reservation": null - }, - "d86ea9ef-a941-4a6d-a44e-a202fe2f1bca": { - "id": "d86ea9ef-a941-4a6d-a44e-a202fe2f1bca", - "name": { - "pool_name": "oxp_4eb2e4eb-41d8-496c-9a5a-687d7e004aa4", - "kind": "debug" - }, - "compression": { - "type": "gzip_n", - "level": 9 - }, - "quota": 107374182400, - "reservation": null - }, - "dc36c11c-c0ee-4138-a305-65969a1b839b": { - "id": "dc36c11c-c0ee-4138-a305-65969a1b839b", - "name": { - "pool_name": "oxp_eb1234a5-fdf7-4977-94d5-2eef25ce56a1", - "kind": "zone/oxz_crucible_92d3e4e9-0768-4772-83c1-23cce52190e9" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "dc3d5ac2-346f-464a-9995-fcbbb4cb5ed8": { - "id": "dc3d5ac2-346f-464a-9995-fcbbb4cb5ed8", - "name": { - "pool_name": "oxp_4358f47f-f21e-4cc8-829e-0c7fc2400a59", - "kind": "debug" - }, - "compression": { - "type": "gzip_n", - "level": 9 - }, - "quota": 107374182400, - "reservation": null - }, - "e05a0149-5d58-4e7b-89d1-5a27ce869883": { - "id": "e05a0149-5d58-4e7b-89d1-5a27ce869883", - "name": { - "pool_name": "oxp_0ae29053-29a2-489e-a1e6-6aec0ecd05f8", - "kind": "zone" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "f3d28ea4-930d-4e96-aef9-97fa34a7f76c": { - "id": "f3d28ea4-930d-4e96-aef9-97fa34a7f76c", - "name": { - "pool_name": "oxp_4eb2e4eb-41d8-496c-9a5a-687d7e004aa4", - "kind": "zone" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "f7ede72f-fd43-4d91-8043-b35b541276ff": { - "id": "f7ede72f-fd43-4d91-8043-b35b541276ff", - "name": { - "pool_name": "oxp_f8b11629-ced6-412a-9c3f-d169b99ee996", - "kind": "zone" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "f9940969-b0e8-4e8c-86c7-4bc49cd15a5f": { - "id": "f9940969-b0e8-4e8c-86c7-4bc49cd15a5f", - "name": { - "pool_name": "oxp_f8b11629-ced6-412a-9c3f-d169b99ee996", - "kind": "crucible" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "f9c1deca-1898-429e-8c93-254c7aa7bae6": { - "id": "f9c1deca-1898-429e-8c93-254c7aa7bae6", - "name": { - "pool_name": "oxp_d1cb6b7d-2b92-4b7d-8a4d-551987f0277e", - "kind": "crucible" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "fd94b5a1-ca44-4aab-923e-bf9ff29b79df": { - "id": "fd94b5a1-ca44-4aab-923e-bf9ff29b79df", - "name": { - "pool_name": "oxp_0ae29053-29a2-489e-a1e6-6aec0ecd05f8", - "kind": "zone/oxz_crucible_b3e9fee2-24d2-44e7-8539-a6918e85cf2b" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - } - }, - "zones": { - "23dca27d-c79b-4930-a817-392e8aeaa4c1": { - "id": "23dca27d-c79b-4930-a817-392e8aeaa4c1", - "filesystem_pool": "oxp_57650e05-36ff-4de8-865f-b9562bdb67f5", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:105::e]:32345", - "dataset": { - "pool_name": "oxp_57650e05-36ff-4de8-865f-b9562bdb67f5" - } - }, - "image_source": { - "type": "install_dataset" - } - }, - "375296e5-0a23-466c-b605-4204080f8103": { - "id": "375296e5-0a23-466c-b605-4204080f8103", - "filesystem_pool": "oxp_0ae29053-29a2-489e-a1e6-6aec0ecd05f8", - "zone_type": { - "type": "crucible_pantry", - "address": "[fd00:1122:3344:105::4]:17000" - }, - "image_source": { - "type": "install_dataset" - } - }, - "3d420dff-c616-4c7d-bab1-0f9c2b5396bf": { - "id": "3d420dff-c616-4c7d-bab1-0f9c2b5396bf", - "filesystem_pool": "oxp_4eb2e4eb-41d8-496c-9a5a-687d7e004aa4", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:105::a]:32345", - "dataset": { - "pool_name": "oxp_4eb2e4eb-41d8-496c-9a5a-687d7e004aa4" - } - }, - "image_source": { - "type": "install_dataset" - } - }, - "4c3ef132-ec83-4b1b-9574-7c7d3035f9e9": { - "id": "4c3ef132-ec83-4b1b-9574-7c7d3035f9e9", - "filesystem_pool": "oxp_b358fb1e-f52a-4a63-9aab-170225509b37", - "zone_type": { - "type": "cockroach_db", - "address": "[fd00:1122:3344:105::3]:32221", - "dataset": { - "pool_name": "oxp_b358fb1e-f52a-4a63-9aab-170225509b37" - } - }, - "image_source": { - "type": "install_dataset" - } - }, - "76b79b96-eaa2-4341-9aba-e77cfc92e0a9": { - "id": "76b79b96-eaa2-4341-9aba-e77cfc92e0a9", - "filesystem_pool": "oxp_57650e05-36ff-4de8-865f-b9562bdb67f5", - "zone_type": { - "type": "internal_ntp", - "address": "[fd00:1122:3344:105::f]:123" - }, - "image_source": { - "type": "install_dataset" - } - }, - "912346a2-d7e6-427e-b373-e8dcbe4fcea9": { - "id": "912346a2-d7e6-427e-b373-e8dcbe4fcea9", - "filesystem_pool": "oxp_b358fb1e-f52a-4a63-9aab-170225509b37", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:105::5]:32345", - "dataset": { - "pool_name": "oxp_b358fb1e-f52a-4a63-9aab-170225509b37" - } - }, - "image_source": { - "type": "install_dataset" - } - }, - "92d3e4e9-0768-4772-83c1-23cce52190e9": { - "id": "92d3e4e9-0768-4772-83c1-23cce52190e9", - "filesystem_pool": "oxp_eb1234a5-fdf7-4977-94d5-2eef25ce56a1", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:105::6]:32345", - "dataset": { - "pool_name": "oxp_eb1234a5-fdf7-4977-94d5-2eef25ce56a1" - } - }, - "image_source": { - "type": "install_dataset" - } - }, - "9470ea7d-1920-4b4b-8fca-e7659a1ef733": { - "id": "9470ea7d-1920-4b4b-8fca-e7659a1ef733", - "filesystem_pool": "oxp_17eff217-f0b1-4353-b133-0f68bbd5ceaa", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:105::c]:32345", - "dataset": { - "pool_name": "oxp_17eff217-f0b1-4353-b133-0f68bbd5ceaa" - } - }, - "image_source": { - "type": "install_dataset" - } - }, - "9c5d88c9-8ff1-4f23-9438-7b81322eaf68": { - "id": "9c5d88c9-8ff1-4f23-9438-7b81322eaf68", - "filesystem_pool": "oxp_aadf48eb-6ff0-40b5-a092-1fdd06c03e11", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:105::b]:32345", - "dataset": { - "pool_name": "oxp_aadf48eb-6ff0-40b5-a092-1fdd06c03e11" - } - }, - "image_source": { - "type": "install_dataset" - } - }, - "b3e9fee2-24d2-44e7-8539-a6918e85cf2b": { - "id": "b3e9fee2-24d2-44e7-8539-a6918e85cf2b", - "filesystem_pool": "oxp_0ae29053-29a2-489e-a1e6-6aec0ecd05f8", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:105::d]:32345", - "dataset": { - "pool_name": "oxp_0ae29053-29a2-489e-a1e6-6aec0ecd05f8" - } - }, - "image_source": { - "type": "install_dataset" - } - }, - "ce8563f3-4a93-45ff-b727-cbfbee6aa413": { - "id": "ce8563f3-4a93-45ff-b727-cbfbee6aa413", - "filesystem_pool": "oxp_4358f47f-f21e-4cc8-829e-0c7fc2400a59", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:105::9]:32345", - "dataset": { - "pool_name": "oxp_4358f47f-f21e-4cc8-829e-0c7fc2400a59" - } - }, - "image_source": { - "type": "install_dataset" - } - }, - "f9940969-b0e8-4e8c-86c7-4bc49cd15a5f": { - "id": "f9940969-b0e8-4e8c-86c7-4bc49cd15a5f", - "filesystem_pool": "oxp_f8b11629-ced6-412a-9c3f-d169b99ee996", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:105::7]:32345", - "dataset": { - "pool_name": "oxp_f8b11629-ced6-412a-9c3f-d169b99ee996" - } - }, - "image_source": { - "type": "install_dataset" - } - }, - "f9c1deca-1898-429e-8c93-254c7aa7bae6": { - "id": "f9c1deca-1898-429e-8c93-254c7aa7bae6", - "filesystem_pool": "oxp_d1cb6b7d-2b92-4b7d-8a4d-551987f0277e", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:105::8]:32345", - "dataset": { - "pool_name": "oxp_d1cb6b7d-2b92-4b7d-8a4d-551987f0277e" - } - }, - "image_source": { - "type": "install_dataset" - } - } - }, - "remove_mupdate_override": null, - "host_phase_2": { - "slot_a": { - "type": "current_contents" - }, - "slot_b": { - "type": "current_contents" - } - } -} \ No newline at end of file diff --git a/sled-agent/config-reconciler/test-data/omicron-datasets.json b/sled-agent/config-reconciler/test-data/omicron-datasets.json deleted file mode 100644 index 665952d0a29..00000000000 --- a/sled-agent/config-reconciler/test-data/omicron-datasets.json +++ /dev/null @@ -1,543 +0,0 @@ -{ - "generation": 5, - "datasets": { - "010e5295-84de-4820-b7ae-c68c6fd5fbba": { - "id": "010e5295-84de-4820-b7ae-c68c6fd5fbba", - "name": { - "pool_name": "oxp_0ae29053-29a2-489e-a1e6-6aec0ecd05f8", - "kind": "debug" - }, - "compression": { - "type": "gzip_n", - "level": 9 - }, - "quota": 107374182400, - "reservation": null - }, - "056fd7c9-56ab-4c27-93ed-c7ae716567e1": { - "id": "056fd7c9-56ab-4c27-93ed-c7ae716567e1", - "name": { - "pool_name": "oxp_d1cb6b7d-2b92-4b7d-8a4d-551987f0277e", - "kind": "zone" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "18ffa6fb-99f7-49fd-a192-bf10499c5654": { - "id": "18ffa6fb-99f7-49fd-a192-bf10499c5654", - "name": { - "pool_name": "oxp_57650e05-36ff-4de8-865f-b9562bdb67f5", - "kind": "debug" - }, - "compression": { - "type": "gzip_n", - "level": 9 - }, - "quota": 107374182400, - "reservation": null - }, - "239245eb-2917-4be3-94ea-f38adb70ed9a": { - "id": "239245eb-2917-4be3-94ea-f38adb70ed9a", - "name": { - "pool_name": "oxp_4358f47f-f21e-4cc8-829e-0c7fc2400a59", - "kind": "zone" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "23dca27d-c79b-4930-a817-392e8aeaa4c1": { - "id": "23dca27d-c79b-4930-a817-392e8aeaa4c1", - "name": { - "pool_name": "oxp_57650e05-36ff-4de8-865f-b9562bdb67f5", - "kind": "crucible" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "240f0791-4b3c-4506-a2ff-43f567095b87": { - "id": "240f0791-4b3c-4506-a2ff-43f567095b87", - "name": { - "pool_name": "oxp_0ae29053-29a2-489e-a1e6-6aec0ecd05f8", - "kind": "zone/oxz_crucible_pantry_375296e5-0a23-466c-b605-4204080f8103" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "25368942-b0a1-4063-8a54-f929d694f49e": { - "id": "25368942-b0a1-4063-8a54-f929d694f49e", - "name": { - "pool_name": "oxp_57650e05-36ff-4de8-865f-b9562bdb67f5", - "kind": "zone/oxz_crucible_23dca27d-c79b-4930-a817-392e8aeaa4c1" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "36a1bb9a-5985-43ab-ac3c-cfe168431fa9": { - "id": "36a1bb9a-5985-43ab-ac3c-cfe168431fa9", - "name": { - "pool_name": "oxp_d1cb6b7d-2b92-4b7d-8a4d-551987f0277e", - "kind": "debug" - }, - "compression": { - "type": "gzip_n", - "level": 9 - }, - "quota": 107374182400, - "reservation": null - }, - "3aaed2d8-7581-427f-9b0c-9b3d316b33a0": { - "id": "3aaed2d8-7581-427f-9b0c-9b3d316b33a0", - "name": { - "pool_name": "oxp_17eff217-f0b1-4353-b133-0f68bbd5ceaa", - "kind": "zone/oxz_crucible_9470ea7d-1920-4b4b-8fca-e7659a1ef733" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "3c14b954-e3b4-4cdd-bc02-b597b133e564": { - "id": "3c14b954-e3b4-4cdd-bc02-b597b133e564", - "name": { - "pool_name": "oxp_b358fb1e-f52a-4a63-9aab-170225509b37", - "kind": "zone/oxz_crucible_912346a2-d7e6-427e-b373-e8dcbe4fcea9" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "3d420dff-c616-4c7d-bab1-0f9c2b5396bf": { - "id": "3d420dff-c616-4c7d-bab1-0f9c2b5396bf", - "name": { - "pool_name": "oxp_4eb2e4eb-41d8-496c-9a5a-687d7e004aa4", - "kind": "crucible" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "3e26445a-b225-4432-b947-445139e29815": { - "id": "3e26445a-b225-4432-b947-445139e29815", - "name": { - "pool_name": "oxp_d1cb6b7d-2b92-4b7d-8a4d-551987f0277e", - "kind": "zone/oxz_crucible_f9c1deca-1898-429e-8c93-254c7aa7bae6" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "4090f4ca-89d5-403e-a8fb-8e2dcb9c5229": { - "id": "4090f4ca-89d5-403e-a8fb-8e2dcb9c5229", - "name": { - "pool_name": "oxp_57650e05-36ff-4de8-865f-b9562bdb67f5", - "kind": "zone/oxz_ntp_76b79b96-eaa2-4341-9aba-e77cfc92e0a9" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "419b3c50-17d0-438e-a456-b94acc9aee0d": { - "id": "419b3c50-17d0-438e-a456-b94acc9aee0d", - "name": { - "pool_name": "oxp_4eb2e4eb-41d8-496c-9a5a-687d7e004aa4", - "kind": "zone/oxz_crucible_3d420dff-c616-4c7d-bab1-0f9c2b5396bf" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "4c3ef132-ec83-4b1b-9574-7c7d3035f9e9": { - "id": "4c3ef132-ec83-4b1b-9574-7c7d3035f9e9", - "name": { - "pool_name": "oxp_b358fb1e-f52a-4a63-9aab-170225509b37", - "kind": "cockroachdb" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "4e83fc2f-4a80-4049-bcbb-a53cf017540c": { - "id": "4e83fc2f-4a80-4049-bcbb-a53cf017540c", - "name": { - "pool_name": "oxp_eb1234a5-fdf7-4977-94d5-2eef25ce56a1", - "kind": "zone" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "5c35e44c-0c03-4f9c-9387-59f5bee29e84": { - "id": "5c35e44c-0c03-4f9c-9387-59f5bee29e84", - "name": { - "pool_name": "oxp_4358f47f-f21e-4cc8-829e-0c7fc2400a59", - "kind": "zone/oxz_crucible_ce8563f3-4a93-45ff-b727-cbfbee6aa413" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "5e08effd-c18a-48da-857d-c90f48564281": { - "id": "5e08effd-c18a-48da-857d-c90f48564281", - "name": { - "pool_name": "oxp_aadf48eb-6ff0-40b5-a092-1fdd06c03e11", - "kind": "zone/oxz_crucible_9c5d88c9-8ff1-4f23-9438-7b81322eaf68" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "6b195654-0073-407d-a49a-e2bbfde71f9e": { - "id": "6b195654-0073-407d-a49a-e2bbfde71f9e", - "name": { - "pool_name": "oxp_b358fb1e-f52a-4a63-9aab-170225509b37", - "kind": "zone" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "731613cc-081e-4f7c-ae64-8d4345b6389e": { - "id": "731613cc-081e-4f7c-ae64-8d4345b6389e", - "name": { - "pool_name": "oxp_aadf48eb-6ff0-40b5-a092-1fdd06c03e11", - "kind": "zone" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "777aca07-5b08-451f-8f86-a41943941922": { - "id": "777aca07-5b08-451f-8f86-a41943941922", - "name": { - "pool_name": "oxp_17eff217-f0b1-4353-b133-0f68bbd5ceaa", - "kind": "zone" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "7dc65f64-984b-4aef-87cd-3d3596023b0e": { - "id": "7dc65f64-984b-4aef-87cd-3d3596023b0e", - "name": { - "pool_name": "oxp_b358fb1e-f52a-4a63-9aab-170225509b37", - "kind": "zone/oxz_cockroachdb_4c3ef132-ec83-4b1b-9574-7c7d3035f9e9" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "8c5473f1-3168-4ce6-b680-ad9159fa729d": { - "id": "8c5473f1-3168-4ce6-b680-ad9159fa729d", - "name": { - "pool_name": "oxp_17eff217-f0b1-4353-b133-0f68bbd5ceaa", - "kind": "debug" - }, - "compression": { - "type": "gzip_n", - "level": 9 - }, - "quota": 107374182400, - "reservation": null - }, - "8d7214d8-168c-42de-9ab6-8c4480f3ca88": { - "id": "8d7214d8-168c-42de-9ab6-8c4480f3ca88", - "name": { - "pool_name": "oxp_aadf48eb-6ff0-40b5-a092-1fdd06c03e11", - "kind": "debug" - }, - "compression": { - "type": "gzip_n", - "level": 9 - }, - "quota": 107374182400, - "reservation": null - }, - "912346a2-d7e6-427e-b373-e8dcbe4fcea9": { - "id": "912346a2-d7e6-427e-b373-e8dcbe4fcea9", - "name": { - "pool_name": "oxp_b358fb1e-f52a-4a63-9aab-170225509b37", - "kind": "crucible" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "92d3e4e9-0768-4772-83c1-23cce52190e9": { - "id": "92d3e4e9-0768-4772-83c1-23cce52190e9", - "name": { - "pool_name": "oxp_eb1234a5-fdf7-4977-94d5-2eef25ce56a1", - "kind": "crucible" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "9470ea7d-1920-4b4b-8fca-e7659a1ef733": { - "id": "9470ea7d-1920-4b4b-8fca-e7659a1ef733", - "name": { - "pool_name": "oxp_17eff217-f0b1-4353-b133-0f68bbd5ceaa", - "kind": "crucible" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "9c5d88c9-8ff1-4f23-9438-7b81322eaf68": { - "id": "9c5d88c9-8ff1-4f23-9438-7b81322eaf68", - "name": { - "pool_name": "oxp_aadf48eb-6ff0-40b5-a092-1fdd06c03e11", - "kind": "crucible" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "9f20b123-0bfe-4e00-bfe7-4ac45e1c3982": { - "id": "9f20b123-0bfe-4e00-bfe7-4ac45e1c3982", - "name": { - "pool_name": "oxp_f8b11629-ced6-412a-9c3f-d169b99ee996", - "kind": "zone/oxz_crucible_f9940969-b0e8-4e8c-86c7-4bc49cd15a5f" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "a23fbf9f-e215-4624-a472-52935ac43c38": { - "id": "a23fbf9f-e215-4624-a472-52935ac43c38", - "name": { - "pool_name": "oxp_57650e05-36ff-4de8-865f-b9562bdb67f5", - "kind": "zone" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "b3e9fee2-24d2-44e7-8539-a6918e85cf2b": { - "id": "b3e9fee2-24d2-44e7-8539-a6918e85cf2b", - "name": { - "pool_name": "oxp_0ae29053-29a2-489e-a1e6-6aec0ecd05f8", - "kind": "crucible" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "bc9ed1d3-6f10-40d5-b7b2-ad93495e3052": { - "id": "bc9ed1d3-6f10-40d5-b7b2-ad93495e3052", - "name": { - "pool_name": "oxp_b358fb1e-f52a-4a63-9aab-170225509b37", - "kind": "debug" - }, - "compression": { - "type": "gzip_n", - "level": 9 - }, - "quota": 107374182400, - "reservation": null - }, - "be805bfe-01f0-479e-8b9b-869926caaa22": { - "id": "be805bfe-01f0-479e-8b9b-869926caaa22", - "name": { - "pool_name": "oxp_eb1234a5-fdf7-4977-94d5-2eef25ce56a1", - "kind": "debug" - }, - "compression": { - "type": "gzip_n", - "level": 9 - }, - "quota": 107374182400, - "reservation": null - }, - "ce8563f3-4a93-45ff-b727-cbfbee6aa413": { - "id": "ce8563f3-4a93-45ff-b727-cbfbee6aa413", - "name": { - "pool_name": "oxp_4358f47f-f21e-4cc8-829e-0c7fc2400a59", - "kind": "crucible" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "cf636ba2-5214-4c3b-8b8d-fc64a555a0fe": { - "id": "cf636ba2-5214-4c3b-8b8d-fc64a555a0fe", - "name": { - "pool_name": "oxp_f8b11629-ced6-412a-9c3f-d169b99ee996", - "kind": "debug" - }, - "compression": { - "type": "gzip_n", - "level": 9 - }, - "quota": 107374182400, - "reservation": null - }, - "d86ea9ef-a941-4a6d-a44e-a202fe2f1bca": { - "id": "d86ea9ef-a941-4a6d-a44e-a202fe2f1bca", - "name": { - "pool_name": "oxp_4eb2e4eb-41d8-496c-9a5a-687d7e004aa4", - "kind": "debug" - }, - "compression": { - "type": "gzip_n", - "level": 9 - }, - "quota": 107374182400, - "reservation": null - }, - "dc36c11c-c0ee-4138-a305-65969a1b839b": { - "id": "dc36c11c-c0ee-4138-a305-65969a1b839b", - "name": { - "pool_name": "oxp_eb1234a5-fdf7-4977-94d5-2eef25ce56a1", - "kind": "zone/oxz_crucible_92d3e4e9-0768-4772-83c1-23cce52190e9" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "dc3d5ac2-346f-464a-9995-fcbbb4cb5ed8": { - "id": "dc3d5ac2-346f-464a-9995-fcbbb4cb5ed8", - "name": { - "pool_name": "oxp_4358f47f-f21e-4cc8-829e-0c7fc2400a59", - "kind": "debug" - }, - "compression": { - "type": "gzip_n", - "level": 9 - }, - "quota": 107374182400, - "reservation": null - }, - "e05a0149-5d58-4e7b-89d1-5a27ce869883": { - "id": "e05a0149-5d58-4e7b-89d1-5a27ce869883", - "name": { - "pool_name": "oxp_0ae29053-29a2-489e-a1e6-6aec0ecd05f8", - "kind": "zone" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "f3d28ea4-930d-4e96-aef9-97fa34a7f76c": { - "id": "f3d28ea4-930d-4e96-aef9-97fa34a7f76c", - "name": { - "pool_name": "oxp_4eb2e4eb-41d8-496c-9a5a-687d7e004aa4", - "kind": "zone" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "f7ede72f-fd43-4d91-8043-b35b541276ff": { - "id": "f7ede72f-fd43-4d91-8043-b35b541276ff", - "name": { - "pool_name": "oxp_f8b11629-ced6-412a-9c3f-d169b99ee996", - "kind": "zone" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "f9940969-b0e8-4e8c-86c7-4bc49cd15a5f": { - "id": "f9940969-b0e8-4e8c-86c7-4bc49cd15a5f", - "name": { - "pool_name": "oxp_f8b11629-ced6-412a-9c3f-d169b99ee996", - "kind": "crucible" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "f9c1deca-1898-429e-8c93-254c7aa7bae6": { - "id": "f9c1deca-1898-429e-8c93-254c7aa7bae6", - "name": { - "pool_name": "oxp_d1cb6b7d-2b92-4b7d-8a4d-551987f0277e", - "kind": "crucible" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - }, - "fd94b5a1-ca44-4aab-923e-bf9ff29b79df": { - "id": "fd94b5a1-ca44-4aab-923e-bf9ff29b79df", - "name": { - "pool_name": "oxp_0ae29053-29a2-489e-a1e6-6aec0ecd05f8", - "kind": "zone/oxz_crucible_b3e9fee2-24d2-44e7-8539-a6918e85cf2b" - }, - "compression": { - "type": "off" - }, - "quota": null, - "reservation": null - } - } -} diff --git a/sled-agent/config-reconciler/test-data/omicron-physical-disks.json b/sled-agent/config-reconciler/test-data/omicron-physical-disks.json deleted file mode 100644 index db66e25bcdf..00000000000 --- a/sled-agent/config-reconciler/test-data/omicron-physical-disks.json +++ /dev/null @@ -1,95 +0,0 @@ -{ - "generation": 5, - "disks": [ - { - "identity": { - "vendor": "1b96", - "model": "WUS4C6432DSP3X3", - "serial": "A084A5E5" - }, - "id": "2fd7c854-5c0e-408e-8e4d-4b36ae42725d", - "pool_id": "f8b11629-ced6-412a-9c3f-d169b99ee996" - }, - { - "identity": { - "vendor": "1b96", - "model": "WUS4C6432DSP3X3", - "serial": "A084A606" - }, - "id": "735d639f-f9c9-438d-a286-12190ce419db", - "pool_id": "4358f47f-f21e-4cc8-829e-0c7fc2400a59" - }, - { - "identity": { - "vendor": "1b96", - "model": "WUS4C6432DSP3X3", - "serial": "A084A60D" - }, - "id": "c463143f-9a4e-4ac0-8c9f-49bd07f0f7f4", - "pool_id": "aadf48eb-6ff0-40b5-a092-1fdd06c03e11" - }, - { - "identity": { - "vendor": "1b96", - "model": "WUS4C6432DSP3X3", - "serial": "A084A63C" - }, - "id": "e67a2c76-22dc-4f99-8b5b-c8c633fcf000", - "pool_id": "17eff217-f0b1-4353-b133-0f68bbd5ceaa" - }, - { - "identity": { - "vendor": "1b96", - "model": "WUS4C6432DSP3X3", - "serial": "A084A6CB" - }, - "id": "76e4d7bf-c908-4843-bd41-ecd62bb42bd1", - "pool_id": "0ae29053-29a2-489e-a1e6-6aec0ecd05f8" - }, - { - "identity": { - "vendor": "1b96", - "model": "WUS4C6432DSP3X3", - "serial": "A084A6EF" - }, - "id": "6a19ddca-447e-4579-90b3-6826fa3f7950", - "pool_id": "d1cb6b7d-2b92-4b7d-8a4d-551987f0277e" - }, - { - "identity": { - "vendor": "1b96", - "model": "WUS4C6432DSP3X3", - "serial": "A084A703" - }, - "id": "e63d3ba9-7a02-4171-bdab-9ccca465b08a", - "pool_id": "57650e05-36ff-4de8-865f-b9562bdb67f5" - }, - { - "identity": { - "vendor": "1b96", - "model": "WUS4C6432DSP3X3", - "serial": "A084A795" - }, - "id": "1201b2d5-5491-4e96-aa9d-efd7afed0612", - "pool_id": "b358fb1e-f52a-4a63-9aab-170225509b37" - }, - { - "identity": { - "vendor": "1b96", - "model": "WUS4C6432DSP3X3", - "serial": "A084A7C0" - }, - "id": "25a61844-be5a-4b6d-bd3d-e6c7906ee52a", - "pool_id": "4eb2e4eb-41d8-496c-9a5a-687d7e004aa4" - }, - { - "identity": { - "vendor": "1b96", - "model": "WUS4C6432DSP3X3", - "serial": "A084A7F3" - }, - "id": "6ad551bd-487e-48fd-bf7a-fc80da2a027c", - "pool_id": "eb1234a5-fdf7-4977-94d5-2eef25ce56a1" - } - ] -} diff --git a/sled-agent/config-reconciler/test-data/omicron-zones.json b/sled-agent/config-reconciler/test-data/omicron-zones.json deleted file mode 100644 index 1f28894e9d1..00000000000 --- a/sled-agent/config-reconciler/test-data/omicron-zones.json +++ /dev/null @@ -1,221 +0,0 @@ -{ - "omicron_generation": 5, - "ledger_generation": 72, - "zones": [ - { - "zone": { - "id": "4c3ef132-ec83-4b1b-9574-7c7d3035f9e9", - "filesystem_pool": "oxp_b358fb1e-f52a-4a63-9aab-170225509b37", - "zone_type": { - "type": "cockroach_db", - "address": "[fd00:1122:3344:105::3]:32221", - "dataset": { - "pool_name": "oxp_b358fb1e-f52a-4a63-9aab-170225509b37" - } - }, - "image_source": { - "type": "install_dataset" - } - }, - "root": "/pool/ext/b358fb1e-f52a-4a63-9aab-170225509b37/crypt/zone" - }, - { - "zone": { - "id": "23dca27d-c79b-4930-a817-392e8aeaa4c1", - "filesystem_pool": "oxp_57650e05-36ff-4de8-865f-b9562bdb67f5", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:105::e]:32345", - "dataset": { - "pool_name": "oxp_57650e05-36ff-4de8-865f-b9562bdb67f5" - } - }, - "image_source": { - "type": "install_dataset" - } - }, - "root": "/pool/ext/57650e05-36ff-4de8-865f-b9562bdb67f5/crypt/zone" - }, - { - "zone": { - "id": "3d420dff-c616-4c7d-bab1-0f9c2b5396bf", - "filesystem_pool": "oxp_4eb2e4eb-41d8-496c-9a5a-687d7e004aa4", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:105::a]:32345", - "dataset": { - "pool_name": "oxp_4eb2e4eb-41d8-496c-9a5a-687d7e004aa4" - } - }, - "image_source": { - "type": "install_dataset" - } - }, - "root": "/pool/ext/4eb2e4eb-41d8-496c-9a5a-687d7e004aa4/crypt/zone" - }, - { - "zone": { - "id": "912346a2-d7e6-427e-b373-e8dcbe4fcea9", - "filesystem_pool": "oxp_b358fb1e-f52a-4a63-9aab-170225509b37", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:105::5]:32345", - "dataset": { - "pool_name": "oxp_b358fb1e-f52a-4a63-9aab-170225509b37" - } - }, - "image_source": { - "type": "install_dataset" - } - }, - "root": "/pool/ext/b358fb1e-f52a-4a63-9aab-170225509b37/crypt/zone" - }, - { - "zone": { - "id": "92d3e4e9-0768-4772-83c1-23cce52190e9", - "filesystem_pool": "oxp_eb1234a5-fdf7-4977-94d5-2eef25ce56a1", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:105::6]:32345", - "dataset": { - "pool_name": "oxp_eb1234a5-fdf7-4977-94d5-2eef25ce56a1" - } - }, - "image_source": { - "type": "install_dataset" - } - }, - "root": "/pool/ext/eb1234a5-fdf7-4977-94d5-2eef25ce56a1/crypt/zone" - }, - { - "zone": { - "id": "9470ea7d-1920-4b4b-8fca-e7659a1ef733", - "filesystem_pool": "oxp_17eff217-f0b1-4353-b133-0f68bbd5ceaa", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:105::c]:32345", - "dataset": { - "pool_name": "oxp_17eff217-f0b1-4353-b133-0f68bbd5ceaa" - } - }, - "image_source": { - "type": "install_dataset" - } - }, - "root": "/pool/ext/17eff217-f0b1-4353-b133-0f68bbd5ceaa/crypt/zone" - }, - { - "zone": { - "id": "9c5d88c9-8ff1-4f23-9438-7b81322eaf68", - "filesystem_pool": "oxp_aadf48eb-6ff0-40b5-a092-1fdd06c03e11", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:105::b]:32345", - "dataset": { - "pool_name": "oxp_aadf48eb-6ff0-40b5-a092-1fdd06c03e11" - } - }, - "image_source": { - "type": "install_dataset" - } - }, - "root": "/pool/ext/aadf48eb-6ff0-40b5-a092-1fdd06c03e11/crypt/zone" - }, - { - "zone": { - "id": "b3e9fee2-24d2-44e7-8539-a6918e85cf2b", - "filesystem_pool": "oxp_0ae29053-29a2-489e-a1e6-6aec0ecd05f8", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:105::d]:32345", - "dataset": { - "pool_name": "oxp_0ae29053-29a2-489e-a1e6-6aec0ecd05f8" - } - }, - "image_source": { - "type": "install_dataset" - } - }, - "root": "/pool/ext/0ae29053-29a2-489e-a1e6-6aec0ecd05f8/crypt/zone" - }, - { - "zone": { - "id": "ce8563f3-4a93-45ff-b727-cbfbee6aa413", - "filesystem_pool": "oxp_4358f47f-f21e-4cc8-829e-0c7fc2400a59", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:105::9]:32345", - "dataset": { - "pool_name": "oxp_4358f47f-f21e-4cc8-829e-0c7fc2400a59" - } - }, - "image_source": { - "type": "install_dataset" - } - }, - "root": "/pool/ext/4358f47f-f21e-4cc8-829e-0c7fc2400a59/crypt/zone" - }, - { - "zone": { - "id": "f9940969-b0e8-4e8c-86c7-4bc49cd15a5f", - "filesystem_pool": "oxp_f8b11629-ced6-412a-9c3f-d169b99ee996", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:105::7]:32345", - "dataset": { - "pool_name": "oxp_f8b11629-ced6-412a-9c3f-d169b99ee996" - } - }, - "image_source": { - "type": "install_dataset" - } - }, - "root": "/pool/ext/f8b11629-ced6-412a-9c3f-d169b99ee996/crypt/zone" - }, - { - "zone": { - "id": "f9c1deca-1898-429e-8c93-254c7aa7bae6", - "filesystem_pool": "oxp_d1cb6b7d-2b92-4b7d-8a4d-551987f0277e", - "zone_type": { - "type": "crucible", - "address": "[fd00:1122:3344:105::8]:32345", - "dataset": { - "pool_name": "oxp_d1cb6b7d-2b92-4b7d-8a4d-551987f0277e" - } - }, - "image_source": { - "type": "install_dataset" - } - }, - "root": "/pool/ext/d1cb6b7d-2b92-4b7d-8a4d-551987f0277e/crypt/zone" - }, - { - "zone": { - "id": "375296e5-0a23-466c-b605-4204080f8103", - "filesystem_pool": "oxp_0ae29053-29a2-489e-a1e6-6aec0ecd05f8", - "zone_type": { - "type": "crucible_pantry", - "address": "[fd00:1122:3344:105::4]:17000" - }, - "image_source": { - "type": "install_dataset" - } - }, - "root": "/pool/ext/0ae29053-29a2-489e-a1e6-6aec0ecd05f8/crypt/zone" - }, - { - "zone": { - "id": "76b79b96-eaa2-4341-9aba-e77cfc92e0a9", - "filesystem_pool": "oxp_57650e05-36ff-4de8-865f-b9562bdb67f5", - "zone_type": { - "type": "internal_ntp", - "address": "[fd00:1122:3344:105::f]:123" - }, - "image_source": { - "type": "install_dataset" - } - }, - "root": "/pool/ext/57650e05-36ff-4de8-865f-b9562bdb67f5/crypt/zone" - } - ] -} diff --git a/sled-agent/config-reconciler/test-data/v4-sled-config.json b/sled-agent/config-reconciler/test-data/v4-sled-config.json new file mode 100644 index 00000000000..7ba7fcdbf7c --- /dev/null +++ b/sled-agent/config-reconciler/test-data/v4-sled-config.json @@ -0,0 +1,993 @@ +{ + "generation": 351, + "disks": { + "10fec275-f937-40f7-9c25-616079ef3816": { + "identity": { + "vendor": "1b96", + "model": "WUS4C6432DSP3X3", + "serial": "A084A5E3" + }, + "id": "10fec275-f937-40f7-9c25-616079ef3816", + "pool_id": "6340805e-c5af-418d-8bd1-fc0085667f33" + }, + "883b970b-2b70-4771-bb0e-aed2765c3e6a": { + "identity": { + "vendor": "1b96", + "model": "WUS4C6432DSP3X3", + "serial": "A084A79D" + }, + "id": "883b970b-2b70-4771-bb0e-aed2765c3e6a", + "pool_id": "414e235b-55c3-4dc1-a568-8adf4ea1a052" + }, + "9272fa96-eef8-43ed-8658-12ccf722bec2": { + "identity": { + "vendor": "1b96", + "model": "WUS4C6432DSP3X3", + "serial": "A084A61D" + }, + "id": "9272fa96-eef8-43ed-8658-12ccf722bec2", + "pool_id": "7b24095a-72df-45e3-984f-2b795e052ac7" + }, + "b20f225f-fef6-4ef5-a474-bd818013fceb": { + "identity": { + "vendor": "1b96", + "model": "WUS4C6432DSP3X3", + "serial": "A084A7EE" + }, + "id": "b20f225f-fef6-4ef5-a474-bd818013fceb", + "pool_id": "b93f880e-c55b-4d6c-9a16-939d84b628fc" + }, + "b483c693-700f-4630-92bb-9659e735648b": { + "identity": { + "vendor": "1b96", + "model": "WUS4C6432DSP3X3", + "serial": "A084A67C" + }, + "id": "b483c693-700f-4630-92bb-9659e735648b", + "pool_id": "cf940e15-dbc5-481b-866a-4de4b018898e" + }, + "c9bd1b35-c87a-4acf-bf52-06ed624e3be0": { + "identity": { + "vendor": "1b96", + "model": "WUS4C6432DSP3X3", + "serial": "A084A6F3" + }, + "id": "c9bd1b35-c87a-4acf-bf52-06ed624e3be0", + "pool_id": "8a199f12-4f5c-483a-8aca-f97856658a35" + }, + "d45fb895-f500-473f-9bdb-3d1f15464055": { + "identity": { + "vendor": "1b96", + "model": "WUS4C6432DSP3X3", + "serial": "A084A5C3" + }, + "id": "d45fb895-f500-473f-9bdb-3d1f15464055", + "pool_id": "26e698bb-006d-4208-94b9-d1bc279111fa" + }, + "d9fb1545-4051-4710-bcfd-8d33115bb022": { + "identity": { + "vendor": "1b96", + "model": "WUS4C6432DSP3X3", + "serial": "A084A7BE" + }, + "id": "d9fb1545-4051-4710-bcfd-8d33115bb022", + "pool_id": "e126ddcc-8bee-46ba-8199-2a74df0ba040" + }, + "e1bfe0a7-e848-4907-9068-22e02bad03ca": { + "identity": { + "vendor": "1b96", + "model": "WUS4C6432DSP3X3", + "serial": "A084A7DA" + }, + "id": "e1bfe0a7-e848-4907-9068-22e02bad03ca", + "pool_id": "2115b084-be0f-4fba-941b-33a659798a9e" + }, + "f6d26664-f32e-46c4-a3f3-74d55dae7fac": { + "identity": { + "vendor": "1b96", + "model": "WUS4C6432DSP3X3", + "serial": "A084A75D" + }, + "id": "f6d26664-f32e-46c4-a3f3-74d55dae7fac", + "pool_id": "bf428719-1b16-4503-99f4-ad95846d916f" + } + }, + "datasets": { + "01f93020-7e7d-4185-93fb-6ca234056c82": { + "id": "01f93020-7e7d-4185-93fb-6ca234056c82", + "name": { + "pool_name": "oxp_7b24095a-72df-45e3-984f-2b795e052ac7", + "kind": "crucible" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "01ffd316-ea25-4287-95aa-01bf6b036a16": { + "id": "01ffd316-ea25-4287-95aa-01bf6b036a16", + "name": { + "pool_name": "oxp_7b24095a-72df-45e3-984f-2b795e052ac7", + "kind": "zone/oxz_crucible_01f93020-7e7d-4185-93fb-6ca234056c82" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "02a5be47-df19-4159-b793-98a888603200": { + "id": "02a5be47-df19-4159-b793-98a888603200", + "name": { + "pool_name": "oxp_cf940e15-dbc5-481b-866a-4de4b018898e", + "kind": "debug" + }, + "compression": { + "type": "gzip_n", + "level": 9 + }, + "quota": 107374182400, + "reservation": null + }, + "072fdae8-2adf-4fd2-94ce-e9b0663b91e7": { + "id": "072fdae8-2adf-4fd2-94ce-e9b0663b91e7", + "name": { + "pool_name": "oxp_26e698bb-006d-4208-94b9-d1bc279111fa", + "kind": "crucible" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "088ff0e3-9b7e-4798-901c-fe88cf7aca52": { + "id": "088ff0e3-9b7e-4798-901c-fe88cf7aca52", + "name": { + "pool_name": "oxp_bf428719-1b16-4503-99f4-ad95846d916f", + "kind": "zone" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "0b41c560-3b20-42f4-82ad-92f5bb575d6b": { + "id": "0b41c560-3b20-42f4-82ad-92f5bb575d6b", + "name": { + "pool_name": "oxp_b93f880e-c55b-4d6c-9a16-939d84b628fc", + "kind": "crucible" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "0ccf27c0-e32d-4b52-a2c5-6db0c64a26f9": { + "id": "0ccf27c0-e32d-4b52-a2c5-6db0c64a26f9", + "name": { + "pool_name": "oxp_2115b084-be0f-4fba-941b-33a659798a9e", + "kind": "crucible" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "14b70f75-89e1-4ded-a7c4-dcf49ebd87ba": { + "id": "14b70f75-89e1-4ded-a7c4-dcf49ebd87ba", + "name": { + "pool_name": "oxp_b93f880e-c55b-4d6c-9a16-939d84b628fc", + "kind": "zone/oxz_crucible_0b41c560-3b20-42f4-82ad-92f5bb575d6b" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "1a00597c-8225-4324-9530-aaad3d7a9138": { + "id": "1a00597c-8225-4324-9530-aaad3d7a9138", + "name": { + "pool_name": "oxp_414e235b-55c3-4dc1-a568-8adf4ea1a052", + "kind": "zone/oxz_crucible_7d44ba36-4a69-490a-bc40-f6f90a4208d4" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "257d5c91-5bd5-4a13-802b-0995f76df671": { + "id": "257d5c91-5bd5-4a13-802b-0995f76df671", + "name": { + "pool_name": "oxp_2115b084-be0f-4fba-941b-33a659798a9e", + "kind": "zone/oxz_nexus_470fbf4d-0178-45ee-a422-136fa5f4a158" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "27bb57f7-abc6-4550-b1c6-5a18c7356748": { + "id": "27bb57f7-abc6-4550-b1c6-5a18c7356748", + "name": { + "pool_name": "oxp_26e698bb-006d-4208-94b9-d1bc279111fa", + "kind": "debug" + }, + "compression": { + "type": "gzip_n", + "level": 9 + }, + "quota": 107374182400, + "reservation": null + }, + "2bd226bd-edce-488c-bbe8-e0b301664de0": { + "id": "2bd226bd-edce-488c-bbe8-e0b301664de0", + "name": { + "pool_name": "oxp_2115b084-be0f-4fba-941b-33a659798a9e", + "kind": "local_storage" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "2c260613-a7bc-401e-ab73-cde4069ef09a": { + "id": "2c260613-a7bc-401e-ab73-cde4069ef09a", + "name": { + "pool_name": "oxp_7b24095a-72df-45e3-984f-2b795e052ac7", + "kind": "debug" + }, + "compression": { + "type": "gzip_n", + "level": 9 + }, + "quota": 107374182400, + "reservation": null + }, + "2fa20fca-7b61-4e56-8dbf-f56171bf35e1": { + "id": "2fa20fca-7b61-4e56-8dbf-f56171bf35e1", + "name": { + "pool_name": "oxp_2115b084-be0f-4fba-941b-33a659798a9e", + "kind": "debug" + }, + "compression": { + "type": "gzip_n", + "level": 9 + }, + "quota": 107374182400, + "reservation": null + }, + "34007214-81f0-4768-804d-d090695f1f09": { + "id": "34007214-81f0-4768-804d-d090695f1f09", + "name": { + "pool_name": "oxp_2115b084-be0f-4fba-941b-33a659798a9e", + "kind": "external_dns" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "46596dcd-4bea-4878-b498-1b9da4437aff": { + "id": "46596dcd-4bea-4878-b498-1b9da4437aff", + "name": { + "pool_name": "oxp_8a199f12-4f5c-483a-8aca-f97856658a35", + "kind": "debug" + }, + "compression": { + "type": "gzip_n", + "level": 9 + }, + "quota": 107374182400, + "reservation": null + }, + "468152ab-b771-4caf-9ca2-8abbd6fc5bec": { + "id": "468152ab-b771-4caf-9ca2-8abbd6fc5bec", + "name": { + "pool_name": "oxp_e126ddcc-8bee-46ba-8199-2a74df0ba040", + "kind": "debug" + }, + "compression": { + "type": "gzip_n", + "level": 9 + }, + "quota": 107374182400, + "reservation": null + }, + "46c13daf-0808-496a-b0f8-9eca75fcfa84": { + "id": "46c13daf-0808-496a-b0f8-9eca75fcfa84", + "name": { + "pool_name": "oxp_6340805e-c5af-418d-8bd1-fc0085667f33", + "kind": "debug" + }, + "compression": { + "type": "gzip_n", + "level": 9 + }, + "quota": 107374182400, + "reservation": null + }, + "4b771fc2-312a-4abf-9eef-ae9ff3853a13": { + "id": "4b771fc2-312a-4abf-9eef-ae9ff3853a13", + "name": { + "pool_name": "oxp_2115b084-be0f-4fba-941b-33a659798a9e", + "kind": "zone" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "4e3b3938-ad72-4443-9d96-4d6ba8ab19fb": { + "id": "4e3b3938-ad72-4443-9d96-4d6ba8ab19fb", + "name": { + "pool_name": "oxp_6340805e-c5af-418d-8bd1-fc0085667f33", + "kind": "zone/oxz_crucible_585cd8c5-c41e-4be4-beb8-bfbef9b53856" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "50b12371-0120-4210-89c7-2ecd58bea4d3": { + "id": "50b12371-0120-4210-89c7-2ecd58bea4d3", + "name": { + "pool_name": "oxp_b93f880e-c55b-4d6c-9a16-939d84b628fc", + "kind": "local_storage" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "5171b6ba-b282-4e71-917e-f253c7b2eb22": { + "id": "5171b6ba-b282-4e71-917e-f253c7b2eb22", + "name": { + "pool_name": "oxp_7b24095a-72df-45e3-984f-2b795e052ac7", + "kind": "zone" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "5625f171-927d-4e4a-b009-be250ac92bc3": { + "id": "5625f171-927d-4e4a-b009-be250ac92bc3", + "name": { + "pool_name": "oxp_8a199f12-4f5c-483a-8aca-f97856658a35", + "kind": "local_storage" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "56b0119a-f49d-45d7-a93e-d4a4e1d76559": { + "id": "56b0119a-f49d-45d7-a93e-d4a4e1d76559", + "name": { + "pool_name": "oxp_e126ddcc-8bee-46ba-8199-2a74df0ba040", + "kind": "zone" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "585cd8c5-c41e-4be4-beb8-bfbef9b53856": { + "id": "585cd8c5-c41e-4be4-beb8-bfbef9b53856", + "name": { + "pool_name": "oxp_6340805e-c5af-418d-8bd1-fc0085667f33", + "kind": "crucible" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "5b0bc0d3-24c6-4f9c-937b-f38e8ccee03c": { + "id": "5b0bc0d3-24c6-4f9c-937b-f38e8ccee03c", + "name": { + "pool_name": "oxp_26e698bb-006d-4208-94b9-d1bc279111fa", + "kind": "local_storage" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "5c4e9d03-f202-46dd-ba50-179b2b84f849": { + "id": "5c4e9d03-f202-46dd-ba50-179b2b84f849", + "name": { + "pool_name": "oxp_bf428719-1b16-4503-99f4-ad95846d916f", + "kind": "zone/oxz_crucible_7153983f-8fd7-4fb9-92ac-0f07a07798b4" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "69794309-1082-410b-a2a1-8b97588efa16": { + "id": "69794309-1082-410b-a2a1-8b97588efa16", + "name": { + "pool_name": "oxp_b93f880e-c55b-4d6c-9a16-939d84b628fc", + "kind": "zone" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "69a6412f-8438-4a0d-9c6e-a2e766750b2c": { + "id": "69a6412f-8438-4a0d-9c6e-a2e766750b2c", + "name": { + "pool_name": "oxp_2115b084-be0f-4fba-941b-33a659798a9e", + "kind": "zone/oxz_external_dns_5c97418b-8318-4427-8f65-14f3e3362d13" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "7153983f-8fd7-4fb9-92ac-0f07a07798b4": { + "id": "7153983f-8fd7-4fb9-92ac-0f07a07798b4", + "name": { + "pool_name": "oxp_bf428719-1b16-4503-99f4-ad95846d916f", + "kind": "crucible" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "77906e4e-1bbc-49c9-a7ee-f581de5552c4": { + "id": "77906e4e-1bbc-49c9-a7ee-f581de5552c4", + "name": { + "pool_name": "oxp_e126ddcc-8bee-46ba-8199-2a74df0ba040", + "kind": "zone/oxz_crucible_e238116d-e5cc-43d4-9c8a-6f138ae8a15d" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "7d44ba36-4a69-490a-bc40-f6f90a4208d4": { + "id": "7d44ba36-4a69-490a-bc40-f6f90a4208d4", + "name": { + "pool_name": "oxp_414e235b-55c3-4dc1-a568-8adf4ea1a052", + "kind": "crucible" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "8bce1ea9-5d2f-451a-87fd-db9140e07420": { + "id": "8bce1ea9-5d2f-451a-87fd-db9140e07420", + "name": { + "pool_name": "oxp_8a199f12-4f5c-483a-8aca-f97856658a35", + "kind": "zone/oxz_crucible_a6ba8273-0320-4dab-b801-281f041b0c50" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "8f50c2e8-d091-4440-b9cc-0c6c3e62b8b8": { + "id": "8f50c2e8-d091-4440-b9cc-0c6c3e62b8b8", + "name": { + "pool_name": "oxp_2115b084-be0f-4fba-941b-33a659798a9e", + "kind": "zone/oxz_crucible_0ccf27c0-e32d-4b52-a2c5-6db0c64a26f9" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "9721d822-c80a-4856-a715-02c9c0c89184": { + "id": "9721d822-c80a-4856-a715-02c9c0c89184", + "name": { + "pool_name": "oxp_e126ddcc-8bee-46ba-8199-2a74df0ba040", + "kind": "local_storage" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "978354d3-17cb-40ce-815d-b4edaad79f11": { + "id": "978354d3-17cb-40ce-815d-b4edaad79f11", + "name": { + "pool_name": "oxp_26e698bb-006d-4208-94b9-d1bc279111fa", + "kind": "zone" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "9bf9e7bd-269b-4925-ba99-a0cdb8138fb8": { + "id": "9bf9e7bd-269b-4925-ba99-a0cdb8138fb8", + "name": { + "pool_name": "oxp_cf940e15-dbc5-481b-866a-4de4b018898e", + "kind": "local_storage" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "a2d0f801-bf2d-44a3-b39b-bbfb3b387a4a": { + "id": "a2d0f801-bf2d-44a3-b39b-bbfb3b387a4a", + "name": { + "pool_name": "oxp_bf428719-1b16-4503-99f4-ad95846d916f", + "kind": "debug" + }, + "compression": { + "type": "gzip_n", + "level": 9 + }, + "quota": 107374182400, + "reservation": null + }, + "a6ba8273-0320-4dab-b801-281f041b0c50": { + "id": "a6ba8273-0320-4dab-b801-281f041b0c50", + "name": { + "pool_name": "oxp_8a199f12-4f5c-483a-8aca-f97856658a35", + "kind": "crucible" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "a6cbbb5d-f7b3-4d91-b54e-c3cf55762adc": { + "id": "a6cbbb5d-f7b3-4d91-b54e-c3cf55762adc", + "name": { + "pool_name": "oxp_bf428719-1b16-4503-99f4-ad95846d916f", + "kind": "local_storage" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "a724aab1-2fdc-45aa-8fa2-2f0a272aae62": { + "id": "a724aab1-2fdc-45aa-8fa2-2f0a272aae62", + "name": { + "pool_name": "oxp_414e235b-55c3-4dc1-a568-8adf4ea1a052", + "kind": "local_storage" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "aa44f101-8502-4480-bec8-9c48d3f4106b": { + "id": "aa44f101-8502-4480-bec8-9c48d3f4106b", + "name": { + "pool_name": "oxp_cf940e15-dbc5-481b-866a-4de4b018898e", + "kind": "zone" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "adb8db9b-2cd7-45b7-bb9f-adf094c4ccca": { + "id": "adb8db9b-2cd7-45b7-bb9f-adf094c4ccca", + "name": { + "pool_name": "oxp_414e235b-55c3-4dc1-a568-8adf4ea1a052", + "kind": "debug" + }, + "compression": { + "type": "gzip_n", + "level": 9 + }, + "quota": 107374182400, + "reservation": null + }, + "b156677f-cafa-4d73-9719-6b0d16dad722": { + "id": "b156677f-cafa-4d73-9719-6b0d16dad722", + "name": { + "pool_name": "oxp_8a199f12-4f5c-483a-8aca-f97856658a35", + "kind": "zone" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "b9b7b4c2-284a-4ec1-80ea-75b7a43b71c4": { + "id": "b9b7b4c2-284a-4ec1-80ea-75b7a43b71c4", + "name": { + "pool_name": "oxp_cf940e15-dbc5-481b-866a-4de4b018898e", + "kind": "crucible" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "c5e4bd8a-d323-48ec-a641-5c7dbecf3252": { + "id": "c5e4bd8a-d323-48ec-a641-5c7dbecf3252", + "name": { + "pool_name": "oxp_7b24095a-72df-45e3-984f-2b795e052ac7", + "kind": "local_storage" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "c9c7a527-d432-490d-86b3-658da7b555cc": { + "id": "c9c7a527-d432-490d-86b3-658da7b555cc", + "name": { + "pool_name": "oxp_26e698bb-006d-4208-94b9-d1bc279111fa", + "kind": "zone/oxz_crucible_072fdae8-2adf-4fd2-94ce-e9b0663b91e7" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "d8b3ba09-1267-43af-9734-1fdc3e22b23e": { + "id": "d8b3ba09-1267-43af-9734-1fdc3e22b23e", + "name": { + "pool_name": "oxp_cf940e15-dbc5-481b-866a-4de4b018898e", + "kind": "zone/oxz_crucible_b9b7b4c2-284a-4ec1-80ea-75b7a43b71c4" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "dee3ca8e-c6f5-4e12-aa0d-74ed9a6245a3": { + "id": "dee3ca8e-c6f5-4e12-aa0d-74ed9a6245a3", + "name": { + "pool_name": "oxp_2115b084-be0f-4fba-941b-33a659798a9e", + "kind": "zone/oxz_ntp_a700528f-f600-4908-94ac-9c06442ef6b4" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "e1c7ecae-faed-4d02-b446-2dd3478dc27d": { + "id": "e1c7ecae-faed-4d02-b446-2dd3478dc27d", + "name": { + "pool_name": "oxp_b93f880e-c55b-4d6c-9a16-939d84b628fc", + "kind": "debug" + }, + "compression": { + "type": "gzip_n", + "level": 9 + }, + "quota": 107374182400, + "reservation": null + }, + "e238116d-e5cc-43d4-9c8a-6f138ae8a15d": { + "id": "e238116d-e5cc-43d4-9c8a-6f138ae8a15d", + "name": { + "pool_name": "oxp_e126ddcc-8bee-46ba-8199-2a74df0ba040", + "kind": "crucible" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "e3d07396-5ab6-4008-b590-df8b5794f9e1": { + "id": "e3d07396-5ab6-4008-b590-df8b5794f9e1", + "name": { + "pool_name": "oxp_6340805e-c5af-418d-8bd1-fc0085667f33", + "kind": "local_storage" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "e7d578b0-2c40-4e1f-a1c2-2dc2a6f9f5d8": { + "id": "e7d578b0-2c40-4e1f-a1c2-2dc2a6f9f5d8", + "name": { + "pool_name": "oxp_6340805e-c5af-418d-8bd1-fc0085667f33", + "kind": "zone" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + }, + "fb307365-fd47-4112-9a88-519ee5cf6445": { + "id": "fb307365-fd47-4112-9a88-519ee5cf6445", + "name": { + "pool_name": "oxp_414e235b-55c3-4dc1-a568-8adf4ea1a052", + "kind": "zone" + }, + "compression": { + "type": "off" + }, + "quota": null, + "reservation": null + } + }, + "zones": { + "01f93020-7e7d-4185-93fb-6ca234056c82": { + "id": "01f93020-7e7d-4185-93fb-6ca234056c82", + "filesystem_pool": "oxp_7b24095a-72df-45e3-984f-2b795e052ac7", + "zone_type": { + "type": "crucible", + "address": "[fd00:1122:3344:103::5]:32345", + "dataset": { + "pool_name": "oxp_7b24095a-72df-45e3-984f-2b795e052ac7" + } + }, + "image_source": { + "type": "artifact", + "hash": "988cab6ea184b7912350e5af151bd18152ee2702bad7dc0b977d414eb8062e27" + } + }, + "072fdae8-2adf-4fd2-94ce-e9b0663b91e7": { + "id": "072fdae8-2adf-4fd2-94ce-e9b0663b91e7", + "filesystem_pool": "oxp_26e698bb-006d-4208-94b9-d1bc279111fa", + "zone_type": { + "type": "crucible", + "address": "[fd00:1122:3344:103::b]:32345", + "dataset": { + "pool_name": "oxp_26e698bb-006d-4208-94b9-d1bc279111fa" + } + }, + "image_source": { + "type": "artifact", + "hash": "988cab6ea184b7912350e5af151bd18152ee2702bad7dc0b977d414eb8062e27" + } + }, + "0b41c560-3b20-42f4-82ad-92f5bb575d6b": { + "id": "0b41c560-3b20-42f4-82ad-92f5bb575d6b", + "filesystem_pool": "oxp_b93f880e-c55b-4d6c-9a16-939d84b628fc", + "zone_type": { + "type": "crucible", + "address": "[fd00:1122:3344:103::9]:32345", + "dataset": { + "pool_name": "oxp_b93f880e-c55b-4d6c-9a16-939d84b628fc" + } + }, + "image_source": { + "type": "artifact", + "hash": "988cab6ea184b7912350e5af151bd18152ee2702bad7dc0b977d414eb8062e27" + } + }, + "0ccf27c0-e32d-4b52-a2c5-6db0c64a26f9": { + "id": "0ccf27c0-e32d-4b52-a2c5-6db0c64a26f9", + "filesystem_pool": "oxp_2115b084-be0f-4fba-941b-33a659798a9e", + "zone_type": { + "type": "crucible", + "address": "[fd00:1122:3344:103::d]:32345", + "dataset": { + "pool_name": "oxp_2115b084-be0f-4fba-941b-33a659798a9e" + } + }, + "image_source": { + "type": "artifact", + "hash": "988cab6ea184b7912350e5af151bd18152ee2702bad7dc0b977d414eb8062e27" + } + }, + "470fbf4d-0178-45ee-a422-136fa5f4a158": { + "id": "470fbf4d-0178-45ee-a422-136fa5f4a158", + "filesystem_pool": "oxp_2115b084-be0f-4fba-941b-33a659798a9e", + "zone_type": { + "type": "nexus", + "internal_address": "[fd00:1122:3344:103::47]:12221", + "lockstep_port": 12232, + "external_ip": "172.20.26.8", + "nic": { + "id": "98d2e08e-a3a6-43ed-a2a0-7cf52fd211f8", + "kind": { + "type": "service", + "id": "470fbf4d-0178-45ee-a422-136fa5f4a158" + }, + "name": "nexus-470fbf4d-0178-45ee-a422-136fa5f4a158", + "ip": "172.30.2.9", + "mac": "A8:40:25:FF:80:05", + "subnet": "172.30.2.0/24", + "vni": 100, + "primary": true, + "slot": 0 + }, + "external_tls": true, + "external_dns_servers": [ + "1.1.1.1", + "9.9.9.9" + ] + }, + "image_source": { + "type": "artifact", + "hash": "1ae3b88364f311ce588ac802cb8177c4806b76da0ce42e39aab0b0d8bb04c197" + } + }, + "585cd8c5-c41e-4be4-beb8-bfbef9b53856": { + "id": "585cd8c5-c41e-4be4-beb8-bfbef9b53856", + "filesystem_pool": "oxp_6340805e-c5af-418d-8bd1-fc0085667f33", + "zone_type": { + "type": "crucible", + "address": "[fd00:1122:3344:103::7]:32345", + "dataset": { + "pool_name": "oxp_6340805e-c5af-418d-8bd1-fc0085667f33" + } + }, + "image_source": { + "type": "artifact", + "hash": "988cab6ea184b7912350e5af151bd18152ee2702bad7dc0b977d414eb8062e27" + } + }, + "5c97418b-8318-4427-8f65-14f3e3362d13": { + "id": "5c97418b-8318-4427-8f65-14f3e3362d13", + "filesystem_pool": "oxp_2115b084-be0f-4fba-941b-33a659798a9e", + "zone_type": { + "type": "external_dns", + "dataset": { + "pool_name": "oxp_2115b084-be0f-4fba-941b-33a659798a9e" + }, + "http_address": "[fd00:1122:3344:103::46]:5353", + "dns_address": "172.20.26.2:53", + "nic": { + "id": "9e5b3233-1bb2-4d10-a99a-6884d6ab4d7d", + "kind": { + "type": "service", + "id": "5c97418b-8318-4427-8f65-14f3e3362d13" + }, + "name": "external-dns-5c97418b-8318-4427-8f65-14f3e3362d13", + "ip": "172.30.1.6", + "mac": "A8:40:25:FF:80:01", + "subnet": "172.30.1.0/24", + "vni": 100, + "primary": true, + "slot": 0 + } + }, + "image_source": { + "type": "artifact", + "hash": "389335a28c7bb548e68537df4bf5be5df7f2f54db1fba6b1cba3ad36ad48e625" + } + }, + "7153983f-8fd7-4fb9-92ac-0f07a07798b4": { + "id": "7153983f-8fd7-4fb9-92ac-0f07a07798b4", + "filesystem_pool": "oxp_bf428719-1b16-4503-99f4-ad95846d916f", + "zone_type": { + "type": "crucible", + "address": "[fd00:1122:3344:103::a]:32345", + "dataset": { + "pool_name": "oxp_bf428719-1b16-4503-99f4-ad95846d916f" + } + }, + "image_source": { + "type": "artifact", + "hash": "988cab6ea184b7912350e5af151bd18152ee2702bad7dc0b977d414eb8062e27" + } + }, + "7d44ba36-4a69-490a-bc40-f6f90a4208d4": { + "id": "7d44ba36-4a69-490a-bc40-f6f90a4208d4", + "filesystem_pool": "oxp_414e235b-55c3-4dc1-a568-8adf4ea1a052", + "zone_type": { + "type": "crucible", + "address": "[fd00:1122:3344:103::c]:32345", + "dataset": { + "pool_name": "oxp_414e235b-55c3-4dc1-a568-8adf4ea1a052" + } + }, + "image_source": { + "type": "artifact", + "hash": "988cab6ea184b7912350e5af151bd18152ee2702bad7dc0b977d414eb8062e27" + } + }, + "a6ba8273-0320-4dab-b801-281f041b0c50": { + "id": "a6ba8273-0320-4dab-b801-281f041b0c50", + "filesystem_pool": "oxp_8a199f12-4f5c-483a-8aca-f97856658a35", + "zone_type": { + "type": "crucible", + "address": "[fd00:1122:3344:103::4]:32345", + "dataset": { + "pool_name": "oxp_8a199f12-4f5c-483a-8aca-f97856658a35" + } + }, + "image_source": { + "type": "artifact", + "hash": "988cab6ea184b7912350e5af151bd18152ee2702bad7dc0b977d414eb8062e27" + } + }, + "a700528f-f600-4908-94ac-9c06442ef6b4": { + "id": "a700528f-f600-4908-94ac-9c06442ef6b4", + "filesystem_pool": "oxp_2115b084-be0f-4fba-941b-33a659798a9e", + "zone_type": { + "type": "internal_ntp", + "address": "[fd00:1122:3344:103::45]:123" + }, + "image_source": { + "type": "artifact", + "hash": "2b0988a6122b34391f3310ce1ade733c175316331f408cf1e40329c419318142" + } + }, + "b9b7b4c2-284a-4ec1-80ea-75b7a43b71c4": { + "id": "b9b7b4c2-284a-4ec1-80ea-75b7a43b71c4", + "filesystem_pool": "oxp_cf940e15-dbc5-481b-866a-4de4b018898e", + "zone_type": { + "type": "crucible", + "address": "[fd00:1122:3344:103::8]:32345", + "dataset": { + "pool_name": "oxp_cf940e15-dbc5-481b-866a-4de4b018898e" + } + }, + "image_source": { + "type": "artifact", + "hash": "988cab6ea184b7912350e5af151bd18152ee2702bad7dc0b977d414eb8062e27" + } + }, + "e238116d-e5cc-43d4-9c8a-6f138ae8a15d": { + "id": "e238116d-e5cc-43d4-9c8a-6f138ae8a15d", + "filesystem_pool": "oxp_e126ddcc-8bee-46ba-8199-2a74df0ba040", + "zone_type": { + "type": "crucible", + "address": "[fd00:1122:3344:103::6]:32345", + "dataset": { + "pool_name": "oxp_e126ddcc-8bee-46ba-8199-2a74df0ba040" + } + }, + "image_source": { + "type": "artifact", + "hash": "988cab6ea184b7912350e5af151bd18152ee2702bad7dc0b977d414eb8062e27" + } + } + }, + "remove_mupdate_override": null, + "host_phase_2": { + "slot_a": { + "type": "artifact", + "hash": "8234c10964ef7f62880772caaf96f449234bad8428b2a6a09e623d383550bfdf" + }, + "slot_b": { + "type": "artifact", + "hash": "8234c10964ef7f62880772caaf96f449234bad8428b2a6a09e623d383550bfdf" + } + } +} From 14499011504fa1bac1a98f65ba79f576c9b179b3 Mon Sep 17 00:00:00 2001 From: John Gallagher Date: Thu, 18 Dec 2025 17:16:29 -0500 Subject: [PATCH 6/7] macro instead of manual trait impls --- .../ledger/ledgered_sled_config_versioning.rs | 47 +++++++++++-------- 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/sled-agent/config-reconciler/src/ledger/ledgered_sled_config_versioning.rs b/sled-agent/config-reconciler/src/ledger/ledgered_sled_config_versioning.rs index a6eaaf9602b..2e6bed31915 100644 --- a/sled-agent/config-reconciler/src/ledger/ledgered_sled_config_versioning.rs +++ b/sled-agent/config-reconciler/src/ledger/ledgered_sled_config_versioning.rs @@ -22,12 +22,10 @@ use std::error::Error as StdError; /// Trait describing an ordered sequence of `OmicronSledConfig` versions, each /// of which can be converted from its previous version. /// -/// When adding a new [`OmicronSledConfig`] version, implement -/// [`VersionConversionChain`] for your new version. Use its fully-versioned -/// name (e.g., `vN::inventory::OmicronSledConfig`), not the -/// [`OmicronSledConfig`] alias from `latest`. The `Previous` associated type -/// should point to the prior version (what was the current version before your -/// change). +/// When adding a new [`OmicronSledConfig`] version, add your new version to the +/// `version_conversion_chain!()` invocation below. Use the fully-versioned name +/// (e.g., `vN::inventory::OmicronSledConfig`), not the [`OmicronSledConfig`] +/// alias from `latest`. /// /// Also update the unit tests at the bottom of this file to cover your new /// version as well. @@ -37,8 +35,8 @@ trait VersionConversionChain: Ledgerable { /// Special terminal state; this must be `false` for all implementors except /// [`VersionConversionChainTerminal`]. - /// [`try_convert_old_ledgered_config_versions_chain()] uses this to know - /// when to stop recursing. + // `try_ledgered_config_versions_chain() uses this to know when to stop + // recursing. const IS_TERMINAL: bool = false; /// The previous [`OmicronSledConfig`] version, which must be convertible @@ -46,20 +44,31 @@ trait VersionConversionChain: Ledgerable { type Previous: VersionConversionChain + TryInto; } -impl VersionConversionChain for v11::inventory::OmicronSledConfig { - const DESCRIPTION: &str = "v11::inventory::OmicronSledConfig"; - type Previous = v10::inventory::OmicronSledConfig; -} +macro_rules! version_conversion_chain { + // base case + ($current:path, $previous:path) => { + impl VersionConversionChain for $current { + const DESCRIPTION: &str = stringify!($current); + type Previous = $previous; + } + }; -impl VersionConversionChain for v10::inventory::OmicronSledConfig { - const DESCRIPTION: &str = "v10::inventory::OmicronSledConfig"; - type Previous = v4::inventory::OmicronSledConfig; + // recursive case + ($current:path, $previous:path, $($rest:path),+ $(,)?) => { + version_conversion_chain!($current, $previous); + version_conversion_chain!($previous, $($rest),+); + }; } -impl VersionConversionChain for v4::inventory::OmicronSledConfig { - const DESCRIPTION: &str = "v4::inventory::OmicronSledConfig"; - type Previous = VersionConversionChainTerminal; -} +// This list is ordered from newest to oldest; this is the order in which we'll +// attempt to parse the ledgered config. Add new versions to the top of the +// list. +version_conversion_chain!( + v11::inventory::OmicronSledConfig, + v10::inventory::OmicronSledConfig, + v4::inventory::OmicronSledConfig, + VersionConversionChainTerminal, +); /// Read the ledgered [`OmicronSledConfig`], converting from older versions if /// needed. From f2669048091c7d2fab3adab7061778dc71923588 Mon Sep 17 00:00:00 2001 From: John Gallagher Date: Fri, 19 Dec 2025 10:28:39 -0500 Subject: [PATCH 7/7] reword comment explaining impl Ledgerable --- .../add_dual_stack_external_ip_config/inventory.rs | 13 +++++++++---- .../inventory.rs | 13 +++++++++---- .../inventory.rs | 13 +++++++++---- 3 files changed, 27 insertions(+), 12 deletions(-) diff --git a/sled-agent/types/versions/src/add_dual_stack_external_ip_config/inventory.rs b/sled-agent/types/versions/src/add_dual_stack_external_ip_config/inventory.rs index 828405bd27d..1d64553394e 100644 --- a/sled-agent/types/versions/src/add_dual_stack_external_ip_config/inventory.rs +++ b/sled-agent/types/versions/src/add_dual_stack_external_ip_config/inventory.rs @@ -113,10 +113,15 @@ pub struct OmicronSledConfig { pub host_phase_2: HostPhase2DesiredSlots, } -// NOTE: Most trait impls live in the `impls` module of this crate, but we -// ledger sled configs on disk, so have to be able to read them from the ledger -// even for old versions. Therefore, we implement `Ledgerable` on this type -// directly. +// NOTE: Most trait impls live in the `impls` module of this crate and are only +// implemented for the `latest` version of each type. However, +// `OmicronSledConfig` is special: it's not only used in the sled-agent API +// (which would only require trait impls on `latest`); it's also ledgered to +// disk to support cold boot of the rack. In the ledgering case, we have to be +// able to handle reading older versions, which means all the old versions we +// support also need to implement `Ledgerable`. Therefore, we implement this +// trait for this specific version (and do so for every other version of +// `OmicronSledConfig` too). impl Ledgerable for OmicronSledConfig { fn is_newer_than(&self, other: &Self) -> bool { self.generation > other.generation diff --git a/sled-agent/types/versions/src/add_dual_stack_shared_network_interfaces/inventory.rs b/sled-agent/types/versions/src/add_dual_stack_shared_network_interfaces/inventory.rs index ad2e9c4b6ff..3f616522ed4 100644 --- a/sled-agent/types/versions/src/add_dual_stack_shared_network_interfaces/inventory.rs +++ b/sled-agent/types/versions/src/add_dual_stack_shared_network_interfaces/inventory.rs @@ -115,10 +115,15 @@ pub struct OmicronSledConfig { pub host_phase_2: HostPhase2DesiredSlots, } -// NOTE: Most trait impls live in the `impls` module of this crate, but we -// ledger sled configs on disk, so have to be able to read them from the ledger -// even for old versions. Therefore, we implement `Ledgerable` on this type -// directly. +// NOTE: Most trait impls live in the `impls` module of this crate and are only +// implemented for the `latest` version of each type. However, +// `OmicronSledConfig` is special: it's not only used in the sled-agent API +// (which would only require trait impls on `latest`); it's also ledgered to +// disk to support cold boot of the rack. In the ledgering case, we have to be +// able to handle reading older versions, which means all the old versions we +// support also need to implement `Ledgerable`. Therefore, we implement this +// trait for this specific version (and do so for every other version of +// `OmicronSledConfig` too). impl Ledgerable for OmicronSledConfig { fn is_newer_than(&self, other: &Self) -> bool { self.generation > other.generation diff --git a/sled-agent/types/versions/src/add_nexus_lockstep_port_to_inventory/inventory.rs b/sled-agent/types/versions/src/add_nexus_lockstep_port_to_inventory/inventory.rs index e49c58231c9..2eb7db54042 100644 --- a/sled-agent/types/versions/src/add_nexus_lockstep_port_to_inventory/inventory.rs +++ b/sled-agent/types/versions/src/add_nexus_lockstep_port_to_inventory/inventory.rs @@ -70,10 +70,15 @@ pub struct OmicronSledConfig { pub host_phase_2: HostPhase2DesiredSlots, } -// NOTE: Most trait impls live in the `impls` module of this crate, but we -// ledger sled configs on disk, so have to be able to read them from the ledger -// even for old versions. Therefore, we implement `Ledgerable` on this type -// directly. +// NOTE: Most trait impls live in the `impls` module of this crate and are only +// implemented for the `latest` version of each type. However, +// `OmicronSledConfig` is special: it's not only used in the sled-agent API +// (which would only require trait impls on `latest`); it's also ledgered to +// disk to support cold boot of the rack. In the ledgering case, we have to be +// able to handle reading older versions, which means all the old versions we +// support also need to implement `Ledgerable`. Therefore, we implement this +// trait for this specific version (and do so for every other version of +// `OmicronSledConfig` too). impl Ledgerable for OmicronSledConfig { fn is_newer_than(&self, other: &Self) -> bool { self.generation > other.generation