-
Notifications
You must be signed in to change notification settings - Fork 17
Expand file tree
/
Copy pathcli-workflow.ts
More file actions
74 lines (62 loc) · 2.84 KB
/
cli-workflow.ts
File metadata and controls
74 lines (62 loc) · 2.84 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
70
71
72
73
74
import { WrapperConfig } from './types';
export interface WorkflowDependencies {
ensureFirewallNetwork: () => Promise<{ squidIp: string; agentIp: string; proxyIp: string; subnet: string }>;
setupHostIptables: (squidIp: string, port: number, dnsServers: string[], apiProxyIp?: string) => Promise<void>;
writeConfigs: (config: WrapperConfig) => Promise<void>;
startContainers: (workDir: string, allowedDomains: string[], proxyLogsDir?: string, skipPull?: boolean) => Promise<void>;
runAgentCommand: (
workDir: string,
allowedDomains: string[],
proxyLogsDir?: string,
agentTimeoutMinutes?: number
) => Promise<{ exitCode: number }>;
}
export interface WorkflowCallbacks {
onHostIptablesSetup?: () => void;
onContainersStarted?: () => void;
}
export interface WorkflowLogger {
info: (message: string, ...args: unknown[]) => void;
success: (message: string, ...args: unknown[]) => void;
warn: (message: string, ...args: unknown[]) => void;
}
export interface WorkflowOptions extends WorkflowCallbacks {
logger: WorkflowLogger;
performCleanup: () => Promise<void>;
}
/**
* Executes the primary workflow for the CLI. This function is intentionally pure so
* it can be unit tested with mocked dependencies.
*/
export async function runMainWorkflow(
config: WrapperConfig,
dependencies: WorkflowDependencies,
options: WorkflowOptions
): Promise<number> {
const { logger, performCleanup, onHostIptablesSetup, onContainersStarted } = options;
// Step 0: Setup host-level network and iptables
logger.info('Setting up host-level firewall network and iptables rules...');
const networkConfig = await dependencies.ensureFirewallNetwork();
const dnsServers = config.dnsServers || ['8.8.8.8', '8.8.4.4'];
// When API proxy is enabled, allow agent→sidecar traffic at the host level.
// The sidecar itself routes through Squid, so domain whitelisting is still enforced.
const apiProxyIp = config.enableApiProxy ? networkConfig.proxyIp : undefined;
await dependencies.setupHostIptables(networkConfig.squidIp, 3128, dnsServers, apiProxyIp);
onHostIptablesSetup?.();
// Step 1: Write configuration files
logger.info('Generating configuration files...');
await dependencies.writeConfigs(config);
// Step 2: Start containers
await dependencies.startContainers(config.workDir, config.allowedDomains, config.proxyLogsDir, config.skipPull);
onContainersStarted?.();
// Step 3: Wait for agent to complete
const result = await dependencies.runAgentCommand(config.workDir, config.allowedDomains, config.proxyLogsDir, config.agentTimeout);
// Step 4: Cleanup (logs will be preserved automatically if they exist)
await performCleanup();
if (result.exitCode === 0) {
logger.success('Command completed successfully');
} else {
logger.warn(`Command completed with exit code: ${result.exitCode}`);
}
return result.exitCode;
}