@magpiecloud/mags 1.6.0 → 1.6.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.
- package/bin/mags.js +14 -11
- package/package.json +1 -1
package/bin/mags.js
CHANGED
|
@@ -215,6 +215,7 @@ ${colors.bold}Run Options:${colors.reset}
|
|
|
215
215
|
-w, --workspace <id> Use persistent workspace (S3 sync)
|
|
216
216
|
-n, --name <name> Set job name (for easier reference)
|
|
217
217
|
-p, --persistent Keep VM alive after script completes
|
|
218
|
+
--base <workspace> Mount workspace read-only as base image
|
|
218
219
|
-e, --ephemeral No workspace/S3 sync (fastest execution)
|
|
219
220
|
-f, --file <path> Upload file(s) to VM (repeatable)
|
|
220
221
|
--url Enable public URL access (requires -p)
|
|
@@ -242,6 +243,8 @@ ${colors.bold}Examples:${colors.reset}
|
|
|
242
243
|
mags run -e 'echo fast' # Ephemeral (no S3 sync)
|
|
243
244
|
mags run -f script.py 'python3 script.py' # Upload + run file
|
|
244
245
|
mags run -w myproject 'python3 script.py'
|
|
246
|
+
mags run --base golden 'npm test' # Use golden as read-only base
|
|
247
|
+
mags run --base golden -w fork-1 'npm test' # Base + save changes to fork-1
|
|
245
248
|
mags run -p --url 'python3 -m http.server 8080'
|
|
246
249
|
mags run -n webapp -w webapp -p --url --port 3000 'npm start'
|
|
247
250
|
mags workspace list # List workspaces
|
|
@@ -436,6 +439,7 @@ async function newVM(name) {
|
|
|
436
439
|
async function runJob(args) {
|
|
437
440
|
let script = '';
|
|
438
441
|
let workspace = '';
|
|
442
|
+
let baseWorkspace = '';
|
|
439
443
|
let name = '';
|
|
440
444
|
let persistent = false;
|
|
441
445
|
let ephemeral = false;
|
|
@@ -455,6 +459,9 @@ async function runJob(args) {
|
|
|
455
459
|
case '--name':
|
|
456
460
|
name = args[++i];
|
|
457
461
|
break;
|
|
462
|
+
case '--base':
|
|
463
|
+
baseWorkspace = args[++i];
|
|
464
|
+
break;
|
|
458
465
|
case '-p':
|
|
459
466
|
case '--persistent':
|
|
460
467
|
persistent = true;
|
|
@@ -496,6 +503,10 @@ async function runJob(args) {
|
|
|
496
503
|
log('red', 'Error: Cannot use --ephemeral with --persistent; ephemeral VMs are destroyed after execution');
|
|
497
504
|
process.exit(1);
|
|
498
505
|
}
|
|
506
|
+
if (ephemeral && baseWorkspace) {
|
|
507
|
+
log('red', 'Error: Cannot use --ephemeral with --base; ephemeral VMs have no workspace support');
|
|
508
|
+
process.exit(1);
|
|
509
|
+
}
|
|
499
510
|
|
|
500
511
|
// Upload files if any
|
|
501
512
|
let fileIds = [];
|
|
@@ -523,6 +534,7 @@ async function runJob(args) {
|
|
|
523
534
|
// Only set workspace_id if not ephemeral
|
|
524
535
|
if (!ephemeral && workspace) payload.workspace_id = workspace;
|
|
525
536
|
if (name) payload.name = name;
|
|
537
|
+
if (baseWorkspace) payload.base_workspace_id = baseWorkspace;
|
|
526
538
|
if (startupCommand) payload.startup_command = startupCommand;
|
|
527
539
|
if (fileIds.length > 0) payload.file_ids = fileIds;
|
|
528
540
|
|
|
@@ -538,6 +550,7 @@ async function runJob(args) {
|
|
|
538
550
|
log('green', `Job submitted: ${requestId}`);
|
|
539
551
|
if (name) log('blue', `Name: ${name}`);
|
|
540
552
|
if (workspace) log('blue', `Workspace: ${workspace}`);
|
|
553
|
+
if (baseWorkspace) log('blue', `Base workspace: ${baseWorkspace} (read-only)`);
|
|
541
554
|
if (persistent) log('yellow', 'Persistent: VM will stay alive');
|
|
542
555
|
|
|
543
556
|
// Poll for completion
|
|
@@ -1067,16 +1080,6 @@ async function sshToJob(nameOrId) {
|
|
|
1067
1080
|
} else if (existingJob && existingJob.status === 'sleeping') {
|
|
1068
1081
|
log('yellow', `Waking sleeping VM for '${nameOrId}'...`);
|
|
1069
1082
|
jobID = existingJob.request_id;
|
|
1070
|
-
// Trigger wake by requesting SSH access
|
|
1071
|
-
await request('POST', `/api/v1/mags-jobs/${jobID}/access`, { port: 22 });
|
|
1072
|
-
// Wait for VM to wake up
|
|
1073
|
-
for (let i = 0; i < 30; i++) {
|
|
1074
|
-
const status = await request('GET', `/api/v1/mags-jobs/${jobID}/status`);
|
|
1075
|
-
if (status.status === 'running') break;
|
|
1076
|
-
process.stdout.write('.');
|
|
1077
|
-
await sleep(1000);
|
|
1078
|
-
}
|
|
1079
|
-
console.log('');
|
|
1080
1083
|
} else {
|
|
1081
1084
|
// No running/sleeping VM — start a new persistent one
|
|
1082
1085
|
log('blue', `Starting VM with workspace '${nameOrId}'...`);
|
|
@@ -1212,7 +1215,7 @@ async function main() {
|
|
|
1212
1215
|
break;
|
|
1213
1216
|
case '--version':
|
|
1214
1217
|
case '-v':
|
|
1215
|
-
console.log('mags v1.6.
|
|
1218
|
+
console.log('mags v1.6.2');
|
|
1216
1219
|
process.exit(0);
|
|
1217
1220
|
break;
|
|
1218
1221
|
case 'new':
|