refactor(worker): delete per-job OpenCode container path, host_port split, and dead docker helpers
Claude-Session: https://claude.ai/code/session_01ScyZ1NhfN84LAnHpwhfEQk
This commit is contained in:
@@ -103,138 +103,6 @@ export const jobWorkspaceVolumeSpec = (
|
||||
: `${source}:${containerHome}`;
|
||||
};
|
||||
|
||||
export const runInJobContainer = async (args: {
|
||||
workdir: string;
|
||||
containerHome?: string;
|
||||
containerCwd?: string;
|
||||
command: string[];
|
||||
environment: Record<string, string>;
|
||||
redact: (value: string) => string;
|
||||
timeoutMs: number;
|
||||
}): Promise<CommandResult> => {
|
||||
await ensureJobImagePulled();
|
||||
const result = await execa(
|
||||
containerRuntime(),
|
||||
[
|
||||
'run',
|
||||
'--rm',
|
||||
'--memory',
|
||||
'4g',
|
||||
'--cpus',
|
||||
'2',
|
||||
...networkArgs(),
|
||||
...environmentArgs(args.environment),
|
||||
'-v',
|
||||
jobWorkspaceVolumeSpec(args.workdir, args.containerHome),
|
||||
'-w',
|
||||
args.containerCwd ?? '/workspace/repo',
|
||||
env.jobImage,
|
||||
...args.command,
|
||||
],
|
||||
{
|
||||
all: true,
|
||||
reject: false,
|
||||
stdin: 'ignore',
|
||||
timeout: args.timeoutMs,
|
||||
},
|
||||
);
|
||||
return normalizeRunResult(result, result.all, args.redact);
|
||||
};
|
||||
|
||||
export const startWorkspaceContainer = async (args: {
|
||||
workdir: string;
|
||||
containerHome?: string;
|
||||
containerCwd?: string;
|
||||
containerName: string;
|
||||
environment: Record<string, string>;
|
||||
command?: string[];
|
||||
publishTcpPort?: number;
|
||||
}) => {
|
||||
await ensureJobImagePulled();
|
||||
await execa(containerRuntime(), ['rm', '-f', args.containerName], {
|
||||
reject: false,
|
||||
});
|
||||
const result = await execa(
|
||||
containerRuntime(),
|
||||
[
|
||||
'run',
|
||||
'-d',
|
||||
'--name',
|
||||
args.containerName,
|
||||
'--memory',
|
||||
'4g',
|
||||
'--cpus',
|
||||
'2',
|
||||
...networkArgs(),
|
||||
...(args.publishTcpPort
|
||||
? ['-p', `127.0.0.1::${args.publishTcpPort}`]
|
||||
: []),
|
||||
...environmentArgs(args.environment),
|
||||
'-v',
|
||||
jobWorkspaceVolumeSpec(args.workdir, args.containerHome),
|
||||
'-w',
|
||||
args.containerCwd ?? '/workspace/repo',
|
||||
env.jobImage,
|
||||
...(args.command ?? ['sleep', 'infinity']),
|
||||
],
|
||||
{ all: true, stdin: 'ignore' },
|
||||
);
|
||||
return {
|
||||
containerId: result.stdout.trim(),
|
||||
containerName: args.containerName,
|
||||
hostPort: args.publishTcpPort
|
||||
? await getPublishedPort(args.containerName, args.publishTcpPort)
|
||||
: undefined,
|
||||
};
|
||||
};
|
||||
|
||||
const getPublishedPort = async (
|
||||
containerName: string,
|
||||
containerPort: number,
|
||||
) => {
|
||||
const result = await execa(
|
||||
containerRuntime(),
|
||||
['port', containerName, `${containerPort}/tcp`],
|
||||
{ all: true, reject: false, stdin: 'ignore' },
|
||||
);
|
||||
const output = result.all.trim();
|
||||
const match = /:(\d+)\s*$/.exec(output);
|
||||
if (!match?.[1]) {
|
||||
throw new Error(
|
||||
`Could not determine published port for ${containerName}:${containerPort}.`,
|
||||
);
|
||||
}
|
||||
return match[1];
|
||||
};
|
||||
|
||||
export const execInWorkspaceContainer = async (args: {
|
||||
containerName: string;
|
||||
command: string[];
|
||||
environment?: Record<string, string>;
|
||||
redact: (value: string) => string;
|
||||
timeoutMs: number;
|
||||
}): Promise<CommandResult> => {
|
||||
const result = await execa(
|
||||
containerRuntime(),
|
||||
[
|
||||
'exec',
|
||||
...(args.environment ? environmentArgs(args.environment) : []),
|
||||
args.containerName,
|
||||
...args.command,
|
||||
],
|
||||
{
|
||||
all: true,
|
||||
reject: false,
|
||||
stdin: 'ignore',
|
||||
timeout: args.timeoutMs,
|
||||
},
|
||||
);
|
||||
return {
|
||||
exitCode: result.exitCode ?? 0,
|
||||
output: args.redact(result.all),
|
||||
};
|
||||
};
|
||||
|
||||
// Shared line-streaming + result normalization for a started subprocess
|
||||
// (used by both `docker run` and `docker exec` paths).
|
||||
type StreamingSubprocess = {
|
||||
@@ -296,51 +164,6 @@ const streamSubprocess = async (
|
||||
return normalizeRunResult(result, output.join(''), redact);
|
||||
};
|
||||
|
||||
export const streamInJobContainer = async (args: {
|
||||
workdir: string;
|
||||
containerHome?: string;
|
||||
containerCwd?: string;
|
||||
command: string[];
|
||||
environment: Record<string, string>;
|
||||
redact: (value: string) => string;
|
||||
timeoutMs: number;
|
||||
onStdoutLine?: (line: string) => Promise<void>;
|
||||
onStderrLine?: (line: string) => Promise<void>;
|
||||
}): Promise<CommandResult> => {
|
||||
await ensureJobImagePulled();
|
||||
const subprocess = execa(
|
||||
containerRuntime(),
|
||||
[
|
||||
'run',
|
||||
'--rm',
|
||||
'--memory',
|
||||
'4g',
|
||||
'--cpus',
|
||||
'2',
|
||||
...networkArgs(),
|
||||
...environmentArgs(args.environment),
|
||||
'-v',
|
||||
jobWorkspaceVolumeSpec(args.workdir, args.containerHome),
|
||||
'-w',
|
||||
args.containerCwd ?? '/workspace/repo',
|
||||
env.jobImage,
|
||||
...args.command,
|
||||
],
|
||||
{
|
||||
all: true,
|
||||
reject: false,
|
||||
stdin: 'ignore',
|
||||
timeout: args.timeoutMs,
|
||||
},
|
||||
);
|
||||
return streamSubprocess(
|
||||
subprocess,
|
||||
args.redact,
|
||||
args.onStdoutLine,
|
||||
args.onStderrLine,
|
||||
);
|
||||
};
|
||||
|
||||
// Per-user persistent "box" container that all of a user's threads exec into
|
||||
// (Phase 2). Started once, reused; the home volume persists state across stops.
|
||||
export const userContainerName = (username: string) =>
|
||||
@@ -533,17 +356,6 @@ export const stopWorkspaceContainer = async (containerName: string) => {
|
||||
});
|
||||
};
|
||||
|
||||
export const inspectWorkspaceContainer = async (containerName: string) => {
|
||||
const result = await execa(containerRuntime(), ['inspect', containerName], {
|
||||
all: true,
|
||||
reject: false,
|
||||
});
|
||||
return {
|
||||
exists: result.exitCode === 0,
|
||||
output: result.all,
|
||||
};
|
||||
};
|
||||
|
||||
export const listWorkspaceContainerNames = async (prefix: string) => {
|
||||
const result = await execa(
|
||||
containerRuntime(),
|
||||
|
||||
Reference in New Issue
Block a user