Skip to content

feat(onboarding): add dedicated boot pool option to internal boot wizard#1968

Merged
elibosley merged 5 commits intoclaude/bold-gaussfrom
claude/dedicated-boot-pool
Mar 27, 2026
Merged

feat(onboarding): add dedicated boot pool option to internal boot wizard#1968
elibosley merged 5 commits intoclaude/bold-gaussfrom
claude/dedicated-boot-pool

Conversation

@Ajit-Mehrotra
Copy link
Contributor

Summary

Adds a dedicated boot pool option to the onboarding internal boot wizard, giving users the choice between:

  • Dedicated boot pool — Uses the entire device exclusively for booting Unraid. No data pool is created. The boot partition size equals the size of the smallest selected device (in a 2-device mirror).
  • Boot + data pool — The existing hybrid behavior where the device is partitioned into a boot volume and a storage pool.

Problem

Previously, the internal boot wizard only offered the hybrid "boot + data pool" mode. Users who want a clean separation of boot and data devices — dedicating one device entirely to boot and managing data pools separately — had no way to do this through the onboarding wizard.

Solution

A new "Pool mode" dropdown is added as the first field in the storage boot configuration form. When "Dedicated boot pool" is selected:

  • poolBootSize=0 is passed to cmdMakeBootable via emcmd, which tells the backend to use the entire device for the boot partition
  • The pool name is auto-set to "boot" (hidden from the user)
  • The "Pool name" input and "Boot reserved size" dropdown are hidden
  • Info alerts are updated to explain that no data pool will be created and that mirror size is determined by the smallest device
  • The summary step shows the pool mode and conditionally hides pool name / boot reserved size rows

When "Boot + data pool" is selected, the existing behavior is fully preserved — all fields remain visible and the user configures pool name and boot size as before.

Key Design Decisions

  1. No backend changes neededbootSizeMiB: 0 is already valid per the existing @Min(0) validation on CreateInternalBootPoolInput, and cmdMakeBootable already handles poolBootSize=0 as the "use entire pool" sentinel value
  2. Pool name collision handling — If the auto-set "boot" name conflicts with an existing pool or reserved name, a clear validation error is shown rather than using a fallback name chain
  3. Backward compatibility — The poolMode field in the persisted draft store defaults to 'hybrid' when missing, so existing localStorage data from prior sessions works without issues

Changes

Source Files

File Change
web/src/components/Onboarding/store/onboardingDraft.ts Added OnboardingPoolMode type and poolMode field to OnboardingInternalBootSelection, backward-compatible normalization
web/src/components/Onboarding/composables/internalBoot.ts Added PoolMode type and poolMode to InternalBootSelection interface
web/src/components/Onboarding/steps/OnboardingInternalBootStep.vue Pool mode dropdown, conditional field visibility, updated validation and UAlerts
web/src/components/Onboarding/steps/OnboardingSummaryStep.vue Pool mode row in summary, conditional pool name / boot reserved size display
web/src/locales/en.json 10 new i18n keys for labels, descriptions, warnings, validation

Test Files

File Change
web/__test__/components/Onboarding/internalBoot.test.ts Added poolMode to all selection objects
web/__test__/components/Onboarding/OnboardingInternalBootStep.test.ts Updated type and pool-name tests to work in hybrid mode
web/__test__/components/Onboarding/OnboardingInternalBootStandalone.test.ts Added poolMode to type, selection objects, and assertion
web/__test__/components/Onboarding/OnboardingSummaryStep.test.ts Added poolMode to inline type and all selection objects
web/__test__/components/Onboarding/OnboardingNextStepsStep.test.ts Added poolMode to inline type and all selection objects

Data Flow

User selects "Storage" boot mode
         │
         ▼
┌─────────────────────────┐
│  Pool Mode Dropdown     │  ◄── NEW (first field shown)
│  ┌───────────────────┐  │
│  │ Dedicated Boot    │  │  → poolBootSize=0, auto poolName="boot"
│  │ Boot + Data Pool  │  │  → current behavior (show all fields)
│  └───────────────────┘  │
└─────────────────────────┘
         │
         ▼
┌─────────────────────────┐
│  Shared fields:         │
│  - Slot count (1 or 2)  │
│  - Device selection     │
│  - Update BIOS checkbox │
└─────────────────────────┘
         │
         ▼ (only for "Boot + Data Pool")
┌─────────────────────────┐
│  Hybrid-only fields:    │
│  - Pool name            │
│  - Boot reserved size   │
└─────────────────────────┘

Test Plan

  • All 634 existing tests pass (64 test files)
  • No onboarding-related TypeScript errors
  • Manual: Select "Dedicated boot pool" → pool name and boot size fields hidden
  • Manual: Select "Boot + data pool" → all fields visible (existing behavior)
  • Manual: Toggle between modes → form resets correctly
  • Manual: Complete wizard with dedicated mode → mutation sends bootSizeMiB: 0
  • Manual: Navigate back from summary → pool mode preserved

Stacked On

This PR is stacked on claude/bold-gauss and should be merged after that branch lands.

- Previously, the internal boot wizard only offered a "hybrid" mode where
  the device serves as both a boot volume and a data storage pool
- Users who want a clean separation of boot and data had no option
- Add a "Pool mode" dropdown as the first field in the storage boot
  configuration form with two options:
  - "Dedicated boot pool": uses the entire device exclusively for booting
    Unraid (passes poolBootSize=0 to emcmd), hides pool name and boot
    reserved size fields, auto-sets pool name to "boot"
  - "Boot + data pool": preserves the existing hybrid behavior with all
    fields visible for user configuration
- Update UAlert info panels to show mode-specific descriptions:
  - Dedicated mode explains that no data pool is created and notes that
    in a 2-device mirror, boot partition size equals the smallest device
  - Hybrid mode retains all existing text about two volumes
- Update validation logic in buildValidatedSelection() to skip pool name
  format and boot size validation for dedicated mode, while still checking
  for reserved name conflicts on the auto-set "boot" pool name
- Add poolMode field to OnboardingInternalBootSelection interface and
  draft store with backward-compatible normalization (defaults to 'hybrid'
  for existing persisted data from localStorage)
- Update summary step to show pool mode and conditionally hide pool name
  and boot reserved size rows for dedicated mode
- Add 10 new i18n keys for pool mode labels, descriptions, and validation
- Update all existing test files to include poolMode in selection objects
- No backend changes needed: bootSizeMiB=0 is already valid per @min(0)
  validation and cmdMakeBootable already handles poolBootSize=0 as the
  "use entire pool" sentinel value
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 26, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 523c7c70-eb4a-4486-b249-8ac1a0fd4373

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/dedicated-boot-pool

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@Ajit-Mehrotra
Copy link
Contributor Author

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 26, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@codecov
Copy link

codecov bot commented Mar 26, 2026

Codecov Report

❌ Patch coverage is 71.92118% with 57 lines in your changes missing coverage. Please review.
✅ Project coverage is 52.11%. Comparing base (64daf69) to head (d06d533).
⚠️ Report is 1 commits behind head on claude/bold-gauss.

Files with missing lines Patch % Lines
...ts/Onboarding/steps/OnboardingInternalBootStep.vue 75.56% 43 Missing ⚠️
...src/components/Onboarding/store/onboardingDraft.ts 6.66% 14 Missing ⚠️
Additional details and impacted files
@@                  Coverage Diff                  @@
##           claude/bold-gauss    #1968      +/-   ##
=====================================================
+ Coverage              52.08%   52.11%   +0.03%     
=====================================================
  Files                   1031     1031              
  Lines                  71461    71586     +125     
  Branches                8094     8102       +8     
=====================================================
+ Hits                   37222    37310      +88     
- Misses                 34114    34151      +37     
  Partials                 125      125              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

…uping

- Add pool mode title ("Dedicated boot pool" / "Boot + data pool") as
  the first line in each info UAlert so users immediately know which
  mode's description they're reading
- Swap text order in dedicated mode UAlert: mirror description now comes
  before the mirror size note, which reads more naturally (explain the
  feature, then the detail)
- Reorganize form fields into two logical sections:
  - "Pool Settings": Pool mode dropdown + Data pool name input (hidden
    in dedicated mode)
  - "Devices": Boot devices count + device selection dropdowns + boot
    reserved size (hidden in dedicated mode)
- Rename "Pool name" label to "Data pool name" for clarity in hybrid mode
- Add section header i18n keys for "Pool Settings" and "Devices"
- Change "Each bootable pool contains two volumes:" to
  "Each device contains two volumes:" for clearer language
  that focuses on the physical device rather than the pool abstraction
- When switching from dedicated to hybrid mode, the pool name ref
  retained the value "boot" which would incorrectly prepopulate the
  data pool name input
- Add a watcher on poolMode that resets poolName to the appropriate
  default when switching: "boot" for dedicated, the template default
  (typically "cache") for hybrid — but only if the current value is
  still "boot" to avoid overwriting a user-entered name
…ists

- The poolMode watcher used `?? 'cache'` as fallback, but
  poolNameDefault is '' (empty string) when pools already exist,
  and ?? doesn't catch empty strings — so it would incorrectly
  default to 'cache' even when a cache pool was already present
- Change fallback to '' so the user gets an empty field and must
  choose their own name, matching the existing behavior
@github-actions
Copy link
Contributor

This plugin has been deployed to Cloudflare R2 and is available for testing.
Download it at this URL:

https://preview.dl.unraid.net/unraid-api/tag/PR1968/dynamix.unraid.net.plg

@elibosley elibosley marked this pull request as ready for review March 27, 2026 00:47
@elibosley elibosley merged commit f2cc3b5 into claude/bold-gauss Mar 27, 2026
9 of 10 checks passed
@elibosley elibosley deleted the claude/dedicated-boot-pool branch March 27, 2026 00:47
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d06d533a44

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +579 to +580
if (reservedNames.value.has(normalizedPoolName) || existingPoolNames.value.has(normalizedPoolName)) {
formError.value = t('onboarding.internalBootStep.validation.dedicatedPoolNameConflict');

Choose a reason for hiding this comment

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

P1 Badge Skip reserved-name rejection for dedicated boot mode

In dedicated mode the pool name is forced to boot, but this branch still rejects it when reservedNames contains that value. The internal boot context currently forwards vars.reservedNames directly from emhttp, and those payloads commonly include boot; in that environment this validation path always raises dedicatedPoolNameConflict, so users can never complete the new dedicated flow.

Useful? React with 👍 / 👎.

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.

2 participants