Repository navigation
feat: SSH Tunnel Support for Remote Incus & Integration Tests - #61
Merged
Merged
Conversation
- Add DEFAULT_INCUS_SOCKET_PATH constant and SOCKET_TYPES enum (docker/incus)
- Accept config.socketType in createTunnel() to determine which remote socket to forward
- Add _getRemoteSocketPath() helper to resolve socket path based on type
- Return { dockerHost, incusHost, socketType } in tunnel results
- Add getIncusHost() and getHost() accessor methods
- Include socketType/incusHost in healthCheck() and listTunnels() responses
- Keep backward compatible: default socketType is 'docker'
- Add 30+ unit tests covering all Incus-specific behavior
Co-Authored-By: Claude <noreply@anthropic.com>
- Add _resolveIncusHost() method that queries SSHTunnelManager.getIncusHost() for remote workers (returns null for local workers) - Include incusHost in assignBot() return value alongside dockerHost - Include incusHost in failover() reassignment results - Gracefully handle SSHTunnelManager without getIncusHost method - Add 7 unit tests covering Incus host resolution scenarios Co-Authored-By: Claude <noreply@anthropic.com>
Add comprehensive integration tests for IncusBackend that test the full Incus container lifecycle: - Container creation with resource limits and workspace mounting - Container start/stop lifecycle - Command execution and output capture - Health checks for container state - Container management (list, get by ID, remove) - Package installation (Alpine/apk) - Error handling for invalid inputs Tests follow the same pattern as DockerManager.test.js: - Check Incus availability at module load - Skip gracefully if Incus not available - Use Alpine 3.20 image for fast container boot - Cleanup containers with unique test prefix - Test both success and error paths The tests currently skip on this system as Incus is not installed, which is the expected behavior per the skip pattern used across the test suite. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Fix line length issue in assertion statement to comply with Prettier formatting rules (max 100 chars per line). Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
sebyx07
added a commit
that referenced
this pull request
Feb 14, 2026
… examples - Update configuration.md to document sandbox types: docker, incus, and just-bash - Add Incus-specific options: incusImage, incusProfile, dockerAccess - Include Docker, Incus, and Just-Bash configuration examples with comparison - Create comprehensive incus-bots.md guide covering: - Why Incus (isolation, performance, OVH VPS compatibility) - Quick start for Incus bots - Image selection (Ubuntu, Alpine, Debian) - Resource configuration guidance - Docker inside Incus setup - Lifecycle, migration, and troubleshooting - Best practices and advanced configuration - Multiple example bot configurations No changes to defaults (Docker remains default). Companion to PR #61. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR adds comprehensive support for SSH tunneling to remote Incus sockets, enabling AI Army to manage Incus containers on remote workers just as it does with Docker. This is part of the larger Incus/LXC backend integration (PR Group 4 of 5).
Changes
SSHTunnelManager Incus Support (Task 15)
SOCKET_TYPESenum (docker,incus) andDEFAULT_INCUS_SOCKET_PATHconstantconfig.socketTypeparameter increateTunnel()to determine which remote socket to forward_getRemoteSocketPath()helper to resolve socket path based on type{ dockerHost, incusHost, socketType }in tunnel resultsgetIncusHost()andgetHost()accessor methodssocketType/incusHostinhealthCheck()andlistTunnels()responsessocketTypeis'docker'WorkerAssigner Incus Integration (Task 16)
dockerHostandincusHostin resultsincusHostthrough toContainerPool.initializeContainer()for remote Incus containersIntegration Tests (Task 17)
test/integration/execution/IncusBackend.test.js{ skip: !INCUS_AVAILABLE })Comprehensive Unit Tests (Task 18)
SSHTunnelManager.test.js'docker'(backward compatibility)socketTypein tunnel creation, health checks, and listingTest Results
Backward Compatibility
✅ Default behavior unchanged -
socketTypedefaults to'docker'✅ All existing Docker tunnels continue to work
✅ No breaking changes to existing APIs
Test plan
npm run test:unit)npm run test:integration)npm run lint)Related
Part of Incus/LXC backend integration epic:
🤖 Generated with Claude Code
Greptile Overview
Greptile Summary
Extended SSH tunnel infrastructure to support both Docker and Incus socket forwarding, enabling remote Incus container management through SSH tunnels. The implementation adds a
socketTypeparameter (defaulting to'docker') toSSHTunnelManager.createTunnel(), which determines whether to forward the Docker socket or Incus socket.WorkerAssignernow resolves and provides bothdockerHostandincusHostin assignment results, which are passed through toContainerPool.initializeContainer()to configure remote Incus backends.SOCKET_TYPESenum withDOCKERandINCUSconstants tosrc/worker/ssh-tunnel.js_getRemoteSocketPath()helper to select socket path based on type (Docker:/var/run/docker.sock, Incus:/var/lib/incus/unix.socket)getIncusHost()andgetHost()accessor methods to retrieve tunnel URLsdockerHostandincusHost(one is always null based on type)WorkerAssignerwith_resolveIncusHost()method and addedincusHostto all assignment resultssocketTypeis'docker')Confidence Score: 5/5
socketTypemaintains existing behavior), and clean separation of concerns. The implementation correctly extends bothSSHTunnelManagerandWorkerAssignerto support Incus alongside Docker, with proper validation and null handling throughout the stack.Important Files Changed
SOCKET_TYPESenum and Incus socket support with backward-compatible default to Docker, includes proper validation and tunneling logic_resolveIncusHost()method and includedincusHostin assignment results with proper null handling and backward compatibilityincusHostresolution covering local workers, remote workers, dual tunnels, and failover scenariosSequence Diagram
sequenceDiagram participant BM as BotManager participant WA as WorkerAssigner participant STM as SSHTunnelManager participant CP as ContainerPool participant IB as IncusBackend participant Remote as Remote Worker BM->>WA: assignBot(botId) WA->>WA: _resolveDockerHost(worker) WA->>STM: getDockerHost(workerId) STM-->>WA: dockerHost or null WA->>WA: _resolveIncusHost(worker) WA->>STM: getIncusHost(workerId) STM-->>WA: incusHost or null WA-->>BM: { workerId, dockerHost, incusHost } BM->>CP: initializeContainer(botId, config, workspace, { incusHost }) CP->>CP: _getBackend(botId, config, { incusHost }) alt incusHost provided CP->>IB: new IncusBackend({ socketPath: incusHost }) IB-->>CP: backend instance else no incusHost CP->>IB: use default IncusBackend() IB-->>CP: default backend end CP->>IB: createContainer(botConfig, workspace) IB->>Remote: forward via SSH tunnel (tcp://127.0.0.1:port) Remote-->>IB: container created IB-->>CP: container CP-->>BM: containerLast reviewed commit: d29db35