@ornncompute/cli 1.0.72 → 1.0.97
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 +55 -24
- package/package.json +4 -2
- package/src/admin-capacity-reservations.mjs +6 -13
- package/src/admin-command-handlers.mjs +2 -1
- package/src/admin-credits.mjs +1 -2
- package/src/admin-enrollment.mjs +22 -30
- package/src/admin-mutations.mjs +6 -56
- package/src/admin-node-diagnostics.mjs +3 -41
- package/src/admin-node-lifecycle.mjs +40 -160
- package/src/admin-node-sanitize.mjs +243 -0
- package/src/admin-shell.mjs +39 -32
- package/src/catalog-shell.mjs +6 -6
- package/src/evidence-commands.mjs +4 -6
- package/src/external-bucket-commands.mjs +76 -96
- package/src/interaction-runtime.mjs +5 -37
- package/src/kubernetes-commands.mjs +25 -183
- package/src/launch-mode-handlers.mjs +0 -1
- package/src/machine-reference.mjs +33 -56
- package/src/mount-commands.mjs +25 -131
- package/src/slurm-commands.mjs +13 -2
- package/src/storage-commands.mjs +2 -87
- package/src/vm-commands.mjs +48 -101
- package/vendor/api-client/commerce.js +743 -0
- package/vendor/capabilities/cli.js +7688 -7
- package/vendor/capabilities/capabilities/admin-capacity-reservations.js +0 -101
- package/vendor/capabilities/capabilities/admin-enrollment.js +0 -321
- package/vendor/capabilities/capabilities/admin-node-diagnostics.js +0 -88
- package/vendor/capabilities/capabilities/admin-nodes-lifecycle.js +0 -235
- package/vendor/capabilities/capabilities/admin.js +0 -91
- package/vendor/capabilities/capabilities/cli.js +0 -156
- package/vendor/capabilities/capabilities/clusters.js +0 -248
- package/vendor/capabilities/capabilities/commerce-market.js +0 -405
- package/vendor/capabilities/capabilities/compute.js +0 -523
- package/vendor/capabilities/capabilities/credits.js +0 -78
- package/vendor/capabilities/capabilities/evidence.js +0 -145
- package/vendor/capabilities/capabilities/external-buckets.js +0 -191
- package/vendor/capabilities/capabilities/fleet.js +0 -306
- package/vendor/capabilities/capabilities/identity.js +0 -129
- package/vendor/capabilities/capabilities/listings.js +0 -398
- package/vendor/capabilities/capabilities/locality.js +0 -42
- package/vendor/capabilities/capabilities/market-shared.js +0 -46
- package/vendor/capabilities/capabilities/markets.js +0 -482
- package/vendor/capabilities/capabilities/mounts.js +0 -176
- package/vendor/capabilities/capabilities/native-listing.js +0 -99
- package/vendor/capabilities/capabilities/networks.js +0 -1264
- package/vendor/capabilities/capabilities/observability.js +0 -218
- package/vendor/capabilities/capabilities/organization-invites.js +0 -53
- package/vendor/capabilities/capabilities/reservation-list.js +0 -68
- package/vendor/capabilities/capabilities/staff-shared.js +0 -64
- package/vendor/capabilities/capabilities/tokens.js +0 -165
- package/vendor/capabilities/capabilities/users.js +0 -159
- package/vendor/capabilities/capabilities/volumes.js +0 -178
- package/vendor/capabilities/capability.js +0 -99
- package/vendor/capabilities/cli-catalog.js +0 -73
- package/vendor/capabilities/cli-migrations.js +0 -264
- package/vendor/capabilities/names.js +0 -6
- package/vendor/capabilities/software-catalog.js +0 -82
- package/vendor/capabilities/spec-catalog.js +0 -151
- package/vendor/capabilities/supplier-directory.js +0 -20
package/src/vm-commands.mjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getReservation } from "../vendor/api-client/commerce.js";
|
|
1
2
|
import { spawn as spawnProcessDefault } from "node:child_process";
|
|
2
3
|
import { createHash } from "node:crypto";
|
|
3
4
|
import { readFile } from "node:fs/promises";
|
|
@@ -9,6 +10,7 @@ import { resolvedMountPath } from "./mount-commands.mjs";
|
|
|
9
10
|
import {
|
|
10
11
|
isReferenceMiss,
|
|
11
12
|
listActiveDirectReservations,
|
|
13
|
+
listActiveReservations,
|
|
12
14
|
listOwnedActiveMachines,
|
|
13
15
|
reservationLabeler,
|
|
14
16
|
resolveMachineReference,
|
|
@@ -70,14 +72,13 @@ function machineAccessMode(value) {
|
|
|
70
72
|
|
|
71
73
|
function reservationAccessMode(value) {
|
|
72
74
|
const reservation = record(value);
|
|
73
|
-
const mode =
|
|
74
|
-
(text(reservation.access_mode) ?? text(reservation.accessMode))?.toLowerCase() ?? null;
|
|
75
|
+
const mode = text(reservation.provisioningType)?.toLowerCase() ?? null;
|
|
75
76
|
return mode === "virtual-machine" ? "vm" : mode;
|
|
76
77
|
}
|
|
77
78
|
|
|
78
79
|
function isDirectReservation(value) {
|
|
79
80
|
const mode = reservationAccessMode(value);
|
|
80
|
-
return
|
|
81
|
+
return mode === "vm" || mode === "bare-metal";
|
|
81
82
|
}
|
|
82
83
|
|
|
83
84
|
function machineIsReady(value) {
|
|
@@ -303,7 +304,6 @@ function failedOperationRecoveryCommand(value, interaction) {
|
|
|
303
304
|
`--mode ${accessMode}`,
|
|
304
305
|
`--network ${networkMode}`,
|
|
305
306
|
accessMode !== sourceMode ? "--erase-local-data" : null,
|
|
306
|
-
"--yes",
|
|
307
307
|
`--idempotency-key ${requestId}`,
|
|
308
308
|
]
|
|
309
309
|
.filter(Boolean)
|
|
@@ -317,7 +317,6 @@ function failedOperationRecoveryCommand(value, interaction) {
|
|
|
317
317
|
`ornn machines ${command}`,
|
|
318
318
|
shellQuote(id),
|
|
319
319
|
command === "reset" ? "--erase-local-data" : null,
|
|
320
|
-
"--yes",
|
|
321
320
|
`--idempotency-key ${requestId}`,
|
|
322
321
|
]
|
|
323
322
|
.filter(Boolean)
|
|
@@ -392,7 +391,7 @@ function positional(input, expected, usage, interaction) {
|
|
|
392
391
|
return values;
|
|
393
392
|
}
|
|
394
393
|
|
|
395
|
-
function machineMutationPreflight(input, interaction
|
|
394
|
+
function machineMutationPreflight(input, interaction) {
|
|
396
395
|
if (!interaction.machine) return;
|
|
397
396
|
if (!text(input.idempotencyKey)) {
|
|
398
397
|
interaction.usage("--idempotency-key is required for automation.", {
|
|
@@ -400,12 +399,6 @@ function machineMutationPreflight(input, interaction, { requireYes = true } = {}
|
|
|
400
399
|
field: "idempotencyKey",
|
|
401
400
|
});
|
|
402
401
|
}
|
|
403
|
-
if (requireYes && input.yes !== true) {
|
|
404
|
-
interaction.usage("--yes is required for automation after reviewing the exact intent.", {
|
|
405
|
-
code: "consent_required",
|
|
406
|
-
field: "yes",
|
|
407
|
-
});
|
|
408
|
-
}
|
|
409
402
|
}
|
|
410
403
|
|
|
411
404
|
async function selectedOrganization(context, interaction, expectedId) {
|
|
@@ -432,7 +425,7 @@ async function selectedOrganization(context, interaction, expectedId) {
|
|
|
432
425
|
|
|
433
426
|
function assertActiveReservation(value, expectedRef, interaction, expectedMode = null) {
|
|
434
427
|
const reservation = record(value);
|
|
435
|
-
const ref =
|
|
428
|
+
const ref = text(reservation.reservationId);
|
|
436
429
|
if (!ref || ref !== expectedRef) {
|
|
437
430
|
interaction.error("The gateway returned an unrelated capacity reservation.", {
|
|
438
431
|
code: "reservation_correlation_changed",
|
|
@@ -471,7 +464,7 @@ async function resolveReservation(context, input, interaction, expectedMode = nu
|
|
|
471
464
|
if (supplied) {
|
|
472
465
|
const ref = requireCanonical(interaction, supplied, "reservation", "Capacity reservation");
|
|
473
466
|
return assertActiveReservation(
|
|
474
|
-
await context.fetch
|
|
467
|
+
await getReservation(context.fetch, ref),
|
|
475
468
|
ref,
|
|
476
469
|
interaction,
|
|
477
470
|
expectedMode
|
|
@@ -483,29 +476,23 @@ async function resolveReservation(context, input, interaction, expectedMode = nu
|
|
|
483
476
|
field: "reservation",
|
|
484
477
|
});
|
|
485
478
|
}
|
|
486
|
-
const payload = await context.fetch("/v1/workflows/commerce/reservations?status=active&limit=50");
|
|
487
479
|
const requestedMode = expectedMode ?? text(input.mode)?.toLowerCase() ?? null;
|
|
488
|
-
const candidates = (
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
(reservation) =>
|
|
492
|
-
(text(reservation.status) ?? "").toLowerCase() === ACTIVE_RESERVATION &&
|
|
493
|
-
resourceId(reservation) &&
|
|
494
|
-
(!requestedMode || reservationAccessMode(reservation) === requestedMode)
|
|
495
|
-
);
|
|
480
|
+
const candidates = (await listActiveReservations(context, interaction)).filter(
|
|
481
|
+
(reservation) => !requestedMode || reservationAccessMode(reservation) === requestedMode
|
|
482
|
+
);
|
|
496
483
|
if (!candidates.length) {
|
|
497
484
|
interaction.error("No active capacity reservation is eligible for launch.", {
|
|
498
485
|
code: "no_active_reservation",
|
|
499
486
|
});
|
|
500
487
|
}
|
|
501
|
-
let ref =
|
|
488
|
+
let ref = text(candidates[0].reservationId);
|
|
502
489
|
if (candidates.length > 1) {
|
|
503
490
|
const reservationLabel = await reservationLabeler(context.fetch);
|
|
504
491
|
ref = await interaction.ask({
|
|
505
492
|
label: "Capacity reservation",
|
|
506
493
|
choices: candidates.map((reservation) => ({
|
|
507
494
|
label: reservationLabel(reservation),
|
|
508
|
-
value:
|
|
495
|
+
value: text(reservation.reservationId),
|
|
509
496
|
})),
|
|
510
497
|
});
|
|
511
498
|
}
|
|
@@ -514,7 +501,7 @@ async function resolveReservation(context, input, interaction, expectedMode = nu
|
|
|
514
501
|
code: "missing_input",
|
|
515
502
|
});
|
|
516
503
|
return assertActiveReservation(
|
|
517
|
-
await context.fetch
|
|
504
|
+
await getReservation(context.fetch, ref),
|
|
518
505
|
ref,
|
|
519
506
|
interaction,
|
|
520
507
|
expectedMode
|
|
@@ -821,12 +808,6 @@ function launchInputPreflight(input, interaction) {
|
|
|
821
808
|
field: "label",
|
|
822
809
|
});
|
|
823
810
|
}
|
|
824
|
-
if (input.yes !== true) {
|
|
825
|
-
interaction.usage("--yes is required for automation after reviewing the launch intent.", {
|
|
826
|
-
code: "consent_required",
|
|
827
|
-
field: "yes",
|
|
828
|
-
});
|
|
829
|
-
}
|
|
830
811
|
if (!text(input.idempotencyKey)) {
|
|
831
812
|
interaction.usage("--idempotency-key is required for automation.", {
|
|
832
813
|
code: "idempotency_key_required",
|
|
@@ -1058,7 +1039,7 @@ export const vmLaunchModeHandler = {
|
|
|
1058
1039
|
input = await normalizePublicKeyInput(input);
|
|
1059
1040
|
const organization = await selectedOrganization(context, interaction);
|
|
1060
1041
|
const reservation = await resolveReservation(context, input, interaction, "vm");
|
|
1061
|
-
const reservationId =
|
|
1042
|
+
const reservationId = text(reservation.reservationId);
|
|
1062
1043
|
const keyPlan = await keyPlanFromInput(context, input, interaction);
|
|
1063
1044
|
const [reviewedMachines, reviewedRelationships] = await Promise.all([
|
|
1064
1045
|
fetchMachines(context, reservationId),
|
|
@@ -1109,9 +1090,7 @@ export const vmLaunchModeHandler = {
|
|
|
1109
1090
|
|
|
1110
1091
|
await selectedOrganization(context, interaction, organization.id);
|
|
1111
1092
|
const currentReservation = assertActiveReservation(
|
|
1112
|
-
await context.fetch
|
|
1113
|
-
`/v1/workflows/commerce/reservations/${encodeURIComponent(reservationId)}`
|
|
1114
|
-
),
|
|
1093
|
+
await getReservation(context.fetch, reservationId),
|
|
1115
1094
|
reservationId,
|
|
1116
1095
|
interaction,
|
|
1117
1096
|
"vm"
|
|
@@ -1199,7 +1178,7 @@ export const vmLaunchModeHandler = {
|
|
|
1199
1178
|
resourceId(key),
|
|
1200
1179
|
"--idempotency-key",
|
|
1201
1180
|
idempotencyKey,
|
|
1202
|
-
...(interaction.machine ? ["--
|
|
1181
|
+
...(interaction.machine ? ["--no-wait", "--format", "json"] : []),
|
|
1203
1182
|
].join(" ");
|
|
1204
1183
|
return uncertainMutationFailure(interaction, error, {
|
|
1205
1184
|
data: {
|
|
@@ -1362,15 +1341,13 @@ function reservationAllocationContext(value) {
|
|
|
1362
1341
|
const reservation = record(value);
|
|
1363
1342
|
return {
|
|
1364
1343
|
term: {
|
|
1365
|
-
start: text(reservation.
|
|
1366
|
-
end: text(reservation.
|
|
1344
|
+
start: text(reservation.startsAt),
|
|
1345
|
+
end: text(reservation.endsAt),
|
|
1367
1346
|
},
|
|
1368
|
-
machine_count:
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
: null,
|
|
1373
|
-
gpu_count: Number.isSafeInteger(reservation.gpu_count) ? reservation.gpu_count : null,
|
|
1347
|
+
machine_count: reservation.reservedNodeCount,
|
|
1348
|
+
gpu_count: Number.isSafeInteger(reservation.reservedGpuCount)
|
|
1349
|
+
? reservation.reservedGpuCount
|
|
1350
|
+
: null,
|
|
1374
1351
|
};
|
|
1375
1352
|
}
|
|
1376
1353
|
|
|
@@ -1434,7 +1411,7 @@ function bareMetalIntentSignature(reservation, relationships) {
|
|
|
1434
1411
|
}
|
|
1435
1412
|
|
|
1436
1413
|
function bareMetalLaunchData(reservation, machine, key, relationships, waitPolicy, replayed) {
|
|
1437
|
-
const reservationId =
|
|
1414
|
+
const reservationId = text(reservation.reservationId);
|
|
1438
1415
|
const invocation = isSshReady(machine, key) ? sshInvocation(machine) : null;
|
|
1439
1416
|
return {
|
|
1440
1417
|
mode: "bare-metal",
|
|
@@ -1520,16 +1497,13 @@ function durableWorkspaceAllocation(reservation, interaction) {
|
|
|
1520
1497
|
const endMilliseconds = Date.parse(end ?? "");
|
|
1521
1498
|
const duration = endMilliseconds - startMilliseconds;
|
|
1522
1499
|
const machineCount = allocation.machine_count;
|
|
1523
|
-
const gpusPerMachine =
|
|
1524
|
-
? reservation.gpus_per_node
|
|
1525
|
-
: Number.isSafeInteger(reservation.gpus_per_machine)
|
|
1526
|
-
? reservation.gpus_per_machine
|
|
1527
|
-
: null;
|
|
1500
|
+
const gpusPerMachine = reservation.gpusPerNode;
|
|
1528
1501
|
const gpuCount = Number.isSafeInteger(allocation.gpu_count)
|
|
1529
1502
|
? allocation.gpu_count
|
|
1530
1503
|
: Number.isSafeInteger(machineCount) && Number.isSafeInteger(gpusPerMachine)
|
|
1531
1504
|
? machineCount * gpusPerMachine
|
|
1532
1505
|
: null;
|
|
1506
|
+
// CPU capacity has no GPUs; a workspace needs only its whole machines.
|
|
1533
1507
|
if (
|
|
1534
1508
|
!start ||
|
|
1535
1509
|
!end ||
|
|
@@ -1537,9 +1511,7 @@ function durableWorkspaceAllocation(reservation, interaction) {
|
|
|
1537
1511
|
!Number.isFinite(endMilliseconds) ||
|
|
1538
1512
|
duration <= 0 ||
|
|
1539
1513
|
!Number.isSafeInteger(machineCount) ||
|
|
1540
|
-
machineCount < 1
|
|
1541
|
-
!Number.isSafeInteger(gpuCount) ||
|
|
1542
|
-
gpuCount < 1
|
|
1514
|
+
machineCount < 1
|
|
1543
1515
|
) {
|
|
1544
1516
|
interaction.error("The active capacity reservation does not contain valid allocation facts.", {
|
|
1545
1517
|
code: "reservation_allocation_incomplete",
|
|
@@ -1559,7 +1531,6 @@ function durableWorkspaceAllocation(reservation, interaction) {
|
|
|
1559
1531
|
function workspaceStepContext(context, interaction, signal) {
|
|
1560
1532
|
const stepInteraction = Object.create(interaction);
|
|
1561
1533
|
stepInteraction.review = async () => true;
|
|
1562
|
-
stepInteraction.options = { ...interaction.options, yes: true };
|
|
1563
1534
|
return {
|
|
1564
1535
|
...context,
|
|
1565
1536
|
fetch: (path, init = {}) =>
|
|
@@ -1642,7 +1613,7 @@ function workspaceRelationshipConflict(facts, goal, interaction) {
|
|
|
1642
1613
|
function durableWorkspaceSignature(reservation, key, facts, goal, interaction) {
|
|
1643
1614
|
return JSON.stringify({
|
|
1644
1615
|
capacity_reservation: {
|
|
1645
|
-
id:
|
|
1616
|
+
id: text(reservation.reservationId),
|
|
1646
1617
|
status: text(reservation.status),
|
|
1647
1618
|
allocation: durableWorkspaceAllocation(reservation, interaction),
|
|
1648
1619
|
},
|
|
@@ -1681,7 +1652,7 @@ function workspaceResumeCommand(input, goal, facts, id, interaction, localResume
|
|
|
1681
1652
|
if (goal.username) parts.push("--username", goal.username);
|
|
1682
1653
|
if (input.noWait) parts.push("--no-wait");
|
|
1683
1654
|
if (input.wait) parts.push("--wait", "--timeout", text(input.timeout));
|
|
1684
|
-
if (interaction.machine) parts.push("--
|
|
1655
|
+
if (interaction.machine) parts.push("--format", interaction.format);
|
|
1685
1656
|
return parts.map(shellQuote).join(" ");
|
|
1686
1657
|
}
|
|
1687
1658
|
|
|
@@ -1799,7 +1770,7 @@ async function launchDurableBareMetalWorkspace({
|
|
|
1799
1770
|
keyPlan,
|
|
1800
1771
|
}) {
|
|
1801
1772
|
const id = workspaceId(input, interaction);
|
|
1802
|
-
const reservationId =
|
|
1773
|
+
const reservationId = text(reservation.reservationId);
|
|
1803
1774
|
if (keyPlan.kind !== "existing") {
|
|
1804
1775
|
interaction.usage("A durable Bare Metal workspace requires a declared existing SSH key.", {
|
|
1805
1776
|
code: "workspace_ssh_key_required",
|
|
@@ -1843,8 +1814,8 @@ async function launchDurableBareMetalWorkspace({
|
|
|
1843
1814
|
value: `${allocation.term.start} to ${allocation.term.end} (${allocation.term.hours} hours)`,
|
|
1844
1815
|
},
|
|
1845
1816
|
{
|
|
1846
|
-
label: "
|
|
1847
|
-
value: `${allocation.quantity.gpu_count} GPUs across ${allocation.quantity.machine_count} machine${allocation.quantity.machine_count === 1 ? "" : "s"}`,
|
|
1817
|
+
label: "Quantity",
|
|
1818
|
+
value: `${allocation.quantity.gpu_count > 0 ? `${allocation.quantity.gpu_count} GPUs` : "CPU"} across ${allocation.quantity.machine_count} machine${allocation.quantity.machine_count === 1 ? "" : "s"}`,
|
|
1848
1819
|
},
|
|
1849
1820
|
{
|
|
1850
1821
|
label: "Creation",
|
|
@@ -1875,7 +1846,7 @@ async function launchDurableBareMetalWorkspace({
|
|
|
1875
1846
|
|
|
1876
1847
|
await selectedOrganization(context, interaction, organization.id);
|
|
1877
1848
|
const [currentReservationValue, currentKeyPlan, currentFacts] = await Promise.all([
|
|
1878
|
-
context.fetch
|
|
1849
|
+
getReservation(context.fetch, reservationId),
|
|
1879
1850
|
keyPlanFromInput(context, input, interaction),
|
|
1880
1851
|
workspaceResourceFacts(context, interaction, input, reservationId),
|
|
1881
1852
|
]);
|
|
@@ -1952,7 +1923,6 @@ async function launchDurableBareMetalWorkspace({
|
|
|
1952
1923
|
$positionals: [reservationId],
|
|
1953
1924
|
key: resourceId(key),
|
|
1954
1925
|
idempotencyKey: `${id}:ssh-key`,
|
|
1955
|
-
yes: true,
|
|
1956
1926
|
}
|
|
1957
1927
|
);
|
|
1958
1928
|
states.ssh_key_assignment = {
|
|
@@ -1988,7 +1958,6 @@ async function launchDurableBareMetalWorkspace({
|
|
|
1988
1958
|
idempotencyKey: `${id}:volume-mount`,
|
|
1989
1959
|
noWait: true,
|
|
1990
1960
|
volume: facts.volume.id,
|
|
1991
|
-
yes: true,
|
|
1992
1961
|
}
|
|
1993
1962
|
);
|
|
1994
1963
|
facts.volumeMount = mount.data.volume_mount;
|
|
@@ -2307,7 +2276,7 @@ export const bareMetalLaunchModeHandler = {
|
|
|
2307
2276
|
input = await normalizePublicKeyInput(input);
|
|
2308
2277
|
const organization = await selectedOrganization(context, interaction, resumeOrganizationId);
|
|
2309
2278
|
const reservation = await resolveReservation(context, input, interaction, "bare-metal");
|
|
2310
|
-
const reservationId =
|
|
2279
|
+
const reservationId = text(reservation.reservationId);
|
|
2311
2280
|
const keyPlan = await keyPlanFromInput(context, input, interaction);
|
|
2312
2281
|
if (durableWorkspace) {
|
|
2313
2282
|
return launchDurableBareMetalWorkspace({
|
|
@@ -2375,7 +2344,7 @@ export const bareMetalLaunchModeHandler = {
|
|
|
2375
2344
|
|
|
2376
2345
|
const [currentReservationValue, currentRelationships, existingAssigned, projectedMachines] =
|
|
2377
2346
|
await Promise.all([
|
|
2378
|
-
context.fetch
|
|
2347
|
+
getReservation(context.fetch, reservationId),
|
|
2379
2348
|
bareMetalRelationships(context, reservationId),
|
|
2380
2349
|
fetchAssignedKeys(context, reservationId),
|
|
2381
2350
|
fetchMachines(context, reservationId),
|
|
@@ -2464,7 +2433,7 @@ export const bareMetalLaunchModeHandler = {
|
|
|
2464
2433
|
resourceId(key),
|
|
2465
2434
|
"--idempotency-key",
|
|
2466
2435
|
idempotencyKey,
|
|
2467
|
-
...(interaction.machine ? ["--
|
|
2436
|
+
...(interaction.machine ? ["--no-wait", "--format", "json"] : []),
|
|
2468
2437
|
].join(" ");
|
|
2469
2438
|
return uncertainMutationFailure(interaction, error, {
|
|
2470
2439
|
data: {
|
|
@@ -2757,9 +2726,7 @@ function createDirectMachineConnectModeHandler({
|
|
|
2757
2726
|
code: "machine_correlation_failed",
|
|
2758
2727
|
});
|
|
2759
2728
|
}
|
|
2760
|
-
const reservation = await context.fetch
|
|
2761
|
-
`/v1/workflows/commerce/reservations/${encodeURIComponent(reservationId)}`
|
|
2762
|
-
);
|
|
2729
|
+
const reservation = await getReservation(context.fetch, reservationId);
|
|
2763
2730
|
if (!isDirectReservation(reservation)) return null;
|
|
2764
2731
|
const privateTransportRequired = text(machine.network_mode) === "private";
|
|
2765
2732
|
return {
|
|
@@ -3002,24 +2969,12 @@ function validateWaitInput(input, interaction, { waitCommand = false } = {}) {
|
|
|
3002
2969
|
function requireMachineMutationSafety(input, interaction, { destructive = false } = {}) {
|
|
3003
2970
|
validateWaitInput(input, interaction);
|
|
3004
2971
|
if (destructive && input.eraseLocalData !== true) {
|
|
3005
|
-
interaction.usage(
|
|
3006
|
-
|
|
3007
|
-
|
|
3008
|
-
|
|
3009
|
-
field: "eraseLocalData",
|
|
3010
|
-
}
|
|
3011
|
-
);
|
|
2972
|
+
interaction.usage("machines reset requires --erase-local-data.", {
|
|
2973
|
+
code: "erase_local_data_required",
|
|
2974
|
+
field: "eraseLocalData",
|
|
2975
|
+
});
|
|
3012
2976
|
}
|
|
3013
2977
|
if (interaction.machine || !interaction.eligibleHuman) {
|
|
3014
|
-
if (input.yes !== true) {
|
|
3015
|
-
interaction.usage(
|
|
3016
|
-
"--yes is required outside an eligible terminal after reviewing the exact intent.",
|
|
3017
|
-
{
|
|
3018
|
-
code: "consent_required",
|
|
3019
|
-
field: "yes",
|
|
3020
|
-
}
|
|
3021
|
-
);
|
|
3022
|
-
}
|
|
3023
2978
|
if (!text(input.idempotencyKey)) {
|
|
3024
2979
|
interaction.usage("--idempotency-key is required outside an eligible terminal.", {
|
|
3025
2980
|
code: "idempotency_key_required",
|
|
@@ -3103,9 +3058,7 @@ async function resolveMachineCommandTarget(input, context, interaction, usage) {
|
|
|
3103
3058
|
code: "machine_correlation_failed",
|
|
3104
3059
|
});
|
|
3105
3060
|
}
|
|
3106
|
-
const reservation = await context.fetch
|
|
3107
|
-
`/v1/workflows/commerce/reservations/${encodeURIComponent(reservationId)}`
|
|
3108
|
-
);
|
|
3061
|
+
const reservation = await getReservation(context.fetch, reservationId);
|
|
3109
3062
|
if (!isDirectReservation(reservation)) {
|
|
3110
3063
|
interaction.error(
|
|
3111
3064
|
"The selected machine belongs to a cluster rather than the direct-machine lifecycle.",
|
|
@@ -3360,19 +3313,19 @@ async function guidedSwitchReservation(context, interaction) {
|
|
|
3360
3313
|
code: "no_active_reservation",
|
|
3361
3314
|
});
|
|
3362
3315
|
}
|
|
3363
|
-
let reference =
|
|
3316
|
+
let reference = text(reservations[0].reservationId);
|
|
3364
3317
|
if (reservations.length > 1) {
|
|
3365
3318
|
const reservationLabel = await reservationLabeler(context.fetch);
|
|
3366
3319
|
reference = await interaction.ask({
|
|
3367
3320
|
label: "Capacity reservation",
|
|
3368
3321
|
choices: reservations.map((reservation) => ({
|
|
3369
3322
|
label: reservationLabel(reservation),
|
|
3370
|
-
value:
|
|
3323
|
+
value: text(reservation.reservationId),
|
|
3371
3324
|
})),
|
|
3372
3325
|
});
|
|
3373
3326
|
}
|
|
3374
3327
|
return assertActiveReservation(
|
|
3375
|
-
await context.fetch
|
|
3328
|
+
await getReservation(context.fetch, reference),
|
|
3376
3329
|
reference,
|
|
3377
3330
|
interaction
|
|
3378
3331
|
);
|
|
@@ -3409,14 +3362,12 @@ async function switchMachine(input, context, interaction) {
|
|
|
3409
3362
|
}
|
|
3410
3363
|
const reservation = suppliedReservation
|
|
3411
3364
|
? assertActiveReservation(
|
|
3412
|
-
await context.fetch
|
|
3413
|
-
`/v1/workflows/commerce/reservations/${encodeURIComponent(suppliedReservation)}`
|
|
3414
|
-
),
|
|
3365
|
+
await getReservation(context.fetch, suppliedReservation),
|
|
3415
3366
|
suppliedReservation,
|
|
3416
3367
|
interaction
|
|
3417
3368
|
)
|
|
3418
3369
|
: await guidedSwitchReservation(context, interaction);
|
|
3419
|
-
const reservationId =
|
|
3370
|
+
const reservationId = text(reservation.reservationId);
|
|
3420
3371
|
if (!isDirectReservation(reservation)) {
|
|
3421
3372
|
interaction.error("machines switch accepts only a direct VM or Bare Metal reservation.", {
|
|
3422
3373
|
code: "reservation_not_direct",
|
|
@@ -3452,7 +3403,7 @@ async function switchMachine(input, context, interaction) {
|
|
|
3452
3403
|
const erasesLocalData = targetMode !== currentMode;
|
|
3453
3404
|
if (erasesLocalData && input.eraseLocalData !== true) {
|
|
3454
3405
|
interaction.usage(
|
|
3455
|
-
"Changing between VM and Bare Metal permanently erases source-local data and requires --erase-local-data;
|
|
3406
|
+
"Changing between VM and Bare Metal permanently erases source-local data and requires --erase-local-data; cannot infer destructive scope.",
|
|
3456
3407
|
{ code: "erase_local_data_required", field: "eraseLocalData" }
|
|
3457
3408
|
);
|
|
3458
3409
|
}
|
|
@@ -3525,7 +3476,7 @@ async function switchMachine(input, context, interaction) {
|
|
|
3525
3476
|
}
|
|
3526
3477
|
const [currentReservationValue, currentMachines, currentRelationships, currentKeys] =
|
|
3527
3478
|
await Promise.all([
|
|
3528
|
-
context.fetch
|
|
3479
|
+
getReservation(context.fetch, reservationId),
|
|
3529
3480
|
fetchMachines(context, reservationId),
|
|
3530
3481
|
bareMetalRelationships(context, reservationId),
|
|
3531
3482
|
fetchAssignedKeys(context, reservationId),
|
|
@@ -3561,7 +3512,6 @@ async function switchMachine(input, context, interaction) {
|
|
|
3561
3512
|
requestedMode ? `--mode ${requestedMode}` : null,
|
|
3562
3513
|
requestedNetwork ? `--network ${requestedNetwork}` : null,
|
|
3563
3514
|
erasesLocalData ? "--erase-local-data" : null,
|
|
3564
|
-
"--yes",
|
|
3565
3515
|
"--no-wait",
|
|
3566
3516
|
`--idempotency-key ${shellQuote(idempotencyKey)}`,
|
|
3567
3517
|
]
|
|
@@ -3663,7 +3613,6 @@ async function switchMachine(input, context, interaction) {
|
|
|
3663
3613
|
`--mode ${targetMode}`,
|
|
3664
3614
|
`--network ${targetNetwork}`,
|
|
3665
3615
|
erasesLocalData ? "--erase-local-data" : null,
|
|
3666
|
-
"--yes",
|
|
3667
3616
|
`--idempotency-key ${shellQuote(interaction.idempotencyKey())}`,
|
|
3668
3617
|
]
|
|
3669
3618
|
.filter(Boolean)
|
|
@@ -3781,7 +3730,6 @@ async function maintainMachine(command, input, context, interaction) {
|
|
|
3781
3730
|
`ornn machines ${command}`,
|
|
3782
3731
|
shellQuote(machineId(machine)),
|
|
3783
3732
|
destructive ? "--erase-local-data" : null,
|
|
3784
|
-
"--yes",
|
|
3785
3733
|
"--no-wait",
|
|
3786
3734
|
`--idempotency-key ${shellQuote(idempotencyKey)}`,
|
|
3787
3735
|
]
|
|
@@ -3874,7 +3822,6 @@ async function maintainMachine(command, input, context, interaction) {
|
|
|
3874
3822
|
`ornn machines ${command}`,
|
|
3875
3823
|
shellQuote(machineId(waitOutcome.value)),
|
|
3876
3824
|
destructive ? "--erase-local-data" : null,
|
|
3877
|
-
"--yes",
|
|
3878
3825
|
`--idempotency-key ${shellQuote(interaction.idempotencyKey())}`,
|
|
3879
3826
|
]
|
|
3880
3827
|
.filter(Boolean)
|