Skip to content

Commit

Permalink
add CLI tool to test migration
Browse files Browse the repository at this point in the history
  • Loading branch information
davepacheco committed Nov 15, 2023
1 parent 655d9f8 commit 964c1a7
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 8 deletions.
53 changes: 53 additions & 0 deletions sled-agent/src/bin/services-ledger-check-migrate.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

//! Test-migrates one or more old-format services ledger files to new-format
//! Omicron zones ledgers
use anyhow::Context;
use camino::Utf8PathBuf;
use clap::Parser;
use omicron_common::cmd::fatal;
use omicron_common::cmd::CmdError;
use omicron_sled_agent::services::ZonesConfig;
use omicron_sled_agent::services_migration::AllServiceRequests;

#[tokio::main]
async fn main() {
if let Err(message) = do_run().await {
fatal(CmdError::Failure(format!("{:#}", message)));
}
}

// XXX-dap make this two subcommands:
// - `check` does what this does now
// - `show` takes one argument and pretty-prints the converted form

#[derive(Debug, Parser)]
struct Args {
#[clap(action)]
files: Vec<Utf8PathBuf>,
}

async fn do_run() -> Result<(), anyhow::Error> {
let args = Args::parse();
for file_path in &args.files {
let contents = tokio::fs::read_to_string(file_path)
.await
.with_context(|| format!("read {:?}", &file_path))?;
let parsed: AllServiceRequests = serde_json::from_str(&contents)
.with_context(|| format!("parse {:?}", &file_path))?;
let converted = ZonesConfig::try_from(parsed)
.with_context(|| format!("migrate contents of {:?}", &file_path))?;
// XXX-dap what sanity-checks on the result?
println!(
"{}: converted okay (zones: {})",
file_path,
converted.zones.len()
);
}

println!("all files converted okay (files: {})", args.files.len());
Ok(())
}
4 changes: 2 additions & 2 deletions sled-agent/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ pub mod params;
mod profile;
pub mod rack_setup;
pub mod server;
mod services;
mod services_migration;
pub mod services;
pub mod services_migration;
mod sled_agent;
mod smf_helper;
pub(crate) mod storage;
Expand Down
43 changes: 43 additions & 0 deletions sled-agent/src/services.rs
Original file line number Diff line number Diff line change
Expand Up @@ -672,6 +672,49 @@ impl ServiceManager {
);

ledger.commit().await?;

// We could consider removing the old ledger here. That would
// not guarantee that it would be gone, though, because we could
// crash during `ledger.commit()` above having written at least
// one of the new ledgers. In that case, we won't go through
// this code path again on restart. If we wanted to ensure the
// old-format ledger was gone after the migration, we could
// consider unconditionally removing the old ledger paths in the
// caller, after we've got a copy of the new-format ledger.
//
// Should we? In principle, it shouldn't matter either way
// because we will never look at the old-format ledger unless we
// don't have a new-format one, and we should now have a
// new-format one forever now.
//
// When might it matter? Two cases:
//
// (1) If the sled agent is downgraded to a previous version
// that doesn't know about the new-format ledger. Do we
// want that sled agent to use the old-format one? It
// depends. If that downgrade happens immediately because
// the upgrade to the first new-format version was a
// disaster, then we'd probably rather the downgraded sled
// agent _did_ start its zones. If the downgrade happens
// months later, potentially after various additional
// reconfigurations, then that old-format ledger is probably
// out of date and shouldn't be used. There's no way to
// really know which case we're in, but the latter seems
// quite unlikely (why would we downgrade so far back after
// so long?). So that's a reason to keep the old-format
// ledger.
//
// (2) Suppose a developer or Oxide support engineer removes the
// new ledger for some reason, maybe thinking sled agent
// would come up with no zones running. They'll be
// surprised to discover that it actually starts running a
// potentially old set of zones. This probably only matters
// on a production system, and even then, it probably
// shouldn't happen.
//
// Given these cases, we're left ambivalent. We choose to keep
// the old ledger around. If nothing else, if something goes
// wrong, we'll have a copy of its last contents!
Ok(Some(ledger))
}
}
Expand Down
6 changes: 0 additions & 6 deletions sled-agent/src/services_migration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,12 +177,6 @@ impl std::fmt::Display for ServiceType {
}
}

/// Used to request that the Sled initialize multiple services.
#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq)]
pub struct ServiceEnsureBody {
pub services: Vec<ServiceZoneRequest>,
}

/// Describes a request to provision a specific dataset
#[derive(
Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq, Eq, Hash,
Expand Down

0 comments on commit 964c1a7

Please sign in to comment.