Skip to content

fix(execd): skip chmod/chown for pre-existing dirs in MakeDir#1035

Closed
ashishpatel26 wants to merge 2 commits into
opensandbox-group:mainfrom
ashishpatel26:fix/issue-1024-mkdir-chmod-existing
Closed

fix(execd): skip chmod/chown for pre-existing dirs in MakeDir#1035
ashishpatel26 wants to merge 2 commits into
opensandbox-group:mainfrom
ashishpatel26:fix/issue-1024-mkdir-chmod-existing

Conversation

@ashishpatel26

Copy link
Copy Markdown

Summary

  • MakeDir in components/execd/pkg/web/controller/utils.go (and the Windows counterpart utils_windows.go) unconditionally called ChmodFile after os.MkdirAll, even when the target directory already existed before the call.
  • For system directories the sandbox process does not own (e.g. /tmp, /var), this caused chmod: operation not permitted, breaking createDirectories for any path whose components already exist.
  • Fix: stat the target before calling os.MkdirAll; if it already existed, return early without calling ChmodFile. Only newly-created directories receive the requested permission. This matches POSIX mkdir -p --mode semantics.

Fixes #1024.

Test plan

  • TestMakeDirCreatesNewDirectory — new dir is created successfully
  • TestMakeDirIsIdempotentOnExistingDirectory — calling MakeDir on a pre-existing dir returns no error and does not alter its permissions
  • TestMakeDirCreatesNestedDirectoriesWithoutChmodingParents — creating /parent/child when /parent already exists does not chmod /parent
  • Full controller test suite passes (go test ./pkg/web/controller/...): 67/67

When a Volume with pvc backend and readOnly=True is mounted, only the
VolumeMount readOnly field was set. Some CSI drivers (e.g.
mountpoint-s3-csi-driver) require readOnly on the PersistentVolumeClaim
volume source as well, so the mount remained writable despite the flag.

Fix: also set persistentVolumeClaim.readOnly=true in the pod volumes list
when the volume is declared read-only.

Additionally change the dedup key from claim_name alone to
(claim_name, read_only) so the same PVC can be mounted both read-only
and read-write within the same pod without one mount silently overriding
the other.

Fixes opensandbox-group#545
When createDirectories is called on a path whose parent components
already exist (e.g. /tmp), MakeDir was unconditionally calling
ChmodFile on the target after os.MkdirAll, even if the directory
was not newly created. For system directories the process does not
own this causes 'chmod: operation not permitted'.

Fix: stat the target before MkdirAll; if it already exists, skip
ChmodFile entirely. Only newly-created directories receive the
requested permission. This matches POSIX mkdir -p --mode semantics.

Fixes opensandbox-group#1024
Copilot AI review requested due to automatic review settings June 12, 2026 12:50
@github-actions

Copy link
Copy Markdown
Contributor

⚠️ This PR has no labels. Please add one based on the changes.

Changed directories: components、server.

📋 Recommended labels (based on changed files):

  • component/execd ⬅️
  • component/server ⬅️

Other available labels:

  • bug - Something isn't working
  • dependencies - Pull requests that update a dependency file
  • documentation - Improvements or additions to documentation
  • feature - New feature or request
  • packages - Changes for package, image and configuration

💡 Tip: Use feature for new functionality or improvements, bug for fixes.

cc @ashishpatel26

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

This PR improves Kubernetes volume handling (especially PVC readonly behavior and RO/RW mixing) and adjusts directory creation utilities to avoid permission/ownership changes on pre-existing directories.

Changes:

  • Update apply_volumes_to_pod_spec to key PVC volumes by (claim_name, read_only) and propagate readOnly into the PVC volume spec when needed.
  • Add/extend tests to validate PVC readonly behavior, subPath forwarding, and mixed RO/RW mounts for the same PVC.
  • Change MakeDir (Unix + Windows) to skip chmod/chown when the target directory already exists, with new tests for idempotency.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
server/opensandbox_server/services/k8s/volume_helper.py Support separate PVC entries for RO vs RW and set PVC spec readOnly; adjust logging.
server/tests/k8s/test_volume_helper.py New unit tests covering PVC readOnly, mixed RO/RW behavior, host readonly, conflicts, and subPath.
server/tests/k8s/test_batchsandbox_provider.py Extend provider test to assert PVC volume spec has readOnly: true.
components/execd/pkg/web/controller/utils.go Skip chmod/chown when MakeDir target already exists.
components/execd/pkg/web/controller/utils_windows.go Same MakeDir behavior change for Windows build.
components/execd/pkg/web/controller/utils_test.go Add tests for MakeDir creation and idempotency behavior.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 60 to 86
@@ -73,7 +80,9 @@ def apply_volumes_to_pod_spec(
mounts.append(mount)

logger.info(
f"Added PVC volume '{vol_name}' (claim: {pvc_claim_name}) mounted at '{vol.mount_path}' for sandbox"
"Added PVC volume '%s' (claim: %s, readOnly: %s) "
"mounted at '%s' for sandbox",
vol_name, pvc_claim_name, vol.read_only, vol.mount_path,
)
v.get("name") for v in pod_volumes if isinstance(v, dict)
}
# Key: (claim_name, read_only) so the same PVC can be mounted both RO and RW.
pvc_to_volume_name: Dict[tuple, str] = {}
Comment on lines +159 to +171
// Record whether the target directory already exists before MkdirAll so
// we can skip chmod/chown on pre-existing directories (including system
// dirs like /tmp that the sandbox user does not own).
_, statErr := os.Stat(abs)
alreadyExisted := statErr == nil

if err = os.MkdirAll(abs, os.ModePerm); err != nil {
return err
}

if alreadyExisted {
return nil
}

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bbdd752b0a

ℹ️ 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 +58 to +60
pvc_key = (pvc_claim_name, vol.read_only)

if pvc_key not in pvc_to_volume_name:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve PVC de-duplication for mixed readOnly mounts

When a sandbox request mounts the same PVC once read-only and once read-write, including vol.read_only in this cache key bypasses the existing claim de-duplication and appends two persistentVolumeClaim volumes for the same claim. The existing test_apply_volumes_to_pod_spec_same_pvc_multiple_mounts documents that this de-duplication avoids CSI driver issues from duplicate PVC volume definitions; this mixed RO/RW case now reintroduces that failure mode on those clusters. Keep a single PVC volume for the claim and rely on per-volumeMount readOnly (or reject mixed modes) instead of emitting duplicate claim entries.

Useful? React with 👍 / 👎.

@Pangjiping

Copy link
Copy Markdown
Collaborator

Duplicate of #1025

@Pangjiping Pangjiping marked this as a duplicate of #1025 Jun 12, 2026
@Pangjiping Pangjiping closed this Jun 12, 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.

createDirectories chmods pre-existing directories, breaking writeFile under /tmp and other system dirs

3 participants