Skip to content

feat: reuse LVM volume groups#3380

Merged
joseivanlopez merged 52 commits intomasterfrom
feature-reuse-vg-ui
Apr 14, 2026
Merged

feat: reuse LVM volume groups#3380
joseivanlopez merged 52 commits intomasterfrom
feature-reuse-vg-ui

Conversation

@joseivanlopez
Copy link
Copy Markdown
Contributor

@joseivanlopez joseivanlopez commented Apr 13, 2026

joseivanlopez and others added 30 commits March 23, 2026 14:17
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.
dgdavid and others added 18 commits April 9, 2026 21:26
- 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.
@joseivanlopez joseivanlopez marked this pull request as ready for review April 13, 2026 15:28
joseivanlopez and others added 2 commits April 13, 2026 16:31
## 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
Copy link
Copy Markdown
Contributor

@ancorgs ancorgs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Contributor

@ancorgs ancorgs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not that I added a guard class to (hopefully) mitigate that error I was not able to reproduce... this LGTM.

@joseivanlopez joseivanlopez merged commit e719fad into master Apr 14, 2026
22 checks passed
@joseivanlopez joseivanlopez deleted the feature-reuse-vg-ui branch April 14, 2026 10:20
@imobachgs imobachgs mentioned this pull request Apr 14, 2026
imobachgs added a commit that referenced this pull request Apr 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants