@vm0/runner 2.0.0 → 2.0.1

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 +38 -37
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -654,10 +654,12 @@ var FirecrackerVM = class {
654
654
  console.log(`[VM ${this.config.vmId}] Stopping...`);
655
655
  try {
656
656
  if (this.client) {
657
- try {
658
- await this.client.sendCtrlAltDel();
659
- } catch {
660
- }
657
+ await this.client.sendCtrlAltDel().catch((error) => {
658
+ console.log(
659
+ `[VM ${this.config.vmId}] Graceful shutdown signal failed (VM may already be stopping):`,
660
+ error instanceof Error ? error.message : error
661
+ );
662
+ });
661
663
  }
662
664
  } finally {
663
665
  await this.cleanup();
@@ -851,14 +853,9 @@ var SSHClient = class {
851
853
  */
852
854
  async waitUntilReachable(timeoutMs = 12e4, intervalMs = 2e3) {
853
855
  const start = Date.now();
854
- let lastError = null;
855
856
  while (Date.now() - start < timeoutMs) {
856
- try {
857
- if (await this.isReachable()) {
858
- return;
859
- }
860
- } catch (err) {
861
- lastError = err instanceof Error ? err : new Error(String(err));
857
+ if (await this.isReachable()) {
858
+ return;
862
859
  }
863
860
  await new Promise((resolve) => {
864
861
  const remaining = timeoutMs - (Date.now() - start);
@@ -870,7 +867,7 @@ var SSHClient = class {
870
867
  });
871
868
  }
872
869
  throw new Error(
873
- `SSH not reachable after ${timeoutMs}ms at ${this.config.host}: ${lastError?.message || "timeout"}`
870
+ `SSH not reachable after ${timeoutMs}ms at ${this.config.host}`
874
871
  );
875
872
  }
876
873
  /**
@@ -9162,16 +9159,34 @@ async function executeJob(context, config) {
9162
9159
  );
9163
9160
  await ssh.writeFile(ENV_JSON_PATH, envJson);
9164
9161
  const systemLogFile = `/tmp/vm0-main-${context.runId}.log`;
9165
- console.log(`[Executor] Running agent via env-loader...`);
9162
+ const exitCodeFile = `/tmp/vm0-exit-${context.runId}`;
9163
+ console.log(`[Executor] Running agent via env-loader (background)...`);
9166
9164
  const startTime = Date.now();
9167
- const result = await ssh.exec(
9168
- `{ python3 -u ${ENV_LOADER_PATH}; } > ${systemLogFile} 2>&1; echo "EXIT_CODE:$?"`
9165
+ await ssh.exec(
9166
+ `nohup sh -c 'python3 -u ${ENV_LOADER_PATH}; echo $? > ${exitCodeFile}' > ${systemLogFile} 2>&1 &`
9169
9167
  );
9170
- const lines = result.stdout.trim().split("\n");
9171
- const exitCodeLine = lines[lines.length - 1] ?? "";
9172
- const exitCodeMatch = exitCodeLine.match(/EXIT_CODE:(\d+)/);
9173
- const exitCode = exitCodeMatch && exitCodeMatch[1] ? parseInt(exitCodeMatch[1], 10) : 1;
9168
+ console.log(`[Executor] Agent started in background`);
9169
+ const pollIntervalMs = 2e3;
9170
+ const maxWaitMs = 24 * 60 * 60 * 1e3;
9171
+ let exitCode = 1;
9172
+ let completed = false;
9173
+ while (Date.now() - startTime < maxWaitMs) {
9174
+ await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
9175
+ const checkResult = await ssh.exec(`cat ${exitCodeFile} 2>/dev/null`);
9176
+ if (checkResult.exitCode === 0 && checkResult.stdout.trim()) {
9177
+ exitCode = parseInt(checkResult.stdout.trim(), 10) || 1;
9178
+ completed = true;
9179
+ break;
9180
+ }
9181
+ }
9174
9182
  const duration = Math.round((Date.now() - startTime) / 1e3);
9183
+ if (!completed) {
9184
+ console.log(`[Executor] Agent timed out after ${duration}s`);
9185
+ return {
9186
+ exitCode: 1,
9187
+ error: `Agent execution timed out after ${duration}s`
9188
+ };
9189
+ }
9175
9190
  console.log(
9176
9191
  `[Executor] Agent finished in ${duration}s with exit code ${exitCode}`
9177
9192
  );
@@ -9195,14 +9210,7 @@ async function executeJob(context, config) {
9195
9210
  } finally {
9196
9211
  if (vm) {
9197
9212
  console.log(`[Executor] Cleaning up VM ${vmId}...`);
9198
- try {
9199
- await vm.kill();
9200
- } catch (error) {
9201
- console.error(
9202
- `[Executor] Failed to cleanup VM ${vmId}:`,
9203
- error instanceof Error ? error.message : error
9204
- );
9205
- }
9213
+ await vm.kill();
9206
9214
  }
9207
9215
  }
9208
9216
  }
@@ -9224,15 +9232,8 @@ async function executeJob2(context, config) {
9224
9232
  } catch (err) {
9225
9233
  const error = err instanceof Error ? err.message : "Unknown execution error";
9226
9234
  console.error(` Job ${context.runId} execution failed: ${error}`);
9227
- try {
9228
- const result = await completeJob(context, 1, error);
9229
- console.log(` Job ${context.runId} reported as ${result.status}`);
9230
- } catch (reportErr) {
9231
- console.error(
9232
- ` Failed to report job ${context.runId} completion:`,
9233
- reportErr instanceof Error ? reportErr.message : "Unknown error"
9234
- );
9235
- }
9235
+ const result = await completeJob(context, 1, error);
9236
+ console.log(` Job ${context.runId} reported as ${result.status}`);
9236
9237
  }
9237
9238
  }
9238
9239
  var startCommand = new Command("start").description("Start the runner").option("--config <path>", "Config file path", "./runner.yaml").action(async (options) => {
@@ -9336,7 +9337,7 @@ var statusCommand = new Command2("status").description("Show runner status").act
9336
9337
  });
9337
9338
 
9338
9339
  // src/index.ts
9339
- var version = true ? "2.0.0" : "0.1.0";
9340
+ var version = true ? "2.0.1" : "0.1.0";
9340
9341
  program.name("vm0-runner").version(version).description("Self-hosted runner for VM0 agents");
9341
9342
  program.addCommand(startCommand);
9342
9343
  program.addCommand(statusCommand);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vm0/runner",
3
- "version": "2.0.0",
3
+ "version": "2.0.1",
4
4
  "description": "Self-hosted runner for VM0 agents",
5
5
  "repository": {
6
6
  "type": "git",