Merged
Conversation
Extend the storage model used by UI to allow reusing LVM volume groups and logical volumes.
- Do not plan MD RAID, volume group or logical volume if the config is skipped (device not found) or the config represents a delete action.
- Do not convert skipped logical volumes.
- Similar to partitions, now some logical volumes are valid without a mount path (volumes used for deleting or resizing actions).
Add missing bits for reusing volume groups: * Fix schemas. * Export available volume groups. * Add missing checks for reused volume groups. * Fix planned devices Note for reviewers: * Easier to review commit by commit. * The target of this PR is a feature branch, so a changelog entry is not added yet.
Replace the flat single-table selector with a modal that categorizes
devices across three tabs: Disks, RAID, and LVM volume groups, each
backed by DrivesTable, MdRaidsTable, and VolumeGroupsTable respectively.
Other new features:
- `intro` prop for contextual content above the tabs
- `initialTab` and `selected` control which tab opens and what is
pre-selected
- Per-category side-effects alerts shown near the confirm button when
the selection differs from the prior device
- `newVolumeGroupLinkText` renders a creation link in the LVM tab, both
as a tab intro sentence and in the empty state
- `autoSelectOnTabChange` (default true) auto-selects the first device
on tab switch, or clears the selection when the tab is empty
- Confirm button label reflects the state: "Add X", "Keep X",
"Change to X", or "Add"/"Change" when no device is selected
- Sticky tabs and per-tab empty states
ConfigureDeviceMenu now passes devices split by category (disks, mdRaids, volumeGroups) and uses the intro and newVolumeGroupLinkText props. SearchedDeviceMenu drops ReuseVgMenuItem and the ChangeDeviceDescription component, which are no longer needed after the modal gained full tabbed support and side-effects props. SearchedVolumeGroupMenu replaces two separate selector modals with a single unified DeviceSelectorModal covering all device categories
Previously, activeTab was initialized before selectedDevices using previousDevice, which is undefined when no selected prop is given. When no previous device exists, the first available device is auto-selected across all tabs — but the tab still defaulted to 0 (Disks), leaving the confirm button and the active tab out of sync. Extract initialDevice as a plain variable shared by both state initializers, so the initial tab always reflects where the actual initial selection lives, regardless of whether a prior device was given.
Extend MdRaidsTable with a "Current content" column that shows the content of each member device using the new DeviceContent component. Add tests for both, fix the useFlattenDevices mock, and document DeviceContent.
- Make sentence more generic (device vs disk).
By adding missing mocks needed after recent storage refactoring for allowing to reuse LVM VGs. Also please linters.
- The menu content was partially hidden
Add complete UI support for reusing existing LVM volume groups in storage configuration. Users can now select and reuse existing volume groups from the system, configure their space policy, and manage logical volumes within them. A new tabbed device selector is added: * Rewrote `DeviceSelectorModal` with three tabs: **Disks**, **RAID**, and **LVM** * Auto-selects first device on tab change with smart initial tab detection * Shows contextual side-effects alerts when changing devices * Dynamic confirm button labels: "Add", "Keep", or "Change to" based on state * Per-category empty states and intro text support
Replace individual props (disksSideEffects, mdRaidsSideEffects, etc.) with unified structured props keyed by tab type. The new API groups related configuration by concern rather than scattering it across multiple props, making it easier to discover what content can be customized for each tab. The structure is more maintainable and reduces errors since the compiler enforces consistent keys across all props. Adding support for new device types becomes trivial as the shape automatically scales with the available tabs.
## Changes
**Before:**
```tsx
<DeviceSelectorModal
disksSideEffects={<DiskNote />}
mdRaidsSideEffects={<MdNote />}
volumeGroupsSideEffects={<VgNote />}
disksIntro="Choose a disk..."
mdRaidsIntro="Choose a RAID..."
volumeGroupsIntro="Choose a VG..."
volumeGroupsEmptyTitle="No VGs"
newVolumeGroupLinkText="Create LVM"
/>
```
**After:**
```tsx
<DeviceSelectorModal
sideEffects={{ disks: <DiskNote />, mdRaids: <MdNote />, volumeGroups: <VgNote /> }}
tabIntros={{ disks: "Choose a disk...", mdRaids: "Choose a RAID...", volumeGroups: "Choose a VG..." }}
emptyStateTitles={{ volumeGroups: "No VGs" }}
newDeviceLinkTexts={{ volumeGroups: "Create LVM" }}
/>
```
## Benefits
- Type-safe: compiler enforces valid tab keys
- Cleaner: groups related config by concern
- Extensible: adding new tabs only requires updating TabKey type
ancorgs
reviewed
Apr 13, 2026
Contributor
ancorgs
left a comment
There was a problem hiding this comment.
Sometimes it is possible to get an UI error around ConfigEditor because it looks like config can be null there. I cannot reproduce it consistently but I'm pretty sure it can happen and we should defend against it before merging.
ancorgs
approved these changes
Apr 14, 2026
Contributor
ancorgs
left a comment
There was a problem hiding this comment.
Not that I added a guard class to (hopefully) mitigate that error I was not able to reproduce... this LGTM.
Merged
imobachgs
added a commit
that referenced
this pull request
Apr 14, 2026
Prepare to release version 20. * #3294 * #3295 * #3296 * #3297 * #3298 * #3299 * #3300 * #3301 * #3302 * #3303 * #3304 * #3305 * #3306 * #3307 * #3308 * #3309 * #3310 * #3311 * #3312 * #3313 * #3315 * #3316 * #3317 * #3318 * #3319 * #3320 * #3322 * #3323 * #3325 * #3326 * #3327 * #3329 * #3330 * #3331 * #3333 * #3334 * #3336 * #3338 * #3339 * #3342 * #3343 * #3349 * #3351 * #3352 * #3353 * #3354 * #3356 * #3357 * #3358 * #3359 * #3360 * #3361 * #3362 * #3363 * #3364 * #3365 * #3366 * #3367 * #3368 * #3371 * #3372 * #3373 * #3375 * #3376 * #3378 * #3379 * #3380 * #3381 * #3382 * #3385 * #3386
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.
Feature for reusing LVM volume groups: