mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-05 23:19:43 +02:00
fix(docker): verify the container workdir and end the probe with exit 0
Two defects that only a real container exposes. The probe chained `command -v X && echo X` with semicolons, and a script's exit status is its last command's. A container without the last probed CLI made the whole `sh -lc` exit 1, so a perfectly healthy container with tmux and claude was reported as "could not exec into the container". A missing CLI is data here, not failure, so the script now ends with `exit 0`. containerWorkdir defaulted to hostWorkspacePath. That default holds for an owned container only because the create-time bind mount puts the host directory at that exact path; attaching mounts nothing, so the two are independent facts. A host path absent inside the container makes `docker exec --workdir` fail with an OCI chdir error that surfaces in the pane as a bare "execvp failed". The preflight now proves the directory exists inside the container and refuses at link time.
This commit is contained in:
@@ -2856,6 +2856,11 @@
|
||||
<input type="text" id="dockerContainerName" placeholder="my-dev-box" pattern="[a-zA-Z0-9][a-zA-Z0-9_.-]+" autocomplete="off" autocapitalize="off" spellcheck="false">
|
||||
<span class="form-hint">Must be running already. <button type="button" class="btn-inline-check" id="dockerAdoptCheckBtn">Check container</button></span>
|
||||
</div>
|
||||
<div class="form-row docker-adopt-only">
|
||||
<label>Container Workdir</label>
|
||||
<input type="text" id="dockerAdoptWorkdir" placeholder="/workspace" autocomplete="off" autocapitalize="off" autocorrect="off" spellcheck="false">
|
||||
<span class="form-hint">A path that already exists <em>inside</em> the container. Adoption mounts nothing, so this need not match the host workspace path — leave blank to reuse it only if you mounted it there yourself.</span>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label>Case Name</label>
|
||||
<input type="text" id="dockerCaseName" placeholder="sandbox" pattern="[a-zA-Z0-9_-]+" autocomplete="off" autocapitalize="off" spellcheck="false">
|
||||
|
||||
@@ -2975,6 +2975,7 @@ Object.assign(CodemanApp.prototype, {
|
||||
async _dockerAdoptPreflight() {
|
||||
const statusEl = document.getElementById('dockerLinkStatus');
|
||||
const container = document.getElementById('dockerContainerName')?.value.trim();
|
||||
const containerWorkdir = document.getElementById('dockerAdoptWorkdir')?.value.trim();
|
||||
const hostId = document.getElementById('dockerHostId').value.trim() || 'local';
|
||||
if (!container) {
|
||||
if (statusEl) statusEl.textContent = 'Enter a container name first.';
|
||||
@@ -2986,7 +2987,7 @@ Object.assign(CodemanApp.prototype, {
|
||||
const probe = await this._apiJson('/api/docker-cases/adopt-preflight', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ hostId, container }),
|
||||
body: JSON.stringify({ hostId, container, ...(containerWorkdir ? { containerWorkdir } : {}) }),
|
||||
});
|
||||
if (!statusEl) return;
|
||||
if (!probe) {
|
||||
@@ -3009,6 +3010,7 @@ Object.assign(CodemanApp.prototype, {
|
||||
const hostId = document.getElementById('dockerHostId').value.trim() || 'local';
|
||||
const adopting = !!document.getElementById('dockerAdoptExisting')?.checked;
|
||||
const container = document.getElementById('dockerContainerName')?.value.trim() || '';
|
||||
const adoptWorkdir = document.getElementById('dockerAdoptWorkdir')?.value.trim() || '';
|
||||
const image = document.getElementById('dockerImage').value.trim() || 'codeman/agent:base';
|
||||
const network = document.getElementById('dockerNetwork').value;
|
||||
const memory = document.getElementById('dockerMemory').value.trim();
|
||||
@@ -3076,7 +3078,11 @@ Object.assign(CodemanApp.prototype, {
|
||||
const caseRes = await fetch(adopting ? '/api/cases/docker-adopt' : '/api/cases/docker-link', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(adopting ? { name, hostId, hostWorkspacePath, container } : { name, hostId, hostWorkspacePath }),
|
||||
body: JSON.stringify(
|
||||
adopting
|
||||
? { name, hostId, hostWorkspacePath, container, ...(adoptWorkdir ? { containerWorkdir: adoptWorkdir } : {}) }
|
||||
: { name, hostId, hostWorkspacePath }
|
||||
),
|
||||
});
|
||||
const caseData = await caseRes.json();
|
||||
if (caseData.success) {
|
||||
|
||||
Reference in New Issue
Block a user