Swadhin Biswas feat(arch): phase 1-4 github parity (sync, daemons, ui, queues) · 4/1/2026
d0c5c9d
69 lines · 2.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import { spawn } from 'child_process';
import { randomUUID } from 'crypto';

/**
 * OpenCodeHub CI Runner
 * Zero-Trust Execution Environment using Docker-in-Docker isolation
 */

export interface RunnerOptions {
  jobId: string;
  image: string;
  repositoryUrl: string;
  commitHash: string;
  env: Record<string, string>;
  command: readonly string[];
}

export class IsolatedDockerRunner {
  static async executeJob(options: RunnerOptions): Promise<{ exitCode: number, logs: string }> {
    const containerName = `och-runner-${options.jobId}-${randomUUID().slice(0, 8)}`;
    
    // Secure isolated execution:
    // 1. No root privileges on host (--privileged only if docker-in-docker explicitly enabled, but avoided here for standard jobs)
    // 2. Memory and CPU constraints
    // 3. Network isolation
    const dockerArgs = [
      'run',
      '--name', containerName,
      '--rm', // Auto-remove container when done
      '--memory=2g',
      '--cpus=2',
      '--network=none', // Default to isolated network for static analysis (can be bridged if internet needed)
    ];

    // Inject environment variables safely
    for (const [key, value] of Object.entries(options.env || {})) {
      dockerArgs.push('-e', `${key}=${String(value).replace(/'/g, "'\\''")}`); // Basic escape
    }

    dockerArgs.push(options.image);
    dockerArgs.push(...options.command);

    console.log(`[CI] Starting isolated job ${options.jobId} in container ${containerName}`);

    return new Promise((resolve) => {
      const child = spawn('docker', dockerArgs);
      
      let logs = '';
      
      child.stdout.on('data', (data) => logs += data.toString());
      child.stderr.on('data', (data) => logs += data.toString());
      
      child.on('close', (code) => {
        resolve({
          exitCode: code ?? 1,
          logs
        });
      });

      // Timeout safeguard (e.g., 10 minutes)
      setTimeout(() => {
        child.kill(); // Terminate local process
        spawn('docker', ['rm', '-f', containerName]); // Forcibly terminate runaway container
        resolve({ exitCode: 124, logs: logs + '\n[ERROR] Job Timed Out after 10 minutes.' });
      }, 10 * 60 * 1000);
    });
  }
}