gigadrive 2.14.0 → 2.15.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/dist/index.cjs +148 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +148 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -32,7 +32,7 @@ var import_effect31 = require("effect");
|
|
|
32
32
|
// package.json
|
|
33
33
|
var package_default = {
|
|
34
34
|
name: "gigadrive",
|
|
35
|
-
version: "2.
|
|
35
|
+
version: "2.15.0",
|
|
36
36
|
repository: {
|
|
37
37
|
type: "git",
|
|
38
38
|
url: "https://github.com/Gigadrive/sdk.git",
|
|
@@ -3108,6 +3108,17 @@ var formatWebhookTable = (webhooks) => formatTable([
|
|
|
3108
3108
|
webhook.id
|
|
3109
3109
|
])
|
|
3110
3110
|
]);
|
|
3111
|
+
var formatVolumeTable = (volumes) => formatTable([
|
|
3112
|
+
["NAME", "SIZE", "STORED", "STATUS", "LAST SAVED", "ID"],
|
|
3113
|
+
...volumes.map((volume) => [
|
|
3114
|
+
volume.name,
|
|
3115
|
+
`${String(volume.sizeMb)} MiB`,
|
|
3116
|
+
volume.storedBytes === null ? "-" : formatBytes(volume.storedBytes),
|
|
3117
|
+
volume.attachedMicrovmId ? `${volume.status} (${volume.attachedMicrovmId})` : volume.status,
|
|
3118
|
+
volume.lastSaveError ? `failed: ${volume.lastSaveError}` : volume.lastSavedAt ?? "never",
|
|
3119
|
+
volume.id
|
|
3120
|
+
])
|
|
3121
|
+
]);
|
|
3111
3122
|
var formatDeliveryTable = (deliveries) => formatTable([
|
|
3112
3123
|
["CREATED", "EVENT", "STATUS", "ATTEMPTS", "RESPONSE", "MICROVM"],
|
|
3113
3124
|
...deliveries.map((delivery) => [
|
|
@@ -3353,6 +3364,25 @@ var withClient = (run) => import_effect24.Effect.gen(function* () {
|
|
|
3353
3364
|
return yield* import_effect24.Effect.tryPromise({ try: () => run(client), catch: toApiRequestError });
|
|
3354
3365
|
});
|
|
3355
3366
|
var signalOnInterrupt = (signal) => (command, exit) => import_effect24.Exit.isInterrupted(exit) ? import_effect24.Effect.tryPromise(() => command.kill(signal)).pipe(import_effect24.Effect.timeout("2 seconds"), import_effect24.Effect.ignore) : import_effect24.Effect.void;
|
|
3367
|
+
var UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
3368
|
+
var parseVolumeFlags = (values) => import_effect24.Effect.gen(function* () {
|
|
3369
|
+
if (values.length > 4) {
|
|
3370
|
+
return yield* new InvalidMicroVmOptionsError({ message: "--volume takes at most 4 volumes." });
|
|
3371
|
+
}
|
|
3372
|
+
const volumes = [];
|
|
3373
|
+
for (const value of values) {
|
|
3374
|
+
const separator = value.indexOf(":");
|
|
3375
|
+
const volumeId = separator > 0 ? value.slice(0, separator) : "";
|
|
3376
|
+
const mountPath = separator > 0 ? value.slice(separator + 1) : "";
|
|
3377
|
+
if (volumeId === "" || !mountPath.startsWith("/")) {
|
|
3378
|
+
return yield* new InvalidMicroVmOptionsError({
|
|
3379
|
+
message: `--volume must be VOLUME:PATH with an absolute path, such as cache:/cache (got ${value}).`
|
|
3380
|
+
});
|
|
3381
|
+
}
|
|
3382
|
+
volumes.push({ volumeId, mountPath });
|
|
3383
|
+
}
|
|
3384
|
+
return volumes;
|
|
3385
|
+
});
|
|
3356
3386
|
var checkEgressFlags = (denyEgress, allowEgress) => import_effect24.Effect.gen(function* () {
|
|
3357
3387
|
if (denyEgress && allowEgress.length > 0) {
|
|
3358
3388
|
return yield* new InvalidMicroVmOptionsError({
|
|
@@ -3383,6 +3413,10 @@ var createInput = (flags) => import_effect24.Effect.gen(function* () {
|
|
|
3383
3413
|
if (badPort !== void 0) {
|
|
3384
3414
|
return yield* new InvalidMicroVmOptionsError({ message: `--port must be between 1 and 65535 (got ${badPort}).` });
|
|
3385
3415
|
}
|
|
3416
|
+
const volumes = yield* parseVolumeFlags(flags.volumes);
|
|
3417
|
+
if (volumes.length > 0 && flags.pauseOnTimeout) {
|
|
3418
|
+
return yield* new InvalidMicroVmOptionsError({ message: "--volume cannot be combined with --pause-on-timeout." });
|
|
3419
|
+
}
|
|
3386
3420
|
const applicationId = yield* resolveApplicationId(flags.app);
|
|
3387
3421
|
const input = {
|
|
3388
3422
|
...applicationId ? { applicationId } : {},
|
|
@@ -3399,6 +3433,7 @@ var createInput = (flags) => import_effect24.Effect.gen(function* () {
|
|
|
3399
3433
|
...flags.ports.length > 0 ? { ports: [...flags.ports] } : {},
|
|
3400
3434
|
...env ? { env } : {},
|
|
3401
3435
|
...metadata ? { metadata } : {},
|
|
3436
|
+
...volumes.length > 0 ? { volumes } : {},
|
|
3402
3437
|
...flags.denyEgress || flags.privatePreviews || flags.allowEgress.length > 0 ? {
|
|
3403
3438
|
network: {
|
|
3404
3439
|
egress: flags.denyEgress ? "deny" : "allow",
|
|
@@ -3412,7 +3447,26 @@ var createInput = (flags) => import_effect24.Effect.gen(function* () {
|
|
|
3412
3447
|
});
|
|
3413
3448
|
var createMicroVm = (flags) => import_effect24.Effect.gen(function* () {
|
|
3414
3449
|
const apiClient = yield* ApiClientService;
|
|
3415
|
-
const
|
|
3450
|
+
const parsed = yield* createInput(flags);
|
|
3451
|
+
const named = (parsed.volumes ?? []).filter((volume) => !UUID.test(volume.volumeId));
|
|
3452
|
+
const known = named.length > 0 ? yield* apiClient.request(
|
|
3453
|
+
(client) => client.microvms.volumes.list({ ...parsed.applicationId ? { applicationId: parsed.applicationId } : {} })
|
|
3454
|
+
) : [];
|
|
3455
|
+
const volumes = [];
|
|
3456
|
+
for (const volume of parsed.volumes ?? []) {
|
|
3457
|
+
if (UUID.test(volume.volumeId)) {
|
|
3458
|
+
volumes.push(volume);
|
|
3459
|
+
continue;
|
|
3460
|
+
}
|
|
3461
|
+
const match = known.find((entry) => entry.name === volume.volumeId);
|
|
3462
|
+
if (match === void 0) {
|
|
3463
|
+
return yield* new InvalidMicroVmOptionsError({
|
|
3464
|
+
message: `No volume is named ${volume.volumeId}. Create it with "gigadrive microvms volumes create ${volume.volumeId}".`
|
|
3465
|
+
});
|
|
3466
|
+
}
|
|
3467
|
+
volumes.push({ volumeId: match.id, mountPath: volume.mountPath });
|
|
3468
|
+
}
|
|
3469
|
+
const input = volumes.length > 0 ? { ...parsed, volumes } : parsed;
|
|
3416
3470
|
if (!flags.json) yield* import_effect24.Console.error(`Creating a microVM from ${input.image ?? "node22"}...`);
|
|
3417
3471
|
const vm = yield* apiClient.request((client) => client.microvms.create(input));
|
|
3418
3472
|
if (flags.json) {
|
|
@@ -3483,6 +3537,13 @@ var createCommand = import_cli12.Command.make(
|
|
|
3483
3537
|
"Resume the paused microVM when a command, file call or public preview request reaches it"
|
|
3484
3538
|
)
|
|
3485
3539
|
),
|
|
3540
|
+
volumes: import_cli12.Options.text("volume").pipe(
|
|
3541
|
+
import_cli12.Options.withAlias("v"),
|
|
3542
|
+
import_cli12.Options.withDescription(
|
|
3543
|
+
"Attach a volume as VOLUME:PATH, by ID or name, such as cache:/cache (repeatable, up to 4; saved when the microVM stops)"
|
|
3544
|
+
),
|
|
3545
|
+
import_cli12.Options.repeated
|
|
3546
|
+
),
|
|
3486
3547
|
region: import_cli12.Options.text("region").pipe(import_cli12.Options.withDescription("Region to place the microVM in"), import_cli12.Options.optional),
|
|
3487
3548
|
json: jsonOption2
|
|
3488
3549
|
},
|
|
@@ -3965,6 +4026,90 @@ var imagesCommand = import_cli12.Command.make("images", {}, () => import_effect2
|
|
|
3965
4026
|
import_cli12.Command.withDescription("Built-in and custom microVM images"),
|
|
3966
4027
|
import_cli12.Command.withSubcommands([imagesListCommand, imagesCreateCommand, imagesRemoveCommand])
|
|
3967
4028
|
);
|
|
4029
|
+
var volumeIdArg = import_cli12.Args.text({ name: "volume-id" }).pipe(import_cli12.Args.withDescription("The volume ID"));
|
|
4030
|
+
var volumesListCommand = import_cli12.Command.make(
|
|
4031
|
+
"ls",
|
|
4032
|
+
{ app: appOption6, json: jsonOption2 },
|
|
4033
|
+
({ app, json }) => import_effect24.Effect.gen(function* () {
|
|
4034
|
+
const apiClient = yield* ApiClientService;
|
|
4035
|
+
const applicationId = yield* resolveApplicationId(app);
|
|
4036
|
+
const volumes = yield* apiClient.request((client) => client.microvms.volumes.list({ applicationId }));
|
|
4037
|
+
if (json) return yield* import_effect24.Console.log(JSON.stringify(volumes, null, 2));
|
|
4038
|
+
if (volumes.length === 0)
|
|
4039
|
+
return yield* import_effect24.Console.log('No volumes yet. Create one with "gigadrive microvms volumes create <name>".');
|
|
4040
|
+
for (const line of formatVolumeTable(volumes)) yield* import_effect24.Console.log(line);
|
|
4041
|
+
}).pipe(reportErrors2("list volumes"))
|
|
4042
|
+
).pipe(import_cli12.Command.withDescription("List the application's volumes"));
|
|
4043
|
+
var createVolume = (flags) => import_effect24.Effect.gen(function* () {
|
|
4044
|
+
const apiClient = yield* ApiClientService;
|
|
4045
|
+
const applicationId = yield* resolveApplicationId(flags.app);
|
|
4046
|
+
const volume = yield* apiClient.request(
|
|
4047
|
+
(client) => client.microvms.volumes.create({
|
|
4048
|
+
name: flags.name,
|
|
4049
|
+
...import_effect24.Option.match(flags.size, { onNone: () => ({}), onSome: (sizeMb) => ({ sizeMb }) }),
|
|
4050
|
+
...applicationId ? { applicationId } : {}
|
|
4051
|
+
})
|
|
4052
|
+
);
|
|
4053
|
+
if (flags.json) {
|
|
4054
|
+
yield* import_effect24.Console.log(JSON.stringify(volume, null, 2));
|
|
4055
|
+
} else {
|
|
4056
|
+
yield* import_effect24.Console.log(`Created volume ${volume.name} (${String(volume.sizeMb)} MiB, ${volume.id}).`);
|
|
4057
|
+
yield* import_effect24.Console.log(`Attach it: gigadrive microvms create --volume ${volume.name}:/data`);
|
|
4058
|
+
}
|
|
4059
|
+
return volume;
|
|
4060
|
+
});
|
|
4061
|
+
var volumesCreateCommand = import_cli12.Command.make(
|
|
4062
|
+
"create",
|
|
4063
|
+
{
|
|
4064
|
+
name: import_cli12.Args.text({ name: "name" }).pipe(
|
|
4065
|
+
import_cli12.Args.withDescription("Lowercase letters, digits and -, unique per application")
|
|
4066
|
+
),
|
|
4067
|
+
size: import_cli12.Options.integer("size").pipe(
|
|
4068
|
+
import_cli12.Options.withDescription("Size in MiB, 1024 to 51200 (default: 10240)"),
|
|
4069
|
+
import_cli12.Options.optional
|
|
4070
|
+
),
|
|
4071
|
+
app: appOption6,
|
|
4072
|
+
json: jsonOption2
|
|
4073
|
+
},
|
|
4074
|
+
(flags) => createVolume(flags).pipe(import_effect24.Effect.asVoid, reportErrors2("create the volume"))
|
|
4075
|
+
).pipe(import_cli12.Command.withDescription("Create an empty volume"));
|
|
4076
|
+
var volumesRenameCommand = import_cli12.Command.make(
|
|
4077
|
+
"rename",
|
|
4078
|
+
{ volumeId: volumeIdArg, name: import_cli12.Args.text({ name: "name" }).pipe(import_cli12.Args.withDescription("The new name")) },
|
|
4079
|
+
({ volumeId, name }) => import_effect24.Effect.gen(function* () {
|
|
4080
|
+
const apiClient = yield* ApiClientService;
|
|
4081
|
+
const volume = yield* apiClient.request((client) => client.microvms.volumes.rename(volumeId, name));
|
|
4082
|
+
yield* import_effect24.Console.log(`Renamed the volume to ${volume.name}.`);
|
|
4083
|
+
}).pipe(reportErrors2("rename the volume"))
|
|
4084
|
+
).pipe(import_cli12.Command.withDescription("Rename a volume"));
|
|
4085
|
+
var volumesSaveCommand = import_cli12.Command.make(
|
|
4086
|
+
"save",
|
|
4087
|
+
{ microvmId: import_cli12.Args.text({ name: "microvm-id" }).pipe(import_cli12.Args.withDescription("A running microVM with volumes")) },
|
|
4088
|
+
({ microvmId }) => import_effect24.Effect.gen(function* () {
|
|
4089
|
+
const apiClient = yield* ApiClientService;
|
|
4090
|
+
yield* apiClient.request((client) => client.microvms.saveVolumes(microvmId));
|
|
4091
|
+
yield* import_effect24.Console.log(`Saved the volumes of ${microvmId}.`);
|
|
4092
|
+
}).pipe(reportErrors2("save the volumes"))
|
|
4093
|
+
).pipe(import_cli12.Command.withDescription("Save a running microVM's volumes without stopping it"));
|
|
4094
|
+
var volumesRemoveCommand = import_cli12.Command.make(
|
|
4095
|
+
"rm",
|
|
4096
|
+
{ volumeId: volumeIdArg },
|
|
4097
|
+
({ volumeId }) => import_effect24.Effect.gen(function* () {
|
|
4098
|
+
const apiClient = yield* ApiClientService;
|
|
4099
|
+
yield* apiClient.request((client) => client.microvms.volumes.delete(volumeId));
|
|
4100
|
+
yield* import_effect24.Console.log(`Deleted volume ${volumeId}.`);
|
|
4101
|
+
}).pipe(reportErrors2("delete the volume"))
|
|
4102
|
+
).pipe(import_cli12.Command.withDescription("Delete a volume and its contents (it must not be attached)"));
|
|
4103
|
+
var volumesCommand = import_cli12.Command.make("volumes", {}, () => import_effect24.Effect.void).pipe(
|
|
4104
|
+
import_cli12.Command.withDescription("Persistent filesystems that outlive the microVMs they are attached to"),
|
|
4105
|
+
import_cli12.Command.withSubcommands([
|
|
4106
|
+
volumesListCommand,
|
|
4107
|
+
volumesCreateCommand,
|
|
4108
|
+
volumesRenameCommand,
|
|
4109
|
+
volumesSaveCommand,
|
|
4110
|
+
volumesRemoveCommand
|
|
4111
|
+
])
|
|
4112
|
+
);
|
|
3968
4113
|
var WEBHOOK_EVENTS = [
|
|
3969
4114
|
"microvm.created",
|
|
3970
4115
|
"microvm.running",
|
|
@@ -4093,6 +4238,7 @@ var SUBCOMMANDS = [
|
|
|
4093
4238
|
extendCommand,
|
|
4094
4239
|
networkCommand,
|
|
4095
4240
|
imagesCommand,
|
|
4241
|
+
volumesCommand,
|
|
4096
4242
|
webhooksCommand
|
|
4097
4243
|
];
|
|
4098
4244
|
var microvmsCommand = import_cli12.Command.make("microvms", {}, () => import_effect24.Effect.void).pipe(
|