feat(volume): batch Change Type, so a backend can be rebalanced in one action - #133
Draft
traviswu-bigstack wants to merge 1 commit into
Draft
traviswu-bigstack wants to merge 1 commit into
traviswu-bigstack wants to merge 1 commit into
Conversation
traviswu-bigstack
marked this pull request as draft
September 15, 2026 03:40
Change Type already existed per volume, but moving more than one volume
meant opening the dialog once per row. The two cases that need it are an
operator rebalancing a backend (a subset of its volumes, not a full
evacuation) and a tenant moving a set of volumes onto a faster tier.
The volume list already has row checkboxes -- Delete is a batch action --
so the work is making the existing action accept a selection:
- `items` from the framework decides batch vs single. The framework
enables a batch button on any selection and never consults `allowed`,
so `disableSubmit` repeats the per-item check and the tip names the
volumes to deselect, matching how batch Delete refuses a mixed set.
- The type list drops the current type only when every selected volume
shares one; a mixed selection keeps all of them on offer, and volumes
already on the chosen type are skipped rather than sent to cinder to
be refused. The tip says so.
- Submission is allSettled, so one failure reports against its own
volume instead of losing the rest -- the same shape Create uses for
multi-volume creation, which BaseForm.onOk already unpacks per
instance.
- migration_policy stays on-demand, so an in-use volume moves live.
Also drops the !isOsDisk condition, which came from the initial upstream
import and refused what nova permits. swap_volume has no root-disk guard
in compute/api.py or the libvirt driver -- its gates are instance state,
size, multiattach and native LUKS -- so a running BFV instance's root
volume retypes like any other in-use volume. CubeCOS's own preflight has
no root blocker either, so the console was refusing what its CLI allows,
and a rebalance that cannot touch boot disks only half-drains a backend.
Status remains the gate.
Added to the admin list too, as a row action beside Migrate and as a
batch action, since the rebalance case is the operator's.
Verified by a production webpack build; not yet exercised on a cluster.
Signed-off-by: Travis Wu <travis.wu@bigstack.co>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013cE5vKGkQQn3nAnn9TLKAU
traviswu-bigstack
force-pushed
the
travis.wu/batch-volume-retype
branch
from
September 15, 2026 05:32
d70bc83 to
4cc4925
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.
What type of PR is this?
/kind feature
What this PR does / why we need it
Skyline can already retype a volume —
Change Typehas been a row action on the volume list, and it already passesmigration_policy: 'on-demand', so an in-use volume moves live. What it cannot do is retype more than one volume without opening the dialog once per row.Two cases need that, and both arrived together:
The volume list already renders row checkboxes (
Deleteis a batch action), so the work is making the existing action accept a selection rather than adding a new one.itemsdecides batch vs single.BatchActionButtons.updateConfpassesitems: selectedItemsandisAllowed: selectedItems.length > 0— the framework never consults an action'sallowedfor a batch button, so per-item eligibility has to be re-checked inside the action.disableSubmitdoes that, and the tip names the volumes to deselect. That matches how batchDeleterefuses a mixed selection (ConfirmAction.perform→ "There are resources that cannot be deleted in the selected resources, such as:") rather than silently dropping the ones it cannot handle.The type list adapts to the selection. The single-volume behaviour is unchanged: the volume's own type is dropped from the options. A mixed selection keeps every type on offer, and volumes already on the chosen type are skipped instead of being sent to cinder to be refused — the tip says so when that can happen.
The root-disk exclusion is dropped.
allowedcarried!isOsDisksince4eb68e7f(99cloud's initial import), and it refuses what nova permits.swap_volumehas no root-disk guard —compute/api.pygates on@check_instance_state([ACTIVE, PAUSED, RESIZED]), old-volume-attached-here, new-volume-detached, size, and >1 read/write attachment on a multiattach volume; the libvirt driver adds native LUKS and disk-present-in-domain. Everyroot_bdm/boot_indexreference in that file is in server-create validation. CubeCOS's own preflight has no root blocker either, so the console was refusing what its CLI allows — and a rebalance that cannot touch boot disks only half-drains a backend. Status stays the gate.Submission is
allSettled. One failure then reports against its own volume instead of taking the rest of the batch down with it. This is the shapeCreatealready uses for multi-volume creation, andBaseForm.onOkalready unpacks an array response into per-instance notices keyed offinstanceName.Added to the admin volume list too — as a row action beside
Migrate, and as a batch action — since the rebalance case is the operator's, and the admin list previously had no retype at all.Which issue(s) this PR fixes
Refs bigstack-oss/cubecos#1492, bigstack-oss/cubecmp#1373 — the CubeCOS/CMP half of the same tenant storage-tier change.
Special notes for your reviewer
Not yet exercised on a cluster. The sky lab was repurposed mid-stream, so verification here is a clean production webpack build plus lint; the behaviour is reasoned from the framework code cited above, not observed. Worth a pass on a lab before it merges.
Two things a reviewer may want to weigh in on:
available/in-use) follows theDeleteconvention, but for a 30-volume rebalance it means deselect-and-retry. Skipping the ineligible ones with a note in the modal is the alternative.defaultValuereturns avolume_typekey while the form field is namednew_type, so the default select value has never applied and the required select opens empty. That predates this change and I left it alone — auto-selecting the first type is more dangerous for a batch than for one volume.Two new strings, translated for zh-hans / zh-hant / ko-kr / ru;
tr-trskipped, matching #132.Additional documentation
🤖 Generated with Claude Code
https://claude.ai/code/session_013cE5vKGkQQn3nAnn9TLKAU