@inquir/compute-cli 0.4.2 → 0.4.4
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 +61 -11
- package/dist/commands/admin-tenants.d.ts.map +1 -1
- package/dist/commands/admin-tenants.js +8 -7
- package/dist/commands/admin-tenants.js.map +1 -1
- package/dist/commands/admin.js +2 -2
- package/dist/commands/admin.js.map +1 -1
- package/dist/commands/apps-replicas.d.ts +27 -0
- package/dist/commands/apps-replicas.d.ts.map +1 -0
- package/dist/commands/apps-replicas.js +278 -0
- package/dist/commands/apps-replicas.js.map +1 -0
- package/dist/commands/apps.d.ts +5 -3
- package/dist/commands/apps.d.ts.map +1 -1
- package/dist/commands/apps.js +58 -15
- package/dist/commands/apps.js.map +1 -1
- package/dist/commands/compose.d.ts +29 -0
- package/dist/commands/compose.d.ts.map +1 -0
- package/dist/commands/compose.js +159 -0
- package/dist/commands/compose.js.map +1 -0
- package/dist/commands/deploy.d.ts +8 -11
- package/dist/commands/deploy.d.ts.map +1 -1
- package/dist/commands/deploy.js +23 -33
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/logout.js +1 -1
- package/dist/commands/logout.js.map +1 -1
- package/dist/commands/mcp.d.ts.map +1 -1
- package/dist/commands/mcp.js +10 -2
- package/dist/commands/mcp.js.map +1 -1
- package/dist/commands/sandbox.d.ts +58 -0
- package/dist/commands/sandbox.d.ts.map +1 -0
- package/dist/commands/sandbox.js +462 -0
- package/dist/commands/sandbox.js.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/mcp-replica-tools.d.ts +10 -0
- package/dist/lib/mcp-replica-tools.d.ts.map +1 -0
- package/dist/lib/mcp-replica-tools.js +77 -0
- package/dist/lib/mcp-replica-tools.js.map +1 -0
- package/dist/lib/mcp-sandbox-tools.d.ts +30 -0
- package/dist/lib/mcp-sandbox-tools.d.ts.map +1 -0
- package/dist/lib/mcp-sandbox-tools.js +211 -0
- package/dist/lib/mcp-sandbox-tools.js.map +1 -0
- package/dist/lib/replica-roles.d.ts +22 -0
- package/dist/lib/replica-roles.d.ts.map +1 -0
- package/dist/lib/replica-roles.js +39 -0
- package/dist/lib/replica-roles.js.map +1 -0
- package/dist/lib/sandbox-api.d.ts +165 -0
- package/dist/lib/sandbox-api.d.ts.map +1 -0
- package/dist/lib/sandbox-api.js +241 -0
- package/dist/lib/sandbox-api.js.map +1 -0
- package/dist/lib/tar-safety.d.ts +17 -0
- package/dist/lib/tar-safety.d.ts.map +1 -0
- package/dist/lib/tar-safety.js +135 -0
- package/dist/lib/tar-safety.js.map +1 -0
- package/dist/utils/api.d.ts +31 -2
- package/dist/utils/api.d.ts.map +1 -1
- package/dist/utils/api.js +61 -2
- package/dist/utils/api.js.map +1 -1
- package/dist/utils/auth.d.ts.map +1 -1
- package/dist/utils/auth.js +2 -4
- package/dist/utils/auth.js.map +1 -1
- package/dist/utils/context.d.ts +7 -0
- package/dist/utils/context.d.ts.map +1 -1
- package/dist/utils/context.js +23 -1
- package/dist/utils/context.js.map +1 -1
- package/dist/utils/deploy-follow.d.ts +1 -5
- package/dist/utils/deploy-follow.d.ts.map +1 -1
- package/dist/utils/deploy-follow.js +21 -1
- package/dist/utils/deploy-follow.js.map +1 -1
- package/dist/utils/detect.d.ts.map +1 -1
- package/dist/utils/detect.js +35 -9
- package/dist/utils/detect.js.map +1 -1
- package/dist/utils/errors.d.ts +11 -0
- package/dist/utils/errors.d.ts.map +1 -1
- package/dist/utils/errors.js +42 -7
- package/dist/utils/errors.js.map +1 -1
- package/dist/utils/go-handler.d.ts +59 -0
- package/dist/utils/go-handler.d.ts.map +1 -0
- package/dist/utils/go-handler.js +417 -0
- package/dist/utils/go-handler.js.map +1 -0
- package/dist/utils/package-metadata.js +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
import { cancelApplicationRollout, deleteAppReplicaVolumes, getAppReplicas, listApplicationRollouts, rebuildAppReplica, requireAuth, resolveApplication, updateApplication, } from '../utils/api.js';
|
|
2
|
+
import { hasFlag, readFlagValue, readJsonFlag } from '../utils/args.js';
|
|
3
|
+
import { usageError } from '../utils/errors.js';
|
|
4
|
+
import { confirm } from '../utils/prompt.js';
|
|
5
|
+
import { dim, formatTable, printInfo, printLine, printSuccess, printWarning } from '../utils/output.js';
|
|
6
|
+
import { formatRoleEndpoints, replicaRoleCell, roleConditionWarnings } from '../lib/replica-roles.js';
|
|
7
|
+
/**
|
|
8
|
+
* Stateful replicas on the command line (docs/roadmap/STATEFUL_REPLICAS.md
|
|
9
|
+
* §7.2). Every command writes the same `scale` object as inquir.yaml's
|
|
10
|
+
* services.web.scale and the API: nothing here is a CLI-only setting.
|
|
11
|
+
*
|
|
12
|
+
* inquir apps scale <app> --replicas N --stateful scale.mode: stateful, scale.replicas: N
|
|
13
|
+
* inquir apps replicas <app> the ordinals: server, volume, release, state
|
|
14
|
+
* inquir apps replicas rebuild <app> <n> rebuild ordinal n on another server
|
|
15
|
+
* inquir apps replicas delete-volume <app> <n> delete ordinal n's retained volumes
|
|
16
|
+
* inquir apps rollout <app> [--partition P] the stateful rollout; P holds ordinals below it
|
|
17
|
+
* inquir apps rollout cancel <app> [<rollout-id>] end a stateful rollout that can move nothing (ABORTED), or pause a live one
|
|
18
|
+
*/
|
|
19
|
+
export const REPLICAS_VALUE_FLAGS = ['--partition', '--reason'];
|
|
20
|
+
export const REPLICAS_HELP = {
|
|
21
|
+
replicas: [
|
|
22
|
+
'Usage: inquir apps replicas <app> [--json]',
|
|
23
|
+
' inquir apps replicas rebuild <app> <n> [--reason <text>] [--yes]',
|
|
24
|
+
' inquir apps replicas delete-volume <app> <n> [--yes]',
|
|
25
|
+
'',
|
|
26
|
+
' Stateful replicas are Alpha: they may change and have limits; keep backups of their data.',
|
|
27
|
+
' The ordinals of a stateful application (scale.mode: stateful): each one\'s server,',
|
|
28
|
+
' volume (generation, state), the release it runs and its state.',
|
|
29
|
+
' rebuild Start ordinal <n> on another server with a new, empty volume. Its',
|
|
30
|
+
' runtime.hooks.init (when: emptyVolume) or the image bootstraps the data;',
|
|
31
|
+
' the old volume is kept for scale.retention.retentionDays.',
|
|
32
|
+
' delete-volume Delete the retained volumes of ordinal <n> (scaled down, or the old',
|
|
33
|
+
' generation a rebuild left). Its data is gone for good.',
|
|
34
|
+
],
|
|
35
|
+
rollout: [
|
|
36
|
+
'Usage: inquir apps rollout <app> [--partition <n>] [--json]',
|
|
37
|
+
'',
|
|
38
|
+
' How the newest release reaches a stateful application\'s ordinals: one at a time,',
|
|
39
|
+
' the highest first (scale.update). --partition <n> keeps ordinals below <n> on their',
|
|
40
|
+
' release (a canary: --partition <replicas-1>, check, then --partition 0).',
|
|
41
|
+
'',
|
|
42
|
+
' inquir apps rollout cancel <app> [<rollout-id>] [--reason <text>] [--yes]',
|
|
43
|
+
' Cancel the newest open stateful rollout (or <rollout-id>): one that can move nothing',
|
|
44
|
+
' any more (the application is stateless again, or production is another release) ends;',
|
|
45
|
+
' a live one pauses until you deploy a fix or roll back.',
|
|
46
|
+
],
|
|
47
|
+
};
|
|
48
|
+
function parseOrdinal(raw, usage) {
|
|
49
|
+
if (raw === undefined || !/^(0|[1-9][0-9]?)$/.test(raw))
|
|
50
|
+
throw usageError('The replica ordinal must be an integer such as 0 or 2', usage);
|
|
51
|
+
return Number(raw);
|
|
52
|
+
}
|
|
53
|
+
/** The stored block with `change` merged over it: the CLI never drops keys it was not asked to change. */
|
|
54
|
+
export function mergeScale(stored, change) {
|
|
55
|
+
const merged = { ...(stored ?? {}), ...change };
|
|
56
|
+
if (change.update || stored?.update)
|
|
57
|
+
merged.update = { ...(stored?.update ?? {}), ...(change.update ?? {}) };
|
|
58
|
+
if (merged.mode === 'stateless') {
|
|
59
|
+
// A stateless application carries no stateful key (the schema refuses them).
|
|
60
|
+
return { mode: 'stateless' };
|
|
61
|
+
}
|
|
62
|
+
return merged;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* `inquir apps scale <app> --replicas N --stateful` (or `--stateless`): the
|
|
66
|
+
* `scale` block of the application. Returns false when neither flag is given,
|
|
67
|
+
* so the caller handles the stateless scaling policy as before.
|
|
68
|
+
*/
|
|
69
|
+
export async function statefulScaleSubcommand(args, identifier, apiOptions) {
|
|
70
|
+
const stateful = hasFlag(args, '--stateful');
|
|
71
|
+
const stateless = hasFlag(args, '--stateless');
|
|
72
|
+
if (!stateful && !stateless)
|
|
73
|
+
return false;
|
|
74
|
+
const usage = 'inquir apps scale <app> --replicas <n> --stateful';
|
|
75
|
+
if (stateful && stateless)
|
|
76
|
+
throw usageError('--stateful and --stateless are exclusive', usage);
|
|
77
|
+
const replicasRaw = readFlagValue(args, '--replicas');
|
|
78
|
+
const replicas = replicasRaw === undefined ? undefined : Number(replicasRaw);
|
|
79
|
+
if (replicas !== undefined && (!Number.isInteger(replicas) || replicas < 1 || replicas > 8)) {
|
|
80
|
+
throw usageError('--replicas must be an integer from 1 to 8', usage);
|
|
81
|
+
}
|
|
82
|
+
await requireAuth(apiOptions);
|
|
83
|
+
const app = await resolveApplication(identifier, apiOptions);
|
|
84
|
+
const current = await getAppReplicas(app.id, apiOptions);
|
|
85
|
+
const scale = mergeScale(current.scale, stateless
|
|
86
|
+
? { mode: 'stateless' }
|
|
87
|
+
: { mode: 'stateful', ...(replicas !== undefined ? { replicas } : {}) });
|
|
88
|
+
const updated = await updateApplication(app.id, { scale, ...(hasFlag(args, '--override') ? { scaleOverride: true } : {}) }, apiOptions);
|
|
89
|
+
if (readJsonFlag(args)) {
|
|
90
|
+
printLine(JSON.stringify(updated, null, 2));
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
printSuccess(stateless ? `${app.name} scales as identical replicas again` : `${app.name}: ${scale.replicas ?? 1} stateful replica(s)`);
|
|
94
|
+
if (!stateless)
|
|
95
|
+
printInfo(dim(` Each replica has its own volume and name; see: inquir apps replicas ${app.name}`));
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
98
|
+
function describeVolumes(ordinal) {
|
|
99
|
+
return ordinal.volumes.map((volume) => `${volume.logicalName}@g${volume.generation}${volume.state === 'ACTIVE' ? '' : ` ${volume.state.toLowerCase()}`}`).join(', ');
|
|
100
|
+
}
|
|
101
|
+
function ordinalStatus(ordinal) {
|
|
102
|
+
if (ordinal.state === 'RETAINED')
|
|
103
|
+
return 'retained';
|
|
104
|
+
if (ordinal.rebuildRequested)
|
|
105
|
+
return 'rebuilding';
|
|
106
|
+
if (ordinal.conditions.some((condition) => condition.reason === 'RunnerLost'))
|
|
107
|
+
return 'server lost';
|
|
108
|
+
if (ordinal.conditions.some((condition) => condition.type === 'VolumeGenerationRefused'))
|
|
109
|
+
return 'volume refused';
|
|
110
|
+
if (!ordinal.attempt)
|
|
111
|
+
return 'stopped';
|
|
112
|
+
return ordinal.attempt.serving ? 'serving' : ordinal.attempt.observedState.toLowerCase();
|
|
113
|
+
}
|
|
114
|
+
export async function replicasSubcommand(args, positionals, apiOptions) {
|
|
115
|
+
const [first, ...rest] = positionals;
|
|
116
|
+
if (first === 'rebuild')
|
|
117
|
+
return rebuildReplica(args, rest, apiOptions);
|
|
118
|
+
if (first === 'delete-volume')
|
|
119
|
+
return deleteReplicaVolume(args, rest, apiOptions);
|
|
120
|
+
if (!first)
|
|
121
|
+
throw usageError('Missing application', 'inquir apps replicas <app>');
|
|
122
|
+
if (rest.length > 0)
|
|
123
|
+
throw usageError(`Unexpected argument '${rest[0]}'`, 'inquir apps replicas <app>');
|
|
124
|
+
await requireAuth(apiOptions);
|
|
125
|
+
const app = await resolveApplication(first, apiOptions);
|
|
126
|
+
const replicas = await getAppReplicas(app.id, apiOptions);
|
|
127
|
+
if (readJsonFlag(args)) {
|
|
128
|
+
printLine(JSON.stringify(replicas, null, 2));
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
if (replicas.mode !== 'stateful') {
|
|
132
|
+
printInfo(`${app.name} runs identical (stateless) replicas. Give each its own volume: inquir apps scale ${app.name} --replicas 2 --stateful`);
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
printLine(formatTable(replicas.ordinals.map((ordinal) => ({
|
|
136
|
+
replica: `${app.name}-${ordinal.ordinal}`,
|
|
137
|
+
server: ordinal.host ?? ordinal.runnerId?.slice(0, 8) ?? '-',
|
|
138
|
+
location: ordinal.location ?? '',
|
|
139
|
+
volume: describeVolumes(ordinal),
|
|
140
|
+
release: (ordinal.releaseId ?? '').slice(0, 8),
|
|
141
|
+
role: replicaRoleCell(ordinal),
|
|
142
|
+
status: ordinalStatus(ordinal),
|
|
143
|
+
})), ['replica', 'server', 'location', 'volume', 'release', 'role', 'status']));
|
|
144
|
+
// P2 role endpoints (§3.5, §3.8): the endpoints block, and a warning per RoleConflict.
|
|
145
|
+
for (const line of formatRoleEndpoints(replicas))
|
|
146
|
+
printLine(line);
|
|
147
|
+
for (const warning of roleConditionWarnings(replicas.conditions))
|
|
148
|
+
printWarning(warning);
|
|
149
|
+
for (const entry of replicas.status?.unplaced ?? [])
|
|
150
|
+
printWarning(`${app.name}-${entry.ordinal}: not placed: ${entry.message}`);
|
|
151
|
+
if (replicas.status?.waitingFor !== undefined)
|
|
152
|
+
printInfo(dim(` Waiting for ${app.name}-${replicas.status.waitingFor} to serve before the next replica starts`));
|
|
153
|
+
if (replicas.rollout && ['PROGRESSING', 'PAUSED'].includes(replicas.rollout.phase)) {
|
|
154
|
+
printInfo(dim(` Rollout of ${replicas.rollout.releaseId.slice(0, 8)}: ${replicas.rollout.phase.toLowerCase()}; see inquir apps rollout ${app.name}`));
|
|
155
|
+
}
|
|
156
|
+
if (replicas.managedKeys?.length)
|
|
157
|
+
printInfo(dim(` Managed by inquir.yaml: scale.${replicas.managedKeys.join(', scale.')}`));
|
|
158
|
+
}
|
|
159
|
+
async function rebuildReplica(args, positionals, apiOptions) {
|
|
160
|
+
const usage = 'inquir apps replicas rebuild <app> <n> [--reason <text>]';
|
|
161
|
+
const [identifier, rawOrdinal] = positionals;
|
|
162
|
+
if (!identifier)
|
|
163
|
+
throw usageError('Missing application', usage);
|
|
164
|
+
const ordinal = parseOrdinal(rawOrdinal, usage);
|
|
165
|
+
await requireAuth(apiOptions);
|
|
166
|
+
const app = await resolveApplication(identifier, apiOptions);
|
|
167
|
+
if (!hasFlag(args, '--yes') && !(await confirm(`Rebuild ${app.name}-${ordinal} on another server? It starts on a new, empty volume; the current one is kept for the retention period.`))) {
|
|
168
|
+
printInfo('Nothing changed.');
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
const reason = readFlagValue(args, '--reason');
|
|
172
|
+
const result = await rebuildAppReplica(app.id, ordinal, { ...(reason ? { reason } : {}) }, apiOptions);
|
|
173
|
+
if (readJsonFlag(args)) {
|
|
174
|
+
printLine(JSON.stringify(result, null, 2));
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
printSuccess(`Rebuild of ${app.name}-${ordinal} requested`);
|
|
178
|
+
printInfo(dim(` Follow it: inquir apps replicas ${app.name}`));
|
|
179
|
+
}
|
|
180
|
+
async function deleteReplicaVolume(args, positionals, apiOptions) {
|
|
181
|
+
const usage = 'inquir apps replicas delete-volume <app> <n>';
|
|
182
|
+
const [identifier, rawOrdinal] = positionals;
|
|
183
|
+
if (!identifier)
|
|
184
|
+
throw usageError('Missing application', usage);
|
|
185
|
+
const ordinal = parseOrdinal(rawOrdinal, usage);
|
|
186
|
+
await requireAuth(apiOptions);
|
|
187
|
+
const app = await resolveApplication(identifier, apiOptions);
|
|
188
|
+
if (!hasFlag(args, '--yes') && !(await confirm(`Delete the retained volumes of ${app.name}-${ordinal}? The data cannot be recovered.`))) {
|
|
189
|
+
printInfo('Nothing changed.');
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
const result = await deleteAppReplicaVolumes(app.id, ordinal, apiOptions);
|
|
193
|
+
if (readJsonFlag(args)) {
|
|
194
|
+
printLine(JSON.stringify(result, null, 2));
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
printSuccess(`Deleting ${result.volumes} retained volume(s) of ${app.name}-${ordinal}`);
|
|
198
|
+
}
|
|
199
|
+
async function cancelRollout(args, positionals, apiOptions) {
|
|
200
|
+
const usage = 'inquir apps rollout cancel <app> [<rollout-id>] [--reason <text>]';
|
|
201
|
+
const [identifier, rolloutId, ...extra] = positionals;
|
|
202
|
+
if (!identifier)
|
|
203
|
+
throw usageError('Missing application', usage);
|
|
204
|
+
if (extra.length > 0)
|
|
205
|
+
throw usageError(`Unexpected argument '${extra[0]}'`, usage);
|
|
206
|
+
await requireAuth(apiOptions);
|
|
207
|
+
const app = await resolveApplication(identifier, apiOptions);
|
|
208
|
+
let target = rolloutId;
|
|
209
|
+
if (!target) {
|
|
210
|
+
const { items } = await listApplicationRollouts(app.id, 20, apiOptions);
|
|
211
|
+
target = items.find((rollout) => rollout.kind === 'STATEFUL' && (rollout.phase === 'PROGRESSING' || rollout.phase === 'PAUSED'))?.id;
|
|
212
|
+
if (!target) {
|
|
213
|
+
printInfo(`${app.name} has no open stateful rollout.`);
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
if (!hasFlag(args, '--yes') && !(await confirm(`Cancel rollout ${target.slice(0, 8)} of ${app.name}?`))) {
|
|
218
|
+
printInfo('Nothing changed.');
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
const reason = readFlagValue(args, '--reason');
|
|
222
|
+
const result = await cancelApplicationRollout(app.id, target, { ...(reason ? { reason } : {}) }, apiOptions);
|
|
223
|
+
if (readJsonFlag(args)) {
|
|
224
|
+
printLine(JSON.stringify(result, null, 2));
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
printSuccess(`Rollout ${result.id.slice(0, 8)} of ${app.name}: ${result.phase.toLowerCase()}`);
|
|
228
|
+
if (result.reason)
|
|
229
|
+
printInfo(dim(` ${result.reason}`));
|
|
230
|
+
}
|
|
231
|
+
export async function rolloutSubcommand(args, positionals, apiOptions) {
|
|
232
|
+
if (positionals[0] === 'cancel')
|
|
233
|
+
return cancelRollout(args, positionals.slice(1), apiOptions);
|
|
234
|
+
const usage = 'inquir apps rollout <app> [--partition <n>]';
|
|
235
|
+
const [identifier, ...extra] = positionals;
|
|
236
|
+
if (!identifier)
|
|
237
|
+
throw usageError('Missing application', usage);
|
|
238
|
+
if (extra.length > 0)
|
|
239
|
+
throw usageError(`Unexpected argument '${extra[0]}'`, usage);
|
|
240
|
+
await requireAuth(apiOptions);
|
|
241
|
+
const app = await resolveApplication(identifier, apiOptions);
|
|
242
|
+
const partitionRaw = readFlagValue(args, '--partition');
|
|
243
|
+
if (partitionRaw !== undefined) {
|
|
244
|
+
const partition = Number(partitionRaw);
|
|
245
|
+
if (!Number.isInteger(partition) || partition < 0 || partition > 8)
|
|
246
|
+
throw usageError('--partition must be an integer from 0 to 8', usage);
|
|
247
|
+
const current = await getAppReplicas(app.id, apiOptions);
|
|
248
|
+
if (current.mode !== 'stateful')
|
|
249
|
+
throw usageError(`${app.name} is not stateful; a partition holds stateful replicas`, usage);
|
|
250
|
+
await updateApplication(app.id, {
|
|
251
|
+
scale: mergeScale(current.scale, { update: { partition } }),
|
|
252
|
+
...(hasFlag(args, '--override') ? { scaleOverride: true } : {}),
|
|
253
|
+
}, apiOptions);
|
|
254
|
+
printSuccess(`${app.name}: replicas below ${partition} keep their release`);
|
|
255
|
+
}
|
|
256
|
+
const replicas = await getAppReplicas(app.id, apiOptions);
|
|
257
|
+
if (readJsonFlag(args)) {
|
|
258
|
+
printLine(JSON.stringify({ rollout: replicas.rollout ?? null, ordinals: replicas.ordinals.map((o) => ({ ordinal: o.ordinal, releaseId: o.releaseId })) }, null, 2));
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
const rollout = replicas.rollout;
|
|
262
|
+
if (!rollout) {
|
|
263
|
+
printInfo(`No rollout yet for ${app.name}.`);
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
printLine(`Release ${rollout.releaseId.slice(0, 8)}: ${rollout.phase.toLowerCase()}` +
|
|
267
|
+
`${rollout.predecessorReleaseId ? ` (from ${rollout.predecessorReleaseId.slice(0, 8)})` : ''}`);
|
|
268
|
+
printLine(`Replicas on it: ${replicas.ordinals.filter((o) => o.releaseId === rollout.releaseId).map((o) => o.ordinal).join(', ') || 'none'}`);
|
|
269
|
+
if (rollout.strategy) {
|
|
270
|
+
printInfo(dim(` order ${rollout.strategy.order}, partition ${rollout.strategy.partition}, ` +
|
|
271
|
+
`min ready ${rollout.strategy.minReadySeconds}s, at most ${rollout.strategy.maxUnavailable} unavailable`));
|
|
272
|
+
}
|
|
273
|
+
if (rollout.reason)
|
|
274
|
+
printInfo(dim(` ${rollout.reason}`));
|
|
275
|
+
if (rollout.phase === 'PAUSED')
|
|
276
|
+
printWarning('Paused: deploy a fix, or roll back explicitly (inquir apps rollback).');
|
|
277
|
+
}
|
|
278
|
+
//# sourceMappingURL=apps-replicas.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apps-replicas.js","sourceRoot":"","sources":["../../src/commands/apps-replicas.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/apps.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type AppNetworkPolicy, type AppPortSpec, type AppRuntimeSpec, type AppScalingPolicy, type ApiRequestOptions, type ApplicationDetail, type AppLocationStatus, type AppVolumeBackup, type AppBackupPolicy, type Build, type Release } from '../utils/api.js';
|
|
1
|
+
import { type AppNetworkPolicy, type AppNetworkPolicyInput, type AppPortSpec, type AppRuntimeSpec, type AppScalingPolicy, type ApiRequestOptions, type ApplicationDetail, type AppLocationStatus, type AppVolumeBackup, type AppBackupPolicy, type Build, type Release } from '../utils/api.js';
|
|
2
2
|
import { type AppLogHistoryResponse, type AppRuntimeLogEntry, type AppRuntimeLogQuery } from '../sdk.js';
|
|
3
3
|
export declare function appsCommand(args: string[]): Promise<void>;
|
|
4
4
|
/**
|
|
@@ -38,7 +38,7 @@ export declare function parseDurationSeconds(value: string): number;
|
|
|
38
38
|
/** Build the partial policy sent by `apps scale`; omitted values remain unchanged server-side. */
|
|
39
39
|
export declare function buildScalingPatchFromFlags(args: string[], positionalActivation?: string): Partial<AppScalingPolicy>;
|
|
40
40
|
type AppVolumeSpec = NonNullable<AppRuntimeSpec['volumes']>[number];
|
|
41
|
-
/** `--volume name:/absolute/container/path[:ro]`; host paths are never accepted. */
|
|
41
|
+
/** `--volume name:/absolute/container/path[:ro][:size=<MB>]`; host paths are never accepted. */
|
|
42
42
|
export declare function parseVolumeFlag(value: string): AppVolumeSpec;
|
|
43
43
|
/** `--drain-grace <seconds>`: whole seconds, 0..3600, as the API's runtime schema. */
|
|
44
44
|
export declare function parseDrainGraceFlag(value: string): number;
|
|
@@ -59,6 +59,8 @@ export declare function formatBackupPolicy(policy: AppBackupPolicy): string;
|
|
|
59
59
|
* suggesting it.
|
|
60
60
|
*/
|
|
61
61
|
export declare function emptyBackupsLines(appName: string, policy: AppBackupPolicy | undefined): string[];
|
|
62
|
+
/** A row's status as the CLI prints it: an empty volume's backup is READY (restorable) and says it is empty. */
|
|
63
|
+
export declare function formatBackupStatus(backup: Pick<AppVolumeBackup, 'status' | 'empty'>): string;
|
|
62
64
|
/**
|
|
63
65
|
* The refusals of `apps connect` and `apps connection-url`, told as what to do
|
|
64
66
|
* next. The server's code and message are kept; the cause, the fix and the
|
|
@@ -133,7 +135,7 @@ export declare function buildNetworkPolicyPatch(input: {
|
|
|
133
135
|
egress?: string;
|
|
134
136
|
ingress?: string;
|
|
135
137
|
current?: AppNetworkPolicy;
|
|
136
|
-
}):
|
|
138
|
+
}): AppNetworkPolicyInput | undefined;
|
|
137
139
|
/** A build-sourced release is best named by its build; a pulled one by its ref. */
|
|
138
140
|
export declare function describeImage(release: Pick<Release, 'imageSource' | 'buildId' | 'imageRef' | 'imageDigest'>): string;
|
|
139
141
|
/** One line for a startup probe; defaults as the server applies them (src/apps/startup-probe.ts). */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apps.d.ts","sourceRoot":"","sources":["../../src/commands/apps.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"apps.d.ts","sourceRoot":"","sources":["../../src/commands/apps.ts"],"names":[],"mappings":"AAeA,OAAO,EAyCL,KAAK,gBAAgB,EACrB,KAAK,qBAAqB,EAC1B,KAAK,WAAW,EAChB,KAAK,cAAc,EAEnB,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,KAAK,EACV,KAAK,OAAO,EACb,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAA2G,KAAK,qBAAqB,EAAE,KAAK,kBAAkB,EAAE,KAAK,kBAAkB,EAA2B,MAAM,WAAW,CAAC;AA+D3O,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAqF/D;AAqGD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,CA6B3D;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAO/E;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,GAAG,SAAS,CAUrF;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAc/E;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,cAAc,GAAG,SAAS,GAAG,cAAc,GAAG,SAAS,CAgBnH;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAUtE;AAKD,2EAA2E;AAC3E,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAgC1D;AAgCD,kGAAkG;AAClG,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,MAAM,EAAE,EACd,oBAAoB,CAAC,EAAE,MAAM,GAC5B,OAAO,CAAC,gBAAgB,CAAC,CAuD3B;AAED,KAAK,aAAa,GAAG,WAAW,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;AAMpE,gGAAgG;AAChG,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,CA8D5D;AAoCD,sFAAsF;AACtF,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CASzD;AAED,gGAAgG;AAChG,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,MAAM,EAAE,EACd,WAAW,CAAC,EAAE,cAAc,GAC3B,cAAc,GAAG,SAAS,CAiE5B;AAgJD,oFAAoF;AACpF,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAgNpD,CAAC;AAIF;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,CAOjE;AAED,4DAA4D;AAC5D,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,CAYlE;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,GAAG,SAAS,GAAG,MAAM,EAAE,CAUhG;AAED,gHAAgH;AAChH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,IAAI,CAAC,eAAe,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,MAAM,CAE5F;AAmND;;;;;GAKG;AACH,wBAAgB,8BAA8B,CAC5C,KAAK,EAAE,OAAO,EACd,OAAO,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAC7C,OAAO,CAkFT;AAyED,wBAAgB,mBAAmB,CACjC,MAAM,EAAE;IACN,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wEAAwE;IACxE,kBAAkB,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CACxD,EACD,UAAU,GAAE,MAAM,GAAG,SAAS,GAAG,QAAiB,GACjD;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,SAAS,GAAG,QAAQ,CAAA;CAAE,CAiBnD;AAwED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAa5D;AA+MD,oFAAoF;AACpF,wBAAsB,YAAY,CAChC,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,iBAAiB,EAC7B,OAAO,GAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,IAAI,CAAC,KAAK,EAAE,QAAQ,GAAG,eAAe,GAAG,oBAAoB,CAAC,CAAA;CAAO,GAC3H,OAAO,CAAC,KAAK,CAAC,CAkHhB;AAaD;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,OAAO,CAAC;IAAE,eAAe,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,EAC3F,KAAK,SAA0B,GAC9B;IAAE,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,GAAG,eAAe,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;CAAE,CAmB9E;AAyED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,OAAO,EAChB,UAAU,CAAC,EAAE,MAAM,EACnB,OAAO,GAAE;IAAE,gBAAgB,CAAC,EAAE,OAAO,CAAA;CAAO,GAC3C,MAAM,EAAE,CAwBV;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,IAAI,CAAC,iBAAiB,EAAE,eAAe,GAAG,gBAAgB,CAAC,EACnE,MAAM,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS,EAC5F,OAAO,GAAE;IAAE,iBAAiB,CAAC,EAAE,OAAO,CAAA;CAAO,GAC5C,MAAM,EAAE,CAyBV;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE;IAC7C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,gBAAgB,CAAC;CAC5B,GAAG,qBAAqB,GAAG,SAAS,CAepC;AAED,mFAAmF;AACnF,wBAAgB,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,aAAa,GAAG,SAAS,GAAG,UAAU,GAAG,aAAa,CAAC,GAAG,MAAM,CAGpH;AAgCD,qGAAqG;AACrG,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,WAAW,CAAC,cAAc,CAAC,cAAc,CAAC,CAAC,GAAG,MAAM,CAU/F;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,CAMtE;AAyRD;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,IAAI,EAChB,OAAO,GAAE;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAA4E,GAC3H;IAAE,KAAK,IAAI,IAAI,CAAC;IAAC,MAAM,IAAI,IAAI,CAAA;CAAE,CAWnC;AAGD;;;;GAIG;AACH,wBAAsB,qBAAqB,CACzC,SAAS,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,OAAO,CAAC,qBAAqB,CAAC,kBAAkB,CAAC,CAAC,EAC5F,OAAO,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAChF,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAoB/B;AA6DD;;;;GAIG;AACH,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,GAAG,IAAI,EACxC,GAAG,EAAE,IAAI,CAAC,iBAAiB,EAAE,MAAM,GAAG,gBAAgB,CAAC,GAAG,IAAI,GAC7D,MAAM,EAAE,CAcV;AAkQD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,EACf,OAAO,EAAE;IAAE,OAAO,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;IAAC,WAAW,EAAE,OAAO,CAAC;IAAC,aAAa,CAAC,EAAE,OAAO,CAAA;CAAE,GACzF,MAAM,EAAE,CAgBV;AAoFD,yFAAyF;AACzF,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAY9D"}
|
package/dist/commands/apps.js
CHANGED
|
@@ -3,6 +3,7 @@ import { alertsSubcommand, logHistorySubcommand, metricsSubcommand, OBSERVATION_
|
|
|
3
3
|
import { RESOURCES_HELP, RESOURCES_VALUE_FLAGS, resourcesSubcommand } from './apps-resources.js';
|
|
4
4
|
import { DESCRIBE_HELP, describeSubcommand } from './apps-describe.js';
|
|
5
5
|
import { INSTANCES_HELP, instancesSubcommand, resolveReplicaAllocationId } from './apps-instances.js';
|
|
6
|
+
import { REPLICAS_HELP, REPLICAS_VALUE_FLAGS, replicasSubcommand, rolloutSubcommand, statefulScaleSubcommand } from './apps-replicas.js';
|
|
6
7
|
import { followPromoteRollout } from './apps-promote.js';
|
|
7
8
|
import { hasFlag, readFlagValue, readJsonFlag, readLimitFlag, readMultiFlag, readPositionalArgs, } from '../utils/args.js';
|
|
8
9
|
import { listAppBackups, getAppBackup, createAppBackup, deleteAppBackup, restoreAppBackup, getAppConnectionUrl, connectApps, createApiClient, addApplicationDomain, archiveApplication, cancelBuild, createApplication, getBuild, listApplicationDomains, listBuilds, queueBuild, removeApplicationDomain, createRelease, redeployApplication, execInApplication, getAppLimits, getAppLocation, getApplication, getProject, getProductionReplacement, getRelease, listApplications, promoteRelease, isPromoteAccepted, requireAuth, resolveApplication, rollbackApplication, stopRelease, streamBuildLogs, streamReleaseLogs, updateApplication, wakeApplication, pauseApplication, verifyApplicationDomain, } from '../utils/api.js';
|
|
@@ -19,6 +20,7 @@ import { packSourceForUpload } from '../utils/source-pack.js';
|
|
|
19
20
|
/** Value flags across every subcommand — readPositionalArgs must know them all. */
|
|
20
21
|
const VALUE_FLAGS = [
|
|
21
22
|
...OBSERVATION_VALUE_FLAGS,
|
|
23
|
+
...REPLICAS_VALUE_FLAGS,
|
|
22
24
|
...RESOURCES_VALUE_FLAGS,
|
|
23
25
|
'--project',
|
|
24
26
|
'--template',
|
|
@@ -120,6 +122,10 @@ export async function appsCommand(args) {
|
|
|
120
122
|
return updateSubcommand(args, rest, apiOptions);
|
|
121
123
|
case 'scale':
|
|
122
124
|
return scaleSubcommand(args, rest, apiOptions);
|
|
125
|
+
case 'replicas':
|
|
126
|
+
return replicasSubcommand(args, rest, apiOptions);
|
|
127
|
+
case 'rollout':
|
|
128
|
+
return rolloutSubcommand(args, rest, apiOptions);
|
|
123
129
|
case 'wake':
|
|
124
130
|
return wakeSubcommand(args, rest, apiOptions);
|
|
125
131
|
case 'pause':
|
|
@@ -164,6 +170,9 @@ function printAppsHelp() {
|
|
|
164
170
|
'exec <app> [--replica <r>] -- <cmd> Run a command in production (one replica: name or index)',
|
|
165
171
|
'update <app> Change env vars, ports, resources, egress, node selector',
|
|
166
172
|
'scale <app> [mode] Set always/http/manual scaling (--replicas for always)',
|
|
173
|
+
'scale <app> --replicas <n> --stateful Ordered replicas, each with its own volume and name (Alpha)',
|
|
174
|
+
'replicas <app> [rebuild|delete-volume] Replicas of a stateful app: server, volume, release (Alpha)',
|
|
175
|
+
'rollout <app> [--partition <n>] How a release reaches the replicas of a stateful app (Alpha)',
|
|
167
176
|
'wake <app> Start a sleeping application',
|
|
168
177
|
'pause <app> Stop an http/manual app (HTTP wakes only http mode)',
|
|
169
178
|
"domain <app> [hostname] Bind a hostname (or list them); --verify / --remove; '*.example.com' needs --yes (not recommended)",
|
|
@@ -187,8 +196,9 @@ function printAppsHelp() {
|
|
|
187
196
|
'--volume-runner <id> Pin volumes (and the container) to a worker runner',
|
|
188
197
|
'--node-selector KEY=VALUE update: run only on servers with this node label (repeatable),',
|
|
189
198
|
' e.g. inquir.io/region=eu; --clear-node-selector removes it',
|
|
190
|
-
'--location <id|auto> update (experimental): run in this location, e.g. nl or ru; auto',
|
|
191
|
-
' runs wherever there is capacity.
|
|
199
|
+
'--location <id|auto> create/update (experimental): run in this location, e.g. nl or ru; auto',
|
|
200
|
+
' runs wherever there is capacity (inquir.yaml: services.web.location).',
|
|
201
|
+
' Applies from the next deploy',
|
|
192
202
|
'--set KEY=VALUE create/update: environment variable (repeatable)',
|
|
193
203
|
'--unset KEY update: remove an environment variable and its production-only marker (repeatable)',
|
|
194
204
|
'--memory <mb> Memory ceiling (default 512)',
|
|
@@ -427,22 +437,27 @@ const VOLUME_NAME_RE = /^[a-z0-9]([a-z0-9-]{0,30}[a-z0-9])?$/;
|
|
|
427
437
|
const MAX_APP_VOLUMES = 16;
|
|
428
438
|
// eslint-disable-next-line no-control-regex -- Container mount paths must reject control characters.
|
|
429
439
|
const CONTROL_CHAR_RE = /[\u0000-\u001f\u007f]/;
|
|
430
|
-
/** `--volume name:/absolute/container/path[:ro]`; host paths are never accepted. */
|
|
440
|
+
/** `--volume name:/absolute/container/path[:ro][:size=<MB>]`; host paths are never accepted. */
|
|
431
441
|
export function parseVolumeFlag(value) {
|
|
432
442
|
const separator = value.indexOf(':');
|
|
433
443
|
const name = separator > 0 ? value.slice(0, separator) : '';
|
|
434
444
|
let mountPath = separator > 0 ? value.slice(separator + 1) : '';
|
|
435
445
|
let readOnly = false;
|
|
446
|
+
let sizeMb;
|
|
436
447
|
if (/^[A-Za-z]:[\\/]/.test(mountPath)) {
|
|
437
448
|
throw usageError(`Invalid --volume mount path '${mountPath}'`, `Volume targets are absolute paths inside the Linux container, for example data:/var/lib/data. ${MSYS_PATH_HINT}`);
|
|
438
449
|
}
|
|
439
|
-
|
|
440
|
-
|
|
450
|
+
// Trailing modifiers, each at most once: ro, size=<MB> (the same sizeMb inquir.yaml takes).
|
|
451
|
+
for (let modifierAt = mountPath.lastIndexOf(':'); modifierAt >= 0; modifierAt = mountPath.lastIndexOf(':')) {
|
|
441
452
|
const modifier = mountPath.slice(modifierAt + 1);
|
|
442
|
-
|
|
443
|
-
|
|
453
|
+
const size = /^size=(\d{1,7})$/.exec(modifier);
|
|
454
|
+
if (modifier === 'ro' && !readOnly)
|
|
455
|
+
readOnly = true;
|
|
456
|
+
else if (size && sizeMb === undefined && Number(size[1]) >= 64 && Number(size[1]) <= 1048576)
|
|
457
|
+
sizeMb = Number(size[1]);
|
|
458
|
+
else {
|
|
459
|
+
throw usageError(`Invalid --volume modifier '${modifier}' in '${value}'`, 'inquir apps deploy <app> --volume data:/var/lib/data[:ro][:size=1024] (size in MB, 64 to 1048576)');
|
|
444
460
|
}
|
|
445
|
-
readOnly = true;
|
|
446
461
|
mountPath = mountPath.slice(0, modifierAt);
|
|
447
462
|
}
|
|
448
463
|
if (!VOLUME_NAME_RE.test(name)) {
|
|
@@ -464,7 +479,7 @@ export function parseVolumeFlag(value) {
|
|
|
464
479
|
['/dev', '/proc', '/sys'].some((root) => normalized === root || normalized.startsWith(`${root}/`))) {
|
|
465
480
|
throw usageError(`Invalid --volume mount path '${mountPath}'`, 'Mount below an application data directory, for example data:/var/lib/data');
|
|
466
481
|
}
|
|
467
|
-
return { name, mountPath: normalized, ...(readOnly ? { readOnly: true } : {}) };
|
|
482
|
+
return { name, mountPath: normalized, ...(readOnly ? { readOnly: true } : {}), ...(sizeMb !== undefined ? { sizeMb } : {}) };
|
|
468
483
|
}
|
|
469
484
|
function assertVolumeSet(volumes) {
|
|
470
485
|
if (volumes.length > MAX_APP_VOLUMES) {
|
|
@@ -610,6 +625,7 @@ async function createAppSubcommand(args, positionals, apiOptions) {
|
|
|
610
625
|
egress: readFlagValue(args, '--egress'),
|
|
611
626
|
ingress: readFlagValue(args, '--ingress'),
|
|
612
627
|
});
|
|
628
|
+
const location = parseLocationFlag(readFlagValue(args, '--location'));
|
|
613
629
|
const project = await resolveCreateProject(args, apiOptions);
|
|
614
630
|
const app = await createApplication({
|
|
615
631
|
name,
|
|
@@ -620,6 +636,7 @@ async function createAppSubcommand(args, positionals, apiOptions) {
|
|
|
620
636
|
runtime: buildRuntimeFromFlags(args),
|
|
621
637
|
...(Object.keys(envVars).length > 0 ? { envVars } : {}),
|
|
622
638
|
...(networkPolicy ? { networkPolicy } : {}),
|
|
639
|
+
...(location ? { location } : {}),
|
|
623
640
|
}, project.apiOptions).catch((error) => {
|
|
624
641
|
// A worker runner pulls only a digest-pinned registry image, and this
|
|
625
642
|
// installation has no mirror of the template's image yet.
|
|
@@ -693,6 +710,7 @@ export const SUBCOMMAND_HELP = {
|
|
|
693
710
|
...RESOURCES_HELP,
|
|
694
711
|
...DESCRIBE_HELP,
|
|
695
712
|
...INSTANCES_HELP,
|
|
713
|
+
...REPLICAS_HELP,
|
|
696
714
|
logs: [
|
|
697
715
|
'Usage: inquir apps logs <app|release|build> [--tail <n>] [--no-follow] [--replica <name|index|allocation>]',
|
|
698
716
|
' Prints the last --tail lines (default 200, at most 2000), then follows new',
|
|
@@ -783,6 +801,12 @@ export const SUBCOMMAND_HELP = {
|
|
|
783
801
|
'Examples:',
|
|
784
802
|
' inquir apps scale web always --replicas 2',
|
|
785
803
|
' inquir apps scale web http --idle-timeout 15m',
|
|
804
|
+
'',
|
|
805
|
+
'Stateful replicas (Alpha: may change and has limits; keep backups of their data)',
|
|
806
|
+
' An application with a volume: each replica its own volume and name',
|
|
807
|
+
' inquir apps scale db --replicas 3 --stateful (scale.mode: stateful, as in inquir.yaml)',
|
|
808
|
+
' inquir apps scale db --stateless back to identical replicas, from one replica',
|
|
809
|
+
' --override change a scale key the deployed inquir.yaml manages (until the next Git deploy)',
|
|
786
810
|
],
|
|
787
811
|
wake: [
|
|
788
812
|
'Usage: inquir apps wake <app> [--json]',
|
|
@@ -937,13 +961,17 @@ export function emptyBackupsLines(appName, policy) {
|
|
|
937
961
|
}
|
|
938
962
|
return [`No backups for ${appName} yet — create one: inquir apps backups ${appName} create`];
|
|
939
963
|
}
|
|
964
|
+
/** A row's status as the CLI prints it: an empty volume's backup is READY (restorable) and says it is empty. */
|
|
965
|
+
export function formatBackupStatus(backup) {
|
|
966
|
+
return backup.status === 'READY' && backup.empty === true ? 'READY (empty)' : backup.status;
|
|
967
|
+
}
|
|
940
968
|
/** The one backup table: `create` prints it too, once the rows settle. */
|
|
941
969
|
function renderBackupTable(items) {
|
|
942
970
|
const keeps = items.some((b) => b.retention);
|
|
943
971
|
printLine(formatTable(items.map((b) => ({
|
|
944
972
|
id: b.id.slice(0, 8),
|
|
945
973
|
volume: b.volumeName,
|
|
946
|
-
status: b
|
|
974
|
+
status: formatBackupStatus(b),
|
|
947
975
|
trigger: b.trigger,
|
|
948
976
|
size: formatBytes(b.sizeBytes ?? b.artifactSizeBytes),
|
|
949
977
|
created: b.createdAt.replace('T', ' ').slice(0, 19),
|
|
@@ -986,7 +1014,7 @@ async function waitForBackups(applicationId, started, apiOptions, json, timeoutM
|
|
|
986
1014
|
continue;
|
|
987
1015
|
settled.set(row.id, current);
|
|
988
1016
|
const size = current.status === 'READY' ? ` ${formatBytes(current.sizeBytes ?? current.artifactSizeBytes)}` : '';
|
|
989
|
-
announce(`— ${current.volumeName} ${current
|
|
1017
|
+
announce(`— ${current.volumeName} ${formatBackupStatus(current)}${size} (${formatElapsed(Date.now() - startedAt)}) —`);
|
|
990
1018
|
}
|
|
991
1019
|
if (settled.size === started.length)
|
|
992
1020
|
return started.map((row) => settled.get(row.id));
|
|
@@ -1066,7 +1094,9 @@ async function backupsSubcommand(args, positionals, apiOptions) {
|
|
|
1066
1094
|
const when = match.createdAt.replace('T', ' ').slice(0, 16);
|
|
1067
1095
|
const summary = `${app.name} volume ${match.volumeName} from the ${when} backup (${formatBytes(match.sizeBytes ?? match.artifactSizeBytes)})`;
|
|
1068
1096
|
if (!runtime().yes) {
|
|
1069
|
-
|
|
1097
|
+
// The backup of an empty volume restores as an empty volume: say so, it removes every file.
|
|
1098
|
+
const emptied = match.empty === true ? ` The volume was empty then: the restore removes every file in ${match.volumeName}.` : '';
|
|
1099
|
+
const approved = await confirm(`Overwrite ${summary}? Everything written since ${when} is lost, and ${app.name} stops during the restore.${emptied}`, false);
|
|
1070
1100
|
if (!approved) {
|
|
1071
1101
|
throw usageError(`Refusing to restore ${app.name} without confirmation`, `inquir apps backups ${identifier} restore ${match.id.slice(0, 8)} --yes`);
|
|
1072
1102
|
}
|
|
@@ -1323,6 +1353,10 @@ export function printManifestEnvOutcome(queued) {
|
|
|
1323
1353
|
const applied = Array.isArray(outcome.manifestEnv?.applied) ? outcome.manifestEnv.applied : [];
|
|
1324
1354
|
if (applied.length > 0)
|
|
1325
1355
|
printInfo(dim(` inquir.yaml env applied: ${applied.join(', ')}`));
|
|
1356
|
+
// networkPolicy / scaling / location the deploy applied (deferred and restored keys come as warnings).
|
|
1357
|
+
const settings = Array.isArray(outcome.manifestSettings?.applied) ? outcome.manifestSettings.applied : [];
|
|
1358
|
+
if (settings.length > 0)
|
|
1359
|
+
printInfo(dim(` inquir.yaml settings applied: ${settings.join(', ')}`));
|
|
1326
1360
|
const warnings = Array.isArray(outcome.warnings) ? outcome.warnings : [];
|
|
1327
1361
|
for (const warning of warnings)
|
|
1328
1362
|
printWarning(` warning: ${warning}`);
|
|
@@ -1456,9 +1490,15 @@ async function runSourceBuild(applicationId, appName, args, apiOptions) {
|
|
|
1456
1490
|
},
|
|
1457
1491
|
}, apiOptions);
|
|
1458
1492
|
if (!json) {
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1493
|
+
const image = queued.image === true ? queued.imageRef : undefined;
|
|
1494
|
+
printInfo(image
|
|
1495
|
+
? `Build ${queued.buildId.slice(0, 8)}: inquir.yaml imageRef, nothing to build (deploys ${image})`
|
|
1496
|
+
: queued.deduplicated
|
|
1497
|
+
? `Build ${queued.buildId.slice(0, 8)} reused (identical source already built)`
|
|
1498
|
+
: `Build ${queued.buildId.slice(0, 8)} queued for ${appName}`);
|
|
1499
|
+
// inquir.yaml keys the platform ignored (a typo is named, never silent).
|
|
1500
|
+
for (const warning of queued.warnings ?? [])
|
|
1501
|
+
printWarning(` warning: ${warning}`);
|
|
1462
1502
|
}
|
|
1463
1503
|
return waitForBuild(queued.buildId, apiOptions, {
|
|
1464
1504
|
json, initial: queued, noLogs: queued.deduplicated || isTerminalBuildStatus(queued.status),
|
|
@@ -2347,6 +2387,9 @@ async function scaleSubcommand(args, positionals, apiOptions) {
|
|
|
2347
2387
|
if (!identifier) {
|
|
2348
2388
|
throw usageError('Missing application', 'inquir apps scale <app> <always|http|manual>');
|
|
2349
2389
|
}
|
|
2390
|
+
// Stateful replicas: the scale block (scale.mode, scale.replicas), not the stateless policy.
|
|
2391
|
+
if (positionalActivation === undefined && await statefulScaleSubcommand(args, identifier, apiOptions))
|
|
2392
|
+
return;
|
|
2350
2393
|
if (extra.length > 0) {
|
|
2351
2394
|
throw usageError(`Unexpected argument '${extra[0]}'`, 'inquir apps scale <app> <always|http|manual>');
|
|
2352
2395
|
}
|