baremetal: give clean --raid three named modes - #2633
Merged
Conversation
`create_configuration` on a full clean is currently asserted in exactly one place: node 3 of `test_clean_all_builds_the_step_list_per_node`, under the default. An upcoming change moves the create step off the default path and behind an explicit `--raid recreate`, which means editing that expectation. Bare `--raid` is documented to keep its current meaning across that change, but nothing pins it, so the edit would leave the full-clean rebuild with no test at all. Add that test now, while it still passes. It is deliberately a duplicate assertion against the current code: with `raid=None` and `raid=True` both resolving to the same thing on a full clean, no test at either level passes `raid=True` with `metadata_only=False`. It stops being a duplicate as soon as the default changes. Written before the behaviour change on purpose. A test added afterwards would only restate whatever the new code does; this one records what the code does today, so it can fail if the compatibility promise is broken. Assisted-by: Claude:claude-opus-5 Signed-off-by: Roger Luethi <luethi@osism.tech>
There was a problem hiding this comment.
Hey - I've found 1 issue
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="osism/commands/baremetal.py" line_range="1286" />
<code_context>
+ wipe a node completely, leaving no array behind
+ osism baremetal clean node101
+
+ recycle a node into the pool with its array intact
+ osism baremetal clean --raid recreate node101
+
+ wipe the data but leave the existing array in place
</code_context>
<issue_to_address>
**nitpick:** The help example describes `--raid recreate` as recycling a node with its array intact, but that mode explicitly deletes the existing RAID configuration before creating a new one, so the example misleads operators about the destructive operation it performs.
**Suggested fix:** Describe the example as deleting and rebuilding the declared array, or use `--raid keep` for an array-preserving recycle.
```suggestion
delete and rebuild the declared array
```
</issue_to_address>Sourcery assessment
Needs a human reviewer. The new RAID modes can delete RAID configurations and erase disk data, and a mistaken recreate or keep operation can leave selected bare-metal nodes with irreversible data loss or a changed storage layout. Reverting the code would not restore deleted data or the prior RAID state, although the affected scope is limited to nodes on which the command is run.
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
`--raid` / `--no-raid` could only express two of the three things an operator
does with a RAID configuration during a clean. "Leave the existing array
alone" and "tear it down without rebuilding" are different outcomes, and a
boolean has to conflate them: `--no-raid` suppressed the delete step as well,
making it less destructive than the pre-change default rather than equal to
it.
Replace them with `--raid {delete,keep,recreate}`, an optional value whose
bare form still means recreate, so `clean --metadata-only --raid` keeps
working. `--no-raid` is removed rather than aliased: it has not been in a
release, so no operator has ever had it, and `--raid keep` says what it does.
delete delete_configuration in front of the erase step
keep no raid steps, erase through the existing array
recreate delete_configuration in front, create_configuration behind
The default resolves to delete on a full clean and keep with
`--metadata-only`, so it tracks the erase depth and restores the behaviour the
command had before the create step was added. That step now needs an explicit
`--raid recreate`. A `target_raid_config` can be declared fleet-wide from one
conductor.yml, so keying the default on it turned a routine `clean --all` into
a fleet-wide array build, and create is the only one of the three outcomes
that can fail into `clean failed` plus maintenance mode.
recreate delivers its outcome or refuses; it never degrades to delete, which
would be the destructive opposite of what was asked for. A named node that
cannot be built is refused before any provision state transition, which is
stricter than before the clean call because an available node is moved to
manageable and waited for first. Under `--all` the node set is discovered
rather than asserted, so an undeclared node is skipped and reported and the
rest of the fleet still runs, with a non-zero exit so automation sees the gap;
a node with no raid interface is out of scope there and is cleaned with the
erase step alone. Nodes in a state the loop would not clean anyway are left
out of the preflight entirely.
`--raid` taking an optional value means argparse claims a node name written
directly after it, so `clean --raid node101` cannot work. The error names the
two spellings that do instead of leaving the stock "invalid choice" message.
The five use cases are in the parser epilog, which is the only user-facing
documentation these flags have; osism.github.io documents none of them.
DocImpact
Assisted-by: Claude:claude-opus-5
Signed-off-by: Roger Luethi <luethi@osism.tech>
ideaship
force-pushed
the
baremetal-raid-flag-shape
branch
from
August 27, 2026 15:22
8497fb5 to
1b9afcf
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to the RAID clean work, and release-coupled to it:
That PR added
--raid/--no-raidas booleans. This replaces them with three namedmodes before either reaches a release, so no operator ever sees the boolean form and
removing
--no-raidcosts nothing. If a release ships in between,--no-raidbecomes areleased flag on a destructive command and has to be carried as a deprecated alias
instead.
Why a boolean is not enough
"Leave the existing array alone" and "tear it down without rebuilding" are different
outcomes, and one flag cannot express both.
--no-raidsuppressed the delete step aswell, which made it less destructive than the pre-change default rather than equal
to it — so the pre-#2609 sequence (delete, erase, leave the disks bare) became
unreachable for exactly the nodes it used to apply to.
The modes
--raiddeletedelete_configurationkeeprecreatedelete_configuration+create_configurationThe value is optional and bare
--raidstill meansrecreate, soclean --metadata-only --raidkeeps working.The default resolves to
deleteon a full clean andkeepwith--metadata-only. Thattracks the erase depth in one sentence and restores the behaviour the command had before
the create step existed.
create_configurationnow needs an explicit--raid recreate, which is the substantive change: atarget_raid_configcan bedeclared fleet-wide from a single
conductor.yml, so keying the default on it turned aroutine
clean --allinto a fleet-wide array build — and create is the only one of thethree outcomes that can fail into
clean failedplus maintenance mode.Migration
clean(node with a declaration)clean --raid recreateclean --raidclean --metadata-only --raidclean --no-raidclean --raid keeprecreatedelivers or refusesIt never degrades to
delete, which would be the destructive opposite of what wasasked for. Upstream shows why this is worth a preflight rather than a warning:
AgentRAID.create_configurationcallsraid.filter_target_raid_config, which raisesMissingParameterValueon an emptytarget_raid_config; the conductor'scleaning_error_handlerthen puts the node inCLEANFAILand sets maintenance mode.Because create runs last, a node passed through would be erased first and parked in
maintenance afterwards. Nothing gates it earlier — step validation only checks argument
names, and both of this step's arguments are optional.
no-raidnode--allRefusals land before any provision-state transition, not merely before the clean call —
an
availablenode is otherwise moved tomanageableand waited for first. Nodes in astate the loop would not clean anyway are left out of the preflight, so an
activeundeclared node cannot fail a run over a node that was never going to be touched.
--allskips rather than aborts on purpose. "RAID-capable but undeclared" is alegitimate state — it is what
deleteandkeepdo today — andcleanhas no nodeselection, so aborting would strand an entire fleet on one such node with no way to
exclude it.
One rough edge, documented rather than fixed
An optional value competes with the optional positional: argparse claims the next
non-
-token, soclean --raid node101is rejected. It cannot be fixed while--raidhas both an optional value and an optional positional beside it, and a required value
would break bare
--raid. The error names the two spellings that work instead ofleaving argparse's
invalid choice: 'node101'.Testing
tests/unit/commands/test_baremetal.pygoes 140 → 168; full unit suite 3176 passed, 4xfailed (pre-existing, unrelated).
The first commit is a test on its own, added before the behaviour changed while it
was still a duplicate assertion.
create_configurationon a full clean was previouslyasserted only by the default path, and this change edits exactly that expectation, so
bare
--raidwould otherwise have lost its only witness.Every guard was mutation-checked — removing the preflight, dropping the named
no-raidrefusal, mapping bare
--raidtodelete, restoring the old default, aborting insteadof skipping, letting
recreatedegrade, dropping the loop skip, dropping the preflightstate filter, and dropping the ordering error each fail the intended test and no others.
Docs
The
osism.github.iopages documented none of these flags. Covered in:Draft until both are reviewed. They should land together — and in the same release as
#2609, per the flag-shape coupling above.