Skip to content

Deduplicate the unified mount list before invoking podman#73

Open
yarikoptic wants to merge 1 commit into
mainfrom
bf-dedup
Open

Deduplicate the unified mount list before invoking podman#73
yarikoptic wants to merge 1 commit into
mainfrom
bf-dedup

Conversation

@yarikoptic
Copy link
Copy Markdown
Member

When the same host path appeared both as a default yolo mount (CWD, ~/.claude, ~/.gitconfig, worktree-original-repo) and in a config entry — or in multiple config entries / on the CLI — yolo previously passed two -v flags for it, with conflicting SELinux labels (default :z vs config-derived :Z), and podman refused to start. In my case it was the skills/ folder (for https://github.com/con/skills/) which I wanted to make available to all sessions but then I wanted to work on it in yolo as well, which caused duplication and yolo did not start.

Restructure the mount handling so that, right before composing the podman run command, all -v sources are gathered into one ordered list and deduplicated by host path (the first colon-delimited segment of the spec). When two entries share a host path, the LATER one in the list wins:

  1. Config volumes (YOLO_PODMAN_VOLUMES, lowest)
  2. Default yolo mounts (claude home, gitconfig, workspace)
  3. Worktree-original-repo (when --worktree=bind / ask-confirmed)
  4. CLI -v / --volume (explicit user intent, highest)

So:

  • workspace (CWD) overrides a config entry for the same path — keeping the :z (shared/rw) label needed for the directory you're working in
  • worktree-original beats a config entry for that path
  • a CLI -v overrides config and default mounts (explicit override wins)
  • user-wide + project configs that list the same path collapse

Comparison is exact-string on host paths after expand_volume. So:

  • ~/data and $HOME/data collapse (same expanded string)
  • /foo/bar and /foo//bar do not (no canonicalisation)
  • ~/data (rw) and ~/data::ro collapse to the later one when present

Implementation changes:

  • New dedup_mount_specs function (sourceable, testable) that walks a flat list of specs and emits the last-occurrence-per-host-path subset
  • Config volume processing populates a flat CONFIG_MOUNT_SPECS array instead of prepending into PODMAN_ARGS
  • Worktree handling populates WORKTREE_MOUNT_SPECS (specs only; previously stored as alternating -v <spec> pairs)
  • Right before podman run, CLI -v / --volume (also -v=X and --volume=X) are extracted from PODMAN_ARGS into CLI_MOUNT_SPECS; non-mount args stay in PODMAN_ARGS
  • The four sources (config / defaults / worktree / CLI) are concatenated in priority order and passed to dedup_mount_specs; the result is expanded back into -v <spec> pairs and inserted into podman run

Files

  • bin/yolodedup_mount_specs helper, unified mount-list assembly and dedup right before podman run; CLI -v/--volume extraction
  • tests/yolo.bats — function-level tests for dedup_mount_specs plus end-to-end cases: cross-config dedup, intra-config dedup, CWD vs config, ~/.claude vs config, CLI vs config, CLI vs workspace, and worktree-original-repo vs config
  • SPEC.md — §3 "Volume Mount Handling" now documents the unified dedup, priority order, and CLI extraction; §2 just points at §3

When the same host path appeared both as a default yolo mount (CWD,
~/.claude, ~/.gitconfig, worktree-original-repo) and in a config entry —
or in multiple config entries / on the CLI — yolo previously passed two
`-v` flags for it, with conflicting SELinux labels (default `:z` vs
config-derived `:Z`), and podman refused to start. In my case it was
the skills/ folder which I wanted to make available to all sessions but
then I wanted to work on it in yolo as well, which caused duplication
and yolo did not start.

Restructure the mount handling so that, right before composing the
`podman run` command, all `-v` sources are gathered into one ordered
list and deduplicated by host path (the first colon-delimited segment
of the spec). When two entries share a host path, the LATER one in the
list wins:

  1. Config volumes              (YOLO_PODMAN_VOLUMES, lowest)
  2. Default yolo mounts         (claude home, gitconfig, workspace)
  3. Worktree-original-repo      (when --worktree=bind / ask-confirmed)
  4. CLI -v / --volume           (explicit user intent, highest)

So:

- workspace (CWD) overrides a config entry for the same path — keeping
  the `:z` (shared/rw) label needed for the directory you're working in
- worktree-original beats a config entry for that path
- a CLI `-v` overrides config and default mounts (explicit override wins)
- user-wide + project configs that list the same path collapse

Comparison is exact-string on host paths after `expand_volume`. So:

- `~/data` and `$HOME/data` collapse (same expanded string)
- `/foo/bar` and `/foo//bar` do not (no canonicalisation)
- `~/data` (rw) and `~/data::ro` collapse to the later one when present

Implementation changes:

- New `dedup_mount_specs` function (sourceable, testable) that walks a
  flat list of specs and emits the last-occurrence-per-host-path subset
- Config volume processing populates a flat `CONFIG_MOUNT_SPECS` array
  instead of prepending into `PODMAN_ARGS`
- Worktree handling populates `WORKTREE_MOUNT_SPECS` (specs only;
  previously stored as alternating `-v <spec>` pairs)
- Right before `podman run`, CLI `-v` / `--volume` (also `-v=X` and
  `--volume=X`) are extracted from `PODMAN_ARGS` into `CLI_MOUNT_SPECS`;
  non-mount args stay in `PODMAN_ARGS`
- The four sources (config / defaults / worktree / CLI) are concatenated
  in priority order and passed to `dedup_mount_specs`; the result is
  expanded back into `-v <spec>` pairs and inserted into `podman run`

## Files

- `bin/yolo` — `dedup_mount_specs` helper, unified mount-list assembly
  and dedup right before `podman run`; CLI `-v`/`--volume` extraction
- `tests/yolo.bats` — function-level tests for `dedup_mount_specs` plus
  end-to-end cases: cross-config dedup, intra-config dedup, CWD vs
  config, ~/.claude vs config, CLI vs config, CLI vs workspace, and
  worktree-original-repo vs config
- `SPEC.md` — §3 "Volume Mount Handling" now documents the unified
  dedup, priority order, and CLI extraction; §2 just points at §3

Co-Authored-By: Claude Code 2.1.143 / Claude Opus 4.7 <noreply@anthropic.com>
@yarikoptic yarikoptic added the bug Something isn't working label May 21, 2026
@github-actions
Copy link
Copy Markdown

pr-scout: spec-audit

✅ Spec update matches code changes

Code change summary

Here's a summary of the new or changed functionality:

  • Volume Deduplication and Prioritization: The script now deduplicates volume mounts based on their host path. When multiple sources (configuration files, default mounts, command-line arguments) specify a mount for the same host path, the mount from the highest priority source is used. The order of priority (lowest to highest) is: configuration file volumes, the default $CLAUDE_HOME_DIR mount, the default .gitconfig mount, the default current working directory mount, the git worktree original repository mount, and finally, command-line specified -v/--volume mounts. This means command-line mounts always override others, and default mounts override config file mounts for the same path.
  • Collection of Configuration Volumes: Volumes specified in YOLO_PODMAN_VOLUMES within configuration files are no longer immediately added as podman command arguments. Instead, they are collected into an intermediate list (CONFIG_MOUNT_SPECS) to participate in the new deduplication and prioritization process.
  • Collection of Git Worktree Mounts: The mount for the original Git repository when inside a worktree is now collected as a raw mount specification (WORKTREE_MOUNT_SPECS) instead of being directly added as "-v" arguments to the podman command. This allows it to participate in the new deduplication and prioritization logic.
  • Extraction of Command-Line Volumes: Command-line arguments (-v or --volume) are now explicitly extracted from the PODMAN_ARGS list into a dedicated CLI_MOUNT_SPECS list. These are then processed with the new deduplication and prioritization logic, ensuring they take precedence over other volume sources.
  • Unified Volume Argument Generation: All volume mount arguments for the podman run command are now generated centrally after the deduplication and prioritization process, replacing the previous fragmented approach of adding individual -v options at different stages.

Verdict

PASS

The spec update accurately and comprehensively describes the code changes from a user-visible perspective.

  • All user-visible functionality described in the code changes summary is covered by the spec update.
  • There are no contradictions between the spec claims and the actual behavior described in the code summary.
  • The spec even provides excellent clarifying examples and details (like expand_volume and specific CLI argument formats) that enhance understanding.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant