gigadrive 2.11.0 → 2.13.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.mjs CHANGED
@@ -9,7 +9,7 @@ import { Effect as Effect29, Layer, LogLevel, Logger } from "effect";
9
9
  // package.json
10
10
  var package_default = {
11
11
  name: "gigadrive",
12
- version: "2.11.0",
12
+ version: "2.13.0",
13
13
  repository: {
14
14
  type: "git",
15
15
  url: "https://github.com/Gigadrive/sdk.git",
@@ -3323,29 +3323,32 @@ var withClient = (run) => Effect22.gen(function* () {
3323
3323
  return yield* Effect22.tryPromise({ try: () => run(client), catch: toApiRequestError });
3324
3324
  });
3325
3325
  var signalOnInterrupt = (signal) => (command, exit) => Exit.isInterrupted(exit) ? Effect22.tryPromise(() => command.kill(signal)).pipe(Effect22.timeout("2 seconds"), Effect22.ignore) : Effect22.void;
3326
- var createInput = (flags) => Effect22.gen(function* () {
3327
- const env = yield* keyValues("--env", flags.env);
3328
- const metadata = yield* keyValues("--metadata", flags.metadata);
3329
- const timeoutMs = yield* Option14.match(flags.timeout, {
3330
- onNone: () => Effect22.succeed(void 0),
3331
- onSome: (text) => parseLifetime("--timeout", text)
3332
- });
3333
- if (flags.denyEgress && flags.allowEgress.length > 0) {
3326
+ var checkEgressFlags = (denyEgress, allowEgress) => Effect22.gen(function* () {
3327
+ if (denyEgress && allowEgress.length > 0) {
3334
3328
  return yield* new InvalidMicroVmOptionsError({
3335
3329
  message: "--allow-egress cannot be combined with --deny-egress."
3336
3330
  });
3337
3331
  }
3338
- if (flags.allowEgress.length > 32) {
3332
+ if (allowEgress.length > 32) {
3339
3333
  return yield* new InvalidMicroVmOptionsError({ message: "--allow-egress takes at most 32 entries." });
3340
3334
  }
3341
3335
  const network = /^\d{1,3}(\.\d{1,3}){3}\/\d{1,2}$/;
3342
3336
  const domain = /^(\*\.)?([a-z0-9-]+\.)+[a-z0-9-]*[a-z][a-z0-9-]*\.?$/i;
3343
- const badEntry = flags.allowEgress.find((entry) => !network.test(entry.trim()) && !domain.test(entry.trim()));
3337
+ const badEntry = allowEgress.find((entry) => !network.test(entry.trim()) && !domain.test(entry.trim()));
3344
3338
  if (badEntry !== void 0) {
3345
3339
  return yield* new InvalidMicroVmOptionsError({
3346
3340
  message: `--allow-egress must be a domain name such as api.openai.com or *.github.com, or an IPv4 network such as 140.82.112.0/20 (got ${badEntry}).`
3347
3341
  });
3348
3342
  }
3343
+ });
3344
+ var createInput = (flags) => Effect22.gen(function* () {
3345
+ const env = yield* keyValues("--env", flags.env);
3346
+ const metadata = yield* keyValues("--metadata", flags.metadata);
3347
+ const timeoutMs = yield* Option14.match(flags.timeout, {
3348
+ onNone: () => Effect22.succeed(void 0),
3349
+ onSome: (text) => parseLifetime("--timeout", text)
3350
+ });
3351
+ yield* checkEgressFlags(flags.denyEgress, flags.allowEgress);
3349
3352
  const badPort = flags.ports.find((port) => !Number.isInteger(port) || port < 1 || port > 65535);
3350
3353
  if (badPort !== void 0) {
3351
3354
  return yield* new InvalidMicroVmOptionsError({ message: `--port must be between 1 and 65535 (got ${badPort}).` });
@@ -3361,6 +3364,8 @@ var createInput = (flags) => Effect22.gen(function* () {
3361
3364
  ...Option14.match(flags.memory, { onNone: () => ({}), onSome: (memoryMb) => ({ memoryMb }) }),
3362
3365
  ...Option14.match(flags.disk, { onNone: () => ({}), onSome: (diskMb) => ({ diskMb }) }),
3363
3366
  ...timeoutMs !== void 0 ? { timeoutMs } : {},
3367
+ ...flags.pauseOnTimeout ? { onTimeout: "pause" } : {},
3368
+ ...flags.autoResume ? { autoResume: true } : {},
3364
3369
  ...flags.ports.length > 0 ? { ports: [...flags.ports] } : {},
3365
3370
  ...env ? { env } : {},
3366
3371
  ...metadata ? { metadata } : {},
@@ -3368,7 +3373,7 @@ var createInput = (flags) => Effect22.gen(function* () {
3368
3373
  network: {
3369
3374
  egress: flags.denyEgress ? "deny" : "allow",
3370
3375
  ...flags.privatePreviews ? { previews: "private" } : {},
3371
- ...flags.allowEgress.length > 0 ? { allow: [...flags.allowEgress] } : {}
3376
+ ...flags.allowEgress.length > 0 ? { allow: flags.allowEgress.map((entry) => entry.trim()) } : {}
3372
3377
  }
3373
3378
  } : {},
3374
3379
  ...Option14.match(flags.region, { onNone: () => ({}), onSome: (region) => ({ region }) })
@@ -3440,6 +3445,14 @@ var createCommand = Command12.make(
3440
3445
  ),
3441
3446
  Options7.repeated
3442
3447
  ),
3448
+ pauseOnTimeout: Options7.boolean("pause-on-timeout").pipe(
3449
+ Options7.withDescription("Pause the microVM when its timeout ends instead of stopping it")
3450
+ ),
3451
+ autoResume: Options7.boolean("auto-resume").pipe(
3452
+ Options7.withDescription(
3453
+ "Resume the paused microVM when a command, file call or public preview request reaches it"
3454
+ )
3455
+ ),
3443
3456
  region: Options7.text("region").pipe(Options7.withDescription("Region to place the microVM in"), Options7.optional),
3444
3457
  json: jsonOption2
3445
3458
  },
@@ -3495,6 +3508,36 @@ var getCommand = Command12.make(
3495
3508
  for (const line of describeMicroVm(vm)) yield* Console12.log(line);
3496
3509
  }).pipe(reportErrors2("get the microVM"))
3497
3510
  ).pipe(Command12.withDescription("Show a microVM"));
3511
+ var formatGigabytes = (bytes) => `${(bytes / 1e9).toFixed(1)} GB`;
3512
+ var describeMicroVmMetrics = (metrics) => {
3513
+ const latest = metrics.cpu.at(-1);
3514
+ const peak = metrics.cpu.reduce((max, point) => Math.max(max, point.cpuPercent), 0);
3515
+ return [
3516
+ `CPU (last ${metrics.windowMinutes} min, ${metrics.vcpus} vCPU): ${latest ? `${latest.cpuPercent}% at ${latest.time}, peak ${peak}%` : "no samples"}`,
3517
+ metrics.current ? `Memory: ${formatGigabytes(metrics.current.memoryUsedBytes)} of ${formatGigabytes(metrics.current.memoryTotalBytes)}` : "Memory: unavailable (not running, or no answer)",
3518
+ metrics.current ? `Disk: ${formatGigabytes(metrics.current.diskUsedBytes)} of ${formatGigabytes(metrics.current.diskTotalBytes)}` : "Disk: unavailable (not running, or no answer)"
3519
+ ];
3520
+ };
3521
+ var metricsCommand = Command12.make(
3522
+ "metrics",
3523
+ {
3524
+ microvmId: microvmIdArg,
3525
+ window: Options7.integer("window").pipe(
3526
+ Options7.withDescription("Minutes of CPU history, 1 to 1440 (default: 15)"),
3527
+ Options7.optional
3528
+ ),
3529
+ json: jsonOption2
3530
+ },
3531
+ ({ microvmId, window, json }) => Effect22.gen(function* () {
3532
+ const apiClient = yield* ApiClientService;
3533
+ const windowMinutes = Option14.getOrUndefined(window);
3534
+ const metrics = yield* apiClient.request(
3535
+ (client) => client.microvms.getMetrics(microvmId, windowMinutes === void 0 ? {} : { windowMinutes })
3536
+ );
3537
+ if (json) return yield* Console12.log(JSON.stringify(metrics, null, 2));
3538
+ for (const line of describeMicroVmMetrics(metrics)) yield* Console12.log(line);
3539
+ }).pipe(reportErrors2("read the microVM metrics"))
3540
+ ).pipe(Command12.withDescription("Show a microVM's CPU, memory and disk use"));
3498
3541
  var execInMicroVm = (flags, io = nodeSessionIo()) => Effect22.gen(function* () {
3499
3542
  const env = yield* keyValues("--env", flags.env);
3500
3543
  const timeout = yield* optionalDuration("--timeout", flags.timeout);
@@ -3756,6 +3799,46 @@ var extendCommand = Command12.make(
3756
3799
  },
3757
3800
  ({ microvmId, duration }) => extendMicroVm(microvmId, duration).pipe(Effect22.asVoid, reportErrors2("extend the microVM"))
3758
3801
  ).pipe(Command12.withDescription("Set how long a microVM keeps running, counted from now"));
3802
+ var updateMicroVmNetwork = (microvmId, flags) => Effect22.gen(function* () {
3803
+ const chosen = [flags.denyEgress, flags.allowEgress.length > 0, flags.allowAllEgress].filter(Boolean).length;
3804
+ if (chosen !== 1) {
3805
+ return yield* new InvalidMicroVmOptionsError({
3806
+ message: "Pass exactly one of --deny-egress, --allow-egress or --allow-all-egress."
3807
+ });
3808
+ }
3809
+ yield* checkEgressFlags(flags.denyEgress, flags.allowEgress);
3810
+ const apiClient = yield* ApiClientService;
3811
+ const vm = yield* apiClient.request(
3812
+ (client) => client.microvms.updateNetwork(
3813
+ microvmId,
3814
+ flags.denyEgress ? { egress: "deny" } : flags.allowEgress.length > 0 ? { egress: "allow", allow: flags.allowEgress.map((entry) => entry.trim()) } : { egress: "allow" }
3815
+ )
3816
+ );
3817
+ const reach = vm.network.egress === "deny" ? "no outbound traffic" : vm.network.allow ? vm.network.allow.join(", ") : "the whole internet";
3818
+ yield* Console12.log(`${vm.id} now reaches ${reach}.`);
3819
+ return vm;
3820
+ });
3821
+ var networkCommand = Command12.make(
3822
+ "network",
3823
+ {
3824
+ microvmId: microvmIdArg,
3825
+ denyEgress: Options7.boolean("deny-egress").pipe(Options7.withDescription("Block all outbound network traffic")),
3826
+ allowEgress: Options7.text("allow-egress").pipe(
3827
+ Options7.withDescription(
3828
+ "Only reach this domain name (api.openai.com, *.github.com for every subdomain) or public IPv4 network (140.82.112.0/20) (repeatable, up to 32)"
3829
+ ),
3830
+ Options7.repeated
3831
+ ),
3832
+ allowAllEgress: Options7.boolean("allow-all-egress").pipe(
3833
+ Options7.withDescription("Reach the whole internet again (private networks stay blocked)")
3834
+ )
3835
+ },
3836
+ ({ microvmId, ...flags }) => updateMicroVmNetwork(microvmId, flags).pipe(Effect22.asVoid, reportErrors2("update the microVM network"))
3837
+ ).pipe(
3838
+ Command12.withDescription(
3839
+ "Change what a running or paused microVM may reach; connections the new rules no longer allow are closed"
3840
+ )
3841
+ );
3759
3842
  var imagesListCommand = Command12.make(
3760
3843
  "ls",
3761
3844
  { app: appOption6, json: jsonOption2 },
@@ -3856,12 +3939,14 @@ var SUBCOMMANDS = [
3856
3939
  createCommand,
3857
3940
  listCommand2,
3858
3941
  getCommand,
3942
+ metricsCommand,
3859
3943
  execCommand,
3860
3944
  shellCommand,
3861
3945
  copyCommand,
3862
3946
  stopCommand,
3863
3947
  removeCommand2,
3864
3948
  extendCommand,
3949
+ networkCommand,
3865
3950
  imagesCommand
3866
3951
  ];
3867
3952
  var microvmsCommand = Command12.make("microvms", {}, () => Effect22.void).pipe(