Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ svc.command('add [type] [name]').description('Provision a service on demand (ass
.option('--image <url>', 'compute only: run this container image at creation')
.option('--port <n>', 'compute only: port the image listens on (default 8080)')
.option('--always-on', 'compute only: create as always-on — never scales to zero (all plans; billing is actual usage either way)')
.option('--volume <gi>', 'compute only: attach a persistent /data volume of this many whole Gi (also attachable later: `insta compute volume <name> --size <gi>`; any plan may attach at the default 1; larger sizes are paid and plan-capped). Volume services keep 1 machine and stop (cold wake) instead of suspend when idle')
.option('--volume <gi>', 'compute only: attach a persistent /data volume of this many whole Gi (also attachable later: `insta compute volume <name> --size <gi>`; any plan may attach at the default 10 (the free cap, on every plan); larger sizes are paid and plan-capped). Volume services keep 1 machine and stop (cold wake) instead of suspend when idle')
.option('--json')
.action(guard(async (type, name, o) => {
const a = await resolveServiceArgs(type, name, serviceArgsDeps(o.json), o)
Expand Down Expand Up @@ -233,7 +233,7 @@ compute.command('restart [service]').description("Restart a compute service by r
.option('--json').option('--branch <branch>', 'branch (default: current)').action(guard((service, o) => computeCmd.computeRestart(service, o)))
compute.command('status [service]').description("Show a compute service's desired vs. live state")
.option('--json').option('--branch <branch>', 'branch (default: current)').action(guard((service, o) => computeCmd.computeStatus(service, o)))
compute.command('limits [service]').description("Show or set a compute service's resource ceiling (paid plans). --memory is the dial; cpu derives from it unless --cpu is given. Billing is actual usage — the ceiling caps what the app may burn, it is not a price")
compute.command('limits [service]').description("Show or set a compute service's resource ceiling (any plan within the free cap; raising above it needs a paid plan). --memory is the dial; cpu derives from it unless --cpu is given. Billing is actual usage — the ceiling caps what the app may burn, it is not a price")
.option('--memory <size>', 'memory ceiling, e.g. 512mb or 1gb').option('--cpu <n>', 'vCPU ceiling override (provider sizes: 1, 2, 4, 6, 8)')
.option('--json').option('--branch <branch>', 'branch (default: current)').action(guard((service, o) => computeCmd.computeLimits(service, o)))
compute.command('always-on <mode> [service]').description('Set a compute service always-on (mode: on|off). on = machines never scale to zero; off = default scale-to-zero. All plans; billing is actual usage either way')
Expand All @@ -243,7 +243,7 @@ const execCmd = compute.command('exec [service]').description("Run a one-shot co
// Declared from the same list splitExecArgs uses to find where the CLI's own arguments stop, so a
// new option cannot reach the CLI surface while the split still reads it as part of the command.
for (const [flags, description] of computeCmd.EXEC_OPTIONS) execCmd.option(flags, description)
compute.command('volume [service]').description("Show, attach, grow, or delete a compute service's persistent /data volume. No flag: print size, mount path, and the plan cap (any plan). --size on a volumeless service ATTACHES one (any plan at the default 1Gi; larger is paid and plan-capped; the disk mounts at /data on the next deploy); on a volume-bearing one it grows (paid plans; grow-only — a provisioned disk cannot shrink). --delete DESTROYS the disk and ALL its data immediately (no detach, no undo; billing stops now, and suspend fast-wake + scale-out return). Billing is actual data stored — the size is a cap, not a price")
compute.command('volume [service]').description("Show, attach, grow, or delete a compute service's persistent /data volume. No flag: print size, mount path, and the plan cap (any plan). --size on a volumeless service ATTACHES one (any plan at the default 10Gi, the free cap; larger is paid and plan-capped; the disk mounts at /data on the next deploy); on a volume-bearing one it grows (paid plans; grow-only — a provisioned disk cannot shrink). --delete DESTROYS the disk and ALL its data immediately (no detach, no undo; billing stops now, and suspend fast-wake + scale-out return). Billing is actual data stored — the size is a cap, not a price")
.option('--size <gi>', 'new size in whole Gi, e.g. 10 (must be ≥ the current size)')
.option('--delete', 'destroy the volume and ALL its data (irreversible; download anything you need first)')
.option('--json').option('--branch <branch>', 'branch (default: current)').action(guard((service, o) => computeCmd.computeVolume(service, o)))
Expand All @@ -256,7 +256,7 @@ db.command('url').description('Print the postgres connection string (DSN) — ba
db.command('connect').description("Open an interactive psql session on the postgres service (needs psql on PATH; gated: secrets.read). A suspended instance wakes on connect — the first prompt can take a few seconds. Exits with psql's own exit code")
.option('--branch <branch>', 'branch (default: current)').option('--group <g>', 'postgres service name (default: the sole/default one)')
.action(guard((o) => dbCmd.dbConnect(o)))
db.command('limits').description("Show or set a postgres service's resource ceiling (paid plans; insta-db-backed only). Moves both directions")
db.command('limits').description("Show or set a postgres service's resource ceiling (any plan within the free cap, paid above it; insta-db-backed only). Moves both directions")
.option('--cpu <n>', "vCPU ceiling, e.g. 2 or 2500m").option('--memory <size>', "memory ceiling, e.g. 4Gi")
.option('--json').option('--branch <branch>', 'branch (default: current)').option('--group <g>', 'postgres service name (default: the sole/default one)')
.action(guard((o) => dbCmd.dbLimits(o)))
Expand Down
5 changes: 3 additions & 2 deletions test/volume.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,9 @@ describe('servicesAddRequestBody --volume', () => {
it('omits volumeGib when the flag is absent (no volume attached)', () => {
expect(servicesAddRequestBody('compute', 'api', 'main', {})).not.toHaveProperty('volumeGib')
})
// The free-plan rule: any plan may pass 1 (the default size) — and larger values just forward;
// the backend enforces paid/cap, so no client-side plan check exists to test against.
// The free-plan rule: any plan may pass a size up to the free cap (the platform's sizeless default,
// 10Gi) — and larger values just forward; the backend enforces paid/cap, so no client-side plan
// check exists to test against.
it('forwards any whole size unjudged — the backend owns the paid/cap gate', () => {
expect(servicesAddRequestBody('compute', 'api', 'main', { volume: '100' })).toMatchObject({ volumeGib: 100 })
})
Expand Down
Loading