29a12bb102
- Add expand_container_path() helper that resolves ~/ and $HOME/ prefixes
- Add get_manifest_home_dir() to compute /home/{user.name} or /root from manifest
- Set ENV HOME=... and ENV USER=... in generated Dockerfile for runtime compatibility
- Pass home_dir through instance creation and startup pipeline
- Expand mount targets in apply_resolved_profile() for regular profile mounts
- Expand mapping targets in _resolve_git_mount_mappings() for git mounts
- Expand working_directory and volume targets in _modify_compose_file()
- Update _prepare_manifest_instance to return home_dir alongside image tag
- Fetch tool_type early in start_instance to determine home_dir before profile application
Quality gates: pytest 188 passed, frontend typecheck clean
Addresses: home-path-expansion
77 lines
3.6 KiB
Markdown
77 lines
3.6 KiB
Markdown
# Exploration: ~ / $HOME Expansion in Mount Paths
|
|
|
|
## User Request
|
|
Allow `~` and `$HOME` in mount paths for both regular mounts and git mounts.
|
|
|
|
## Where This Applies
|
|
|
|
### Container target paths (where it makes sense)
|
|
- **Regular mounts** (`mount.target`): The absolute path inside the container where files are bind-mounted
|
|
- **Git mount mappings** (`mapping.target_path`): The absolute path inside the container where repo subdirectories are mounted
|
|
|
|
### Where it does NOT apply
|
|
- **Regular mount file paths** (`mount.files` keys): These are relative to the mount target
|
|
- **Git mount source paths** (`mapping.source_path`): These are relative to the cloned repo
|
|
- **Host-side source paths**: The API runs in a container; `~` on the host would mean the Docker host's home, which the API container cannot access
|
|
|
|
## Complexity Assessment
|
|
|
|
### The Core Problem
|
|
`~` means "user's home directory". But whose home?
|
|
|
|
| Context | Home Directory | Knowable at Mount Time? |
|
|
|---------|---------------|------------------------|
|
|
| API container | `/root` or `/app` | Yes |
|
|
| Target container (manifest, user=root) | `/root` | Yes (from manifest) |
|
|
| Target container (manifest, user=user) | `/home/user` | Yes (from manifest) |
|
|
| Target container (legacy tool type) | Unknown | No (assume `/root`) |
|
|
| Docker host | `/home/alex` or similar | No (API is containerized) |
|
|
|
|
### Docker Compose Reality Check
|
|
Docker Compose **does not expand** `~` or `$HOME` in volume targets. These are passed literally to the Docker daemon. So `~/workspace` becomes a directory literally named `~` in the container root.
|
|
|
|
This means **we must resolve the path ourselves** before writing the compose file.
|
|
|
|
## Design Options
|
|
|
|
### Option A: Simple `/root` default (minimal change)
|
|
- Replace `~` and `$HOME` with `/root` in all container target paths
|
|
- Apply during compose modification and git mount resolution
|
|
- **Effort**: ~30 min, ~20 lines
|
|
- **Pros**: Dead simple, works for root-running containers (most legacy setups)
|
|
- **Cons**: Wrong for pi-agent (runs as `user`, home `/home/user`)
|
|
|
|
### Option B: Manifest-aware home directory (recommended)
|
|
- For manifest-based tools: read `user.name` from manifest, compute home as `/home/{name}` or `/root`
|
|
- For legacy tools: default to `/root`
|
|
- Pass `home_dir` through the mount resolution pipeline
|
|
- Apply expansion in `apply_resolved_profile()` and `_resolve_git_mount_mappings()`
|
|
- **Effort**: ~2 hours, touches 3-4 files
|
|
- **Pros**: Correct for all container types
|
|
- **Cons**: Slightly more plumbing
|
|
|
|
### Option C: Configurable home per profile
|
|
- Add `home_directory` field to ConfigProfile
|
|
- User can override the container home directory
|
|
- **Effort**: ~3 hours, schema change
|
|
- **Cons**: Overkill, clutters UI
|
|
|
|
## Recommendation
|
|
|
|
**Option B** — manifest-aware expansion. The pi-agent manifest already declares `user.name`, so we can compute the correct home directory. For backward compatibility, legacy tool types default to `/root`.
|
|
|
|
## Files to Touch
|
|
|
|
1. `apps/api/src/services/config_profile_resolver.py` — add `expand_container_path()` helper
|
|
2. `apps/api/src/api/tool_instances.py` — pass `home_dir` to `apply_resolved_profile()` and git mount functions; determine home from manifest/tool type
|
|
3. `apps/api/src/services/manifest_compiler.py` — expose helper to extract user from manifest
|
|
4. Tests for expansion logic
|
|
|
|
## Risks
|
|
|
|
| Risk | Mitigation |
|
|
|------|------------|
|
|
| Wrong home for custom containers | Document that manifest should declare `user.name` |
|
|
| `$HOME` env var not set in container | We resolve it at compose generation time, so no runtime dependency |
|
|
| Breaking existing profiles with literal `~` in path | Very unlikely; we can add an escape hatch if needed |
|