@vm0/cli 4.1.0 → 4.2.0
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 +80 -75
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -2421,88 +2421,93 @@ import chalk15 from "chalk";
|
|
|
2421
2421
|
import { readFile as readFile5 } from "fs/promises";
|
|
2422
2422
|
import { existsSync as existsSync5 } from "fs";
|
|
2423
2423
|
var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
2424
|
-
var buildCommand = new Command16().name("build").description("Build a custom image from a Dockerfile").requiredOption("-f, --file <path>", "Path to Dockerfile").requiredOption("-n, --name <name>", "Name for the image").
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
process.exit(1);
|
|
2438
|
-
}
|
|
2439
|
-
if (name.startsWith("vm0-")) {
|
|
2440
|
-
console.error(
|
|
2441
|
-
chalk15.red(
|
|
2442
|
-
'\u2717 Invalid name. Cannot start with "vm0-" (reserved prefix).'
|
|
2443
|
-
)
|
|
2444
|
-
);
|
|
2445
|
-
process.exit(1);
|
|
2446
|
-
}
|
|
2447
|
-
try {
|
|
2448
|
-
const dockerfile = await readFile5(file, "utf8");
|
|
2449
|
-
console.log(chalk15.blue(`Building image: ${name}`));
|
|
2450
|
-
console.log(chalk15.gray(` Dockerfile: ${file}`));
|
|
2451
|
-
console.log();
|
|
2452
|
-
const buildInfo = await apiClient.createImage({
|
|
2453
|
-
dockerfile,
|
|
2454
|
-
alias: name
|
|
2455
|
-
});
|
|
2456
|
-
const { imageId, buildId } = buildInfo;
|
|
2457
|
-
console.log(chalk15.gray(` Build ID: ${buildId}`));
|
|
2458
|
-
console.log();
|
|
2459
|
-
let logsOffset = 0;
|
|
2460
|
-
let status = "building";
|
|
2461
|
-
while (status === "building") {
|
|
2462
|
-
const statusResponse = await apiClient.get(
|
|
2463
|
-
`/api/images/${imageId}/builds/${buildId}?logsOffset=${logsOffset}`
|
|
2424
|
+
var buildCommand = new Command16().name("build").description("Build a custom image from a Dockerfile").requiredOption("-f, --file <path>", "Path to Dockerfile").requiredOption("-n, --name <name>", "Name for the image").option("--delete-existing", "Delete existing image before building").action(
|
|
2425
|
+
async (options) => {
|
|
2426
|
+
const { file, name, deleteExisting } = options;
|
|
2427
|
+
if (!existsSync5(file)) {
|
|
2428
|
+
console.error(chalk15.red(`\u2717 Dockerfile not found: ${file}`));
|
|
2429
|
+
process.exit(1);
|
|
2430
|
+
}
|
|
2431
|
+
const nameRegex = /^[a-zA-Z0-9][a-zA-Z0-9-]{1,62}[a-zA-Z0-9]$/;
|
|
2432
|
+
if (!nameRegex.test(name)) {
|
|
2433
|
+
console.error(
|
|
2434
|
+
chalk15.red(
|
|
2435
|
+
"\u2717 Invalid name format. Must be 3-64 characters, letters, numbers, and hyphens only."
|
|
2436
|
+
)
|
|
2464
2437
|
);
|
|
2465
|
-
|
|
2466
|
-
const error = await statusResponse.json();
|
|
2467
|
-
throw new Error(
|
|
2468
|
-
error.error?.message || "Failed to get build status"
|
|
2469
|
-
);
|
|
2470
|
-
}
|
|
2471
|
-
const statusData = await statusResponse.json();
|
|
2472
|
-
for (const log of statusData.logs) {
|
|
2473
|
-
console.log(chalk15.gray(` ${log}`));
|
|
2474
|
-
}
|
|
2475
|
-
logsOffset = statusData.logsOffset;
|
|
2476
|
-
status = statusData.status;
|
|
2477
|
-
if (status === "building") {
|
|
2478
|
-
await sleep(2e3);
|
|
2479
|
-
}
|
|
2438
|
+
process.exit(1);
|
|
2480
2439
|
}
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
console.log(chalk15.cyan(` your-agent:`));
|
|
2488
|
-
console.log(chalk15.cyan(` image: "${name}"`));
|
|
2489
|
-
} else {
|
|
2490
|
-
console.error(chalk15.red(`\u2717 Build failed`));
|
|
2440
|
+
if (name.startsWith("vm0-")) {
|
|
2441
|
+
console.error(
|
|
2442
|
+
chalk15.red(
|
|
2443
|
+
'\u2717 Invalid name. Cannot start with "vm0-" (reserved prefix).'
|
|
2444
|
+
)
|
|
2445
|
+
);
|
|
2491
2446
|
process.exit(1);
|
|
2492
2447
|
}
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2448
|
+
try {
|
|
2449
|
+
const dockerfile = await readFile5(file, "utf8");
|
|
2450
|
+
console.log(chalk15.blue(`Building image: ${name}`));
|
|
2451
|
+
console.log(chalk15.gray(` Dockerfile: ${file}`));
|
|
2452
|
+
console.log();
|
|
2453
|
+
const buildInfo = await apiClient.createImage({
|
|
2454
|
+
dockerfile,
|
|
2455
|
+
alias: name,
|
|
2456
|
+
deleteExisting
|
|
2457
|
+
});
|
|
2458
|
+
const { imageId, buildId } = buildInfo;
|
|
2459
|
+
console.log(chalk15.gray(` Build ID: ${buildId}`));
|
|
2460
|
+
console.log();
|
|
2461
|
+
let logsOffset = 0;
|
|
2462
|
+
let status = "building";
|
|
2463
|
+
while (status === "building") {
|
|
2464
|
+
const statusResponse = await apiClient.get(
|
|
2465
|
+
`/api/images/${imageId}/builds/${buildId}?logsOffset=${logsOffset}`
|
|
2466
|
+
);
|
|
2467
|
+
if (!statusResponse.ok) {
|
|
2468
|
+
const error = await statusResponse.json();
|
|
2469
|
+
throw new Error(
|
|
2470
|
+
error.error?.message || "Failed to get build status"
|
|
2471
|
+
);
|
|
2472
|
+
}
|
|
2473
|
+
const statusData = await statusResponse.json();
|
|
2474
|
+
for (const log of statusData.logs) {
|
|
2475
|
+
console.log(chalk15.gray(` ${log}`));
|
|
2476
|
+
}
|
|
2477
|
+
logsOffset = statusData.logsOffset;
|
|
2478
|
+
status = statusData.status;
|
|
2479
|
+
if (status === "building") {
|
|
2480
|
+
await sleep(2e3);
|
|
2481
|
+
}
|
|
2482
|
+
}
|
|
2483
|
+
console.log();
|
|
2484
|
+
if (status === "ready") {
|
|
2485
|
+
console.log(chalk15.green(`\u2713 Image built: ${name}`));
|
|
2486
|
+
console.log();
|
|
2487
|
+
console.log("Use in vm0.yaml:");
|
|
2488
|
+
console.log(chalk15.cyan(` agents:`));
|
|
2489
|
+
console.log(chalk15.cyan(` your-agent:`));
|
|
2490
|
+
console.log(chalk15.cyan(` image: "${name}"`));
|
|
2497
2491
|
} else {
|
|
2498
|
-
console.error(chalk15.red(`\u2717
|
|
2492
|
+
console.error(chalk15.red(`\u2717 Build failed`));
|
|
2493
|
+
process.exit(1);
|
|
2499
2494
|
}
|
|
2500
|
-
}
|
|
2501
|
-
|
|
2495
|
+
} catch (error) {
|
|
2496
|
+
if (error instanceof Error) {
|
|
2497
|
+
if (error.message.includes("Not authenticated")) {
|
|
2498
|
+
console.error(
|
|
2499
|
+
chalk15.red("\u2717 Not authenticated. Run: vm0 auth login")
|
|
2500
|
+
);
|
|
2501
|
+
} else {
|
|
2502
|
+
console.error(chalk15.red(`\u2717 ${error.message}`));
|
|
2503
|
+
}
|
|
2504
|
+
} else {
|
|
2505
|
+
console.error(chalk15.red("\u2717 An unexpected error occurred"));
|
|
2506
|
+
}
|
|
2507
|
+
process.exit(1);
|
|
2502
2508
|
}
|
|
2503
|
-
process.exit(1);
|
|
2504
2509
|
}
|
|
2505
|
-
|
|
2510
|
+
);
|
|
2506
2511
|
|
|
2507
2512
|
// src/commands/image/list.ts
|
|
2508
2513
|
import { Command as Command17 } from "commander";
|
|
@@ -2626,7 +2631,7 @@ var imageCommand = new Command19().name("image").description("Manage custom imag
|
|
|
2626
2631
|
|
|
2627
2632
|
// src/index.ts
|
|
2628
2633
|
var program = new Command20();
|
|
2629
|
-
program.name("vm0").description("VM0 CLI - A modern build tool").version("4.
|
|
2634
|
+
program.name("vm0").description("VM0 CLI - A modern build tool").version("4.2.0");
|
|
2630
2635
|
program.command("info").description("Display environment information").action(async () => {
|
|
2631
2636
|
console.log(chalk18.cyan("System Information:"));
|
|
2632
2637
|
console.log(`Node Version: ${process.version}`);
|