@vm0/runner 3.19.1 → 3.19.2

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.
Files changed (2) hide show
  1. package/index.js +97 -83
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -3046,6 +3046,97 @@ async function uploadNetworkLogs(apiUrl, sandboxToken, runId) {
3046
3046
 
3047
3047
  // src/lib/executor/index.ts
3048
3048
  var logger9 = createLogger("Executor");
3049
+ function setupNetworkSecurity(context, vethNsIp) {
3050
+ const firewallConfig = context.experimentalFirewall;
3051
+ if (firewallConfig?.enabled) {
3052
+ const mitmEnabled = firewallConfig.experimental_mitm ?? false;
3053
+ const sealSecretsEnabled = firewallConfig.experimental_seal_secrets ?? false;
3054
+ logger9.log(
3055
+ `Setting up network security for VM ${vethNsIp} (mitm=${mitmEnabled}, sealSecrets=${sealSecretsEnabled})`
3056
+ );
3057
+ getVMRegistry().register(vethNsIp, context.runId, context.sandboxToken, {
3058
+ firewallRules: firewallConfig?.rules,
3059
+ mitmEnabled,
3060
+ sealSecretsEnabled
3061
+ });
3062
+ }
3063
+ }
3064
+ async function prepareGuest(guest, context, config) {
3065
+ if (config.firecracker.snapshot) {
3066
+ const timestamp = (Date.now() / 1e3).toFixed(3);
3067
+ await guest.execAsRoot(`date -s "@${timestamp}"`);
3068
+ }
3069
+ if (context.storageManifest) {
3070
+ await withSandboxTiming(
3071
+ "storage_download",
3072
+ () => downloadStorages(guest, context.storageManifest)
3073
+ );
3074
+ }
3075
+ if (context.resumeSession) {
3076
+ await withSandboxTiming(
3077
+ "session_restore",
3078
+ () => restoreSessionHistory(
3079
+ guest,
3080
+ context.resumeSession,
3081
+ context.workingDir,
3082
+ context.cliAgentType || "claude-code"
3083
+ )
3084
+ );
3085
+ }
3086
+ }
3087
+ async function checkForOOM(guest, exitCode, durationMs) {
3088
+ if (exitCode === 137 || exitCode === 9) {
3089
+ const dmesgCheck = await guest.exec(
3090
+ `sudo dmesg | tail -20 | grep -iE "killed|oom" 2>/dev/null`
3091
+ );
3092
+ if (dmesgCheck.stdout.toLowerCase().includes("oom") || dmesgCheck.stdout.toLowerCase().includes("killed")) {
3093
+ logger9.log(`OOM detected: ${dmesgCheck.stdout}`);
3094
+ recordOperation({
3095
+ actionType: "agent_execute",
3096
+ durationMs,
3097
+ success: false
3098
+ });
3099
+ return {
3100
+ exitCode: 1,
3101
+ error: "Agent process killed by OOM killer"
3102
+ };
3103
+ }
3104
+ }
3105
+ return null;
3106
+ }
3107
+ async function cleanupJob(context, options, config, vethNsIp, vm, vsockClient, vmId) {
3108
+ if (context.experimentalFirewall?.enabled && vethNsIp) {
3109
+ logger9.log(`Cleaning up network security for VM ${vethNsIp}`);
3110
+ getVMRegistry().unregister(vethNsIp);
3111
+ if (!options.benchmarkMode) {
3112
+ try {
3113
+ await uploadNetworkLogs(
3114
+ config.server.url,
3115
+ context.sandboxToken,
3116
+ context.runId
3117
+ );
3118
+ } catch (err) {
3119
+ logger9.error(
3120
+ `Failed to upload network logs: ${err instanceof Error ? err.message : "Unknown error"}`
3121
+ );
3122
+ }
3123
+ }
3124
+ }
3125
+ if (vm) {
3126
+ if (vsockClient) {
3127
+ const acked = await vsockClient.shutdown(2e3);
3128
+ if (acked) {
3129
+ logger9.log(`Guest acknowledged shutdown`);
3130
+ } else {
3131
+ logger9.log(`Guest shutdown timeout, proceeding with SIGKILL`);
3132
+ }
3133
+ vsockClient.close();
3134
+ }
3135
+ logger9.log(`Cleaning up VM ${vmId}...`);
3136
+ await withSandboxTiming("cleanup", () => vm.kill());
3137
+ }
3138
+ await clearSandboxContext();
3139
+ }
3049
3140
  async function executeJob(context, config, options = {}) {
3050
3141
  setSandboxContext({
3051
3142
  apiUrl: config.server.url,
@@ -3109,43 +3200,11 @@ async function executeJob(context, config, options = {}) {
3109
3200
  `VM ${vmId} started, guest IP: ${guestIp}, veth NS IP: ${vethNsIp}`
3110
3201
  );
3111
3202
  const envVars = buildEnvironmentVariables(context, config.server.url);
3112
- const firewallConfig = context.experimentalFirewall;
3113
- if (firewallConfig?.enabled) {
3114
- const mitmEnabled = firewallConfig.experimental_mitm ?? false;
3115
- const sealSecretsEnabled = firewallConfig.experimental_seal_secrets ?? false;
3116
- logger9.log(
3117
- `Setting up network security for VM ${vethNsIp} (mitm=${mitmEnabled}, sealSecrets=${sealSecretsEnabled})`
3118
- );
3119
- getVMRegistry().register(vethNsIp, context.runId, context.sandboxToken, {
3120
- firewallRules: firewallConfig?.rules,
3121
- mitmEnabled,
3122
- sealSecretsEnabled
3123
- });
3124
- }
3203
+ setupNetworkSecurity(context, vethNsIp);
3125
3204
  logger9.log(`Waiting for guest connection...`);
3126
3205
  await withSandboxTiming("guest_wait", () => guestConnectionPromise);
3127
3206
  logger9.log(`Guest client ready`);
3128
- if (config.firecracker.snapshot) {
3129
- const timestamp = (Date.now() / 1e3).toFixed(3);
3130
- await guest.execAsRoot(`date -s "@${timestamp}"`);
3131
- }
3132
- if (context.storageManifest) {
3133
- await withSandboxTiming(
3134
- "storage_download",
3135
- () => downloadStorages(guest, context.storageManifest)
3136
- );
3137
- }
3138
- if (context.resumeSession) {
3139
- await withSandboxTiming(
3140
- "session_restore",
3141
- () => restoreSessionHistory(
3142
- guest,
3143
- context.resumeSession,
3144
- context.workingDir,
3145
- context.cliAgentType || "claude-code"
3146
- )
3147
- );
3148
- }
3207
+ await prepareGuest(guest, context, config);
3149
3208
  const systemLogFile = `/tmp/vm0-system-${context.runId}.log`;
3150
3209
  const startTime = Date.now();
3151
3210
  const maxWaitMs = 2 * 60 * 60 * 1e3;
@@ -3182,23 +3241,8 @@ async function executeJob(context, config, options = {}) {
3182
3241
  }
3183
3242
  const durationMs = Date.now() - startTime;
3184
3243
  const duration = Math.round(durationMs / 1e3);
3185
- if (exitCode === 137 || exitCode === 9) {
3186
- const dmesgCheck = await guest.exec(
3187
- `sudo dmesg | tail -20 | grep -iE "killed|oom" 2>/dev/null`
3188
- );
3189
- if (dmesgCheck.stdout.toLowerCase().includes("oom") || dmesgCheck.stdout.toLowerCase().includes("killed")) {
3190
- logger9.log(`OOM detected: ${dmesgCheck.stdout}`);
3191
- recordOperation({
3192
- actionType: "agent_execute",
3193
- durationMs,
3194
- success: false
3195
- });
3196
- return {
3197
- exitCode: 1,
3198
- error: "Agent process killed by OOM killer"
3199
- };
3200
- }
3201
- }
3244
+ const oomResult = await checkForOOM(guest, exitCode, durationMs);
3245
+ if (oomResult) return oomResult;
3202
3246
  recordOperation({
3203
3247
  actionType: "agent_execute",
3204
3248
  durationMs,
@@ -3222,37 +3266,7 @@ async function executeJob(context, config, options = {}) {
3222
3266
  error: errorMsg
3223
3267
  };
3224
3268
  } finally {
3225
- if (context.experimentalFirewall?.enabled && vethNsIp) {
3226
- logger9.log(`Cleaning up network security for VM ${vethNsIp}`);
3227
- getVMRegistry().unregister(vethNsIp);
3228
- if (!options.benchmarkMode) {
3229
- try {
3230
- await uploadNetworkLogs(
3231
- config.server.url,
3232
- context.sandboxToken,
3233
- context.runId
3234
- );
3235
- } catch (err) {
3236
- logger9.error(
3237
- `Failed to upload network logs: ${err instanceof Error ? err.message : "Unknown error"}`
3238
- );
3239
- }
3240
- }
3241
- }
3242
- if (vm) {
3243
- if (vsockClient) {
3244
- const acked = await vsockClient.shutdown(2e3);
3245
- if (acked) {
3246
- logger9.log(`Guest acknowledged shutdown`);
3247
- } else {
3248
- logger9.log(`Guest shutdown timeout, proceeding with SIGKILL`);
3249
- }
3250
- vsockClient.close();
3251
- }
3252
- logger9.log(`Cleaning up VM ${vmId}...`);
3253
- await withSandboxTiming("cleanup", () => vm.kill());
3254
- }
3255
- await clearSandboxContext();
3269
+ await cleanupJob(context, options, config, vethNsIp, vm, vsockClient, vmId);
3256
3270
  }
3257
3271
  }
3258
3272
 
@@ -4681,7 +4695,7 @@ var snapshotCommand = new Command5("snapshot").description("Generate a Firecrack
4681
4695
  );
4682
4696
 
4683
4697
  // src/index.ts
4684
- var version = true ? "3.19.1" : "0.1.0";
4698
+ var version = true ? "3.19.2" : "0.1.0";
4685
4699
  program.name("vm0-runner").version(version).description("Self-hosted runner for VM0 agents");
4686
4700
  program.addCommand(startCommand);
4687
4701
  program.addCommand(doctorCommand);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vm0/runner",
3
- "version": "3.19.1",
3
+ "version": "3.19.2",
4
4
  "description": "Self-hosted runner for VM0 agents",
5
5
  "repository": {
6
6
  "type": "git",