@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.
- package/index.js +38 -37
- 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
|
-
|
|
658
|
-
|
|
659
|
-
|
|
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
|
-
|
|
857
|
-
|
|
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}
|
|
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
|
-
|
|
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
|
-
|
|
9168
|
-
`
|
|
9165
|
+
await ssh.exec(
|
|
9166
|
+
`nohup sh -c 'python3 -u ${ENV_LOADER_PATH}; echo $? > ${exitCodeFile}' > ${systemLogFile} 2>&1 &`
|
|
9169
9167
|
);
|
|
9170
|
-
|
|
9171
|
-
const
|
|
9172
|
-
const
|
|
9173
|
-
|
|
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
|
-
|
|
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
|
-
|
|
9228
|
-
|
|
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.
|
|
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);
|