@magpiecloud/mags 1.8.11 → 1.8.13
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/README.md +16 -12
- package/bin/mags.js +31 -5
- package/index.js +7 -2
- package/nodejs/README.md +10 -4
- package/package.json +1 -1
- package/python/README.md +7 -3
- package/python/dist/magpie_mags-1.3.5-py3-none-any.whl +0 -0
- package/python/dist/magpie_mags-1.3.5.tar.gz +0 -0
- package/python/pyproject.toml +1 -1
- package/python/src/magpie_mags.egg-info/PKG-INFO +2 -2
- package/python/src/mags/client.py +13 -3
- package/website/api.html +137 -8
- package/website/cookbook.html +1 -1
- package/website/index.html +149 -95
- package/website/llms.txt +76 -31
- package/website/mags.md +3 -2
- package/python/dist/magpie_mags-1.3.4-py3-none-any.whl +0 -0
- package/python/dist/magpie_mags-1.3.4.tar.gz +0 -0
package/website/index.html
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
/>
|
|
11
11
|
<meta name="api-base" content="https://api.magpiecloud.com" />
|
|
12
12
|
<meta name="auth-base" content="https://api.magpiecloud.com" />
|
|
13
|
-
<link rel="stylesheet" href="styles.css?v=
|
|
13
|
+
<link rel="stylesheet" href="styles.css?v=7" />
|
|
14
14
|
<script src="env.js"></script>
|
|
15
15
|
</head>
|
|
16
16
|
<body>
|
|
@@ -59,10 +59,9 @@
|
|
|
59
59
|
</div>
|
|
60
60
|
<div class="tab-content active" data-tab="hero-cli">
|
|
61
61
|
<pre><code>mags run 'echo Hello World'
|
|
62
|
-
|
|
63
|
-
mags
|
|
64
|
-
|
|
65
|
-
<p class="card-note">Run a script, keep your files, then jump in with SSH.</p>
|
|
62
|
+
mags run -w myproject -p 'pip install flask'
|
|
63
|
+
mags new dev && mags ssh dev</code></pre>
|
|
64
|
+
<p class="card-note">Run a script, persist your files to the cloud, then jump in with SSH.</p>
|
|
66
65
|
</div>
|
|
67
66
|
<div class="tab-content" data-tab="hero-python">
|
|
68
67
|
<pre><code>from mags import Mags
|
|
@@ -112,7 +111,7 @@ console.log(result.logs);</code></pre>
|
|
|
112
111
|
<article class="card" data-reveal>
|
|
113
112
|
<h3>3. Run</h3>
|
|
114
113
|
<pre><code>mags run 'echo Hello World'</code></pre>
|
|
115
|
-
<p>Add <code>-w myproject</code> to
|
|
114
|
+
<p>Add <code>-w myproject -p</code> to persist files to the cloud between runs.</p>
|
|
116
115
|
</article>
|
|
117
116
|
</div>
|
|
118
117
|
</div>
|
|
@@ -186,14 +185,45 @@ mags login</code></pre>
|
|
|
186
185
|
</div>
|
|
187
186
|
|
|
188
187
|
<div class="ref-section">
|
|
189
|
-
<h3>
|
|
188
|
+
<h3>Running Scripts</h3>
|
|
189
|
+
<div class="ref-table-wrap">
|
|
190
|
+
<table class="ref-table">
|
|
191
|
+
<thead><tr><th>Command</th><th>Description</th></tr></thead>
|
|
192
|
+
<tbody>
|
|
193
|
+
<tr><td><code>mags run <script></code></td><td>Run a script in a fresh sandbox. Fastest — no workspace, no persistence.</td></tr>
|
|
194
|
+
<tr><td><code>mags run -w <name> <script></code></td><td>Run with a named workspace. Data stays on the VM only — deleted after 10 min idle.</td></tr>
|
|
195
|
+
<tr><td><code>mags run -w <name> -p <script></code></td><td>Run with a persistent workspace. Files synced to S3 and survive across runs indefinitely.</td></tr>
|
|
196
|
+
<tr><td><code>mags run --url --port <port> <script></code></td><td>Request a public HTTPS URL for your sandbox (requires <code>-p</code>).</td></tr>
|
|
197
|
+
<tr><td><code>mags run --no-sleep <script></code></td><td>Keep sandbox running 24/7, never auto-sleep (requires <code>-p</code>).</td></tr>
|
|
198
|
+
<tr><td><code>mags run -e <script></code></td><td>Ephemeral — no workspace at all, fastest possible execution.</td></tr>
|
|
199
|
+
<tr><td><code>mags run --base <workspace> <script></code></td><td>Use an existing workspace as a read-only base image (OverlayFS).</td></tr>
|
|
200
|
+
<tr><td><code>mags run -f <file> <script></code></td><td>Upload file(s) into the sandbox before running (repeatable).</td></tr>
|
|
201
|
+
</tbody>
|
|
202
|
+
</table>
|
|
203
|
+
</div>
|
|
204
|
+
</div>
|
|
205
|
+
|
|
206
|
+
<div class="ref-section">
|
|
207
|
+
<h3>Sandboxes</h3>
|
|
208
|
+
<div class="ref-table-wrap">
|
|
209
|
+
<table class="ref-table">
|
|
210
|
+
<thead><tr><th>Command</th><th>Description</th></tr></thead>
|
|
211
|
+
<tbody>
|
|
212
|
+
<tr><td><code>mags new <name></code></td><td>Create a new sandbox. Workspace lives on local disk only.</td></tr>
|
|
213
|
+
<tr><td><code>mags new <name> -p</code></td><td>Create a sandbox with persistent workspace — synced to S3.</td></tr>
|
|
214
|
+
<tr><td><code>mags exec <name> <cmd></code></td><td>Execute a command on an existing sandbox.</td></tr>
|
|
215
|
+
<tr><td><code>mags ssh <name></code></td><td>SSH into a sandbox. Auto-starts if sleeping or stopped.</td></tr>
|
|
216
|
+
</tbody>
|
|
217
|
+
</table>
|
|
218
|
+
</div>
|
|
219
|
+
</div>
|
|
220
|
+
|
|
221
|
+
<div class="ref-section">
|
|
222
|
+
<h3>Management</h3>
|
|
190
223
|
<div class="ref-table-wrap">
|
|
191
224
|
<table class="ref-table">
|
|
192
225
|
<thead><tr><th>Command</th><th>Description</th></tr></thead>
|
|
193
226
|
<tbody>
|
|
194
|
-
<tr><td><code>mags run <script></code></td><td>Execute a script in a fresh sandbox</td></tr>
|
|
195
|
-
<tr><td><code>mags ssh <workspace></code></td><td>SSH into a sandbox (auto-starts if needed)</td></tr>
|
|
196
|
-
<tr><td><code>mags exec <workspace> <cmd></code></td><td>Run a command on an existing sandbox</td></tr>
|
|
197
227
|
<tr><td><code>mags list</code></td><td>List recent jobs</td></tr>
|
|
198
228
|
<tr><td><code>mags status <id></code></td><td>Get job status</td></tr>
|
|
199
229
|
<tr><td><code>mags logs <id></code></td><td>Get job output</td></tr>
|
|
@@ -201,10 +231,16 @@ mags login</code></pre>
|
|
|
201
231
|
<tr><td><code>mags set <id> [options]</code></td><td>Update VM settings (e.g. <code>--no-sleep</code>, <code>--sleep</code>)</td></tr>
|
|
202
232
|
<tr><td><code>mags sync <workspace></code></td><td>Sync workspace to the cloud now</td></tr>
|
|
203
233
|
<tr><td><code>mags url <id> [port]</code></td><td>Enable public URL access</td></tr>
|
|
234
|
+
<tr><td><code>mags resize <workspace> --disk <GB></code></td><td>Resize workspace disk</td></tr>
|
|
204
235
|
<tr><td><code>mags workspace list</code></td><td>List persistent workspaces</td></tr>
|
|
205
236
|
<tr><td><code>mags workspace delete <id></code></td><td>Delete workspace + cloud data</td></tr>
|
|
237
|
+
<tr><td><code>mags url alias <sub> <workspace></code></td><td>Create a stable URL alias</td></tr>
|
|
238
|
+
<tr><td><code>mags url alias list</code></td><td>List URL aliases</td></tr>
|
|
239
|
+
<tr><td><code>mags url alias remove <sub></code></td><td>Delete a URL alias</td></tr>
|
|
206
240
|
<tr><td><code>mags cron add [opts] <script></code></td><td>Create a scheduled cron job</td></tr>
|
|
207
241
|
<tr><td><code>mags cron list</code></td><td>List cron jobs</td></tr>
|
|
242
|
+
<tr><td><code>mags cron enable <id></code></td><td>Enable a cron job</td></tr>
|
|
243
|
+
<tr><td><code>mags cron disable <id></code></td><td>Disable a cron job</td></tr>
|
|
208
244
|
<tr><td><code>mags cron remove <id></code></td><td>Delete a cron job</td></tr>
|
|
209
245
|
</tbody>
|
|
210
246
|
</table>
|
|
@@ -212,20 +248,14 @@ mags login</code></pre>
|
|
|
212
248
|
</div>
|
|
213
249
|
|
|
214
250
|
<div class="ref-section">
|
|
215
|
-
<h3>
|
|
251
|
+
<h3>Additional Flags</h3>
|
|
216
252
|
<div class="ref-table-wrap">
|
|
217
253
|
<table class="ref-table">
|
|
218
254
|
<thead><tr><th>Flag</th><th>Description</th></tr></thead>
|
|
219
255
|
<tbody>
|
|
220
|
-
<tr><td><code>-
|
|
221
|
-
<tr><td><code
|
|
222
|
-
<tr><td><code
|
|
223
|
-
<tr><td><code>--no-sleep</code></td><td>Never auto-sleep this VM (requires <code>-p</code>)</td></tr>
|
|
224
|
-
<tr><td><code>-e, --ephemeral</code></td><td>No cloud sync — fastest execution</td></tr>
|
|
225
|
-
<tr><td><code>-f, --file <path></code></td><td>Upload file(s) into the sandbox (repeatable)</td></tr>
|
|
226
|
-
<tr><td><code>-n, --name <name></code></td><td>Name the job for easy reference</td></tr>
|
|
227
|
-
<tr><td><code>--url</code></td><td>Enable public HTTPS URL (requires <code>-p</code>)</td></tr>
|
|
228
|
-
<tr><td><code>--port <port></code></td><td>Port to expose for URL (default: 8080)</td></tr>
|
|
256
|
+
<tr><td><code>-n, --name <name></code></td><td>Alias for <code>-w</code></td></tr>
|
|
257
|
+
<tr><td><code>-e, --ephemeral</code></td><td>No workspace at all, fastest possible execution</td></tr>
|
|
258
|
+
<tr><td><code>--base <workspace></code></td><td>Use an existing workspace as a read-only base image</td></tr>
|
|
229
259
|
<tr><td><code>--disk <GB></code></td><td>Custom disk size in GB (default: 2)</td></tr>
|
|
230
260
|
<tr><td><code>--startup-command <cmd></code></td><td>Command to run when sandbox wakes from sleep</td></tr>
|
|
231
261
|
</tbody>
|
|
@@ -235,39 +265,25 @@ mags login</code></pre>
|
|
|
235
265
|
|
|
236
266
|
<div class="ref-section">
|
|
237
267
|
<h3>Examples</h3>
|
|
238
|
-
<pre><code>#
|
|
239
|
-
mags run
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
mags run -w
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
mags
|
|
249
|
-
mags
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
# Run a command on an existing sandbox
|
|
255
|
-
mags exec myproject 'node --version'
|
|
256
|
-
|
|
257
|
-
# Persistent sandbox with public URL
|
|
258
|
-
mags run -w webapp -p --url --port 8080 \
|
|
268
|
+
<pre><code># Persistent workspace — install packages, then run your app
|
|
269
|
+
mags run -w myproject -p 'pip install flask requests'
|
|
270
|
+
mags run -w myproject -p 'python3 app.py'
|
|
271
|
+
|
|
272
|
+
# Golden image — create once, fork many times
|
|
273
|
+
mags run -w golden -p 'apk add nodejs npm && npm install -g typescript'
|
|
274
|
+
mags sync golden
|
|
275
|
+
mags run --base golden -w fork-1 -p 'npm test'
|
|
276
|
+
|
|
277
|
+
# Interactive sandbox with SSH
|
|
278
|
+
mags new dev -p
|
|
279
|
+
mags ssh dev
|
|
280
|
+
mags exec dev 'node --version'
|
|
281
|
+
|
|
282
|
+
# Always-on web server with public URL
|
|
283
|
+
mags run -w webapp -p --no-sleep --url --port 8080 \
|
|
259
284
|
--startup-command 'python3 -m http.server 8080' \
|
|
260
285
|
'python3 -m http.server 8080'
|
|
261
286
|
|
|
262
|
-
# Always-on sandbox (never auto-sleeps)
|
|
263
|
-
mags run -w worker -p --no-sleep 'python3 worker.py'
|
|
264
|
-
|
|
265
|
-
# Upload files and run
|
|
266
|
-
mags run -f script.py -f data.csv 'python3 script.py'
|
|
267
|
-
|
|
268
|
-
# Ephemeral (fastest — no cloud sync)
|
|
269
|
-
mags run -e 'uname -a && df -h'
|
|
270
|
-
|
|
271
287
|
# Cron job
|
|
272
288
|
mags cron add --name backup --schedule "0 0 * * *" \
|
|
273
289
|
-w backups 'tar czf backup.tar.gz /data'</code></pre>
|
|
@@ -290,21 +306,28 @@ export MAGS_API_TOKEN="your-token"</code></pre>
|
|
|
290
306
|
<tbody>
|
|
291
307
|
<tr><td><code>run(script, **opts)</code></td><td>Submit a job (returns immediately)</td></tr>
|
|
292
308
|
<tr><td><code>run_and_wait(script, **opts)</code></td><td>Submit + block until complete</td></tr>
|
|
293
|
-
<tr><td><code>new(name)</code></td><td>Create persistent
|
|
294
|
-
<tr><td><code>exec(name, command)</code></td><td>Run command on existing sandbox</td></tr>
|
|
309
|
+
<tr><td><code>new(name, **opts)</code></td><td>Create VM sandbox (pass <code>persistent=True</code> for S3)</td></tr>
|
|
310
|
+
<tr><td><code>exec(name, command)</code></td><td>Run command on existing sandbox via SSH</td></tr>
|
|
295
311
|
<tr><td><code>stop(name_or_id)</code></td><td>Stop a running job</td></tr>
|
|
296
312
|
<tr><td><code>find_job(name_or_id)</code></td><td>Find job by name or workspace</td></tr>
|
|
297
313
|
<tr><td><code>url(name_or_id, port)</code></td><td>Enable public URL access</td></tr>
|
|
314
|
+
<tr><td><code>resize(workspace, disk_gb)</code></td><td>Resize workspace disk</td></tr>
|
|
298
315
|
<tr><td><code>status(request_id)</code></td><td>Get job status</td></tr>
|
|
299
316
|
<tr><td><code>logs(request_id)</code></td><td>Get job logs</td></tr>
|
|
300
317
|
<tr><td><code>list_jobs()</code></td><td>List recent jobs</td></tr>
|
|
318
|
+
<tr><td><code>update_job(request_id, **opts)</code></td><td>Update job settings (<code>no_sleep</code>, <code>startup_command</code>)</td></tr>
|
|
301
319
|
<tr><td><code>enable_access(id, port)</code></td><td>Enable URL or SSH access (low-level)</td></tr>
|
|
320
|
+
<tr><td><code>upload_file(path)</code></td><td>Upload a file, returns file ID</td></tr>
|
|
302
321
|
<tr><td><code>upload_files(paths)</code></td><td>Upload files, returns file IDs</td></tr>
|
|
303
322
|
<tr><td><code>list_workspaces()</code></td><td>List persistent workspaces</td></tr>
|
|
304
323
|
<tr><td><code>delete_workspace(id)</code></td><td>Delete workspace + cloud data</td></tr>
|
|
305
324
|
<tr><td><code>sync(request_id)</code></td><td>Sync workspace to S3 now</td></tr>
|
|
325
|
+
<tr><td><code>url_alias_create(sub, ws_id)</code></td><td>Create a stable URL alias</td></tr>
|
|
326
|
+
<tr><td><code>url_alias_list()</code></td><td>List URL aliases</td></tr>
|
|
327
|
+
<tr><td><code>url_alias_delete(sub)</code></td><td>Delete a URL alias</td></tr>
|
|
306
328
|
<tr><td><code>cron_create(**opts)</code></td><td>Create a cron job</td></tr>
|
|
307
329
|
<tr><td><code>cron_list()</code></td><td>List cron jobs</td></tr>
|
|
330
|
+
<tr><td><code>cron_update(id, **opts)</code></td><td>Update a cron job</td></tr>
|
|
308
331
|
<tr><td><code>cron_delete(id)</code></td><td>Delete a cron job</td></tr>
|
|
309
332
|
<tr><td><code>usage(window_days)</code></td><td>Get usage stats</td></tr>
|
|
310
333
|
</tbody>
|
|
@@ -318,11 +341,11 @@ export MAGS_API_TOKEN="your-token"</code></pre>
|
|
|
318
341
|
<table class="ref-table">
|
|
319
342
|
<thead><tr><th>Parameter</th><th>Description</th></tr></thead>
|
|
320
343
|
<tbody>
|
|
321
|
-
<tr><td><code>workspace_id</code></td><td>
|
|
344
|
+
<tr><td><code>workspace_id</code></td><td>Name the workspace. Local only unless <code>persistent=True</code>.</td></tr>
|
|
345
|
+
<tr><td><code>persistent</code></td><td>Keep sandbox alive, sync workspace to S3. Files persist indefinitely.</td></tr>
|
|
322
346
|
<tr><td><code>base_workspace_id</code></td><td>Mount a workspace read-only as base image</td></tr>
|
|
323
|
-
<tr><td><code>persistent</code></td><td>Keep sandbox alive after script completes</td></tr>
|
|
324
347
|
<tr><td><code>no_sleep</code></td><td>Never auto-sleep (requires <code>persistent=True</code>)</td></tr>
|
|
325
|
-
<tr><td><code>ephemeral</code></td><td>No
|
|
348
|
+
<tr><td><code>ephemeral</code></td><td>No workspace, no sync (fastest)</td></tr>
|
|
326
349
|
<tr><td><code>file_ids</code></td><td>List of uploaded file IDs to include</td></tr>
|
|
327
350
|
<tr><td><code>startup_command</code></td><td>Command to run when sandbox wakes</td></tr>
|
|
328
351
|
</tbody>
|
|
@@ -339,23 +362,25 @@ m = Mags() # reads MAGS_API_TOKEN from env
|
|
|
339
362
|
result = m.run_and_wait("echo Hello World")
|
|
340
363
|
print(result["status"]) # "completed"
|
|
341
364
|
|
|
342
|
-
#
|
|
365
|
+
# Local workspace (no S3 sync, good for analysis)
|
|
366
|
+
m.run_and_wait("python3 analyze.py", workspace_id="analysis")
|
|
367
|
+
|
|
368
|
+
# Persistent workspace (synced to S3)
|
|
369
|
+
m.run("pip install flask",
|
|
370
|
+
workspace_id="my-project", persistent=True)
|
|
371
|
+
|
|
372
|
+
# Create a sandbox (local disk)
|
|
343
373
|
m.new("my-project")
|
|
344
374
|
|
|
375
|
+
# Create with S3 persistence
|
|
376
|
+
m.new("my-project", persistent=True)
|
|
377
|
+
|
|
345
378
|
# Execute commands on existing sandbox
|
|
346
379
|
result = m.exec("my-project", "ls -la /root")
|
|
347
380
|
print(result["output"])
|
|
348
|
-
m.exec("my-project", "pip install flask")
|
|
349
|
-
|
|
350
|
-
# Stop a job
|
|
351
|
-
m.stop("my-project")
|
|
352
|
-
|
|
353
|
-
# Find a job by name or workspace
|
|
354
|
-
job = m.find_job("my-project")
|
|
355
|
-
print(job["status"]) # "running", "sleeping", etc.
|
|
356
381
|
|
|
357
382
|
# Public URL
|
|
358
|
-
m.new("webapp")
|
|
383
|
+
m.new("webapp", persistent=True)
|
|
359
384
|
info = m.url("webapp", port=3000)
|
|
360
385
|
print(info["url"]) # https://xyz.apps.magpiecloud.com
|
|
361
386
|
|
|
@@ -394,15 +419,28 @@ export MAGS_API_TOKEN="your-token"</code></pre>
|
|
|
394
419
|
<tbody>
|
|
395
420
|
<tr><td><code>run(script, opts)</code></td><td>Submit a job (returns immediately)</td></tr>
|
|
396
421
|
<tr><td><code>runAndWait(script, opts)</code></td><td>Submit + block until complete</td></tr>
|
|
422
|
+
<tr><td><code>new(name, opts)</code></td><td>Create a VM sandbox (add <code>persistent: true</code> for S3)</td></tr>
|
|
423
|
+
<tr><td><code>exec(nameOrId, command)</code></td><td>Run command on existing sandbox via SSH</td></tr>
|
|
424
|
+
<tr><td><code>stop(nameOrId)</code></td><td>Stop a running job</td></tr>
|
|
425
|
+
<tr><td><code>findJob(nameOrId)</code></td><td>Find job by name or workspace</td></tr>
|
|
426
|
+
<tr><td><code>url(nameOrId, port)</code></td><td>Enable public URL access</td></tr>
|
|
397
427
|
<tr><td><code>status(requestId)</code></td><td>Get job status</td></tr>
|
|
398
428
|
<tr><td><code>logs(requestId)</code></td><td>Get job logs</td></tr>
|
|
399
|
-
<tr><td><code>
|
|
400
|
-
<tr><td><code>
|
|
401
|
-
<tr><td><code>
|
|
429
|
+
<tr><td><code>list()</code></td><td>List recent jobs</td></tr>
|
|
430
|
+
<tr><td><code>updateJob(requestId, opts)</code></td><td>Update job settings (<code>noSleep</code>, <code>startupCommand</code>)</td></tr>
|
|
431
|
+
<tr><td><code>enableAccess(requestId, port)</code></td><td>Enable URL or SSH access</td></tr>
|
|
432
|
+
<tr><td><code>resize(workspace, diskGb)</code></td><td>Resize workspace disk</td></tr>
|
|
433
|
+
<tr><td><code>uploadFiles(paths)</code></td><td>Upload files, returns file IDs</td></tr>
|
|
434
|
+
<tr><td><code>sync(requestId)</code></td><td>Sync workspace to S3 now</td></tr>
|
|
435
|
+
<tr><td><code>listWorkspaces()</code></td><td>List persistent workspaces</td></tr>
|
|
436
|
+
<tr><td><code>deleteWorkspace(id)</code></td><td>Delete workspace + cloud data</td></tr>
|
|
437
|
+
<tr><td><code>urlAliasCreate(sub, wsId)</code></td><td>Create a stable URL alias</td></tr>
|
|
438
|
+
<tr><td><code>urlAliasList()</code></td><td>List URL aliases</td></tr>
|
|
439
|
+
<tr><td><code>urlAliasDelete(sub)</code></td><td>Delete a URL alias</td></tr>
|
|
402
440
|
<tr><td><code>cronCreate(opts)</code></td><td>Create a cron job</td></tr>
|
|
403
441
|
<tr><td><code>cronList()</code></td><td>List cron jobs</td></tr>
|
|
404
442
|
<tr><td><code>cronDelete(id)</code></td><td>Delete a cron job</td></tr>
|
|
405
|
-
<tr><td><code>usage(
|
|
443
|
+
<tr><td><code>usage(opts)</code></td><td>Get usage stats</td></tr>
|
|
406
444
|
</tbody>
|
|
407
445
|
</table>
|
|
408
446
|
</div>
|
|
@@ -414,11 +452,11 @@ export MAGS_API_TOKEN="your-token"</code></pre>
|
|
|
414
452
|
<table class="ref-table">
|
|
415
453
|
<thead><tr><th>Parameter</th><th>Description</th></tr></thead>
|
|
416
454
|
<tbody>
|
|
417
|
-
<tr><td><code>workspaceId</code></td><td>
|
|
455
|
+
<tr><td><code>workspaceId</code></td><td>Name the workspace. Local only unless <code>persistent: true</code>.</td></tr>
|
|
456
|
+
<tr><td><code>persistent</code></td><td>Keep sandbox alive, sync workspace to S3. Files persist indefinitely.</td></tr>
|
|
418
457
|
<tr><td><code>baseWorkspaceId</code></td><td>Mount a workspace read-only as base image</td></tr>
|
|
419
|
-
<tr><td><code>persistent</code></td><td>Keep sandbox alive after script completes</td></tr>
|
|
420
458
|
<tr><td><code>noSleep</code></td><td>Never auto-sleep (requires <code>persistent: true</code>)</td></tr>
|
|
421
|
-
<tr><td><code>ephemeral</code></td><td>No
|
|
459
|
+
<tr><td><code>ephemeral</code></td><td>No workspace, no sync (fastest)</td></tr>
|
|
422
460
|
<tr><td><code>fileIds</code></td><td>Array of uploaded file IDs to include</td></tr>
|
|
423
461
|
<tr><td><code>startupCommand</code></td><td>Command to run when sandbox wakes</td></tr>
|
|
424
462
|
</tbody>
|
|
@@ -435,17 +473,23 @@ const mags = new Mags({ apiToken: process.env.MAGS_API_TOKEN });
|
|
|
435
473
|
const result = await mags.runAndWait('echo Hello World');
|
|
436
474
|
console.log(result.status); // "completed"
|
|
437
475
|
|
|
438
|
-
//
|
|
439
|
-
await mags.runAndWait('
|
|
440
|
-
|
|
476
|
+
// Local workspace (no S3 sync, good for analysis)
|
|
477
|
+
await mags.runAndWait('python3 analyze.py', { workspaceId: 'analysis' });
|
|
478
|
+
|
|
479
|
+
// Persistent workspace (synced to S3)
|
|
480
|
+
await mags.runAndWait('pip install flask', { workspaceId: 'myproject', persistent: true });
|
|
481
|
+
await mags.runAndWait('python3 app.py', { workspaceId: 'myproject', persistent: true });
|
|
441
482
|
|
|
442
483
|
// Base image
|
|
443
484
|
await mags.runAndWait('npm test', { baseWorkspaceId: 'golden' });
|
|
444
|
-
await mags.runAndWait('npm test', { baseWorkspaceId: 'golden', workspaceId: 'fork-1' });
|
|
485
|
+
await mags.runAndWait('npm test', { baseWorkspaceId: 'golden', workspaceId: 'fork-1', persistent: true });
|
|
486
|
+
|
|
487
|
+
// Create a sandbox
|
|
488
|
+
await mags.new('dev', { persistent: true });
|
|
445
489
|
|
|
446
490
|
// SSH access
|
|
447
491
|
const job = await mags.run('sleep 3600', { workspaceId: 'dev', persistent: true });
|
|
448
|
-
const ssh = await mags.enableAccess(job.requestId,
|
|
492
|
+
const ssh = await mags.enableAccess(job.requestId, 22);
|
|
449
493
|
console.log(`ssh root@${ssh.sshHost} -p ${ssh.sshPort}`);
|
|
450
494
|
|
|
451
495
|
// Public URL
|
|
@@ -453,8 +497,8 @@ const webJob = await mags.run('python3 -m http.server 8080', {
|
|
|
453
497
|
workspaceId: 'webapp', persistent: true,
|
|
454
498
|
startupCommand: 'python3 -m http.server 8080',
|
|
455
499
|
});
|
|
456
|
-
const
|
|
457
|
-
console.log(
|
|
500
|
+
const { url } = await mags.url('webapp', 8080);
|
|
501
|
+
console.log(url);
|
|
458
502
|
|
|
459
503
|
// Always-on sandbox (never auto-sleeps)
|
|
460
504
|
await mags.run('python3 worker.py', {
|
|
@@ -488,10 +532,10 @@ await mags.cronCreate({
|
|
|
488
532
|
<article class="panel" data-reveal>
|
|
489
533
|
<h3>Backed up to object storage</h3>
|
|
490
534
|
<ul class="list">
|
|
491
|
-
<li>
|
|
492
|
-
<li>
|
|
535
|
+
<li>Use <code>-w</code> for a local workspace (no cloud sync, good for throwaway analysis)</li>
|
|
536
|
+
<li>Add <code>-p</code> to sync to S3 — files, packages, and configs persist indefinitely</li>
|
|
493
537
|
<li>Clone a workspace as a read-only base for new sandboxes</li>
|
|
494
|
-
<li>Survives reboots, sleep, and agent restarts</li>
|
|
538
|
+
<li>Survives reboots, sleep, and agent restarts (with <code>-p</code>)</li>
|
|
495
539
|
</ul>
|
|
496
540
|
</article>
|
|
497
541
|
<article class="panel" data-reveal>
|
|
@@ -569,8 +613,8 @@ await mags.run('node server.js', {
|
|
|
569
613
|
|
|
570
614
|
m = Mags() # reads MAGS_API_TOKEN from env
|
|
571
615
|
|
|
572
|
-
# Create a
|
|
573
|
-
m.new("demo")
|
|
616
|
+
# Create a sandbox, run commands on it
|
|
617
|
+
m.new("demo") # local disk; use persistent=True for S3
|
|
574
618
|
result = m.exec("demo", "uname -a")
|
|
575
619
|
print(result["output"])
|
|
576
620
|
|
|
@@ -583,13 +627,14 @@ print(result["status"]) # "completed"</code></pre>
|
|
|
583
627
|
<ul class="list">
|
|
584
628
|
<li><code>run(script, **opts)</code> — submit a job</li>
|
|
585
629
|
<li><code>run_and_wait(script, **opts)</code> — submit + block</li>
|
|
586
|
-
<li><code>new(name)</code> — create
|
|
630
|
+
<li><code>new(name, **opts)</code> — create VM sandbox</li>
|
|
587
631
|
<li><code>exec(name, command)</code> — run on existing sandbox</li>
|
|
588
632
|
<li><code>stop(name_or_id)</code> — stop a job</li>
|
|
589
633
|
<li><code>find_job(name_or_id)</code> — find by name/workspace</li>
|
|
590
634
|
<li><code>url(name_or_id, port)</code> — enable public URL</li>
|
|
635
|
+
<li><code>resize(workspace, disk_gb)</code> — resize disk</li>
|
|
591
636
|
<li><code>status(id)</code> / <code>logs(id)</code> / <code>list_jobs()</code></li>
|
|
592
|
-
<li><code>
|
|
637
|
+
<li><code>upload_file(path)</code> / <code>upload_files(paths)</code></li>
|
|
593
638
|
<li><code>list_workspaces()</code> / <code>delete_workspace(id)</code></li>
|
|
594
639
|
<li><code>sync(id)</code> — sync workspace to S3</li>
|
|
595
640
|
<li><code>cron_create(**opts)</code> / <code>cron_list()</code> / <code>cron_delete(id)</code></li>
|
|
@@ -619,14 +664,17 @@ console.log(result.logs);</code></pre>
|
|
|
619
664
|
<ul class="list">
|
|
620
665
|
<li><code>run(script, opts)</code> — submit a job</li>
|
|
621
666
|
<li><code>runAndWait(script, opts)</code> — submit + block</li>
|
|
622
|
-
<li><code>
|
|
623
|
-
<li><code>
|
|
624
|
-
<li><code>
|
|
625
|
-
<li><code>
|
|
626
|
-
<li><code>
|
|
627
|
-
<li><code>
|
|
628
|
-
<li><code>
|
|
629
|
-
<li><code>
|
|
667
|
+
<li><code>new(name, opts)</code> — create VM sandbox</li>
|
|
668
|
+
<li><code>exec(nameOrId, command)</code> — run on existing sandbox</li>
|
|
669
|
+
<li><code>stop(nameOrId)</code> — stop a job</li>
|
|
670
|
+
<li><code>findJob(nameOrId)</code> — find by name/workspace</li>
|
|
671
|
+
<li><code>url(nameOrId, port)</code> — enable public URL</li>
|
|
672
|
+
<li><code>status(id)</code> / <code>logs(id)</code> / <code>list()</code></li>
|
|
673
|
+
<li><code>enableAccess(requestId, port)</code> — URL or SSH</li>
|
|
674
|
+
<li><code>uploadFiles(paths)</code> — upload files</li>
|
|
675
|
+
<li><code>listWorkspaces()</code> / <code>deleteWorkspace(id)</code></li>
|
|
676
|
+
<li><code>sync(id)</code> — sync workspace to S3</li>
|
|
677
|
+
<li><code>cronCreate(opts)</code> / <code>cronList()</code> / <code>cronDelete(id)</code></li>
|
|
630
678
|
</ul>
|
|
631
679
|
<p style="margin-top:1rem"><a class="text-link" href="https://www.npmjs.com/package/@magpiecloud/mags" rel="noreferrer">npm →</a></p>
|
|
632
680
|
</article>
|
|
@@ -653,12 +701,18 @@ console.log(result.logs);</code></pre>
|
|
|
653
701
|
<li><code>GET /mags-jobs/:id/status</code> — status</li>
|
|
654
702
|
<li><code>GET /mags-jobs/:id/logs</code> — logs</li>
|
|
655
703
|
<li><code>POST /mags-jobs/:id/access</code> — URL/SSH</li>
|
|
704
|
+
<li><code>POST /mags-jobs/:id/stop</code> — stop job</li>
|
|
705
|
+
<li><code>POST /mags-jobs/:id/sync</code> — sync workspace</li>
|
|
656
706
|
<li><code>PATCH /mags-jobs/:id</code> — update</li>
|
|
657
707
|
<li><code>POST /mags-files</code> — upload file</li>
|
|
658
708
|
<li><code>GET /mags-workspaces</code> — list ws</li>
|
|
659
709
|
<li><code>DELETE /mags-workspaces/:id</code> — delete ws</li>
|
|
710
|
+
<li><code>POST /mags-url-aliases</code> — create alias</li>
|
|
711
|
+
<li><code>GET /mags-url-aliases</code> — list aliases</li>
|
|
712
|
+
<li><code>DELETE /mags-url-aliases/:sub</code> — delete alias</li>
|
|
660
713
|
<li><code>POST /mags-cron</code> — create cron</li>
|
|
661
714
|
<li><code>GET /mags-cron</code> — list cron</li>
|
|
715
|
+
<li><code>PATCH /mags-cron/:id</code> — update cron</li>
|
|
662
716
|
<li><code>DELETE /mags-cron/:id</code> — delete cron</li>
|
|
663
717
|
</ul>
|
|
664
718
|
<p style="margin-top:1rem"><a class="text-link" href="api.html">Full API reference →</a></p>
|
|
@@ -731,7 +785,7 @@ console.log(result.logs);</code></pre>
|
|
|
731
785
|
</div>
|
|
732
786
|
</footer>
|
|
733
787
|
|
|
734
|
-
<script src="script.js?v=
|
|
788
|
+
<script src="script.js?v=8"></script>
|
|
735
789
|
<script>
|
|
736
790
|
(function() {
|
|
737
791
|
var token = localStorage.getItem('microvm-access-token');
|