feat: implement repository clone mode with SSH key support
- Add clone_mode and branch fields to tool_instances - Add ssh_key_id to git_repositories for per-repo SSH key assignment - Implement host-side git cloning with branch selection (default: main) - Mount SSH keys into containers for git operations in clone mode - Add dirty state check on clone-mode instance deletion with confirmation - Update SessionsPage with mount/clone selector, branch input, SSH key display - Add SSH key selector to repository creation form - Add dirty delete confirmation modal with changed files list - Update API schemas and endpoints for new fields - Sync delta specs to main specs (git-repo, tool-instances, repo-clone-mode) - Archive completed OpenSpec change: repo-clone-mode-with-ssh - Document git requirement for custom tool types Quality gates: Frontend typecheck and build passed OpenSpec: repo-clone-mode-with-ssh archived with all tasks complete
This commit is contained in:
@@ -1,83 +0,0 @@
|
||||
## Context
|
||||
|
||||
Currently, tool instances run as Docker containers on the internal Docker network. The backend stores their URL as `http://localhost:{port}`, which is only accessible from inside the API container. Users clicking "Open" in the frontend get a 404 because their browser can't reach the internal container.
|
||||
|
||||
The API and containers share a Docker network, so the API can reach containers by their container name or IP.
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
- Users can access running tool instances through the API via HTTPS
|
||||
- Proxy enforces ownership (only instance owner can access)
|
||||
- Support both HTTP and WebSocket traffic
|
||||
- Minimal latency overhead
|
||||
- Works with existing Docker setup
|
||||
|
||||
**Non-Goals:**
|
||||
- Public URLs / custom domains for instances (that's Option 2/3)
|
||||
- Load balancing across multiple instances
|
||||
- Advanced path rewriting (just pass-through)
|
||||
|
||||
## Decisions
|
||||
|
||||
### Proxy via FastAPI route (not separate service)
|
||||
|
||||
**Decision:** Implement proxying as a FastAPI endpoint using `httpx` for async forwarding.
|
||||
|
||||
**Rationale:**
|
||||
- Keeps everything in one deployable unit
|
||||
- Easy access to existing auth dependencies (`get_current_user_id`)
|
||||
- Can reuse existing session cookie auth
|
||||
- No extra infrastructure needed
|
||||
|
||||
**Alternative considered:** Separate nginx/traefik proxy service
|
||||
- Rejected: adds operational complexity for a single feature
|
||||
|
||||
### Use container name for internal routing
|
||||
|
||||
**Decision:** Store container name in ToolInstance model and route to `http://{container_name}:{port}`
|
||||
|
||||
**Rationale:**
|
||||
- Container names are stable and DNS-resolvable within Docker network
|
||||
- More reliable than IPs which can change
|
||||
- Already using container names in docker.py
|
||||
|
||||
### Path: `/instances/{id}/proxy/{path:path}`
|
||||
|
||||
**Decision:** All proxied traffic goes through `/instances/{id}/proxy/*`
|
||||
|
||||
**Rationale:**
|
||||
- Clear URL structure
|
||||
- Easy to apply auth middleware
|
||||
- `path:path` captures everything after `/proxy/`
|
||||
|
||||
### WebSocket upgrade handling
|
||||
|
||||
**Decision:** Support WebSocket upgrade by inspecting the `Upgrade: websocket` header and establishing a bidirectional pipe.
|
||||
|
||||
**Rationale:**
|
||||
- code-server and jupyter use WebSockets for real-time features
|
||||
- FastAPI doesn't natively support proxying WebSockets, but we can use `starlette.websockets` to handle the upgrade
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
**[Risk]** API becomes bandwidth bottleneck for all instance traffic
|
||||
→ **Mitigation:** Document this limitation. Future migration to Option 2 (Traefik labels) possible.
|
||||
|
||||
**[Risk]** Container name collision
|
||||
→ **Mitigation:** Instance names already include UUID suffix, collision probability is negligible.
|
||||
|
||||
**[Risk]** Large file uploads/downloads through proxy
|
||||
→ **Mitigation:** Use streaming response in httpx. Monitor memory usage.
|
||||
|
||||
## Migration Plan
|
||||
|
||||
1. Deploy backend changes (proxy endpoint + model updates)
|
||||
2. Update frontend links to use proxy URL
|
||||
3. Test with code-server instance
|
||||
4. Monitor API performance
|
||||
|
||||
## Open Questions
|
||||
|
||||
- Should we add rate limiting to the proxy endpoint?
|
||||
- Do we need to rewrite response headers (Location, Set-Cookie)?
|
||||
Reference in New Issue
Block a user