feat: implement configurable tool container home directory
- Add ToolType.home_directory column with default /home/user
- Add Alembic migration to add column, set existing rows, and rewrite
/workspace to /home/user/{{WORKSPACE_NAME}} in legacy templates
- Add merge migration fc8f1a20cbf6 to resolve Alembic multiple heads
- Update manifest compiler to honor manifest.home_directory for HOME,
WORKDIR, /workspace symlink, and default repo mount target
- Update legacy dockerfile/compose instance generation to use
tool_type.home_directory
- Thread resolved home_dir through config profile and git mount expansion
- Generate entrypoint permission fixer to chown home/mounts at startup
- Update base.dockerfile with sudo/passwordless sudo for permission fixer
- Add unit tests for manifest compiler, instance service, and migrations
- Add placeholder integration test for container lifecycle
- Update openspec/tasks/home-path-expansion.md task checkboxes
- Update project maps for modified files
Quality gates: py_compile, ruff, mypy, pytest tests/unit (205 passed),
pytest tests/integration (110 passed, 35 skipped). Alembic round-trip
and container lifecycle integration tests require Docker/PostgreSQL.
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
dir: openspec/tasks
|
||||
|
||||
## role
|
||||
Technical specification and task tracking directory for planned engineering improvements across the project's container runtime, workspace management, and developer tooling systems.
|
||||
Contains technical specification documents tracking planned features and architectural improvements for the project.
|
||||
## parent
|
||||
index: openspec/.pi-map.index.md
|
||||
map: openspec/.pi-map.md
|
||||
|
||||
@@ -4,17 +4,17 @@ dir: openspec/tasks
|
||||
index: openspec/tasks/.pi-map.index.md
|
||||
|
||||
## role
|
||||
Technical specification and task tracking directory for planned engineering improvements across the project's container runtime, workspace management, and developer tooling systems.
|
||||
Contains technical specification documents tracking planned features and architectural improvements for the project.
|
||||
## files
|
||||
- config-profile-multi-repo-mounts.md | Technical specification for refactoring git mount configuration to support multiple repository mappings per mount instead of single source/target pairs | dep: git, docker compose, react/typescript, pytest, npm, fastapi
|
||||
- home-path-expansion.md | Defines a technical implementation plan for adding configurable home/workspace directory support to tool containers in an API service. | dep: SQLAlchemy/Alembic, Docker, Docker Compose, Jinja2 templating, pytest, npm/frontend tooling
|
||||
- home-path-expansion.md | Design and implementation plan for adding configurable home/workspace directory support to tool containers in an API application. | dep: SQLAlchemy/Alembic, Docker, Docker Compose, pytest, PostgreSQL, Node.js/npm
|
||||
- mount-specificity-ordering.md | Tracks completion status of a project task for implementing mount specificity ordering in Docker volume handling | dep: docker.py, pytest, tsc
|
||||
- terminal-responsiveness.md | A technical specification document outlining 7 pending tasks to improve web terminal performance through asyncio-native I/O, binary WebSocket frames, WebGL rendering, flow control, and comprehensive benchmarking. | dep: asyncio, WebSocket, xterm-addon-webgl, docker, pytest
|
||||
- tool-definition-manifest.md | A project task specification document defining a multi-PR system for implementing a Tool Definition Manifest System with backend manifest compilation, frontend workshop UI, and legacy migration support. | dep: SQLAlchemy, Alembic, Docker, Docker Compose, FastAPI/REST API, React/TypeScript frontend
|
||||
## arch
|
||||
Markdown-based living documentation pattern using standalone specification files that each capture a discrete technical initiative with implementation plans, completion tracking, and cross-referencing between backend API changes, frontend UI work, and infrastructure migrations.
|
||||
Markdown-based task tracking system using standalone specification documents that each define discrete feature work across backend, frontend, and infrastructure concerns.
|
||||
## tags
|
||||
mount, docker, pytest, tool, manifest, technical, specification, support
|
||||
mount, docker, pytest, tool, manifest, specification, support, docker compose
|
||||
## symbols
|
||||
-
|
||||
## workflows
|
||||
|
||||
@@ -10,17 +10,17 @@ This task extends the earlier `home-path-expansion` work into a full configurabl
|
||||
|
||||
**File**: `apps/api/src/models/tool/tool_type.py`
|
||||
|
||||
- Add `home_directory: Mapped[str]` column.
|
||||
- Non-nullable with server default `"/home/user"`.
|
||||
- [x] Add `home_directory: Mapped[str]` column.
|
||||
- [x] Non-nullable with server default `"/home/user"`.
|
||||
|
||||
### T1.2: Alembic migration for legacy tool types
|
||||
|
||||
**File**: `apps/api/alembic/versions/<new>_add_tool_type_home_directory.py`
|
||||
|
||||
- Add the column.
|
||||
- Set existing rows to `/home/user`.
|
||||
- Rewrite `compose_template` and `dockerfile_template` to replace `/workspace` with `/home/user/{{WORKSPACE_NAME}}` where applicable.
|
||||
- Provide downgrade that reverses rewrites and drops the column.
|
||||
- [x] Add the column.
|
||||
- [x] Set existing rows to `/home/user`.
|
||||
- [x] Rewrite `compose_template` and `dockerfile_template` to replace `/workspace` with `/home/user/{{WORKSPACE_NAME}}` where applicable.
|
||||
- [x] Provide downgrade that reverses rewrites and drops the column.
|
||||
|
||||
## T2: Manifest compiler
|
||||
|
||||
@@ -28,22 +28,22 @@ This task extends the earlier `home-path-expansion` work into a full configurabl
|
||||
|
||||
**File**: `apps/api/src/services/build/manifest_compiler.py`
|
||||
|
||||
- Update `get_manifest_home_dir()` to return `manifest.home_directory` if present, else derive from `user.name`, else `/root`.
|
||||
- [x] Update `get_manifest_home_dir()` to return `manifest.home_directory` if present, else derive from `user.name`, else `/root`.
|
||||
|
||||
### T2.2: Dockerfile generation
|
||||
|
||||
**File**: `apps/api/src/services/build/manifest_compiler.py`
|
||||
|
||||
- Set `ENV HOME={home_directory}` and `ENV USER={user.name}`.
|
||||
- Set `WORKDIR {home_directory}` unless overridden by `runtime.working_dir`.
|
||||
- Create `/workspace` symlink pointing to `{home_directory}/{{WORKSPACE_NAME}}` placeholder or create it at runtime.
|
||||
- [x] Set `ENV HOME={home_directory}` and `ENV USER={user.name}`.
|
||||
- [x] Set `WORKDIR {home_directory}` unless overridden by `runtime.working_dir`.
|
||||
- [x] Create `/workspace` symlink pointing to `{home_directory}/{{WORKSPACE_NAME}}` placeholder or create it at runtime.
|
||||
|
||||
### T2.3: Compose generation
|
||||
|
||||
**File**: `apps/api/src/services/build/manifest_compiler.py`
|
||||
|
||||
- Use `{home_directory}/{repo_name}` as default repo mount target when the manifest has no explicit repo mount.
|
||||
- Keep `~`/`$HOME` expansion base equal to `home_directory`.
|
||||
- [x] Use `{home_directory}/{repo_name}` as default repo mount target when the manifest has no explicit repo mount.
|
||||
- [x] Keep `~`/`$HOME` expansion base equal to `home_directory`.
|
||||
|
||||
## T3: Legacy instance generation
|
||||
|
||||
@@ -51,16 +51,16 @@ This task extends the earlier `home-path-expansion` work into a full configurabl
|
||||
|
||||
**File**: `apps/api/src/services/tool/instance_service.py`
|
||||
|
||||
- Use `tool_type.home_directory` (default `/home/user`).
|
||||
- Mount `{repo_path}:{home_directory}/{repo_name}`.
|
||||
- Ensure `/workspace` symlink exists.
|
||||
- [x] Use `tool_type.home_directory` (default `/home/user`).
|
||||
- [x] Mount `{repo_path}:{home_directory}/{repo_name}`.
|
||||
- [x] Ensure `/workspace` symlink exists.
|
||||
|
||||
### T3.2: Compose-based tools
|
||||
|
||||
**File**: `apps/api/src/services/docker/compose.py`, `apps/api/src/services/tool/instance_service.py`
|
||||
|
||||
- Add `WORKSPACE_NAME` and `HOME_DIRECTORY` to template variables.
|
||||
- Validate migrated templates render correctly.
|
||||
- [x] Add `WORKSPACE_NAME` and `HOME_DIRECTORY` to template variables.
|
||||
- [x] Validate migrated templates render correctly.
|
||||
|
||||
## T4: Config-profile and git mount expansion
|
||||
|
||||
@@ -68,14 +68,14 @@ This task extends the earlier `home-path-expansion` work into a full configurabl
|
||||
|
||||
**File**: `apps/api/src/services/tool/instance_service.py`
|
||||
|
||||
- Compute `home_dir` from ToolType/manifest in `start_tool_instance()`.
|
||||
- Pass to `apply_resolved_profile()` and `resolve_git_mounts()`.
|
||||
- [x] Compute `home_dir` from ToolType/manifest in `start_tool_instance()`.
|
||||
- [x] Pass to `apply_resolved_profile()` and `resolve_git_mounts()`.
|
||||
|
||||
### T4.2: Verify `~`/`$HOME` expansion
|
||||
|
||||
**File**: `apps/api/src/services/config/config_profile_resolver.py`
|
||||
|
||||
- Ensure `expand_container_path()` is called with the resolved `home_dir`.
|
||||
- [x] Ensure `expand_container_path()` is called with the resolved `home_dir`.
|
||||
|
||||
## T5: Entrypoint permission fixer
|
||||
|
||||
@@ -83,15 +83,15 @@ This task extends the earlier `home-path-expansion` work into a full configurabl
|
||||
|
||||
**File**: `apps/api/src/services/build/manifest_compiler.py`
|
||||
|
||||
- Generate a startup script that chowns `{home_directory}` and mounted paths to the container user.
|
||||
- Create `/workspace` symlink at runtime if needed.
|
||||
- Avoid recursive chown of large repo subtrees.
|
||||
- [x] Generate a startup script that chowns `{home_directory}` and mounted paths to the container user.
|
||||
- [x] Create `/workspace` symlink at runtime if needed.
|
||||
- [x] Avoid recursive chown of large repo subtrees.
|
||||
|
||||
### T5.2: Base image support
|
||||
|
||||
**File**: `tool-images/base.dockerfile` (optional)
|
||||
|
||||
- Ensure `sudo` is available and the runtime user can elevate if the fixer runs inside the base image.
|
||||
- [x] Ensure `sudo` is available and the runtime user can elevate if the fixer runs inside the base image.
|
||||
|
||||
## T6: Tests
|
||||
|
||||
@@ -104,21 +104,21 @@ This task extends the earlier `home-path-expansion` work into a full configurabl
|
||||
- `apps/api/tests/unit/test_alembic_migrations.py`
|
||||
|
||||
Cover:
|
||||
- `expand_container_path` edge cases.
|
||||
- `get_manifest_home_dir` precedence.
|
||||
- `compile_dockerfile`/`compile_compose` behavior.
|
||||
- Legacy instance mount target.
|
||||
- Alembic migration round-trip.
|
||||
- [x] `expand_container_path` edge cases.
|
||||
- [x] `get_manifest_home_dir` precedence.
|
||||
- [x] `compile_dockerfile`/`compile_compose` behavior.
|
||||
- [x] Legacy instance mount target.
|
||||
- [x] Alembic migration round-trip (round-trip against Postgres skipped in this environment).
|
||||
|
||||
### T6.2: Integration tests
|
||||
|
||||
**File**: `apps/api/tests/integration/test_tool_instance_lifecycle.py`
|
||||
|
||||
Cover:
|
||||
- Container starts with `HOME=/home/user` and repo at `/home/user/{repo_name}`.
|
||||
- `/workspace` symlink works.
|
||||
- Config-profile and git mounts under `~` are writable.
|
||||
- Explicit manifest repo mount target is preserved.
|
||||
- [ ] Container starts with `HOME=/home/user` and repo at `/home/user/{repo_name}`.
|
||||
- [ ] `/workspace` symlink works.
|
||||
- [ ] Config-profile and git mounts under `~` are writable.
|
||||
- [ ] Explicit manifest repo mount target is preserved.
|
||||
|
||||
## T7: Verification
|
||||
|
||||
@@ -130,6 +130,9 @@ pytest tests/unit/test_home_path_expansion.py tests/unit/test_manifest_compiler.
|
||||
pytest tests/integration/test_tool_instance_lifecycle.py -xvs
|
||||
```
|
||||
|
||||
- [x] Unit tests passed (32 passed).
|
||||
- [ ] Integration tests require Docker/Postgres.
|
||||
|
||||
### T7.2: Alembic round-trip
|
||||
|
||||
```bash
|
||||
@@ -139,12 +142,18 @@ alembic downgrade -1
|
||||
alembic upgrade head
|
||||
```
|
||||
|
||||
- [ ] Alembic round-trip requires PostgreSQL.
|
||||
- [x] Single head confirmed (`fc8f1a20cbf6`).
|
||||
- [x] Migration imports verified.
|
||||
|
||||
### T7.3: Frontend typecheck
|
||||
|
||||
```bash
|
||||
cd apps/web && npm run typecheck
|
||||
```
|
||||
|
||||
- [x] No frontend changes made.
|
||||
|
||||
## Estimation
|
||||
|
||||
| Task | Effort | Files |
|
||||
|
||||
Reference in New Issue
Block a user