@vm0/runner 2.0.2 → 2.0.4

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 +42 -9
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -824,6 +824,28 @@ var SSHClient = class {
824
824
  }
825
825
  }
826
826
  }
827
+ /**
828
+ * Write content to a file on the remote VM using sudo
829
+ * Used for writing to privileged locations like /usr/local/bin
830
+ */
831
+ async writeFileWithSudo(remotePath, content) {
832
+ const encoded = Buffer.from(content).toString("base64");
833
+ const maxChunkSize = 65e3;
834
+ if (encoded.length <= maxChunkSize) {
835
+ await this.execOrThrow(
836
+ `echo '${encoded}' | base64 -d | sudo tee '${remotePath}' > /dev/null`
837
+ );
838
+ } else {
839
+ await this.execOrThrow(`sudo rm -f '${remotePath}'`);
840
+ for (let i = 0; i < encoded.length; i += maxChunkSize) {
841
+ const chunk = encoded.slice(i, i + maxChunkSize);
842
+ const teeFlag = i === 0 ? "" : "-a";
843
+ await this.execOrThrow(
844
+ `echo '${chunk}' | base64 -d | sudo tee ${teeFlag} '${remotePath}' > /dev/null`
845
+ );
846
+ }
847
+ }
848
+ }
827
849
  /**
828
850
  * Read a file from the remote VM
829
851
  */
@@ -4744,6 +4766,13 @@ var apiErrorSchema = z3.object({
4744
4766
  // ../../packages/core/src/contracts/composes.ts
4745
4767
  import { z as z4 } from "zod";
4746
4768
  var c = initContract();
4769
+ var composeVersionQuerySchema = z4.preprocess(
4770
+ (val) => val === void 0 || val === null ? void 0 : String(val),
4771
+ z4.string().min(1, "Missing version query parameter").regex(
4772
+ /^[a-f0-9]{8,64}$|^latest$/i,
4773
+ "Version must be 8-64 hex characters or 'latest'"
4774
+ )
4775
+ );
4747
4776
  var agentNameSchema = z4.string().min(3, "Agent name must be at least 3 characters").max(64, "Agent name must be 64 characters or less").regex(
4748
4777
  /^[a-zA-Z0-9][a-zA-Z0-9-]{1,62}[a-zA-Z0-9]$/,
4749
4778
  "Agent name must start and end with letter or number, and contain only letters, numbers, and hyphens"
@@ -4880,7 +4909,7 @@ var composesVersionsContract = c.router({
4880
4909
  path: "/api/agent/composes/versions",
4881
4910
  query: z4.object({
4882
4911
  composeId: z4.string().min(1, "Missing composeId query parameter"),
4883
- version: z4.string().min(1, "Missing version query parameter")
4912
+ version: composeVersionQuerySchema
4884
4913
  }),
4885
4914
  responses: {
4886
4915
  200: z4.object({
@@ -5191,6 +5220,10 @@ var runNetworkLogsContract = c2.router({
5191
5220
  import { z as z6 } from "zod";
5192
5221
  var c3 = initContract();
5193
5222
  var storageTypeSchema = z6.enum(["volume", "artifact"]);
5223
+ var versionQuerySchema = z6.preprocess(
5224
+ (val) => val === void 0 || val === null ? void 0 : String(val),
5225
+ z6.string().regex(/^[a-f0-9]{8,64}$/i, "Version must be 8-64 hex characters").optional()
5226
+ );
5194
5227
  var uploadStorageResponseSchema = z6.object({
5195
5228
  name: z6.string(),
5196
5229
  versionId: z6.string(),
@@ -5239,7 +5272,7 @@ var storagesContract = c3.router({
5239
5272
  path: "/api/storages",
5240
5273
  query: z6.object({
5241
5274
  name: z6.string().min(1, "Storage name is required"),
5242
- version: z6.string().optional()
5275
+ version: versionQuerySchema
5243
5276
  }),
5244
5277
  responses: {
5245
5278
  // Binary response - actual handling done at route level
@@ -5339,7 +5372,7 @@ var storagesDownloadContract = c3.router({
5339
5372
  query: z6.object({
5340
5373
  name: z6.string().min(1, "Storage name is required"),
5341
5374
  type: storageTypeSchema,
5342
- version: z6.string().optional()
5375
+ version: versionQuerySchema
5343
5376
  }),
5344
5377
  responses: {
5345
5378
  // Normal response with presigned URL
@@ -9050,13 +9083,13 @@ var ENV_JSON_PATH = "/tmp/vm0-env.json";
9050
9083
  async function uploadScripts(ssh) {
9051
9084
  const scripts = getAllScripts();
9052
9085
  await ssh.execOrThrow(
9053
- `mkdir -p ${SCRIPT_PATHS.baseDir} ${SCRIPT_PATHS.libDir}`
9086
+ `sudo mkdir -p ${SCRIPT_PATHS.baseDir} ${SCRIPT_PATHS.libDir}`
9054
9087
  );
9055
9088
  for (const script of scripts) {
9056
- await ssh.writeFile(script.path, script.content);
9089
+ await ssh.writeFileWithSudo(script.path, script.content);
9057
9090
  }
9058
9091
  await ssh.execOrThrow(
9059
- `chmod +x ${SCRIPT_PATHS.baseDir}/*.py ${SCRIPT_PATHS.libDir}/*.py 2>/dev/null || true`
9092
+ `sudo chmod +x ${SCRIPT_PATHS.baseDir}/*.py ${SCRIPT_PATHS.libDir}/*.py 2>/dev/null || true`
9060
9093
  );
9061
9094
  }
9062
9095
  async function downloadStorages(ssh, manifest) {
@@ -9101,7 +9134,7 @@ async function configureDNS(ssh) {
9101
9134
  nameserver 8.8.4.4
9102
9135
  nameserver 1.1.1.1`;
9103
9136
  await ssh.execOrThrow(
9104
- `rm -f /etc/resolv.conf && echo '${dnsConfig}' > /etc/resolv.conf`
9137
+ `sudo sh -c 'rm -f /etc/resolv.conf && echo "${dnsConfig}" > /etc/resolv.conf'`
9105
9138
  );
9106
9139
  }
9107
9140
  async function executeJob(context, config) {
@@ -9128,7 +9161,7 @@ async function executeJob(context, config) {
9128
9161
  }
9129
9162
  console.log(`[Executor] VM ${vmId} started, guest IP: ${guestIp}`);
9130
9163
  const privateKeyPath = getRunnerSSHKeyPath();
9131
- const ssh = createVMSSHClient(guestIp, "root", privateKeyPath || void 0);
9164
+ const ssh = createVMSSHClient(guestIp, "user", privateKeyPath || void 0);
9132
9165
  console.log(`[Executor] Waiting for SSH on ${guestIp}...`);
9133
9166
  await ssh.waitUntilReachable(12e4, 2e3);
9134
9167
  console.log(`[Executor] SSH ready on ${guestIp}`);
@@ -9333,7 +9366,7 @@ var statusCommand = new Command2("status").description("Show runner status").act
9333
9366
  });
9334
9367
 
9335
9368
  // src/index.ts
9336
- var version = true ? "2.0.2" : "0.1.0";
9369
+ var version = true ? "2.0.4" : "0.1.0";
9337
9370
  program.name("vm0-runner").version(version).description("Self-hosted runner for VM0 agents");
9338
9371
  program.addCommand(startCommand);
9339
9372
  program.addCommand(statusCommand);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vm0/runner",
3
- "version": "2.0.2",
3
+ "version": "2.0.4",
4
4
  "description": "Self-hosted runner for VM0 agents",
5
5
  "repository": {
6
6
  "type": "git",