From b5d976abe98f9b958cf33cbf269a8f26bc1ab97a Mon Sep 17 00:00:00 2001 From: David Pacheco Date: Fri, 4 Sep 2026 15:38:20 -0700 Subject: [PATCH 1/2] add README for reconfigurator-exec-unsafe --- .../reconfigurator-exec-unsafe/README.adoc | 106 ++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 dev-tools/reconfigurator-exec-unsafe/README.adoc diff --git a/dev-tools/reconfigurator-exec-unsafe/README.adoc b/dev-tools/reconfigurator-exec-unsafe/README.adoc new file mode 100644 index 00000000000..bba54b3f000 --- /dev/null +++ b/dev-tools/reconfigurator-exec-unsafe/README.adoc @@ -0,0 +1,106 @@ +:showtitle: +:toc: left +:icons: font + += reconfigurator-exec-unsafe + +`reconfigurator-exec-unsafe` executes a blueprint against a live system from the command line. It reads the blueprint from a JSON file and then runs the same execution code that Nexus runs (the `nexus-reconfigurator-execution` package). It talks directly to the internal DNS servers and to CockroachDB, so it must run somewhere with access to the underlay network. + +This is a tool for development and testing. It is not part of the shipping product. + +For background on Reconfigurator, blueprints, and the rest of the tooling, see: + +* xref:../../docs/reconfigurator.adoc[Reconfigurator documentation] +* xref:../../docs/reconfigurator-dev-guide.adoc[Reconfigurator developer guide] +* xref:../../docs/reconfigurator-ops-guide.adoc[Reconfigurator operator guide] + +== When to use it + +This tool was built to test execution of a blueprint in development where you haven't yet implemented database serialization for part of the blueprint. Specifically, when initially building MGS-managed updates, we added some complex stuff to the blueprint. This was implemented in Rust and so was easy to serialize to a JSON file, too, but it would have been a bunch more work to put this into the database. We wanted to be able to test execution using these blueprints _before_ implementing the database serialization for them so that we could iterate more quickly as we found we needed to change what we stored in the blueprint. + +This is a pretty narrow use case. + +== Why "unsafe" + +This tool is dangerous because it can deploy something to, say, sled agents that's different than what Nexus is deploying for the same blueprint. One of these will "win" on a per-sled basis. The other will see blueprint execution errors. For example, if you're changing `BlueprintSledConfig`, which affects the set of zones deployed to each sled agent, and you generate a new blueprint with your new representation: an existing Nexus and your Nexus will compute different contents for the sled agent config generation `N`. If your `reconfigurator-exec-unsafe` invocation reaches a particular sled first, it will get your version. Otherwise, it will get Nexus's. That will become sticky for that sled, since it won't accept different versions of generation `N`. + +This discrepancy would generally get resolved if ever Nexus had to bump the associated generation for some other reason. But it could have long-term consequences. The specific behavior and impact would depend on how the blueprint differed between Nexus and this tool. + +== Before you run it + +For safety and predictability, this tool requires that: + +- Your blueprint is the current target blueprint. (The system is designed so that it should always be safe to execute an older target blueprint.) +- Blueprint execution is disabled. This helps ensure that your execution will "win" as the blueprint is executed (see above). + +From the switch zone, you can use `omdb` to do this. If the blueprint isn't in the database yet, import it first: + +``` +$ omdb --destructive nexus blueprints import my-blueprint.json +``` + +Then make it the target with execution disabled: + +``` +$ omdb --destructive nexus blueprints target set BLUEPRINT_ID disabled +``` + +If the blueprint is already the target, you can just disable execution for it: + +``` +$ omdb --destructive nexus blueprints target disable BLUEPRINT_ID +``` + +Confirm that both conditions hold before you continue: + +``` +$ omdb nexus blueprints target show +target blueprint: f48b5b5a-05dd-4fab-95a9-e062ae8704b1 +made target at: 2025-05-27 18:36:12.227236 UTC +enabled: false +``` + +Remember that you can only make a blueprint the target if its parent is the current target. See the developer guide for details. + +When you're finished with the tool, re-enable execution so that the system resumes managing itself: + +``` +$ omdb --destructive nexus blueprints target enable BLUEPRINT_ID +``` + +== Usage + +``` +reconfigurator-exec-unsafe [OPTIONS] +``` + +`` is the path to a JSON-serialized blueprint. `reconfigurator-cli` writes files in this format with its `blueprint-save` command. + +.Options +[cols="1,3",options="header"] +|=== +|Option +|Description + +|`--dns-server ` +|Address of an internal DNS server in this deployment. The tool uses this to find CockroachDB and the other services it needs. You will probably need to specify this option for your system. + +|`--log-level ` +|Log level filter, `info` by default. Logs go to stderr. You can also set this with the `LOG_LEVEL` environment variable. + +|`--mgs-updates` +|Run a driver for MGS-managed updates (service processor software and the like). Off by default. See <<_mgs_managed_updates>>. + +|`--color ` +|Whether to colorize the execution report: `auto` (the default), `always`, or `never`. +|=== + +When execution finishes, the tool prints a report of every execution step to stdout. It exits non-zero if execution failed. + +== MGS-managed updates + +Blueprint execution doesn't apply MGS-managed updates itself. It hands the set of pending updates to a separate driver, which lives in Nexus on a real system. If you want those updates to actually happen, pass `--mgs-updates`. The tool then starts its own driver, picks an in-service sled to serve as its repo depot, and keeps running after blueprint execution completes so that the driver can do its work. + +The tool waits until at least one update has completed and no updates are in progress, then shuts the driver down. This means you should only pass `--mgs-updates` when the blueprint actually contains pending MGS updates. If it doesn't, the tool will wait forever, and you'll have to interrupt it. + +For developing or testing the update driver on its own, `reconfigurator-sp-updater` is usually the easier tool. From c3a58a6ca132b578ccc555921a3e5cbcf19f08c2 Mon Sep 17 00:00:00 2001 From: David Pacheco Date: Fri, 4 Sep 2026 15:43:58 -0700 Subject: [PATCH 2/2] soften comment --- dev-tools/reconfigurator-exec-unsafe/src/main.rs | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/dev-tools/reconfigurator-exec-unsafe/src/main.rs b/dev-tools/reconfigurator-exec-unsafe/src/main.rs index 0d3896eb039..a4c4db7f6b6 100644 --- a/dev-tools/reconfigurator-exec-unsafe/src/main.rs +++ b/dev-tools/reconfigurator-exec-unsafe/src/main.rs @@ -62,17 +62,10 @@ struct ReconfiguratorExec { )] log_level: dropshot::ConfigLoggingLevel, - /// an internal DNS server in this deployment - // This default value is currently appropriate for all deployed systems. - // That relies on two assumptions: - // - // 1. The internal DNS servers' underlay addresses are at a fixed location - // from the base of the AZ subnet. This is unlikely to change, since the - // DNS servers must be discoverable with virtually no other information. - // 2. The AZ subnet used for all deployments today is fixed. - // - // For simulated systems (e.g., `cargo xtask omicron-dev run-all`), or if - // these assumptions change in the future, we may need to adjust this. + /// an internal DNS server in this deployment (likely needs to be specified + /// for each deployment) + // This default value was once appropriate for deployed systems, but isn't + // any more since they have different AZ subnets today. #[arg(long, default_value = "[fd00:1122:3344:3::1]:53")] dns_server: SocketAddr,