Skip to content

feat(docker): volume mount readOnly, subpath and volume-nocopy support - #599

Open
madejackson wants to merge 1 commit into
azukaar:unstablefrom
aseracorp:pr/volume-mounts-subpath
Open

madejackson wants to merge 1 commit into
azukaar:unstablefrom
aseracorp:pr/volume-mounts-subpath

Conversation

@madejackson

@madejackson madejackson commented Sep 5, 2026 •

Copy link
Copy Markdown
Contributor

Add volume mount read-only, subpath, and volume-nocopy support

This PR adds docker-compose-style volume mount options to Cosmos, delivered as three stacked commits, each self-contained:

  1. readOnly + case-insensitive mount key parsing — CosmosMount.ReadOnly (:ro / read_only / readOnly) mapped through create/export, and a case-insensitive unmarshal so mixed spellings such as subPath (capital P) are no longer silently dropped.
  2. volume subpaths — mount a directory or a single file inside a named volume:
    • CosmosMount.SubPath → VolumeOptions.Subpath round-tripped through create and export (export now reads HostConfig.Mounts, which preserves the subpath; the top-level Mounts/MountPoint struct has no SubPath field and silently dropped it before).
    • Auto-create missing subpath entries (directories, or a file when the basename contains a dot) inside the volume's mountpoint, mirroring the existing bind-mount folder creation, in both CreateService and EditContainer.
    • Validation that rejects the one combination Docker's volume-subpath cannot handle — a VOLUME mount whose subpath resolves to a FILE with a target nested inside another mount's target directory — with a clear error instead of a cryptic runc ENOTDIR at container start. Plain nested binds and directory subpaths remain allowed.
    • UI: Volumes table gains Subpath and Read-only columns; compose text import parses short-syntax source:target[:subpath][:ro].
  3. volume-nocopy — first-class VolumeOptions.NoCopy support:
    • CosmosMount.NoCopy round-tripped end to end, with a NoCopy checkbox in the Volumes table.
    • Workaround gating: moby#52546 — Docker's seed-from-image copy step treats a FILE subpath as a directory and fails at create (open .../safe-mount...: not a directory). moby PR #52584 fixed this daemon-side in Docker Engine 29.5.0, so Cosmos only auto-sets NoCopy on engines older than 29.5.0 (users can still set it explicitly on any engine).

Dependencies

This branch is based on upstream:unstable and includes only the upstream PRs
that touch the same mount/volume code this feature builds on. This PR depends
on them being merged first
:

Verification

  • go build ./... passes
  • Unit tests for NoCopy gating and version comparison pass
  • vite build passes (frontend)

@cla-bot

cla-bot Bot commented Sep 5, 2026

Copy link
Copy Markdown

We require contributors to sign our Contributor License Agreement. In order for us to review and merge your code, add yourself to the .clabot file as contributor, as a way of signing the CLA.

@madejackson
madejackson force-pushed the pr/volume-mounts-subpath branch from c36d60e to 86cd894 Compare September 5, 2026 14:07
@cla-bot cla-bot Bot added the cla-signed label Sep 5, 2026
@madejackson
madejackson force-pushed the pr/volume-mounts-subpath branch from c5b8ee2 to 62d72df Compare September 5, 2026 15:22
madejackson added a commit to aseracorp/Cosmos-Server that referenced this pull request Sep 8, 2026
…n-comments

Both stacked PRs share mount/volume/export code and depend on the same
dependency chain (azukaar#573 lowercase CosmosMount, azukaar#585 DurationStr). Resolve
the additive conflicts:

- mount.go: take azukaar#599's superset (SubPath/ReadOnly/NoCopy + helpers)
- volumes.jsx / newServiceForm.jsx: azukaar#599's Subpath/Read-only/NoCopy columns
  and file-picker 'any' (for file subpaths) layered on azukaar#590's lowercase fields
- api_blueprint.go: keep azukaar#590's omitempty tags (hide empty fields in the
  compose editor) + healthcheck nil-guard refactor; keep azukaar#599's
  ValidateMountConflicts + volume-subpath auto-create block
- export.go: keep azukaar#590's FormatShmSize + healthcheck pointer alloc; take
  azukaar#599's HostConfig.Mounts/FromDockerMount volume export (subpath-preserving)
- regenerate api-docs + go-sdk from merged code (CosmosMount fields,
  DurationStr healthcheck fields, mount readOnly/subpath/noCopy)

Verified: go build ./... , go test ./src/..., vite client-build all pass.
@madejackson
madejackson force-pushed the pr/volume-mounts-subpath branch from dccc92e to 60240fb Compare September 9, 2026 19:31
madejackson added a commit to aseracorp/Cosmos-Server that referenced this pull request Sep 9, 2026
…path (azukaar#599)

Reconcile the clean azukaar#599 branch (built on upstream, minus generated
files) with azukaar#590's stacked feature work. Shared files take the canonical
union: azukaar#590's omitempty/shm_size/strslice + azukaar#599's subpath/nocopy.

Verified: go build ./..., docker tests pass.
@madejackson
madejackson force-pushed the pr/volume-mounts-subpath branch 2 times, most recently from d84b92f to 7f288fc Compare October 9, 2026 11:35
Clean PR branch built directly on upstream/unstable (v0.24.0-unstable007,
4975324) containing ONLY the feature work and its required code
dependencies — no regenerated api-docs/go-sdk churn.

This deliberately EXCLUDES the generated files (api-docs/*, go-sdk/*):
the embedded swaggerSpec blob in go-sdk/client.gen.go rewrites ~29k lines
on any API change, and the healthcheck spec change here belongs to
dependency PR azukaar#585. Upstream's pre-commit hook regenerates them on merge.
@madejackson
madejackson force-pushed the pr/volume-mounts-subpath branch from 7f288fc to 1cea823 Compare October 12, 2026 07:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant