@computesdk/docker 1.2.42 → 1.2.44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -45,7 +45,7 @@ import { compute } from 'computesdk';
45
45
  // Auto-detects Docker (requires Docker daemon running)
46
46
  const sandbox = await compute.sandbox.create();
47
47
 
48
- const result = await sandbox.runCode(`print("Hello from Python")`, 'python');
48
+ const result = await sandbox.runCommand('python -c "print(\"Hello from Python\")"');
49
49
  console.log(result.stdout.trim()); // Hello from Python
50
50
 
51
51
  await sandbox.destroy();
@@ -65,7 +65,7 @@ const compute = docker({
65
65
 
66
66
  // Create a sandbox and run Python
67
67
  const sandbox = await compute.sandbox.create();
68
- const result = await sandbox.runCode(`print("Hello from Python")`, 'python');
68
+ const result = await sandbox.runCommand('python -c "print(\"Hello from Python\")"');
69
69
  console.log(result.stdout.trim()); // Hello from Python
70
70
 
71
71
  await sandbox.destroy();
@@ -85,9 +85,9 @@ const compute = docker({
85
85
  },
86
86
  });
87
87
 
88
- const sandbox = await compute.sandbox.create({ runtime: 'node' });
88
+ const sandbox = await compute.sandbox.create();
89
89
 
90
- const result = await sandbox.runCode(`console.log("Hello, World!")`, 'node');
90
+ const result = await sandbox.runCommand('node -e "console.log(\"Hello, World!\")"');
91
91
  console.log(result.stdout.trim()); // Hello, World!
92
92
 
93
93
  const cmd = await sandbox.runCommand('sh', ['-lc', 'echo Hello from command']);
@@ -189,7 +189,7 @@ Type: `DockerConfig`
189
189
  ### Code Execution
190
190
 
191
191
  ```ts
192
- sandbox.runCode(code: string, runtime?: 'python' | 'node'): Promise<ExecutionResult>
192
+ sandbox.runCommand(code: string, runtime?: 'python' | 'node'): Promise<ExecutionResult>
193
193
  ```
194
194
 
195
195
  * If `runtime` omitted, the sandbox’s runtime (set at creation) is used.
@@ -239,10 +239,10 @@ await sandbox.destroy();
239
239
 
240
240
  There’s **no auto-detection**. Resolution is:
241
241
 
242
- 1. `runCode(_, runtime)` argument, else
243
- 2. runtime label set at `sandbox.create()` (from `options.runtime` or provider `config.runtime`)
242
+ 1. provider `config.runtime`, else
243
+ 2. fallback default in provider config
244
244
 
245
- If neither yields `'python' | 'node'`, `runCode` throws.
245
+ Use `runCommand('python -c "..."')` or `runCommand('node -e "..."')` when you need language-specific execution.
246
246
 
247
247
  ---
248
248
 
package/dist/index.js CHANGED
@@ -180,24 +180,6 @@ var docker = (0, import_provider.defineProvider)({
180
180
  throw new Error(`Docker provider supports only 'python' or 'node'. Received: ${String(effectiveRuntime)}`);
181
181
  }
182
182
  const docker2 = new import_dockerode.default(cfg.connection);
183
- if (options?.sandboxId) {
184
- try {
185
- const container2 = docker2.getContainer(options.sandboxId);
186
- const info = await container2.inspect();
187
- return {
188
- sandbox: {
189
- docker: docker2,
190
- container: container2,
191
- containerId: options.sandboxId,
192
- image: info.Config?.Image ?? cfg.image.name,
193
- createdAt: new Date(info.Created || Date.now())
194
- },
195
- sandboxId: options.sandboxId
196
- };
197
- } catch (err) {
198
- console.warn(`Could not reattach to Docker container with ID ${options.sandboxId}:`, err);
199
- }
200
- }
201
183
  const chosenImage = pickImageForRuntime(effectiveRuntime, cfg.image);
202
184
  await ensureImage(docker2, chosenImage);
203
185
  const mergedEnv = { ...cfg.container?.env, ...options?.envs };
@@ -307,33 +289,6 @@ var docker = (0, import_provider.defineProvider)({
307
289
  } catch {
308
290
  }
309
291
  },
310
- runCode: async (handle, code, runtime) => {
311
- const start = Date.now();
312
- let rt = runtime;
313
- if (!rt) {
314
- const info = await handle.container.inspect();
315
- rt = info.Config?.Labels?.[LABEL_RUNTIME] || void 0;
316
- }
317
- if (rt !== "python" && rt !== "node") {
318
- throw new Error(`Docker runtime must be 'python' or 'node'. Pass runtime in config or as a parameter.`);
319
- }
320
- const tmpFile = rt === "python" ? "/tmp/compute_code.py" : "/tmp/compute_code.js";
321
- const b64 = Buffer.from(code, "utf8").toString("base64");
322
- const makeAndRun = `printf '%s' "${b64}" | base64 -d > ${tmpFile} && ` + (rt === "python" ? `python3 ${tmpFile}` : `node ${tmpFile}`);
323
- const { stdout, stderr, exitCode } = await runExec(handle, makeAndRun);
324
- if (exitCode !== 0 && stderr) {
325
- const isSyntax = stderr.includes("SyntaxError") || stderr.includes("invalid syntax") || stderr.includes("Unexpected token") || stderr.includes("Unexpected identifier");
326
- if (isSyntax) {
327
- const last = stderr.trim().split("\n").slice(-1)[0] || "Syntax error";
328
- throw new Error(`Syntax error: ${last}`);
329
- }
330
- }
331
- return {
332
- output: stdout + stderr,
333
- exitCode,
334
- language: rt
335
- };
336
- },
337
292
  runCommand: async (handle, command, options) => {
338
293
  const start = Date.now();
339
294
  const { stdout, stderr, exitCode } = await runExec(handle, command);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/types/types.ts"],"sourcesContent":["import Docker from 'dockerode';\nimport { PassThrough } from 'stream';\nimport { defineProvider } from '@computesdk/provider';\nimport type {\n Runtime,\n CodeResult,\n CommandResult,\n RunCommandOptions,\n CreateSandboxOptions,\n SandboxInfo,\n FileEntry,\n} from '@computesdk/provider';\n\nimport { defaultDockerConfig } from './types/types';\nimport type {\n DockerConfig,\n DockerSandboxHandle,\n DockerImage,\n PortBindings,\n} from './types/types';\n\nconst PROVIDER = 'docker' as const;\nconst LABEL_KEY = 'com.computesdk.sandbox';\nconst LABEL_RUNTIME = 'com.computesdk.runtime';\nconst KEEPALIVE_CMD = ['/bin/sh', '-c', 'while :; do sleep 3600; done'];\n\nfunction pick<T>(val: T | undefined, fallback: T): T {\n return typeof val === 'undefined' ? fallback : val;\n}\n\nasync function ensureImage(docker: Docker, image: DockerImage): Promise<void> {\n const policy = image.pullPolicy ?? 'ifNotPresent';\n if (policy === 'never') return;\n\n const images = await docker.listImages();\n const hasImage = images.some(img => (img.RepoTags || []).includes(image.name));\n\n if (policy === 'always' || (policy === 'ifNotPresent' && !hasImage)) {\n await new Promise<void>((resolve, reject) => {\n const cb = (err: any, stream?: NodeJS.ReadableStream) => {\n if (err) return reject(err);\n if (!stream) return reject(new Error('docker.pull returned no stream'));\n (docker as any).modem.followProgress(stream, (err2: any) => (err2 ? reject(err2) : resolve()));\n };\n if (image.auth) docker.pull(image.name, { authconfig: image.auth } as any, cb);\n else docker.pull(image.name, cb);\n });\n }\n}\n\nasync function waitUntilRunning(container: Docker.Container, timeoutMs = 4000) {\n const start = Date.now();\n try {\n const s = await container.inspect();\n if (s.State?.Running) return;\n } catch { /* ignore */ }\n\n while (Date.now() - start < timeoutMs) {\n const s = await container.inspect();\n if (s.State?.Running) return;\n await new Promise(r => setTimeout(r, 100));\n }\n throw new Error('Container did not reach Running state in time');\n}\n\nasync function runExec(\n handle: DockerSandboxHandle,\n shellCommand: string,\n attachTTY = false\n): Promise<{ stdout: string; stderr: string; exitCode: number }> {\n await waitUntilRunning(handle.container);\n\n const exec = await handle.container.exec({\n Cmd: ['/bin/sh', '-c', shellCommand],\n AttachStdout: true,\n AttachStderr: true,\n Tty: attachTTY,\n });\n\n const stream = (await exec.start({ hijack: true, stdin: false })) as NodeJS.ReadableStream;\n\n let stdout = '';\n let stderr = '';\n\n await new Promise<void>((resolve, reject) => {\n if (attachTTY) {\n stream.on('data', (chunk: Buffer) => (stdout += chunk.toString('utf8')));\n stream.on('end', resolve);\n stream.on('error', reject);\n return;\n }\n const out = new PassThrough();\n const err = new PassThrough();\n out.on('data', (c: Buffer) => (stdout += c.toString('utf8')));\n err.on('data', (c: Buffer) => (stderr += c.toString('utf8')));\n (handle.docker as any).modem.demuxStream(stream as any, out as any, err as any);\n stream.on('end', resolve);\n stream.on('error', reject);\n });\n\n const inspect = await exec.inspect();\n const exitCode = inspect.ExitCode ?? 0;\n return { stdout, stderr, exitCode };\n}\n\nfunction toHostBindings(ports?: PortBindings) {\n if (!ports) return undefined;\n const exposed: Record<string, {}> = {};\n const bindings: Record<string, Array<{ HostPort?: string; HostIp?: string }>> = {};\n for (const key of Object.keys(ports)) {\n exposed[key] = {};\n bindings[key] = (ports as any)[key].map((p: any) => ({\n HostPort: p.hostPort ? String(p.hostPort) : undefined,\n HostIp: p.hostIP,\n }));\n }\n return { ExposedPorts: exposed, PortBindings: bindings };\n}\n\nfunction dockerHostNameFromEnv(): string {\n const hostEnv = process.env.DOCKER_HOST;\n if (hostEnv?.startsWith('tcp://')) {\n try {\n const u = new URL(hostEnv);\n return u.hostname || 'localhost';\n } catch { /* noop */ }\n }\n return 'localhost';\n}\n\nfunction pickImageForRuntime(runtime: Runtime, configured?: DockerImage): DockerImage {\n // If user supplied an image that already matches, use it. Otherwise pick a sensible default.\n if (configured?.name) {\n if (runtime === 'python' && /python|conda|pypy/i.test(configured.name)) return configured;\n if (runtime === 'node' && /node/i.test(configured.name)) return configured;\n }\n return {\n name: runtime === 'python' ? 'python:3.11-slim' : 'node:20-alpine',\n pullPolicy: configured?.pullPolicy ?? 'ifNotPresent',\n auth: configured?.auth,\n };\n}\n\nexport const docker = defineProvider<DockerSandboxHandle, DockerConfig>({\n name: PROVIDER,\n methods: {\n sandbox: {\n create: async (config: DockerConfig, options?: CreateSandboxOptions) => {\n const cfg: DockerConfig = { ...defaultDockerConfig, ...config };\n const effectiveRuntime: Runtime = (options?.runtime ?? cfg.runtime ?? 'python') as Runtime;\n\n if (effectiveRuntime !== 'python' && effectiveRuntime !== 'node') {\n throw new Error(`Docker provider supports only 'python' or 'node'. Received: ${String(effectiveRuntime)}`);\n }\n\n const docker = new Docker(cfg.connection as any);\n\n // Reattach?\n if (options?.sandboxId) {\n try {\n const container = docker.getContainer(options.sandboxId);\n const info = await container.inspect();\n return {\n sandbox: <DockerSandboxHandle>{\n docker,\n container,\n containerId: options.sandboxId,\n image: info.Config?.Image ?? cfg.image.name,\n createdAt: new Date(info.Created || Date.now()),\n },\n sandboxId: options.sandboxId,\n };\n } catch (err) {\n // Failed to reattach to existing container; will create a new one.\n console.warn(`Could not reattach to Docker container with ID ${options.sandboxId}:`, err);\n }\n }\n\n // Choose image based on runtime if needed\n const chosenImage = pickImageForRuntime(effectiveRuntime, cfg.image);\n await ensureImage(docker, chosenImage);\n\n // Merge environment variables: config.container.env < options.envs\n const mergedEnv = { ...cfg.container?.env, ...options?.envs };\n\n // Build container create options\n const hb = toHostBindings(cfg.container?.ports);\n const createOptions = {\n Image: chosenImage.name,\n Tty: pick(cfg.container?.tty, false),\n OpenStdin: pick(cfg.container?.openStdin, false),\n Labels: {\n // User metadata is spread first with a namespaced prefix so it\n // cannot overwrite the reserved discovery/runtime labels below.\n ...(options?.metadata ? Object.fromEntries(\n Object.entries(options.metadata).map(([k, v]) => [`com.computesdk.meta.${k}`, typeof v === 'string' ? v : JSON.stringify(v)])\n ) : {}),\n [LABEL_KEY]: 'true',\n [LABEL_RUNTIME]: effectiveRuntime,\n },\n WorkingDir: cfg.container?.workdir,\n Env: Object.keys(mergedEnv).length > 0\n ? Object.entries(mergedEnv).map(([k, v]) => `${k}=${v}`)\n : undefined,\n Cmd: KEEPALIVE_CMD, // keep container alive\n HostConfig: {\n AutoRemove: cfg.container?.autoRemove ?? false, // keep around for exec/FS ops\n Binds: cfg.container?.binds,\n NetworkMode: cfg.container?.networkMode,\n Privileged: cfg.container?.privileged,\n CapAdd: cfg.container?.capabilities?.add,\n CapDrop: cfg.container?.capabilities?.drop,\n LogConfig: cfg.container?.logDriver\n ? { Type: cfg.container.logDriver, Config: cfg.container.logOpts || {} }\n : undefined,\n Resources: cfg.container?.resources,\n DeviceRequests: cfg.container?.gpus\n ? [\n {\n Driver: 'nvidia',\n Count:\n cfg.container.gpus === 'all'\n ? -1\n : typeof cfg.container.gpus === 'number'\n ? cfg.container.gpus\n : 1,\n DeviceIDs:\n typeof cfg.container.gpus === 'string' && cfg.container.gpus !== 'all'\n ? [String(cfg.container.gpus)]\n : undefined,\n Capabilities: [['gpu']],\n },\n ]\n : undefined,\n ...(hb ? { PortBindings: hb.PortBindings } : {}),\n },\n ...(hb ? { ExposedPorts: hb.ExposedPorts } : {}),\n ...(cfg.createOptions || {}),\n } as import('dockerode').ContainerCreateOptions;\n\n const container = await docker.createContainer(createOptions);\n await container.start(cfg.startOptions || {});\n await waitUntilRunning(container);\n\n const inspect = await container.inspect();\n const handle: DockerSandboxHandle = {\n docker,\n container,\n containerId: inspect.Id,\n image: inspect.Config?.Image ?? chosenImage.name,\n createdAt: new Date(inspect.Created || Date.now()),\n };\n\n return { sandbox: handle, sandboxId: handle.containerId };\n },\n\n getById: async (config: DockerConfig, sandboxId: string) => {\n const docker = new Docker((config || defaultDockerConfig).connection as any);\n try {\n const container = docker.getContainer(sandboxId);\n const info = await container.inspect();\n return {\n sandbox: <DockerSandboxHandle>{\n docker,\n container,\n containerId: sandboxId,\n image: info.Config?.Image ?? '',\n createdAt: new Date(info.Created || Date.now()),\n },\n sandboxId,\n };\n } catch {\n return null;\n }\n },\n\n list: async (config: DockerConfig) => {\n const docker = new Docker((config || defaultDockerConfig).connection as any);\n try {\n const items = await docker.listContainers({\n all: true,\n filters: { label: [LABEL_KEY] } as any,\n });\n return items.map(ci => ({\n sandbox: <DockerSandboxHandle>{\n docker,\n container: docker.getContainer(ci.Id),\n containerId: ci.Id,\n image: ci.Image,\n createdAt: new Date((ci as any).Created * 1000),\n },\n sandboxId: ci.Id,\n }));\n } catch {\n return [];\n }\n },\n\n destroy: async (config: DockerConfig, sandboxId: string) => {\n const docker = new Docker((config || defaultDockerConfig).connection as any);\n try {\n const c = docker.getContainer(sandboxId);\n try { await c.stop({ t: 5 } as any); } catch { /* stopped */ }\n await c.remove({ force: true });\n } catch {\n // ok if already gone\n }\n },\n\n runCode: async (handle: DockerSandboxHandle, code: string, runtime?: Runtime): Promise<CodeResult> => {\n const start = Date.now();\n\n // Resolve runtime: param → label → error\n let rt: Runtime | undefined = runtime;\n if (!rt) {\n const info = await handle.container.inspect();\n rt = (info.Config?.Labels?.[LABEL_RUNTIME] as Runtime) || undefined;\n }\n if (rt !== 'python' && rt !== 'node') {\n throw new Error(`Docker runtime must be 'python' or 'node'. Pass runtime in config or as a parameter.`);\n }\n\n // Write to file, then execute. This is robust on Alpine/Debian.\n const tmpFile = rt === 'python' ? '/tmp/compute_code.py' : '/tmp/compute_code.js';\n const b64 = Buffer.from(code, 'utf8').toString('base64');\n const makeAndRun =\n `printf '%s' \"${b64}\" | base64 -d > ${tmpFile} && ` +\n (rt === 'python' ? `python3 ${tmpFile}` : `node ${tmpFile}`);\n\n const { stdout, stderr, exitCode } = await runExec(handle, makeAndRun);\n\n if (exitCode !== 0 && stderr) {\n // Throw ONLY on syntax errors (SDK contract)\n const isSyntax =\n stderr.includes('SyntaxError') ||\n stderr.includes('invalid syntax') ||\n stderr.includes('Unexpected token') ||\n stderr.includes('Unexpected identifier');\n if (isSyntax) {\n const last = stderr.trim().split('\\n').slice(-1)[0] || 'Syntax error';\n throw new Error(`Syntax error: ${last}`);\n }\n }\n\n return {\n output: stdout + stderr,\n exitCode,\n language: rt,\n };\n },\n\n runCommand: async (\n handle: DockerSandboxHandle,\n command: string,\n options?: RunCommandOptions\n ): Promise<CommandResult> => {\n const start = Date.now();\n\n const { stdout, stderr, exitCode } = await runExec(handle, command);\n\n return {\n stdout,\n stderr,\n exitCode,\n durationMs: Date.now() - start,\n };\n },\n\n getInfo: async (handle: DockerSandboxHandle): Promise<SandboxInfo> => {\n const info = await handle.container.inspect();\n const state = info.State || {};\n return {\n id: handle.containerId,\n provider: PROVIDER,\n runtime: (info.Config?.Labels?.[LABEL_RUNTIME] as Runtime) || 'python',\n status: state.Running ? 'running' : 'stopped',\n createdAt: new Date(info.Created || handle.createdAt),\n timeout: 300000,\n metadata: {\n image: info.Config?.Image,\n name: info.Name,\n },\n };\n },\n\n getUrl: async (handle: DockerSandboxHandle, options: { port: number; protocol?: string }): Promise<string> => {\n const info = await handle.container.inspect();\n const protocol = options.protocol || 'http';\n const portKeyTcp = `${options.port}/tcp`;\n\n const ports = info.NetworkSettings?.Ports || {};\n const bindings = ports[portKeyTcp] || ports[`${options.port}/udp`] || [];\n\n let host = dockerHostNameFromEnv();\n let hostPort = String(options.port);\n\n if (Array.isArray(bindings) && bindings.length > 0) {\n hostPort = bindings[0].HostPort || hostPort;\n } else {\n const ip =\n info.NetworkSettings?.IPAddress ||\n Object.values(info.NetworkSettings?.Networks || {})[0]?.IPAddress;\n if (ip) host = ip;\n }\n\n return `${protocol}://${host}:${hostPort}`;\n },\n\n filesystem: {\n readFile: async (handle: DockerSandboxHandle, path: string): Promise<string> => {\n const cmd = `if [ -f ${JSON.stringify(path)} ]; then base64 ${JSON.stringify(path)} | tr -d '\\\\n'; else exit 1; fi`;\n const { stdout, exitCode, stderr } = await runExec(handle, cmd);\n if (exitCode !== 0) throw new Error(stderr || `File not found: ${path}`);\n return Buffer.from(stdout, 'base64').toString('utf8');\n },\n\n writeFile: async (handle: DockerSandboxHandle, path: string, content: string): Promise<void> => {\n const b64 = Buffer.from(content, 'utf8').toString('base64');\n const cmd = `mkdir -p $(dirname ${JSON.stringify(path)}) && echo \"${b64}\" | base64 -d > ${JSON.stringify(path)}`;\n const { exitCode, stderr } = await runExec(handle, cmd);\n if (exitCode !== 0) throw new Error(stderr || `Failed to write: ${path}`);\n },\n\n mkdir: async (handle: DockerSandboxHandle, path: string): Promise<void> => {\n const { exitCode, stderr } = await runExec(handle, `mkdir -p ${JSON.stringify(path)}`);\n if (exitCode !== 0) throw new Error(stderr || `Failed to mkdir: ${path}`);\n },\n\n readdir: async (handle: DockerSandboxHandle, path: string): Promise<FileEntry[]> => {\n const { stdout, exitCode, stderr } = await runExec(\n handle,\n `if [ -d ${JSON.stringify(path)} ]; then ls -la ${JSON.stringify(path)}; else exit 1; fi`\n );\n if (exitCode !== 0) throw new Error(stderr || `Not a directory: ${path}`);\n\n const lines = stdout.split('\\n').slice(1);\n const entries: FileEntry[] = [];\n for (const line of lines) {\n const parts = line.trim().split(/\\s+/);\n if (parts.length < 9) continue;\n const name = parts.slice(8).join(' ');\n if (name === '.' || name === '..') continue;\n const isDir = parts[0].startsWith('d');\n const size = Number(parts[4]) || 0;\n entries.push({\n name,\n type: isDir ? 'directory' as const : 'file' as const,\n size,\n modified: new Date(),\n });\n }\n return entries;\n },\n\n exists: async (handle: DockerSandboxHandle, path: string): Promise<boolean> => {\n const { exitCode } = await runExec(handle, `test -e ${JSON.stringify(path)}`);\n return exitCode === 0;\n },\n\n remove: async (handle: DockerSandboxHandle, path: string): Promise<void> => {\n const { exitCode, stderr } = await runExec(handle, `rm -rf ${JSON.stringify(path)}`);\n if (exitCode !== 0) throw new Error(stderr || `Failed to remove: ${path}`);\n },\n },\n\n getInstance: (handle: DockerSandboxHandle): DockerSandboxHandle => handle,\n },\n },\n});\n\n","import type Docker from 'dockerode';\nimport type {\n DockerOptions,\n Container,\n ContainerCreateOptions,\n ContainerStartOptions,\n ContainerInspectInfo,\n ContainerInfo,\n Exec,\n ImageInfo,\n ImageBuildOptions,\n Network,\n} from 'dockerode';\n\nimport type {\n Runtime,\n FileEntry,\n RunCommandOptions,\n CreateSandboxOptions,\n SandboxInfo,\n} from 'computesdk';\n\n/** When the provider should clean up containers it created */\nexport type CleanupPolicy = 'always' | 'onSuccess' | 'never';\n\n/** Image pull strategy */\nexport type PullPolicy = 'always' | 'ifNotPresent' | 'never';\n\n/** Connection to the Docker daemon (exactly what dockerode accepts) */\nexport type DockerConnection = DockerOptions;\n\n/** Auth when pulling private images (Engine API AuthConfig shape) */\nexport interface RegistryAuth {\n username?: string;\n password?: string;\n serveraddress?: string;\n identitytoken?: string;\n registrytoken?: string;\n}\n\n/** Default image & pull policy for sandboxes */\nexport interface DockerImage {\n name: string; // e.g. 'python:3.11-slim'\n pullPolicy?: PullPolicy; // default: 'ifNotPresent'\n auth?: RegistryAuth;\n}\n\n/** Convenience shape for port bindings */\nexport type PortBindings = Record<\n `${number}/${'tcp' | 'udp'}`,\n Array<{ hostPort?: number; hostIP?: string }>\n>;\n\n/** Subset of HostConfig resources & knobs that are commonly used */\nexport interface ResourceLimits {\n cpuShares?: number;\n cpuQuota?: number;\n cpuPeriod?: number;\n nanoCPUs?: number;\n memory?: number;\n memorySwap?: number;\n pidsLimit?: number;\n}\n\n/** Declarative container defaults that we’ll translate into dockerode create options */\nexport interface ContainerDefaults {\n user?: string;\n workdir?: string;\n env?: Record<string, string>;\n binds?: string[];\n ports?: PortBindings;\n networkMode?: string;\n privileged?: boolean;\n capabilities?: { add?: string[]; drop?: string[] };\n gpus?: 'all' | number | string;\n resources?: ResourceLimits;\n logDriver?: string;\n logOpts?: Record<string, string>;\n autoRemove?: boolean;\n tty?: boolean;\n openStdin?: boolean;\n}\n\n/** Provider-level configuration for Docker */\nexport interface DockerConfig {\n connection?: DockerConnection;\n runtime?: Runtime; // 'python' | 'node'\n timeout?: number;\n image: DockerImage;\n container?: ContainerDefaults;\n createOptions?: ContainerCreateOptions;\n startOptions?: ContainerStartOptions;\n cleanup?: CleanupPolicy;\n streamLogs?: boolean;\n}\n\n/** What we keep for each running sandbox */\nexport interface DockerSandboxHandle {\n docker: Docker;\n container: Container;\n containerId: string;\n image: string;\n createdAt: Date;\n}\n\n/** URL options for port-forwarded services */\nexport interface DockerUrlOptions {\n port: number;\n protocol?: 'http' | 'https';\n host?: string;\n}\n\n/** Optional FS helpers you might expose */\nexport interface DockerSandboxFileSystem {\n readFile(path: string): Promise<string>;\n writeFile(path: string, content: string): Promise<void>;\n mkdir(path: string): Promise<void>;\n readdir(path: string): Promise<FileEntry[]>;\n exists(path: string): Promise<boolean>;\n remove(path: string): Promise<void>;\n}\n\n/** Sensible, safe defaults */\nexport const defaultDockerConfig: DockerConfig = {\n connection: {\n // Let dockerode fall back to DOCKER_HOST or /var/run/docker.sock\n timeout: 60_000,\n version: 'v1.43',\n },\n runtime: 'python',\n timeout: 300_000, // 5 minutes\n image: {\n name: 'python:3.11-slim',\n pullPolicy: 'ifNotPresent',\n },\n container: {\n workdir: '/workspace',\n env: {},\n autoRemove: false, // Keep container around for exec/FS/background\n tty: false, // Non-tty so we can demux stdout/stderr\n openStdin: false,\n resources: { memory: 512 * 1024 * 1024 },\n },\n cleanup: 'always',\n streamLogs: false,\n};\n\n/** Re-exports for convenience */\nexport type {\n Docker,\n Container,\n Exec,\n ContainerCreateOptions,\n ContainerStartOptions,\n ContainerInspectInfo,\n ContainerInfo,\n ImageInfo,\n ImageBuildOptions,\n Network,\n};\n"],"mappings":"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","names":["docker","Docker","container"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/types/types.ts"],"sourcesContent":["import Docker from 'dockerode';\nimport { PassThrough } from 'stream';\nimport { defineProvider } from '@computesdk/provider';\nimport type {\n Runtime,\n CodeResult,\n CommandResult,\n RunCommandOptions,\n CreateSandboxOptions,\n SandboxInfo,\n FileEntry,\n} from '@computesdk/provider';\n\nimport { defaultDockerConfig } from './types/types';\nimport type {\n DockerConfig,\n DockerSandboxHandle,\n DockerImage,\n PortBindings,\n} from './types/types';\n\nconst PROVIDER = 'docker' as const;\nconst LABEL_KEY = 'com.computesdk.sandbox';\nconst LABEL_RUNTIME = 'com.computesdk.runtime';\nconst KEEPALIVE_CMD = ['/bin/sh', '-c', 'while :; do sleep 3600; done'];\n\nfunction pick<T>(val: T | undefined, fallback: T): T {\n return typeof val === 'undefined' ? fallback : val;\n}\n\nasync function ensureImage(docker: Docker, image: DockerImage): Promise<void> {\n const policy = image.pullPolicy ?? 'ifNotPresent';\n if (policy === 'never') return;\n\n const images = await docker.listImages();\n const hasImage = images.some(img => (img.RepoTags || []).includes(image.name));\n\n if (policy === 'always' || (policy === 'ifNotPresent' && !hasImage)) {\n await new Promise<void>((resolve, reject) => {\n const cb = (err: any, stream?: NodeJS.ReadableStream) => {\n if (err) return reject(err);\n if (!stream) return reject(new Error('docker.pull returned no stream'));\n (docker as any).modem.followProgress(stream, (err2: any) => (err2 ? reject(err2) : resolve()));\n };\n if (image.auth) docker.pull(image.name, { authconfig: image.auth } as any, cb);\n else docker.pull(image.name, cb);\n });\n }\n}\n\nasync function waitUntilRunning(container: Docker.Container, timeoutMs = 4000) {\n const start = Date.now();\n try {\n const s = await container.inspect();\n if (s.State?.Running) return;\n } catch { /* ignore */ }\n\n while (Date.now() - start < timeoutMs) {\n const s = await container.inspect();\n if (s.State?.Running) return;\n await new Promise(r => setTimeout(r, 100));\n }\n throw new Error('Container did not reach Running state in time');\n}\n\nasync function runExec(\n handle: DockerSandboxHandle,\n shellCommand: string,\n attachTTY = false\n): Promise<{ stdout: string; stderr: string; exitCode: number }> {\n await waitUntilRunning(handle.container);\n\n const exec = await handle.container.exec({\n Cmd: ['/bin/sh', '-c', shellCommand],\n AttachStdout: true,\n AttachStderr: true,\n Tty: attachTTY,\n });\n\n const stream = (await exec.start({ hijack: true, stdin: false })) as NodeJS.ReadableStream;\n\n let stdout = '';\n let stderr = '';\n\n await new Promise<void>((resolve, reject) => {\n if (attachTTY) {\n stream.on('data', (chunk: Buffer) => (stdout += chunk.toString('utf8')));\n stream.on('end', resolve);\n stream.on('error', reject);\n return;\n }\n const out = new PassThrough();\n const err = new PassThrough();\n out.on('data', (c: Buffer) => (stdout += c.toString('utf8')));\n err.on('data', (c: Buffer) => (stderr += c.toString('utf8')));\n (handle.docker as any).modem.demuxStream(stream as any, out as any, err as any);\n stream.on('end', resolve);\n stream.on('error', reject);\n });\n\n const inspect = await exec.inspect();\n const exitCode = inspect.ExitCode ?? 0;\n return { stdout, stderr, exitCode };\n}\n\nfunction toHostBindings(ports?: PortBindings) {\n if (!ports) return undefined;\n const exposed: Record<string, {}> = {};\n const bindings: Record<string, Array<{ HostPort?: string; HostIp?: string }>> = {};\n for (const key of Object.keys(ports)) {\n exposed[key] = {};\n bindings[key] = (ports as any)[key].map((p: any) => ({\n HostPort: p.hostPort ? String(p.hostPort) : undefined,\n HostIp: p.hostIP,\n }));\n }\n return { ExposedPorts: exposed, PortBindings: bindings };\n}\n\nfunction dockerHostNameFromEnv(): string {\n const hostEnv = process.env.DOCKER_HOST;\n if (hostEnv?.startsWith('tcp://')) {\n try {\n const u = new URL(hostEnv);\n return u.hostname || 'localhost';\n } catch { /* noop */ }\n }\n return 'localhost';\n}\n\nfunction pickImageForRuntime(runtime: Runtime, configured?: DockerImage): DockerImage {\n // If user supplied an image that already matches, use it. Otherwise pick a sensible default.\n if (configured?.name) {\n if (runtime === 'python' && /python|conda|pypy/i.test(configured.name)) return configured;\n if (runtime === 'node' && /node/i.test(configured.name)) return configured;\n }\n return {\n name: runtime === 'python' ? 'python:3.11-slim' : 'node:20-alpine',\n pullPolicy: configured?.pullPolicy ?? 'ifNotPresent',\n auth: configured?.auth,\n };\n}\n\nexport const docker = defineProvider<DockerSandboxHandle, DockerConfig>({\n name: PROVIDER,\n methods: {\n sandbox: {\n create: async (config: DockerConfig, options?: CreateSandboxOptions) => {\n const cfg: DockerConfig = { ...defaultDockerConfig, ...config };\n const effectiveRuntime: Runtime = (options?.runtime ?? cfg.runtime ?? 'python') as Runtime;\n\n if (effectiveRuntime !== 'python' && effectiveRuntime !== 'node') {\n throw new Error(`Docker provider supports only 'python' or 'node'. Received: ${String(effectiveRuntime)}`);\n }\n\n const docker = new Docker(cfg.connection as any);\n\n // Choose image based on runtime if needed\n const chosenImage = pickImageForRuntime(effectiveRuntime, cfg.image);\n await ensureImage(docker, chosenImage);\n\n // Merge environment variables: config.container.env < options.envs\n const mergedEnv = { ...cfg.container?.env, ...options?.envs };\n\n // Build container create options\n const hb = toHostBindings(cfg.container?.ports);\n const createOptions = {\n Image: chosenImage.name,\n Tty: pick(cfg.container?.tty, false),\n OpenStdin: pick(cfg.container?.openStdin, false),\n Labels: {\n // User metadata is spread first with a namespaced prefix so it\n // cannot overwrite the reserved discovery/runtime labels below.\n ...(options?.metadata ? Object.fromEntries(\n Object.entries(options.metadata).map(([k, v]) => [`com.computesdk.meta.${k}`, typeof v === 'string' ? v : JSON.stringify(v)])\n ) : {}),\n [LABEL_KEY]: 'true',\n [LABEL_RUNTIME]: effectiveRuntime,\n },\n WorkingDir: cfg.container?.workdir,\n Env: Object.keys(mergedEnv).length > 0\n ? Object.entries(mergedEnv).map(([k, v]) => `${k}=${v}`)\n : undefined,\n Cmd: KEEPALIVE_CMD, // keep container alive\n HostConfig: {\n AutoRemove: cfg.container?.autoRemove ?? false, // keep around for exec/FS ops\n Binds: cfg.container?.binds,\n NetworkMode: cfg.container?.networkMode,\n Privileged: cfg.container?.privileged,\n CapAdd: cfg.container?.capabilities?.add,\n CapDrop: cfg.container?.capabilities?.drop,\n LogConfig: cfg.container?.logDriver\n ? { Type: cfg.container.logDriver, Config: cfg.container.logOpts || {} }\n : undefined,\n Resources: cfg.container?.resources,\n DeviceRequests: cfg.container?.gpus\n ? [\n {\n Driver: 'nvidia',\n Count:\n cfg.container.gpus === 'all'\n ? -1\n : typeof cfg.container.gpus === 'number'\n ? cfg.container.gpus\n : 1,\n DeviceIDs:\n typeof cfg.container.gpus === 'string' && cfg.container.gpus !== 'all'\n ? [String(cfg.container.gpus)]\n : undefined,\n Capabilities: [['gpu']],\n },\n ]\n : undefined,\n ...(hb ? { PortBindings: hb.PortBindings } : {}),\n },\n ...(hb ? { ExposedPorts: hb.ExposedPorts } : {}),\n ...(cfg.createOptions || {}),\n } as import('dockerode').ContainerCreateOptions;\n\n const container = await docker.createContainer(createOptions);\n await container.start(cfg.startOptions || {});\n await waitUntilRunning(container);\n\n const inspect = await container.inspect();\n const handle: DockerSandboxHandle = {\n docker,\n container,\n containerId: inspect.Id,\n image: inspect.Config?.Image ?? chosenImage.name,\n createdAt: new Date(inspect.Created || Date.now()),\n };\n\n return { sandbox: handle, sandboxId: handle.containerId };\n },\n\n getById: async (config: DockerConfig, sandboxId: string) => {\n const docker = new Docker((config || defaultDockerConfig).connection as any);\n try {\n const container = docker.getContainer(sandboxId);\n const info = await container.inspect();\n return {\n sandbox: <DockerSandboxHandle>{\n docker,\n container,\n containerId: sandboxId,\n image: info.Config?.Image ?? '',\n createdAt: new Date(info.Created || Date.now()),\n },\n sandboxId,\n };\n } catch {\n return null;\n }\n },\n\n list: async (config: DockerConfig) => {\n const docker = new Docker((config || defaultDockerConfig).connection as any);\n try {\n const items = await docker.listContainers({\n all: true,\n filters: { label: [LABEL_KEY] } as any,\n });\n return items.map(ci => ({\n sandbox: <DockerSandboxHandle>{\n docker,\n container: docker.getContainer(ci.Id),\n containerId: ci.Id,\n image: ci.Image,\n createdAt: new Date((ci as any).Created * 1000),\n },\n sandboxId: ci.Id,\n }));\n } catch {\n return [];\n }\n },\n\n destroy: async (config: DockerConfig, sandboxId: string) => {\n const docker = new Docker((config || defaultDockerConfig).connection as any);\n try {\n const c = docker.getContainer(sandboxId);\n try { await c.stop({ t: 5 } as any); } catch { /* stopped */ }\n await c.remove({ force: true });\n } catch {\n // ok if already gone\n }\n },\n\n runCommand: async (\n handle: DockerSandboxHandle,\n command: string,\n options?: RunCommandOptions\n ): Promise<CommandResult> => {\n const start = Date.now();\n\n const { stdout, stderr, exitCode } = await runExec(handle, command);\n\n return {\n stdout,\n stderr,\n exitCode,\n durationMs: Date.now() - start,\n };\n },\n\n getInfo: async (handle: DockerSandboxHandle): Promise<SandboxInfo> => {\n const info = await handle.container.inspect();\n const state = info.State || {};\n return {\n id: handle.containerId,\n provider: PROVIDER,\n runtime: (info.Config?.Labels?.[LABEL_RUNTIME] as Runtime) || 'python',\n status: state.Running ? 'running' : 'stopped',\n createdAt: new Date(info.Created || handle.createdAt),\n timeout: 300000,\n metadata: {\n image: info.Config?.Image,\n name: info.Name,\n },\n };\n },\n\n getUrl: async (handle: DockerSandboxHandle, options: { port: number; protocol?: string }): Promise<string> => {\n const info = await handle.container.inspect();\n const protocol = options.protocol || 'http';\n const portKeyTcp = `${options.port}/tcp`;\n\n const ports = info.NetworkSettings?.Ports || {};\n const bindings = ports[portKeyTcp] || ports[`${options.port}/udp`] || [];\n\n let host = dockerHostNameFromEnv();\n let hostPort = String(options.port);\n\n if (Array.isArray(bindings) && bindings.length > 0) {\n hostPort = bindings[0].HostPort || hostPort;\n } else {\n const ip =\n info.NetworkSettings?.IPAddress ||\n Object.values(info.NetworkSettings?.Networks || {})[0]?.IPAddress;\n if (ip) host = ip;\n }\n\n return `${protocol}://${host}:${hostPort}`;\n },\n\n filesystem: {\n readFile: async (handle: DockerSandboxHandle, path: string): Promise<string> => {\n const cmd = `if [ -f ${JSON.stringify(path)} ]; then base64 ${JSON.stringify(path)} | tr -d '\\\\n'; else exit 1; fi`;\n const { stdout, exitCode, stderr } = await runExec(handle, cmd);\n if (exitCode !== 0) throw new Error(stderr || `File not found: ${path}`);\n return Buffer.from(stdout, 'base64').toString('utf8');\n },\n\n writeFile: async (handle: DockerSandboxHandle, path: string, content: string): Promise<void> => {\n const b64 = Buffer.from(content, 'utf8').toString('base64');\n const cmd = `mkdir -p $(dirname ${JSON.stringify(path)}) && echo \"${b64}\" | base64 -d > ${JSON.stringify(path)}`;\n const { exitCode, stderr } = await runExec(handle, cmd);\n if (exitCode !== 0) throw new Error(stderr || `Failed to write: ${path}`);\n },\n\n mkdir: async (handle: DockerSandboxHandle, path: string): Promise<void> => {\n const { exitCode, stderr } = await runExec(handle, `mkdir -p ${JSON.stringify(path)}`);\n if (exitCode !== 0) throw new Error(stderr || `Failed to mkdir: ${path}`);\n },\n\n readdir: async (handle: DockerSandboxHandle, path: string): Promise<FileEntry[]> => {\n const { stdout, exitCode, stderr } = await runExec(\n handle,\n `if [ -d ${JSON.stringify(path)} ]; then ls -la ${JSON.stringify(path)}; else exit 1; fi`\n );\n if (exitCode !== 0) throw new Error(stderr || `Not a directory: ${path}`);\n\n const lines = stdout.split('\\n').slice(1);\n const entries: FileEntry[] = [];\n for (const line of lines) {\n const parts = line.trim().split(/\\s+/);\n if (parts.length < 9) continue;\n const name = parts.slice(8).join(' ');\n if (name === '.' || name === '..') continue;\n const isDir = parts[0].startsWith('d');\n const size = Number(parts[4]) || 0;\n entries.push({\n name,\n type: isDir ? 'directory' as const : 'file' as const,\n size,\n modified: new Date(),\n });\n }\n return entries;\n },\n\n exists: async (handle: DockerSandboxHandle, path: string): Promise<boolean> => {\n const { exitCode } = await runExec(handle, `test -e ${JSON.stringify(path)}`);\n return exitCode === 0;\n },\n\n remove: async (handle: DockerSandboxHandle, path: string): Promise<void> => {\n const { exitCode, stderr } = await runExec(handle, `rm -rf ${JSON.stringify(path)}`);\n if (exitCode !== 0) throw new Error(stderr || `Failed to remove: ${path}`);\n },\n },\n\n getInstance: (handle: DockerSandboxHandle): DockerSandboxHandle => handle,\n },\n },\n});\n","import type Docker from 'dockerode';\nimport type {\n DockerOptions,\n Container,\n ContainerCreateOptions,\n ContainerStartOptions,\n ContainerInspectInfo,\n ContainerInfo,\n Exec,\n ImageInfo,\n ImageBuildOptions,\n Network,\n} from 'dockerode';\n\nimport type {\n Runtime,\n FileEntry,\n RunCommandOptions,\n CreateSandboxOptions,\n SandboxInfo,\n} from 'computesdk';\n\n/** When the provider should clean up containers it created */\nexport type CleanupPolicy = 'always' | 'onSuccess' | 'never';\n\n/** Image pull strategy */\nexport type PullPolicy = 'always' | 'ifNotPresent' | 'never';\n\n/** Connection to the Docker daemon (exactly what dockerode accepts) */\nexport type DockerConnection = DockerOptions;\n\n/** Auth when pulling private images (Engine API AuthConfig shape) */\nexport interface RegistryAuth {\n username?: string;\n password?: string;\n serveraddress?: string;\n identitytoken?: string;\n registrytoken?: string;\n}\n\n/** Default image & pull policy for sandboxes */\nexport interface DockerImage {\n name: string; // e.g. 'python:3.11-slim'\n pullPolicy?: PullPolicy; // default: 'ifNotPresent'\n auth?: RegistryAuth;\n}\n\n/** Convenience shape for port bindings */\nexport type PortBindings = Record<\n `${number}/${'tcp' | 'udp'}`,\n Array<{ hostPort?: number; hostIP?: string }>\n>;\n\n/** Subset of HostConfig resources & knobs that are commonly used */\nexport interface ResourceLimits {\n cpuShares?: number;\n cpuQuota?: number;\n cpuPeriod?: number;\n nanoCPUs?: number;\n memory?: number;\n memorySwap?: number;\n pidsLimit?: number;\n}\n\n/** Declarative container defaults that we’ll translate into dockerode create options */\nexport interface ContainerDefaults {\n user?: string;\n workdir?: string;\n env?: Record<string, string>;\n binds?: string[];\n ports?: PortBindings;\n networkMode?: string;\n privileged?: boolean;\n capabilities?: { add?: string[]; drop?: string[] };\n gpus?: 'all' | number | string;\n resources?: ResourceLimits;\n logDriver?: string;\n logOpts?: Record<string, string>;\n autoRemove?: boolean;\n tty?: boolean;\n openStdin?: boolean;\n}\n\n/** Provider-level configuration for Docker */\nexport interface DockerConfig {\n connection?: DockerConnection;\n runtime?: Runtime; // 'python' | 'node'\n timeout?: number;\n image: DockerImage;\n container?: ContainerDefaults;\n createOptions?: ContainerCreateOptions;\n startOptions?: ContainerStartOptions;\n cleanup?: CleanupPolicy;\n streamLogs?: boolean;\n}\n\n/** What we keep for each running sandbox */\nexport interface DockerSandboxHandle {\n docker: Docker;\n container: Container;\n containerId: string;\n image: string;\n createdAt: Date;\n}\n\n/** URL options for port-forwarded services */\nexport interface DockerUrlOptions {\n port: number;\n protocol?: 'http' | 'https';\n host?: string;\n}\n\n/** Optional FS helpers you might expose */\nexport interface DockerSandboxFileSystem {\n readFile(path: string): Promise<string>;\n writeFile(path: string, content: string): Promise<void>;\n mkdir(path: string): Promise<void>;\n readdir(path: string): Promise<FileEntry[]>;\n exists(path: string): Promise<boolean>;\n remove(path: string): Promise<void>;\n}\n\n/** Sensible, safe defaults */\nexport const defaultDockerConfig: DockerConfig = {\n connection: {\n // Let dockerode fall back to DOCKER_HOST or /var/run/docker.sock\n timeout: 60_000,\n version: 'v1.43',\n },\n runtime: 'python',\n timeout: 300_000, // 5 minutes\n image: {\n name: 'python:3.11-slim',\n pullPolicy: 'ifNotPresent',\n },\n container: {\n workdir: '/workspace',\n env: {},\n autoRemove: false, // Keep container around for exec/FS/background\n tty: false, // Non-tty so we can demux stdout/stderr\n openStdin: false,\n resources: { memory: 512 * 1024 * 1024 },\n },\n cleanup: 'always',\n streamLogs: false,\n};\n\n/** Re-exports for convenience */\nexport type {\n Docker,\n Container,\n Exec,\n ContainerCreateOptions,\n ContainerStartOptions,\n ContainerInspectInfo,\n ContainerInfo,\n ImageInfo,\n ImageBuildOptions,\n Network,\n};\n"],"mappings":"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","names":["docker","Docker"]}
package/dist/index.mjs CHANGED
@@ -146,24 +146,6 @@ var docker = defineProvider({
146
146
  throw new Error(`Docker provider supports only 'python' or 'node'. Received: ${String(effectiveRuntime)}`);
147
147
  }
148
148
  const docker2 = new Docker(cfg.connection);
149
- if (options?.sandboxId) {
150
- try {
151
- const container2 = docker2.getContainer(options.sandboxId);
152
- const info = await container2.inspect();
153
- return {
154
- sandbox: {
155
- docker: docker2,
156
- container: container2,
157
- containerId: options.sandboxId,
158
- image: info.Config?.Image ?? cfg.image.name,
159
- createdAt: new Date(info.Created || Date.now())
160
- },
161
- sandboxId: options.sandboxId
162
- };
163
- } catch (err) {
164
- console.warn(`Could not reattach to Docker container with ID ${options.sandboxId}:`, err);
165
- }
166
- }
167
149
  const chosenImage = pickImageForRuntime(effectiveRuntime, cfg.image);
168
150
  await ensureImage(docker2, chosenImage);
169
151
  const mergedEnv = { ...cfg.container?.env, ...options?.envs };
@@ -273,33 +255,6 @@ var docker = defineProvider({
273
255
  } catch {
274
256
  }
275
257
  },
276
- runCode: async (handle, code, runtime) => {
277
- const start = Date.now();
278
- let rt = runtime;
279
- if (!rt) {
280
- const info = await handle.container.inspect();
281
- rt = info.Config?.Labels?.[LABEL_RUNTIME] || void 0;
282
- }
283
- if (rt !== "python" && rt !== "node") {
284
- throw new Error(`Docker runtime must be 'python' or 'node'. Pass runtime in config or as a parameter.`);
285
- }
286
- const tmpFile = rt === "python" ? "/tmp/compute_code.py" : "/tmp/compute_code.js";
287
- const b64 = Buffer.from(code, "utf8").toString("base64");
288
- const makeAndRun = `printf '%s' "${b64}" | base64 -d > ${tmpFile} && ` + (rt === "python" ? `python3 ${tmpFile}` : `node ${tmpFile}`);
289
- const { stdout, stderr, exitCode } = await runExec(handle, makeAndRun);
290
- if (exitCode !== 0 && stderr) {
291
- const isSyntax = stderr.includes("SyntaxError") || stderr.includes("invalid syntax") || stderr.includes("Unexpected token") || stderr.includes("Unexpected identifier");
292
- if (isSyntax) {
293
- const last = stderr.trim().split("\n").slice(-1)[0] || "Syntax error";
294
- throw new Error(`Syntax error: ${last}`);
295
- }
296
- }
297
- return {
298
- output: stdout + stderr,
299
- exitCode,
300
- language: rt
301
- };
302
- },
303
258
  runCommand: async (handle, command, options) => {
304
259
  const start = Date.now();
305
260
  const { stdout, stderr, exitCode } = await runExec(handle, command);
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/types/types.ts"],"sourcesContent":["import Docker from 'dockerode';\nimport { PassThrough } from 'stream';\nimport { defineProvider } from '@computesdk/provider';\nimport type {\n Runtime,\n CodeResult,\n CommandResult,\n RunCommandOptions,\n CreateSandboxOptions,\n SandboxInfo,\n FileEntry,\n} from '@computesdk/provider';\n\nimport { defaultDockerConfig } from './types/types';\nimport type {\n DockerConfig,\n DockerSandboxHandle,\n DockerImage,\n PortBindings,\n} from './types/types';\n\nconst PROVIDER = 'docker' as const;\nconst LABEL_KEY = 'com.computesdk.sandbox';\nconst LABEL_RUNTIME = 'com.computesdk.runtime';\nconst KEEPALIVE_CMD = ['/bin/sh', '-c', 'while :; do sleep 3600; done'];\n\nfunction pick<T>(val: T | undefined, fallback: T): T {\n return typeof val === 'undefined' ? fallback : val;\n}\n\nasync function ensureImage(docker: Docker, image: DockerImage): Promise<void> {\n const policy = image.pullPolicy ?? 'ifNotPresent';\n if (policy === 'never') return;\n\n const images = await docker.listImages();\n const hasImage = images.some(img => (img.RepoTags || []).includes(image.name));\n\n if (policy === 'always' || (policy === 'ifNotPresent' && !hasImage)) {\n await new Promise<void>((resolve, reject) => {\n const cb = (err: any, stream?: NodeJS.ReadableStream) => {\n if (err) return reject(err);\n if (!stream) return reject(new Error('docker.pull returned no stream'));\n (docker as any).modem.followProgress(stream, (err2: any) => (err2 ? reject(err2) : resolve()));\n };\n if (image.auth) docker.pull(image.name, { authconfig: image.auth } as any, cb);\n else docker.pull(image.name, cb);\n });\n }\n}\n\nasync function waitUntilRunning(container: Docker.Container, timeoutMs = 4000) {\n const start = Date.now();\n try {\n const s = await container.inspect();\n if (s.State?.Running) return;\n } catch { /* ignore */ }\n\n while (Date.now() - start < timeoutMs) {\n const s = await container.inspect();\n if (s.State?.Running) return;\n await new Promise(r => setTimeout(r, 100));\n }\n throw new Error('Container did not reach Running state in time');\n}\n\nasync function runExec(\n handle: DockerSandboxHandle,\n shellCommand: string,\n attachTTY = false\n): Promise<{ stdout: string; stderr: string; exitCode: number }> {\n await waitUntilRunning(handle.container);\n\n const exec = await handle.container.exec({\n Cmd: ['/bin/sh', '-c', shellCommand],\n AttachStdout: true,\n AttachStderr: true,\n Tty: attachTTY,\n });\n\n const stream = (await exec.start({ hijack: true, stdin: false })) as NodeJS.ReadableStream;\n\n let stdout = '';\n let stderr = '';\n\n await new Promise<void>((resolve, reject) => {\n if (attachTTY) {\n stream.on('data', (chunk: Buffer) => (stdout += chunk.toString('utf8')));\n stream.on('end', resolve);\n stream.on('error', reject);\n return;\n }\n const out = new PassThrough();\n const err = new PassThrough();\n out.on('data', (c: Buffer) => (stdout += c.toString('utf8')));\n err.on('data', (c: Buffer) => (stderr += c.toString('utf8')));\n (handle.docker as any).modem.demuxStream(stream as any, out as any, err as any);\n stream.on('end', resolve);\n stream.on('error', reject);\n });\n\n const inspect = await exec.inspect();\n const exitCode = inspect.ExitCode ?? 0;\n return { stdout, stderr, exitCode };\n}\n\nfunction toHostBindings(ports?: PortBindings) {\n if (!ports) return undefined;\n const exposed: Record<string, {}> = {};\n const bindings: Record<string, Array<{ HostPort?: string; HostIp?: string }>> = {};\n for (const key of Object.keys(ports)) {\n exposed[key] = {};\n bindings[key] = (ports as any)[key].map((p: any) => ({\n HostPort: p.hostPort ? String(p.hostPort) : undefined,\n HostIp: p.hostIP,\n }));\n }\n return { ExposedPorts: exposed, PortBindings: bindings };\n}\n\nfunction dockerHostNameFromEnv(): string {\n const hostEnv = process.env.DOCKER_HOST;\n if (hostEnv?.startsWith('tcp://')) {\n try {\n const u = new URL(hostEnv);\n return u.hostname || 'localhost';\n } catch { /* noop */ }\n }\n return 'localhost';\n}\n\nfunction pickImageForRuntime(runtime: Runtime, configured?: DockerImage): DockerImage {\n // If user supplied an image that already matches, use it. Otherwise pick a sensible default.\n if (configured?.name) {\n if (runtime === 'python' && /python|conda|pypy/i.test(configured.name)) return configured;\n if (runtime === 'node' && /node/i.test(configured.name)) return configured;\n }\n return {\n name: runtime === 'python' ? 'python:3.11-slim' : 'node:20-alpine',\n pullPolicy: configured?.pullPolicy ?? 'ifNotPresent',\n auth: configured?.auth,\n };\n}\n\nexport const docker = defineProvider<DockerSandboxHandle, DockerConfig>({\n name: PROVIDER,\n methods: {\n sandbox: {\n create: async (config: DockerConfig, options?: CreateSandboxOptions) => {\n const cfg: DockerConfig = { ...defaultDockerConfig, ...config };\n const effectiveRuntime: Runtime = (options?.runtime ?? cfg.runtime ?? 'python') as Runtime;\n\n if (effectiveRuntime !== 'python' && effectiveRuntime !== 'node') {\n throw new Error(`Docker provider supports only 'python' or 'node'. Received: ${String(effectiveRuntime)}`);\n }\n\n const docker = new Docker(cfg.connection as any);\n\n // Reattach?\n if (options?.sandboxId) {\n try {\n const container = docker.getContainer(options.sandboxId);\n const info = await container.inspect();\n return {\n sandbox: <DockerSandboxHandle>{\n docker,\n container,\n containerId: options.sandboxId,\n image: info.Config?.Image ?? cfg.image.name,\n createdAt: new Date(info.Created || Date.now()),\n },\n sandboxId: options.sandboxId,\n };\n } catch (err) {\n // Failed to reattach to existing container; will create a new one.\n console.warn(`Could not reattach to Docker container with ID ${options.sandboxId}:`, err);\n }\n }\n\n // Choose image based on runtime if needed\n const chosenImage = pickImageForRuntime(effectiveRuntime, cfg.image);\n await ensureImage(docker, chosenImage);\n\n // Merge environment variables: config.container.env < options.envs\n const mergedEnv = { ...cfg.container?.env, ...options?.envs };\n\n // Build container create options\n const hb = toHostBindings(cfg.container?.ports);\n const createOptions = {\n Image: chosenImage.name,\n Tty: pick(cfg.container?.tty, false),\n OpenStdin: pick(cfg.container?.openStdin, false),\n Labels: {\n // User metadata is spread first with a namespaced prefix so it\n // cannot overwrite the reserved discovery/runtime labels below.\n ...(options?.metadata ? Object.fromEntries(\n Object.entries(options.metadata).map(([k, v]) => [`com.computesdk.meta.${k}`, typeof v === 'string' ? v : JSON.stringify(v)])\n ) : {}),\n [LABEL_KEY]: 'true',\n [LABEL_RUNTIME]: effectiveRuntime,\n },\n WorkingDir: cfg.container?.workdir,\n Env: Object.keys(mergedEnv).length > 0\n ? Object.entries(mergedEnv).map(([k, v]) => `${k}=${v}`)\n : undefined,\n Cmd: KEEPALIVE_CMD, // keep container alive\n HostConfig: {\n AutoRemove: cfg.container?.autoRemove ?? false, // keep around for exec/FS ops\n Binds: cfg.container?.binds,\n NetworkMode: cfg.container?.networkMode,\n Privileged: cfg.container?.privileged,\n CapAdd: cfg.container?.capabilities?.add,\n CapDrop: cfg.container?.capabilities?.drop,\n LogConfig: cfg.container?.logDriver\n ? { Type: cfg.container.logDriver, Config: cfg.container.logOpts || {} }\n : undefined,\n Resources: cfg.container?.resources,\n DeviceRequests: cfg.container?.gpus\n ? [\n {\n Driver: 'nvidia',\n Count:\n cfg.container.gpus === 'all'\n ? -1\n : typeof cfg.container.gpus === 'number'\n ? cfg.container.gpus\n : 1,\n DeviceIDs:\n typeof cfg.container.gpus === 'string' && cfg.container.gpus !== 'all'\n ? [String(cfg.container.gpus)]\n : undefined,\n Capabilities: [['gpu']],\n },\n ]\n : undefined,\n ...(hb ? { PortBindings: hb.PortBindings } : {}),\n },\n ...(hb ? { ExposedPorts: hb.ExposedPorts } : {}),\n ...(cfg.createOptions || {}),\n } as import('dockerode').ContainerCreateOptions;\n\n const container = await docker.createContainer(createOptions);\n await container.start(cfg.startOptions || {});\n await waitUntilRunning(container);\n\n const inspect = await container.inspect();\n const handle: DockerSandboxHandle = {\n docker,\n container,\n containerId: inspect.Id,\n image: inspect.Config?.Image ?? chosenImage.name,\n createdAt: new Date(inspect.Created || Date.now()),\n };\n\n return { sandbox: handle, sandboxId: handle.containerId };\n },\n\n getById: async (config: DockerConfig, sandboxId: string) => {\n const docker = new Docker((config || defaultDockerConfig).connection as any);\n try {\n const container = docker.getContainer(sandboxId);\n const info = await container.inspect();\n return {\n sandbox: <DockerSandboxHandle>{\n docker,\n container,\n containerId: sandboxId,\n image: info.Config?.Image ?? '',\n createdAt: new Date(info.Created || Date.now()),\n },\n sandboxId,\n };\n } catch {\n return null;\n }\n },\n\n list: async (config: DockerConfig) => {\n const docker = new Docker((config || defaultDockerConfig).connection as any);\n try {\n const items = await docker.listContainers({\n all: true,\n filters: { label: [LABEL_KEY] } as any,\n });\n return items.map(ci => ({\n sandbox: <DockerSandboxHandle>{\n docker,\n container: docker.getContainer(ci.Id),\n containerId: ci.Id,\n image: ci.Image,\n createdAt: new Date((ci as any).Created * 1000),\n },\n sandboxId: ci.Id,\n }));\n } catch {\n return [];\n }\n },\n\n destroy: async (config: DockerConfig, sandboxId: string) => {\n const docker = new Docker((config || defaultDockerConfig).connection as any);\n try {\n const c = docker.getContainer(sandboxId);\n try { await c.stop({ t: 5 } as any); } catch { /* stopped */ }\n await c.remove({ force: true });\n } catch {\n // ok if already gone\n }\n },\n\n runCode: async (handle: DockerSandboxHandle, code: string, runtime?: Runtime): Promise<CodeResult> => {\n const start = Date.now();\n\n // Resolve runtime: param → label → error\n let rt: Runtime | undefined = runtime;\n if (!rt) {\n const info = await handle.container.inspect();\n rt = (info.Config?.Labels?.[LABEL_RUNTIME] as Runtime) || undefined;\n }\n if (rt !== 'python' && rt !== 'node') {\n throw new Error(`Docker runtime must be 'python' or 'node'. Pass runtime in config or as a parameter.`);\n }\n\n // Write to file, then execute. This is robust on Alpine/Debian.\n const tmpFile = rt === 'python' ? '/tmp/compute_code.py' : '/tmp/compute_code.js';\n const b64 = Buffer.from(code, 'utf8').toString('base64');\n const makeAndRun =\n `printf '%s' \"${b64}\" | base64 -d > ${tmpFile} && ` +\n (rt === 'python' ? `python3 ${tmpFile}` : `node ${tmpFile}`);\n\n const { stdout, stderr, exitCode } = await runExec(handle, makeAndRun);\n\n if (exitCode !== 0 && stderr) {\n // Throw ONLY on syntax errors (SDK contract)\n const isSyntax =\n stderr.includes('SyntaxError') ||\n stderr.includes('invalid syntax') ||\n stderr.includes('Unexpected token') ||\n stderr.includes('Unexpected identifier');\n if (isSyntax) {\n const last = stderr.trim().split('\\n').slice(-1)[0] || 'Syntax error';\n throw new Error(`Syntax error: ${last}`);\n }\n }\n\n return {\n output: stdout + stderr,\n exitCode,\n language: rt,\n };\n },\n\n runCommand: async (\n handle: DockerSandboxHandle,\n command: string,\n options?: RunCommandOptions\n ): Promise<CommandResult> => {\n const start = Date.now();\n\n const { stdout, stderr, exitCode } = await runExec(handle, command);\n\n return {\n stdout,\n stderr,\n exitCode,\n durationMs: Date.now() - start,\n };\n },\n\n getInfo: async (handle: DockerSandboxHandle): Promise<SandboxInfo> => {\n const info = await handle.container.inspect();\n const state = info.State || {};\n return {\n id: handle.containerId,\n provider: PROVIDER,\n runtime: (info.Config?.Labels?.[LABEL_RUNTIME] as Runtime) || 'python',\n status: state.Running ? 'running' : 'stopped',\n createdAt: new Date(info.Created || handle.createdAt),\n timeout: 300000,\n metadata: {\n image: info.Config?.Image,\n name: info.Name,\n },\n };\n },\n\n getUrl: async (handle: DockerSandboxHandle, options: { port: number; protocol?: string }): Promise<string> => {\n const info = await handle.container.inspect();\n const protocol = options.protocol || 'http';\n const portKeyTcp = `${options.port}/tcp`;\n\n const ports = info.NetworkSettings?.Ports || {};\n const bindings = ports[portKeyTcp] || ports[`${options.port}/udp`] || [];\n\n let host = dockerHostNameFromEnv();\n let hostPort = String(options.port);\n\n if (Array.isArray(bindings) && bindings.length > 0) {\n hostPort = bindings[0].HostPort || hostPort;\n } else {\n const ip =\n info.NetworkSettings?.IPAddress ||\n Object.values(info.NetworkSettings?.Networks || {})[0]?.IPAddress;\n if (ip) host = ip;\n }\n\n return `${protocol}://${host}:${hostPort}`;\n },\n\n filesystem: {\n readFile: async (handle: DockerSandboxHandle, path: string): Promise<string> => {\n const cmd = `if [ -f ${JSON.stringify(path)} ]; then base64 ${JSON.stringify(path)} | tr -d '\\\\n'; else exit 1; fi`;\n const { stdout, exitCode, stderr } = await runExec(handle, cmd);\n if (exitCode !== 0) throw new Error(stderr || `File not found: ${path}`);\n return Buffer.from(stdout, 'base64').toString('utf8');\n },\n\n writeFile: async (handle: DockerSandboxHandle, path: string, content: string): Promise<void> => {\n const b64 = Buffer.from(content, 'utf8').toString('base64');\n const cmd = `mkdir -p $(dirname ${JSON.stringify(path)}) && echo \"${b64}\" | base64 -d > ${JSON.stringify(path)}`;\n const { exitCode, stderr } = await runExec(handle, cmd);\n if (exitCode !== 0) throw new Error(stderr || `Failed to write: ${path}`);\n },\n\n mkdir: async (handle: DockerSandboxHandle, path: string): Promise<void> => {\n const { exitCode, stderr } = await runExec(handle, `mkdir -p ${JSON.stringify(path)}`);\n if (exitCode !== 0) throw new Error(stderr || `Failed to mkdir: ${path}`);\n },\n\n readdir: async (handle: DockerSandboxHandle, path: string): Promise<FileEntry[]> => {\n const { stdout, exitCode, stderr } = await runExec(\n handle,\n `if [ -d ${JSON.stringify(path)} ]; then ls -la ${JSON.stringify(path)}; else exit 1; fi`\n );\n if (exitCode !== 0) throw new Error(stderr || `Not a directory: ${path}`);\n\n const lines = stdout.split('\\n').slice(1);\n const entries: FileEntry[] = [];\n for (const line of lines) {\n const parts = line.trim().split(/\\s+/);\n if (parts.length < 9) continue;\n const name = parts.slice(8).join(' ');\n if (name === '.' || name === '..') continue;\n const isDir = parts[0].startsWith('d');\n const size = Number(parts[4]) || 0;\n entries.push({\n name,\n type: isDir ? 'directory' as const : 'file' as const,\n size,\n modified: new Date(),\n });\n }\n return entries;\n },\n\n exists: async (handle: DockerSandboxHandle, path: string): Promise<boolean> => {\n const { exitCode } = await runExec(handle, `test -e ${JSON.stringify(path)}`);\n return exitCode === 0;\n },\n\n remove: async (handle: DockerSandboxHandle, path: string): Promise<void> => {\n const { exitCode, stderr } = await runExec(handle, `rm -rf ${JSON.stringify(path)}`);\n if (exitCode !== 0) throw new Error(stderr || `Failed to remove: ${path}`);\n },\n },\n\n getInstance: (handle: DockerSandboxHandle): DockerSandboxHandle => handle,\n },\n },\n});\n\n","import type Docker from 'dockerode';\nimport type {\n DockerOptions,\n Container,\n ContainerCreateOptions,\n ContainerStartOptions,\n ContainerInspectInfo,\n ContainerInfo,\n Exec,\n ImageInfo,\n ImageBuildOptions,\n Network,\n} from 'dockerode';\n\nimport type {\n Runtime,\n FileEntry,\n RunCommandOptions,\n CreateSandboxOptions,\n SandboxInfo,\n} from 'computesdk';\n\n/** When the provider should clean up containers it created */\nexport type CleanupPolicy = 'always' | 'onSuccess' | 'never';\n\n/** Image pull strategy */\nexport type PullPolicy = 'always' | 'ifNotPresent' | 'never';\n\n/** Connection to the Docker daemon (exactly what dockerode accepts) */\nexport type DockerConnection = DockerOptions;\n\n/** Auth when pulling private images (Engine API AuthConfig shape) */\nexport interface RegistryAuth {\n username?: string;\n password?: string;\n serveraddress?: string;\n identitytoken?: string;\n registrytoken?: string;\n}\n\n/** Default image & pull policy for sandboxes */\nexport interface DockerImage {\n name: string; // e.g. 'python:3.11-slim'\n pullPolicy?: PullPolicy; // default: 'ifNotPresent'\n auth?: RegistryAuth;\n}\n\n/** Convenience shape for port bindings */\nexport type PortBindings = Record<\n `${number}/${'tcp' | 'udp'}`,\n Array<{ hostPort?: number; hostIP?: string }>\n>;\n\n/** Subset of HostConfig resources & knobs that are commonly used */\nexport interface ResourceLimits {\n cpuShares?: number;\n cpuQuota?: number;\n cpuPeriod?: number;\n nanoCPUs?: number;\n memory?: number;\n memorySwap?: number;\n pidsLimit?: number;\n}\n\n/** Declarative container defaults that we’ll translate into dockerode create options */\nexport interface ContainerDefaults {\n user?: string;\n workdir?: string;\n env?: Record<string, string>;\n binds?: string[];\n ports?: PortBindings;\n networkMode?: string;\n privileged?: boolean;\n capabilities?: { add?: string[]; drop?: string[] };\n gpus?: 'all' | number | string;\n resources?: ResourceLimits;\n logDriver?: string;\n logOpts?: Record<string, string>;\n autoRemove?: boolean;\n tty?: boolean;\n openStdin?: boolean;\n}\n\n/** Provider-level configuration for Docker */\nexport interface DockerConfig {\n connection?: DockerConnection;\n runtime?: Runtime; // 'python' | 'node'\n timeout?: number;\n image: DockerImage;\n container?: ContainerDefaults;\n createOptions?: ContainerCreateOptions;\n startOptions?: ContainerStartOptions;\n cleanup?: CleanupPolicy;\n streamLogs?: boolean;\n}\n\n/** What we keep for each running sandbox */\nexport interface DockerSandboxHandle {\n docker: Docker;\n container: Container;\n containerId: string;\n image: string;\n createdAt: Date;\n}\n\n/** URL options for port-forwarded services */\nexport interface DockerUrlOptions {\n port: number;\n protocol?: 'http' | 'https';\n host?: string;\n}\n\n/** Optional FS helpers you might expose */\nexport interface DockerSandboxFileSystem {\n readFile(path: string): Promise<string>;\n writeFile(path: string, content: string): Promise<void>;\n mkdir(path: string): Promise<void>;\n readdir(path: string): Promise<FileEntry[]>;\n exists(path: string): Promise<boolean>;\n remove(path: string): Promise<void>;\n}\n\n/** Sensible, safe defaults */\nexport const defaultDockerConfig: DockerConfig = {\n connection: {\n // Let dockerode fall back to DOCKER_HOST or /var/run/docker.sock\n timeout: 60_000,\n version: 'v1.43',\n },\n runtime: 'python',\n timeout: 300_000, // 5 minutes\n image: {\n name: 'python:3.11-slim',\n pullPolicy: 'ifNotPresent',\n },\n container: {\n workdir: '/workspace',\n env: {},\n autoRemove: false, // Keep container around for exec/FS/background\n tty: false, // Non-tty so we can demux stdout/stderr\n openStdin: false,\n resources: { memory: 512 * 1024 * 1024 },\n },\n cleanup: 'always',\n streamLogs: false,\n};\n\n/** Re-exports for convenience */\nexport type {\n Docker,\n Container,\n Exec,\n ContainerCreateOptions,\n ContainerStartOptions,\n ContainerInspectInfo,\n ContainerInfo,\n ImageInfo,\n ImageBuildOptions,\n Network,\n};\n"],"mappings":"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","names":["docker","container"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/types/types.ts"],"sourcesContent":["import Docker from 'dockerode';\nimport { PassThrough } from 'stream';\nimport { defineProvider } from '@computesdk/provider';\nimport type {\n Runtime,\n CodeResult,\n CommandResult,\n RunCommandOptions,\n CreateSandboxOptions,\n SandboxInfo,\n FileEntry,\n} from '@computesdk/provider';\n\nimport { defaultDockerConfig } from './types/types';\nimport type {\n DockerConfig,\n DockerSandboxHandle,\n DockerImage,\n PortBindings,\n} from './types/types';\n\nconst PROVIDER = 'docker' as const;\nconst LABEL_KEY = 'com.computesdk.sandbox';\nconst LABEL_RUNTIME = 'com.computesdk.runtime';\nconst KEEPALIVE_CMD = ['/bin/sh', '-c', 'while :; do sleep 3600; done'];\n\nfunction pick<T>(val: T | undefined, fallback: T): T {\n return typeof val === 'undefined' ? fallback : val;\n}\n\nasync function ensureImage(docker: Docker, image: DockerImage): Promise<void> {\n const policy = image.pullPolicy ?? 'ifNotPresent';\n if (policy === 'never') return;\n\n const images = await docker.listImages();\n const hasImage = images.some(img => (img.RepoTags || []).includes(image.name));\n\n if (policy === 'always' || (policy === 'ifNotPresent' && !hasImage)) {\n await new Promise<void>((resolve, reject) => {\n const cb = (err: any, stream?: NodeJS.ReadableStream) => {\n if (err) return reject(err);\n if (!stream) return reject(new Error('docker.pull returned no stream'));\n (docker as any).modem.followProgress(stream, (err2: any) => (err2 ? reject(err2) : resolve()));\n };\n if (image.auth) docker.pull(image.name, { authconfig: image.auth } as any, cb);\n else docker.pull(image.name, cb);\n });\n }\n}\n\nasync function waitUntilRunning(container: Docker.Container, timeoutMs = 4000) {\n const start = Date.now();\n try {\n const s = await container.inspect();\n if (s.State?.Running) return;\n } catch { /* ignore */ }\n\n while (Date.now() - start < timeoutMs) {\n const s = await container.inspect();\n if (s.State?.Running) return;\n await new Promise(r => setTimeout(r, 100));\n }\n throw new Error('Container did not reach Running state in time');\n}\n\nasync function runExec(\n handle: DockerSandboxHandle,\n shellCommand: string,\n attachTTY = false\n): Promise<{ stdout: string; stderr: string; exitCode: number }> {\n await waitUntilRunning(handle.container);\n\n const exec = await handle.container.exec({\n Cmd: ['/bin/sh', '-c', shellCommand],\n AttachStdout: true,\n AttachStderr: true,\n Tty: attachTTY,\n });\n\n const stream = (await exec.start({ hijack: true, stdin: false })) as NodeJS.ReadableStream;\n\n let stdout = '';\n let stderr = '';\n\n await new Promise<void>((resolve, reject) => {\n if (attachTTY) {\n stream.on('data', (chunk: Buffer) => (stdout += chunk.toString('utf8')));\n stream.on('end', resolve);\n stream.on('error', reject);\n return;\n }\n const out = new PassThrough();\n const err = new PassThrough();\n out.on('data', (c: Buffer) => (stdout += c.toString('utf8')));\n err.on('data', (c: Buffer) => (stderr += c.toString('utf8')));\n (handle.docker as any).modem.demuxStream(stream as any, out as any, err as any);\n stream.on('end', resolve);\n stream.on('error', reject);\n });\n\n const inspect = await exec.inspect();\n const exitCode = inspect.ExitCode ?? 0;\n return { stdout, stderr, exitCode };\n}\n\nfunction toHostBindings(ports?: PortBindings) {\n if (!ports) return undefined;\n const exposed: Record<string, {}> = {};\n const bindings: Record<string, Array<{ HostPort?: string; HostIp?: string }>> = {};\n for (const key of Object.keys(ports)) {\n exposed[key] = {};\n bindings[key] = (ports as any)[key].map((p: any) => ({\n HostPort: p.hostPort ? String(p.hostPort) : undefined,\n HostIp: p.hostIP,\n }));\n }\n return { ExposedPorts: exposed, PortBindings: bindings };\n}\n\nfunction dockerHostNameFromEnv(): string {\n const hostEnv = process.env.DOCKER_HOST;\n if (hostEnv?.startsWith('tcp://')) {\n try {\n const u = new URL(hostEnv);\n return u.hostname || 'localhost';\n } catch { /* noop */ }\n }\n return 'localhost';\n}\n\nfunction pickImageForRuntime(runtime: Runtime, configured?: DockerImage): DockerImage {\n // If user supplied an image that already matches, use it. Otherwise pick a sensible default.\n if (configured?.name) {\n if (runtime === 'python' && /python|conda|pypy/i.test(configured.name)) return configured;\n if (runtime === 'node' && /node/i.test(configured.name)) return configured;\n }\n return {\n name: runtime === 'python' ? 'python:3.11-slim' : 'node:20-alpine',\n pullPolicy: configured?.pullPolicy ?? 'ifNotPresent',\n auth: configured?.auth,\n };\n}\n\nexport const docker = defineProvider<DockerSandboxHandle, DockerConfig>({\n name: PROVIDER,\n methods: {\n sandbox: {\n create: async (config: DockerConfig, options?: CreateSandboxOptions) => {\n const cfg: DockerConfig = { ...defaultDockerConfig, ...config };\n const effectiveRuntime: Runtime = (options?.runtime ?? cfg.runtime ?? 'python') as Runtime;\n\n if (effectiveRuntime !== 'python' && effectiveRuntime !== 'node') {\n throw new Error(`Docker provider supports only 'python' or 'node'. Received: ${String(effectiveRuntime)}`);\n }\n\n const docker = new Docker(cfg.connection as any);\n\n // Choose image based on runtime if needed\n const chosenImage = pickImageForRuntime(effectiveRuntime, cfg.image);\n await ensureImage(docker, chosenImage);\n\n // Merge environment variables: config.container.env < options.envs\n const mergedEnv = { ...cfg.container?.env, ...options?.envs };\n\n // Build container create options\n const hb = toHostBindings(cfg.container?.ports);\n const createOptions = {\n Image: chosenImage.name,\n Tty: pick(cfg.container?.tty, false),\n OpenStdin: pick(cfg.container?.openStdin, false),\n Labels: {\n // User metadata is spread first with a namespaced prefix so it\n // cannot overwrite the reserved discovery/runtime labels below.\n ...(options?.metadata ? Object.fromEntries(\n Object.entries(options.metadata).map(([k, v]) => [`com.computesdk.meta.${k}`, typeof v === 'string' ? v : JSON.stringify(v)])\n ) : {}),\n [LABEL_KEY]: 'true',\n [LABEL_RUNTIME]: effectiveRuntime,\n },\n WorkingDir: cfg.container?.workdir,\n Env: Object.keys(mergedEnv).length > 0\n ? Object.entries(mergedEnv).map(([k, v]) => `${k}=${v}`)\n : undefined,\n Cmd: KEEPALIVE_CMD, // keep container alive\n HostConfig: {\n AutoRemove: cfg.container?.autoRemove ?? false, // keep around for exec/FS ops\n Binds: cfg.container?.binds,\n NetworkMode: cfg.container?.networkMode,\n Privileged: cfg.container?.privileged,\n CapAdd: cfg.container?.capabilities?.add,\n CapDrop: cfg.container?.capabilities?.drop,\n LogConfig: cfg.container?.logDriver\n ? { Type: cfg.container.logDriver, Config: cfg.container.logOpts || {} }\n : undefined,\n Resources: cfg.container?.resources,\n DeviceRequests: cfg.container?.gpus\n ? [\n {\n Driver: 'nvidia',\n Count:\n cfg.container.gpus === 'all'\n ? -1\n : typeof cfg.container.gpus === 'number'\n ? cfg.container.gpus\n : 1,\n DeviceIDs:\n typeof cfg.container.gpus === 'string' && cfg.container.gpus !== 'all'\n ? [String(cfg.container.gpus)]\n : undefined,\n Capabilities: [['gpu']],\n },\n ]\n : undefined,\n ...(hb ? { PortBindings: hb.PortBindings } : {}),\n },\n ...(hb ? { ExposedPorts: hb.ExposedPorts } : {}),\n ...(cfg.createOptions || {}),\n } as import('dockerode').ContainerCreateOptions;\n\n const container = await docker.createContainer(createOptions);\n await container.start(cfg.startOptions || {});\n await waitUntilRunning(container);\n\n const inspect = await container.inspect();\n const handle: DockerSandboxHandle = {\n docker,\n container,\n containerId: inspect.Id,\n image: inspect.Config?.Image ?? chosenImage.name,\n createdAt: new Date(inspect.Created || Date.now()),\n };\n\n return { sandbox: handle, sandboxId: handle.containerId };\n },\n\n getById: async (config: DockerConfig, sandboxId: string) => {\n const docker = new Docker((config || defaultDockerConfig).connection as any);\n try {\n const container = docker.getContainer(sandboxId);\n const info = await container.inspect();\n return {\n sandbox: <DockerSandboxHandle>{\n docker,\n container,\n containerId: sandboxId,\n image: info.Config?.Image ?? '',\n createdAt: new Date(info.Created || Date.now()),\n },\n sandboxId,\n };\n } catch {\n return null;\n }\n },\n\n list: async (config: DockerConfig) => {\n const docker = new Docker((config || defaultDockerConfig).connection as any);\n try {\n const items = await docker.listContainers({\n all: true,\n filters: { label: [LABEL_KEY] } as any,\n });\n return items.map(ci => ({\n sandbox: <DockerSandboxHandle>{\n docker,\n container: docker.getContainer(ci.Id),\n containerId: ci.Id,\n image: ci.Image,\n createdAt: new Date((ci as any).Created * 1000),\n },\n sandboxId: ci.Id,\n }));\n } catch {\n return [];\n }\n },\n\n destroy: async (config: DockerConfig, sandboxId: string) => {\n const docker = new Docker((config || defaultDockerConfig).connection as any);\n try {\n const c = docker.getContainer(sandboxId);\n try { await c.stop({ t: 5 } as any); } catch { /* stopped */ }\n await c.remove({ force: true });\n } catch {\n // ok if already gone\n }\n },\n\n runCommand: async (\n handle: DockerSandboxHandle,\n command: string,\n options?: RunCommandOptions\n ): Promise<CommandResult> => {\n const start = Date.now();\n\n const { stdout, stderr, exitCode } = await runExec(handle, command);\n\n return {\n stdout,\n stderr,\n exitCode,\n durationMs: Date.now() - start,\n };\n },\n\n getInfo: async (handle: DockerSandboxHandle): Promise<SandboxInfo> => {\n const info = await handle.container.inspect();\n const state = info.State || {};\n return {\n id: handle.containerId,\n provider: PROVIDER,\n runtime: (info.Config?.Labels?.[LABEL_RUNTIME] as Runtime) || 'python',\n status: state.Running ? 'running' : 'stopped',\n createdAt: new Date(info.Created || handle.createdAt),\n timeout: 300000,\n metadata: {\n image: info.Config?.Image,\n name: info.Name,\n },\n };\n },\n\n getUrl: async (handle: DockerSandboxHandle, options: { port: number; protocol?: string }): Promise<string> => {\n const info = await handle.container.inspect();\n const protocol = options.protocol || 'http';\n const portKeyTcp = `${options.port}/tcp`;\n\n const ports = info.NetworkSettings?.Ports || {};\n const bindings = ports[portKeyTcp] || ports[`${options.port}/udp`] || [];\n\n let host = dockerHostNameFromEnv();\n let hostPort = String(options.port);\n\n if (Array.isArray(bindings) && bindings.length > 0) {\n hostPort = bindings[0].HostPort || hostPort;\n } else {\n const ip =\n info.NetworkSettings?.IPAddress ||\n Object.values(info.NetworkSettings?.Networks || {})[0]?.IPAddress;\n if (ip) host = ip;\n }\n\n return `${protocol}://${host}:${hostPort}`;\n },\n\n filesystem: {\n readFile: async (handle: DockerSandboxHandle, path: string): Promise<string> => {\n const cmd = `if [ -f ${JSON.stringify(path)} ]; then base64 ${JSON.stringify(path)} | tr -d '\\\\n'; else exit 1; fi`;\n const { stdout, exitCode, stderr } = await runExec(handle, cmd);\n if (exitCode !== 0) throw new Error(stderr || `File not found: ${path}`);\n return Buffer.from(stdout, 'base64').toString('utf8');\n },\n\n writeFile: async (handle: DockerSandboxHandle, path: string, content: string): Promise<void> => {\n const b64 = Buffer.from(content, 'utf8').toString('base64');\n const cmd = `mkdir -p $(dirname ${JSON.stringify(path)}) && echo \"${b64}\" | base64 -d > ${JSON.stringify(path)}`;\n const { exitCode, stderr } = await runExec(handle, cmd);\n if (exitCode !== 0) throw new Error(stderr || `Failed to write: ${path}`);\n },\n\n mkdir: async (handle: DockerSandboxHandle, path: string): Promise<void> => {\n const { exitCode, stderr } = await runExec(handle, `mkdir -p ${JSON.stringify(path)}`);\n if (exitCode !== 0) throw new Error(stderr || `Failed to mkdir: ${path}`);\n },\n\n readdir: async (handle: DockerSandboxHandle, path: string): Promise<FileEntry[]> => {\n const { stdout, exitCode, stderr } = await runExec(\n handle,\n `if [ -d ${JSON.stringify(path)} ]; then ls -la ${JSON.stringify(path)}; else exit 1; fi`\n );\n if (exitCode !== 0) throw new Error(stderr || `Not a directory: ${path}`);\n\n const lines = stdout.split('\\n').slice(1);\n const entries: FileEntry[] = [];\n for (const line of lines) {\n const parts = line.trim().split(/\\s+/);\n if (parts.length < 9) continue;\n const name = parts.slice(8).join(' ');\n if (name === '.' || name === '..') continue;\n const isDir = parts[0].startsWith('d');\n const size = Number(parts[4]) || 0;\n entries.push({\n name,\n type: isDir ? 'directory' as const : 'file' as const,\n size,\n modified: new Date(),\n });\n }\n return entries;\n },\n\n exists: async (handle: DockerSandboxHandle, path: string): Promise<boolean> => {\n const { exitCode } = await runExec(handle, `test -e ${JSON.stringify(path)}`);\n return exitCode === 0;\n },\n\n remove: async (handle: DockerSandboxHandle, path: string): Promise<void> => {\n const { exitCode, stderr } = await runExec(handle, `rm -rf ${JSON.stringify(path)}`);\n if (exitCode !== 0) throw new Error(stderr || `Failed to remove: ${path}`);\n },\n },\n\n getInstance: (handle: DockerSandboxHandle): DockerSandboxHandle => handle,\n },\n },\n});\n","import type Docker from 'dockerode';\nimport type {\n DockerOptions,\n Container,\n ContainerCreateOptions,\n ContainerStartOptions,\n ContainerInspectInfo,\n ContainerInfo,\n Exec,\n ImageInfo,\n ImageBuildOptions,\n Network,\n} from 'dockerode';\n\nimport type {\n Runtime,\n FileEntry,\n RunCommandOptions,\n CreateSandboxOptions,\n SandboxInfo,\n} from 'computesdk';\n\n/** When the provider should clean up containers it created */\nexport type CleanupPolicy = 'always' | 'onSuccess' | 'never';\n\n/** Image pull strategy */\nexport type PullPolicy = 'always' | 'ifNotPresent' | 'never';\n\n/** Connection to the Docker daemon (exactly what dockerode accepts) */\nexport type DockerConnection = DockerOptions;\n\n/** Auth when pulling private images (Engine API AuthConfig shape) */\nexport interface RegistryAuth {\n username?: string;\n password?: string;\n serveraddress?: string;\n identitytoken?: string;\n registrytoken?: string;\n}\n\n/** Default image & pull policy for sandboxes */\nexport interface DockerImage {\n name: string; // e.g. 'python:3.11-slim'\n pullPolicy?: PullPolicy; // default: 'ifNotPresent'\n auth?: RegistryAuth;\n}\n\n/** Convenience shape for port bindings */\nexport type PortBindings = Record<\n `${number}/${'tcp' | 'udp'}`,\n Array<{ hostPort?: number; hostIP?: string }>\n>;\n\n/** Subset of HostConfig resources & knobs that are commonly used */\nexport interface ResourceLimits {\n cpuShares?: number;\n cpuQuota?: number;\n cpuPeriod?: number;\n nanoCPUs?: number;\n memory?: number;\n memorySwap?: number;\n pidsLimit?: number;\n}\n\n/** Declarative container defaults that we’ll translate into dockerode create options */\nexport interface ContainerDefaults {\n user?: string;\n workdir?: string;\n env?: Record<string, string>;\n binds?: string[];\n ports?: PortBindings;\n networkMode?: string;\n privileged?: boolean;\n capabilities?: { add?: string[]; drop?: string[] };\n gpus?: 'all' | number | string;\n resources?: ResourceLimits;\n logDriver?: string;\n logOpts?: Record<string, string>;\n autoRemove?: boolean;\n tty?: boolean;\n openStdin?: boolean;\n}\n\n/** Provider-level configuration for Docker */\nexport interface DockerConfig {\n connection?: DockerConnection;\n runtime?: Runtime; // 'python' | 'node'\n timeout?: number;\n image: DockerImage;\n container?: ContainerDefaults;\n createOptions?: ContainerCreateOptions;\n startOptions?: ContainerStartOptions;\n cleanup?: CleanupPolicy;\n streamLogs?: boolean;\n}\n\n/** What we keep for each running sandbox */\nexport interface DockerSandboxHandle {\n docker: Docker;\n container: Container;\n containerId: string;\n image: string;\n createdAt: Date;\n}\n\n/** URL options for port-forwarded services */\nexport interface DockerUrlOptions {\n port: number;\n protocol?: 'http' | 'https';\n host?: string;\n}\n\n/** Optional FS helpers you might expose */\nexport interface DockerSandboxFileSystem {\n readFile(path: string): Promise<string>;\n writeFile(path: string, content: string): Promise<void>;\n mkdir(path: string): Promise<void>;\n readdir(path: string): Promise<FileEntry[]>;\n exists(path: string): Promise<boolean>;\n remove(path: string): Promise<void>;\n}\n\n/** Sensible, safe defaults */\nexport const defaultDockerConfig: DockerConfig = {\n connection: {\n // Let dockerode fall back to DOCKER_HOST or /var/run/docker.sock\n timeout: 60_000,\n version: 'v1.43',\n },\n runtime: 'python',\n timeout: 300_000, // 5 minutes\n image: {\n name: 'python:3.11-slim',\n pullPolicy: 'ifNotPresent',\n },\n container: {\n workdir: '/workspace',\n env: {},\n autoRemove: false, // Keep container around for exec/FS/background\n tty: false, // Non-tty so we can demux stdout/stderr\n openStdin: false,\n resources: { memory: 512 * 1024 * 1024 },\n },\n cleanup: 'always',\n streamLogs: false,\n};\n\n/** Re-exports for convenience */\nexport type {\n Docker,\n Container,\n Exec,\n ContainerCreateOptions,\n ContainerStartOptions,\n ContainerInspectInfo,\n ContainerInfo,\n ImageInfo,\n ImageBuildOptions,\n Network,\n};\n"],"mappings":"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","names":["docker"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@computesdk/docker",
3
- "version": "1.2.42",
3
+ "version": "1.2.44",
4
4
  "description": "Docker provider for ComputeSDK - local containerized sandboxes for development and testing",
5
5
  "author": "IberAI",
6
6
  "license": "MIT",
@@ -19,8 +19,8 @@
19
19
  ],
20
20
  "dependencies": {
21
21
  "dockerode": "^4.0.8",
22
- "computesdk": "2.5.4",
23
- "@computesdk/provider": "1.2.0"
22
+ "@computesdk/provider": "1.4.0",
23
+ "computesdk": "3.0.0"
24
24
  },
25
25
  "keywords": [
26
26
  "computesdk",