Skip to content

feat(app-configs): warn when persistent volume label is used by other apps - #223

Closed
bestony wants to merge 7 commits into
caprover:masterfrom
bestony:execute-plan/809b1149-pr-1-featapp-configs-warn-when-persistent-volume-label
Closed

feat(app-configs): warn when persistent volume label is used by other apps#223
bestony wants to merge 7 commits into
caprover:masterfrom
bestony:execute-plan/809b1149-pr-1-featapp-configs-warn-when-persistent-volume-label

Conversation

@bestony

@bestony bestony commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Auto-fetch Docker named volume inventory via GET /user/system/volumes/ (CapRover PR #2440) when App Configs loads for apps with persistent data.
  • When a Persistent Directories Label maps to a volume used by other CapRover apps, show a yellow warning Alert under that volume row.
  • Warn-only — does not block Save. Silent degrade if the API is unavailable (older CapRover / 2440 not deployed).

Design notes

  • Label control remains plain Ant Design Input (no AutoComplete/Select).
  • Legacy apps resolve physical names as captain--{label}.
  • Mount-only inventory fetch with unmount safety.

Test plan

  • Unit tests: yarn test --watchAll=false --testPathPattern=volumeHelpers (17/17)
  • Manual: open App Configs with hasPersistentData on a captain build that includes #2440
  • Type a Label used by another app → yellow warning lists other app names
  • Label still free-text; host-path toggle unchanged
  • Older captain without volumes API: no toast, form usable
Screenshot 2026-07-27 at 14 02 03@2x

Summary by CodeRabbit

Summary by CodeRabbit

  • New Features

    • Added an API-backed volume inventory used by the app configuration UI.
    • Shows a warning when a persistent directory/volume is already in use by other applications.
  • Bug Fixes

    • Prevented volume inventory state updates after leaving the app details view.
    • Improved persistent volume resolution and compatibility with legacy volume names.
  • Documentation

    • Added new localization strings for the “volume already in use” warning (multiple languages).
  • Tests

    • Added unit and integration-style tests for volume resolution, conflict detection, and localized warning formatting.

@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds typed volume inventory retrieval and helper utilities, then uses the inventory in app configuration to warn when non-bind persistent volumes are shared with other applications.

Changes

Persistent volume warnings

Layer / File(s) Summary
Volume contracts and lookup helpers
src/models/VolumeInfo.ts, src/utils/volumeHelpers.ts, src/utils/volumeHelpers.test.ts
Defines volume inventory types, physical-name resolution, shared-volume lookup, localization formatting, and comprehensive helper tests.
Volume inventory loading
src/api/ApiManager.ts, src/containers/apps/appDetails/AppConfigs.tsx
Adds getAllVolumes() and loads volume inventory during AppConfigs mounting with unmount protection and error handling.
Persistent directory warning UI
src/containers/apps/appDetails/AppConfigs.tsx, src/locales/*.json
Displays sharing warnings for non-bind volumes, excludes the current application, updates host-path toggling, and adds localized warning text.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant AppConfigs
  participant ApiManager
  participant VolumesAPI
  participant volumeHelpers
  AppConfigs->>ApiManager: getAllVolumes()
  ApiManager->>VolumesAPI: GET /user/system/volumes/
  VolumesAPI-->>ApiManager: VolumesListResponse
  ApiManager-->>AppConfigs: volume inventory
  AppConfigs->>volumeHelpers: resolvePhysicalVolumeName()
  AppConfigs->>volumeHelpers: getOtherAppsUsingVolume()
  volumeHelpers-->>AppConfigs: other application names
  AppConfigs->>AppConfigs: Render localized warning
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly matches the main change: warning in app configs when a persistent volume label is used by other apps.
Description check ✅ Passed The description includes Summary, Design notes, and Test plan, and covers the main behavior, fallback, and testing details.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@bestony
bestony marked this pull request as ready for review July 27, 2026 05:59
bestony added 3 commits July 27, 2026 14:04
Replace null with undefined in AppConfigs conditional render and volume
helper test fixtures; loosen VolumeInfo options typing accordingly.
Add apps.app_config_vol_in_use_warning with %s placeholder to every
non-English locale file.
Fix CI prettier --check failure on volume in-use warning UI.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (2)
src/utils/volumeHelpers.ts (1)

45-50: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Docstring says "a single %s" but implementation replaces all occurrences.

Replace a single %s placeholder in a localized template string. The split('%s').join(value) implementation actually replaces every %s occurrence (as the accompanying test confirms). Update the comment to avoid confusing future readers.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/utils/volumeHelpers.ts` around lines 45 - 50, Update the docstring for
formatLocalized to state that it replaces all `%s` occurrences in the localized
template, matching the existing split('%s').join(value) behavior and tests.
src/containers/apps/appDetails/AppConfigs.tsx (1)

59-68: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Ad hoc response type duplicates VolumesListResponse.

The .then callback re-declares the response shape as { volumes?: VolumeListItem[] }, but getAllVolumes() already returns a typed Promise<VolumesListResponse> whose volumes field is required, not optional. Reusing the imported type avoids the two shapes drifting apart.

♻️ Proposed cleanup
+import { VolumesListResponse } from '../../../models/VolumeInfo'
...
-            .then((data: { volumes?: VolumeListItem[] }) => {
+            .then((data: VolumesListResponse) => {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/containers/apps/appDetails/AppConfigs.tsx` around lines 59 - 68, Replace
the ad hoc `.then` callback response type in the volume-loading flow with the
existing `VolumesListResponse` type returned by `getAllVolumes()`. Import and
reuse that shared type, and access the required `volumes` field without the
optional fallback while preserving the existing unmount guard and state update.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/models/VolumeInfo.ts`:
- Around line 1-11: Update the DockerVolumeInfo.options property to be optional
so callers can omit it when no options map is available, while preserving the
existing string-keyed object type and compatibility with null-valued data where
required.

In `@src/utils/volumeHelpers.test.ts`:
- Around line 13-22: Update the volume info type used by the test helper so
DockerVolumeInfo.options is optional and can be omitted, then remove the
options: null property from the returned object. Ensure the related VolumeInfo
definition and helper return type remain consistent without introducing null.

---

Nitpick comments:
In `@src/containers/apps/appDetails/AppConfigs.tsx`:
- Around line 59-68: Replace the ad hoc `.then` callback response type in the
volume-loading flow with the existing `VolumesListResponse` type returned by
`getAllVolumes()`. Import and reuse that shared type, and access the required
`volumes` field without the optional fallback while preserving the existing
unmount guard and state update.

In `@src/utils/volumeHelpers.ts`:
- Around line 45-50: Update the docstring for formatLocalized to state that it
replaces all `%s` occurrences in the localized template, matching the existing
split('%s').join(value) behavior and tests.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: f770fb7f-f9f2-4d4b-8c14-2afd26a3b736

📥 Commits

Reviewing files that changed from the base of the PR and between 435bd2f and 93279c4.

📒 Files selected for processing (6)
  • src/api/ApiManager.ts
  • src/containers/apps/appDetails/AppConfigs.tsx
  • src/locales/en-US.json
  • src/models/VolumeInfo.ts
  • src/utils/volumeHelpers.test.ts
  • src/utils/volumeHelpers.ts

Comment thread src/models/VolumeInfo.ts
Comment thread src/utils/volumeHelpers.test.ts
options is optional on DockerVolumeInfo; drop explicit undefined to avoid null/undefined noise in tests.
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.

1 participant