@ornncompute/cli 0.1.9 → 0.2.1
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 +136 -160
- package/package.json +7 -2
- package/src/api-client.mjs +119 -185
- package/src/auth-store.mjs +9 -5
- package/src/catalog-dispatch.mjs +186 -0
- package/src/cli.mjs +1476 -2598
- package/src/device-auth.mjs +10 -8
- package/vendor/capabilities/capabilities/clusters.d.ts +2 -0
- package/vendor/capabilities/capabilities/clusters.js +99 -0
- package/vendor/capabilities/capabilities/fleet.d.ts +5 -0
- package/vendor/capabilities/capabilities/fleet.js +136 -0
- package/vendor/capabilities/capabilities/identity.d.ts +3 -0
- package/vendor/capabilities/capabilities/identity.js +24 -0
- package/vendor/capabilities/capabilities/listings.d.ts +45 -0
- package/vendor/capabilities/capabilities/listings.js +161 -0
- package/vendor/capabilities/capabilities/users.d.ts +2 -0
- package/vendor/capabilities/capabilities/users.js +49 -0
- package/vendor/capabilities/capability.d.ts +61 -0
- package/vendor/capabilities/capability.js +59 -0
- package/vendor/capabilities/catalog.d.ts +3 -0
- package/vendor/capabilities/catalog.js +14 -0
- package/vendor/capabilities/index.d.ts +10 -0
- package/vendor/capabilities/index.js +10 -0
- package/vendor/capabilities/names.d.ts +6 -0
- package/vendor/capabilities/names.js +6 -0
- package/vendor/capabilities/role.d.ts +6 -0
- package/vendor/capabilities/role.js +17 -0
- package/vendor/capabilities/spec-catalog.d.ts +78 -0
- package/vendor/capabilities/spec-catalog.js +128 -0
package/README.md
CHANGED
|
@@ -17,13 +17,23 @@ curl -fsSL https://compute.ornn.com/cli/install | sh
|
|
|
17
17
|
|
|
18
18
|
The installer requires Node.js 20 or newer and npm. It installs `@ornncompute/cli`
|
|
19
19
|
globally, exposes the `ornn` binary, adds the npm global bin directory to the
|
|
20
|
-
user's shell profile when needed, and records the
|
|
21
|
-
`authBaseUrl`
|
|
22
|
-
|
|
20
|
+
user's shell profile when needed, and records the web browser handoff as
|
|
21
|
+
`authBaseUrl` plus the API gateway as `apiBaseUrl` in
|
|
22
|
+
`~/.config/ornn/config.json`. The
|
|
23
23
|
installer prints a short Ornn Compute welcome banner and next steps; set
|
|
24
24
|
`ORNN_INSTALL_BANNER=0` to skip it or `ORNN_INSTALL_ANIMATION=0` to keep it
|
|
25
25
|
static.
|
|
26
26
|
|
|
27
|
+
`ornn whoami`, `ornn logout`, and `ornn status` call the API gateway's
|
|
28
|
+
`/v1/cli/session` and `/v1/cli/status` contracts. The gateway resolves the CLI
|
|
29
|
+
bearer itself; it never trusts caller-supplied identity or authorization-admin
|
|
30
|
+
headers. Logout asks the gateway to revoke the remote credential, then always
|
|
31
|
+
clears the local bearer. If revocation cannot be confirmed, the CLI reports
|
|
32
|
+
that the remote credential may remain active. Updated legacy installs that
|
|
33
|
+
saved only a deployed web/auth
|
|
34
|
+
origin map that known Ornn origin to its API gateway automatically; custom and
|
|
35
|
+
localhost combined endpoints are left unchanged.
|
|
36
|
+
|
|
27
37
|
## Commands
|
|
28
38
|
|
|
29
39
|
```bash
|
|
@@ -35,14 +45,20 @@ ornn status [--json]
|
|
|
35
45
|
ornn listings list [--gpu-type <type>] [--facility <name>] [--operator <name>] [--json]
|
|
36
46
|
ornn listings show <listing-id> [--open] [--json]
|
|
37
47
|
ornn buy <listing-id> [--no-open] [--json]
|
|
38
|
-
ornn exchange create <listing-id> --
|
|
48
|
+
ornn exchange create <listing-id> --node-count <n> [--min-node-count <n>] --start-date <yyyy-mm-dd> --end-date <yyyy-mm-dd> --price <usd> [--no-open] [--json]
|
|
39
49
|
ornn exchange list [--limit <1-500>] [--cursor <last-id>] [--json]
|
|
40
|
-
ornn exchange show <
|
|
41
|
-
ornn exchange update <
|
|
42
|
-
ornn exchange withdraw <
|
|
50
|
+
ornn exchange show <exchange-id> [--open] [--json]
|
|
51
|
+
ornn exchange update <exchange-id> --node-count <n> --min-node-count <n> --start-date <yyyy-mm-dd> --end-date <yyyy-mm-dd> --price <usd>
|
|
52
|
+
ornn exchange withdraw <exchange-id>
|
|
53
|
+
|
|
54
|
+
Bid create/update prefer `--node-count` and `--min-node-count`. Legacy
|
|
55
|
+
`--gpu-count` and `--min-gpu-count` remain available; they convert using the
|
|
56
|
+
listing's GPUs per node before the gateway translates the request to the
|
|
57
|
+
Commerce bid contract.
|
|
58
|
+
|
|
43
59
|
ornn gpus list [--status <status>] [--limit <1-500>] [--cursor <last-id>] [--json]
|
|
44
|
-
ornn gpus show <
|
|
45
|
-
ornn gpus checkout <
|
|
60
|
+
ornn gpus show <gpu-id> [--open] [--json]
|
|
61
|
+
ornn gpus checkout <gpu-id> [--no-open] [--json]
|
|
46
62
|
ornn nodes list [--json]
|
|
47
63
|
ornn nodes show <node-id> [--json]
|
|
48
64
|
ornn nodes launch <reservation-id> --key <path|id|label> [--mode bare-metal|vm] [--username <name>] [--network public|private] [--storage-load-drive-id <id>] [--storage-save-drive-id <id>] [--wait] [--json]
|
|
@@ -55,15 +71,17 @@ ornn nodes keys attach <node-id> --key <path|id|label> [--json]
|
|
|
55
71
|
ornn nodes keys list <node-id> [--json]
|
|
56
72
|
ornn node health <node-id> [--json]
|
|
57
73
|
ornn node diagnose <node-id> [--json]
|
|
74
|
+
ornn node list [--operator <id-or-slug>] [--facility <id>] [--json]
|
|
75
|
+
ornn node reboot <node-id> [--json]
|
|
76
|
+
ornn node hard-reset <node-id> [--json]
|
|
77
|
+
ornn node off-grid <node-id> [--json]
|
|
78
|
+
ornn node on-grid <node-id> [--json]
|
|
79
|
+
ornn node terminate <node-id> [--reason <text>] [--force] [--json]
|
|
80
|
+
ornn node admin-key <node-id> [--generate] [--json]
|
|
58
81
|
ornn node deenroll <node-id> [--reason <text>] [--keep-record] [--json]
|
|
59
|
-
ornn
|
|
60
|
-
ornn
|
|
61
|
-
ornn
|
|
62
|
-
ornn fleet enroll <fleet-id> --identity-file <path> [--confirm-takeover <ip[,ip...]>] [--json]
|
|
63
|
-
ornn fleet delete <fleet-id> --confirm-delete <fleet-id> [--json]
|
|
64
|
-
ornn reservations commerce list --tenant <email-or-id> [--fleet <fleet-id>] [--json]
|
|
65
|
-
ornn reservations commerce create --tenant <email> --listing <listing-id> --fleet <fleet-id> [--start-at <timestamp>] [--end-at <timestamp>] [--price-per-gpu-hour <rate>] [--json]
|
|
66
|
-
ornn fleet deploy <fleet-id> --tenant <contact-email> [--user <email-or-id>] --commerce-reservation <id> [--network public|private] [--json]
|
|
82
|
+
ornn reservations commerce list --tenant <email-or-id> [--listing <listing-id>] [--json]
|
|
83
|
+
ornn reservations commerce create --tenant <email> --listing <listing-id> [--node-count <n>] [--node <node-id>] [--start-at <timestamp>] [--end-at <timestamp>] [--price-per-gpu-hour <rate>] [--json]
|
|
84
|
+
ornn reservations deploy <node-id> --target-tenant <id> --commerce-reservation <id> [--target-user <id>] [--network public|private] [--json]
|
|
67
85
|
ornn ssh <node-or-reservation-id> [--print] [--identity-file <path>] [--user <name>] [--json]
|
|
68
86
|
ornn metrics nodes [--json]
|
|
69
87
|
ornn metrics node <node-id> [--json]
|
|
@@ -106,10 +124,13 @@ ornn storage volumes create --name <name> [--source <drive-id>] [--json]
|
|
|
106
124
|
ornn storage volumes refresh <drive-id> [--json]
|
|
107
125
|
ornn storage volumes clear <drive-id> [--json]
|
|
108
126
|
ornn storage volumes delete <drive-id> [--json]
|
|
127
|
+
ornn storage files ls <drive-id> [--prefix <path>] [--json]
|
|
109
128
|
ornn storage files upload <drive-id> <local-file> [--destination <path>] [--content-type <type>] [--json]
|
|
110
|
-
ornn storage
|
|
111
|
-
ornn storage
|
|
112
|
-
ornn storage
|
|
129
|
+
ornn storage files download <drive-id> <remote-path> [--output <path>] [--json]
|
|
130
|
+
ornn storage targets [--json]
|
|
131
|
+
ornn storage deploy <drive-id> --reservation <reservation-id> [--all-nodes] [--read-only|--read-write] [--json]
|
|
132
|
+
ornn storage status --reservation <reservation-id> [--watch] [--interval <seconds>] [--timeout <seconds>] [--json]
|
|
133
|
+
ornn storage detach --reservation <reservation-id> [--json]
|
|
113
134
|
ornn storage buckets list [--json]
|
|
114
135
|
ornn storage buckets show <drive-id> [--json]
|
|
115
136
|
ornn storage buckets connect gcs|s3|r2 --bucket <bucket>|--url <url> [--name <name>] [--prefix <prefix>] [--region <region>] [--account-id <id>|--endpoint-url <url>] [--access-key-id <id> --secret-access-key-file <path>] [--read-only|--read-write] [--verify] [--json]
|
|
@@ -117,26 +138,26 @@ ornn storage buckets update-credentials <drive-id> --access-key-id <id> --secret
|
|
|
117
138
|
ornn storage buckets verify <drive-id> [--json]
|
|
118
139
|
ornn storage buckets disconnect <drive-id> [--json]
|
|
119
140
|
ornn keys list [--json]
|
|
120
|
-
ornn keys add [<public-key-file>]
|
|
141
|
+
ornn keys add [<public-key-file>] --label <label> [--public-key <key>] [--json]
|
|
121
142
|
ornn keys delete <key-id> [--json]
|
|
122
143
|
ornn access show <reservation-id> [--json]
|
|
123
144
|
ornn access activate <reservation-id> --key <path|id|label> [--mode bare-metal|vm] [--username <name>] [--network public|private] [--storage-load-drive-id <id>] [--storage-save-drive-id <id>] [--wait] [--no-open] [--json]
|
|
124
145
|
ornn access switch <reservation-id> --network public|private --key <path|id|label> [--mode bare-metal|vm] [--username <name>] [--wait] [--json]
|
|
125
146
|
ornn access push-keys <reservation-id> --ssh-key-id <id> [--json]
|
|
126
147
|
ornn access keys list <reservation-id> [--json]
|
|
127
|
-
ornn access keys add <reservation-id> --public-key <key>
|
|
128
|
-
ornn access keys add <reservation-id> --public-key-file <path>
|
|
148
|
+
ornn access keys add <reservation-id> --public-key <key> --label <label> [--json]
|
|
149
|
+
ornn access keys add <reservation-id> --public-key-file <path> --label <label> [--json]
|
|
129
150
|
ornn access keys push <reservation-id> --ssh-key-id <id> [--json]
|
|
130
151
|
ornn access keys status <reservation-id> [--json]
|
|
131
152
|
ornn ssh-keys list [--json]
|
|
132
|
-
ornn ssh-keys add --public-key <key>
|
|
133
|
-
ornn ssh-keys add --public-key-file <path>
|
|
153
|
+
ornn ssh-keys add --public-key <key> --label <label> [--json]
|
|
154
|
+
ornn ssh-keys add --public-key-file <path> --label <label> [--json]
|
|
134
155
|
ornn ssh-keys delete <key-id> [--json]
|
|
135
156
|
ornn billing summary [--json]
|
|
136
157
|
ornn billing invoices [--json]
|
|
137
158
|
ornn billing showback --start <yyyy-mm-dd> --end <yyyy-mm-dd> [--json]
|
|
138
159
|
ornn billing open [--no-open] [--json]
|
|
139
|
-
ornn api <get|post|patch|put|delete> <
|
|
160
|
+
ornn api <get|post|patch|put|delete> <allowlisted-path> [--data <json>] [--raw]
|
|
140
161
|
ornn logout
|
|
141
162
|
```
|
|
142
163
|
|
|
@@ -145,11 +166,37 @@ active VM or Bare Metal machines, adding the key automatically queues the
|
|
|
145
166
|
current user's complete reservation key set on those machines. Use
|
|
146
167
|
`ornn access keys push` to explicitly re-sync keys that are already attached.
|
|
147
168
|
|
|
148
|
-
`ornn storage
|
|
169
|
+
`ornn storage status` prints reconciled object and byte progress once the
|
|
149
170
|
managed transfer has reported progress, plus the number of target nodes that
|
|
150
171
|
have acknowledged the mount. Internal placement bucket details are not shown.
|
|
151
172
|
AWS S3 and external GCS sources use the managed transfer path. Cloudflare R2
|
|
152
173
|
buckets can be connected and verified, but deployment support is coming soon.
|
|
174
|
+
The mount path is always `/home/tenant/volume`; node agents resolve `tenant` to the
|
|
175
|
+
machine's real Linux user at mount time.
|
|
176
|
+
|
|
177
|
+
`ornn storage status --watch` polls the same status endpoint on an interval
|
|
178
|
+
(10 seconds by default) instead of returning after a single check, re-printing
|
|
179
|
+
the human summary on each poll. It exits 0 once the attachment is attached and
|
|
180
|
+
every scoped node has mounted, exits 1 with an error on stderr if the
|
|
181
|
+
attachment detaches before that happens, and exits 1 with a timeout message on
|
|
182
|
+
stderr after 1800 seconds (or the value passed to `--timeout`) without
|
|
183
|
+
success. Use `--interval <seconds>` to change the poll cadence. `--interval`
|
|
184
|
+
and `--timeout` require `--watch`. Combined with `--json`, only a single JSON
|
|
185
|
+
payload is printed, at the end, instead of a stream of per-poll output.
|
|
186
|
+
|
|
187
|
+
`ornn storage detach` detaches the drive from the reservation's storage
|
|
188
|
+
attachment. Detach is origin-aware: if your reservation individually joined a
|
|
189
|
+
drive that another reservation already had attached, detach releases only
|
|
190
|
+
your reservation's own mount and leaves the rest of the attachment alone. If
|
|
191
|
+
your reservation started the attachment, or it is the last member still
|
|
192
|
+
joined, detach flushes and unmounts every node before releasing the whole
|
|
193
|
+
attachment. A node that fails to unmount is left in a retryable state with
|
|
194
|
+
the reported error; run `ornn storage detach` again with the same
|
|
195
|
+
`--reservation` to retry it. A reservation that detached from a shared drive
|
|
196
|
+
can rejoin it later by running `ornn storage deploy` again. Mounted state is
|
|
197
|
+
tracked per node, not by attachment membership, so `ornn storage status`
|
|
198
|
+
can show one node as unmounted while the rest of the attachment
|
|
199
|
+
stays mounted.
|
|
153
200
|
|
|
154
201
|
`ornn storage files upload` adds a file to the drive's current colocated copy.
|
|
155
202
|
You can upload while a direct FUSE mount is active; every mounted node sees the
|
|
@@ -159,27 +206,31 @@ same mount out across every compatible node in the node group. Avoid writing
|
|
|
159
206
|
the same file path concurrently from multiple nodes because object storage is
|
|
160
207
|
not a POSIX shared filesystem.
|
|
161
208
|
|
|
209
|
+
`ornn storage files download` streams a single object from the drive straight
|
|
210
|
+
to disk. Pass `--output <path>` to control where it's written; without it, the
|
|
211
|
+
file is saved under the remote path's basename in the current directory.
|
|
212
|
+
|
|
162
213
|
For a connected bucket, deploy once before uploading. The first deploy imports
|
|
163
214
|
the source into an Ornn-managed colocated working copy. That copy remains the
|
|
164
215
|
drive's durable data when you unmount, detach, or mount it elsewhere. Ornn
|
|
165
216
|
does not write changes back to the original connected bucket.
|
|
166
217
|
|
|
167
218
|
UI aliases are first-class in the CLI: `listings` maps to the older
|
|
168
|
-
`availability` command, `exchange` maps to `bid`,
|
|
219
|
+
`availability` command, `exchange` maps to `bid`, `gpus` maps to
|
|
169
220
|
`reservations`. The older command names remain available for scripts.
|
|
170
221
|
Bid and reservation list commands return a bounded page (500 rows by default);
|
|
171
|
-
use `--limit
|
|
172
|
-
|
|
222
|
+
use `--limit`, `--json`, and the response's opaque `next_cursor` to traverse
|
|
223
|
+
older history. Replay that cursor exactly; it is not an item ID. `show` and `checkout`
|
|
173
224
|
use exact tenant-owned item lookups, so they are not limited to the current page.
|
|
174
225
|
|
|
175
226
|
## Operator commands
|
|
176
227
|
|
|
177
228
|
The `ornn node` commands are for Ornn operators and reviewers, not tenants. They
|
|
178
|
-
wrap internal-reviewer-gated
|
|
179
|
-
internal-allowed staff user
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
229
|
+
wrap internal-reviewer-gated endpoints. Run `ornn login` as an
|
|
230
|
+
internal-allowed staff user. The CLI calls `/v1/cli/operator/*`; the gateway
|
|
231
|
+
resolves the user bearer and applies staff authorization without downloading a
|
|
232
|
+
review or service secret to the laptop. There is no direct-service break-glass
|
|
233
|
+
path.
|
|
183
234
|
|
|
184
235
|
- `ornn node health <node-id>` shows launch readiness (ready/blocked plus
|
|
185
236
|
reasons), passive fault reasons, and the last validation status.
|
|
@@ -199,17 +250,16 @@ downloads to the laptop. Optionally set `ORNN_INTERNAL_REVIEW_SECRET` plus
|
|
|
199
250
|
- `ornn node terminate <node-id> [--reason <text>] [--force]` best-effort cleans
|
|
200
251
|
the host, removes the Ornn agent, and hard-deletes the node record from the
|
|
201
252
|
platform. It does not return the host to a tenant.
|
|
202
|
-
- `ornn node admin-key <node-id
|
|
203
|
-
(including the private key) so an operator can SSH into the host.
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
listing, and queues the node-agent self-uninstall
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
`--reason <text>` to annotate the audit log. The command is idempotent
|
|
211
|
-
|
|
212
|
-
dead/unreachable node does not block on workload drain.
|
|
253
|
+
- `ornn node admin-key <node-id> [--generate]` prints the Ornn admin SSH keypair
|
|
254
|
+
for the node (including the private key) so an operator can SSH into the host.
|
|
255
|
+
`--generate` always mints a new pair, stores it, and installs the public key
|
|
256
|
+
on the live host. Treat the output as a secret.
|
|
257
|
+
- `ornn node deenroll <node-id>` gracefully terminates the enrollment (revokes
|
|
258
|
+
the node claim, retires any listing, and queues the node-agent self-uninstall
|
|
259
|
+
packet) while retaining the node row as a `deenrolled` audit record. The
|
|
260
|
+
legacy `--keep-record` flag remains accepted but is now a no-op. Pass
|
|
261
|
+
`--reason <text>` to annotate the audit log. The command is idempotent, and
|
|
262
|
+
termination is forced by default so an unreachable node does not block drain.
|
|
213
263
|
|
|
214
264
|
The operator resource commands share the same reviewer auth:
|
|
215
265
|
|
|
@@ -223,136 +273,51 @@ The operator resource commands share the same reviewer auth:
|
|
|
223
273
|
command.
|
|
224
274
|
- `ornn tokens revoke <token-id>` revokes an enrollment token.
|
|
225
275
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
- Before first contact, independently verify each host key and add it to the
|
|
229
|
-
operator's SSH `known_hosts`; fleet SSH uses strict host-key checking and will
|
|
230
|
-
not trust a key first presented during cleanup.
|
|
231
|
-
- `fleet clean ... --dry-run` tries `ubuntu`, `admin`, then `ornn`, or the
|
|
232
|
-
explicit non-root account supplied with `--ssh-user`. It binds the
|
|
233
|
-
inventory to the host's hardware identity, records the plan in Compute, and
|
|
234
|
-
writes an editable mode-`0600` policy beside the local fleet manifest (or to
|
|
235
|
-
`--policy-out`). Inventory covers accounts and orphan homes, authorized SSH
|
|
236
|
-
keys, tenant/log/temp/platform paths, workload and listener processes, GPU
|
|
237
|
-
consumers, custom systemd services, Docker/Podman objects and bind-mount
|
|
238
|
-
dependencies, and every block drive. Each resource advertises its own valid
|
|
239
|
-
actions. Suggestions are never applied silently: unresolved choices and
|
|
240
|
-
conflicts are recorded as plan data, so edit the policy and re-run the same
|
|
241
|
-
fleet with `--policy`; planning is not terminalized just because a choice is
|
|
242
|
-
needed. `--source-user` and `--preserve-user` remain legacy user-only
|
|
243
|
-
shortcuts and cannot be mixed with a policy file.
|
|
244
|
-
Coverage gates also inventory listeners, GPU and container-runtime visibility,
|
|
245
|
-
non-block mounts, advanced SSH sources, filesystem scope, root-owned workloads,
|
|
246
|
-
network state, groups/sudo, IPC, swap/RAM, and active block stacks. A verified
|
|
247
|
-
gate is kept automatically. A present or uninspectable gate must be explicitly
|
|
248
|
-
ignored with a reason, so the receipt exposes the excluded scope.
|
|
249
|
-
- `fleet clean <fleet-id> ... --confirm-clean <plan-hash>` is shown only after
|
|
250
|
-
every choice is resolved. Execution rechecks hardware and resource identity,
|
|
251
|
-
runs an idempotent per-resource journal, preserves the management SSH key,
|
|
252
|
-
enforces key-only SSH, and returns exact deleted, preserved, exception, and
|
|
253
|
-
drive-assurance evidence. `ignore` requires a reason and produces
|
|
254
|
-
`clean_with_exceptions`; it is never reported as residue-free deletion.
|
|
255
|
-
Kept files and directories are content-hashed; process identity, container
|
|
256
|
-
replacement state, and exact drive topology are rechecked. Data-drive actions
|
|
257
|
-
are selectable: `logical_clean`, `discard`, `sanitize`, or
|
|
258
|
-
`reformat`. The system drive and drives without a unique serial/WWN are
|
|
259
|
-
locked to keep/ignore for in-band cleanup. Logical clean is offered only when
|
|
260
|
-
every filesystem in the approved topology is mounted and can be emptied and
|
|
261
|
-
verified; it never substitutes `wipefs` for data deletion. Discard and NVMe
|
|
262
|
-
sanitize require device-reported support, and strong actions refuse active or
|
|
263
|
-
unverified block stacks. `sanitize` requires NVMe plus
|
|
264
|
-
controller-reported completion. Logical cleanup, discard, and reformat are
|
|
265
|
-
not certified physical-media erasure, and the system drive requires an
|
|
266
|
-
out-of-band reimage for that assurance.
|
|
267
|
-
If the local SSH command times out while a long device operation is still in
|
|
268
|
-
progress, the recorded run remains resumable; re-run the same
|
|
269
|
-
`--confirm-clean <plan-hash>` command instead of creating a different plan.
|
|
270
|
-
Plans created by a pre-v7 runner must be replanned with `--dry-run` before
|
|
271
|
-
approval. This keeps newly discovered resources bound to a fresh reviewed
|
|
272
|
-
hash instead of adapting a legacy account-only plan during execution.
|
|
273
|
-
|
|
274
|
-
In the generated policy, change only `action`, plus `reason` for `ignore` or
|
|
275
|
-
`replacement` for `replace`; keep each generated `identity_hash` intact. `keep`
|
|
276
|
-
leaves a resource running, `stop_keep` stops but retains it, `stop` terminates a
|
|
277
|
-
process, `delete` removes it, `restart` restarts a service, and `replace`
|
|
278
|
-
recreates a container from the supplied image/name/network/command/labels/mounts
|
|
279
|
-
specification. The generated `suggested_action` is review guidance, not an
|
|
280
|
-
automatic decision. Do not put secrets in replacement commands or labels; use
|
|
281
|
-
the platform secret manager or a reviewed secret mount.
|
|
282
|
-
|
|
283
|
-
- `fleet enroll <fleet-id>` refuses nodes without successful cleanup proof,
|
|
284
|
-
live-revalidates each receipt under the current enrollment attempt, then
|
|
285
|
-
issues and revokes one cleanup- and attempt-bound token per host, installs the
|
|
286
|
-
agent,
|
|
287
|
-
assigns the IB island, verifies the same management account still has
|
|
288
|
-
key-based SSH and passwordless sudo, and records the resulting GPU node IDs
|
|
289
|
-
in Compute. A private executor credential prevents two CLIs from sharing an
|
|
290
|
-
active lease. Retries reconcile nodes already registered by the same attempt
|
|
291
|
-
before rerunning cleanup or installation. Generic enrollment tokens retain
|
|
292
|
-
the legacy enrollment sanitizer.
|
|
293
|
-
- `fleet delete <fleet-id> --confirm-delete <fleet-id>` hard-deletes only an
|
|
294
|
-
abandoned cleanup plan or an unassigned legacy enrollment record. It saves a
|
|
295
|
-
local audit manifest first and refuses any Commerce/tenant/deployment link,
|
|
296
|
-
active enrollment, assigned GPU node, or completed/running cleanup evidence.
|
|
297
|
-
It never deletes the linked GPU-node records.
|
|
276
|
+
Staff Commerce reservations are listing-backed, not fleet-backed:
|
|
277
|
+
|
|
298
278
|
- `reservations commerce create --tenant <email> --listing <listing-id>
|
|
299
|
-
--
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
- `fleet deploy <fleet-id> --tenant <contact-email>
|
|
308
|
-
[--user <email-or-id>] --commerce-reservation <id>` requires a live,
|
|
309
|
-
tenant-owned Commerce reservation whose listing exactly matches the fleet.
|
|
310
|
-
The user defaults to the tenant's primary administrator. Deployment succeeds
|
|
311
|
-
only after that user's SSH access and passwordless sudo are ready on every
|
|
312
|
-
node; Commerce is stamped only after the entire fleet reports deployed. A
|
|
313
|
-
Commerce reservation can be linked to only one fleet.
|
|
314
|
-
|
|
315
|
-
Compute Postgres is authoritative. The mode-0600 files under
|
|
316
|
-
`~/.config/ornn/fleets/` include a short-lived enrollment resume credential;
|
|
317
|
-
treat them as sensitive and do not copy them into tickets or source control.
|
|
318
|
-
Cleanup proves “no
|
|
319
|
-
observable residue under the verification scope,” not certified physical-media
|
|
320
|
-
erasure. Root is never the preserved management account. `--confirm-takeover`
|
|
321
|
-
names only fleet IPs whose existing node claims may be replaced. The IB-island
|
|
322
|
-
is a locality label, not cluster creation. Test scheduling remains a separate
|
|
323
|
-
control-plane policy.
|
|
279
|
+
[--node-count <n>] [--node <node-id>]` creates and activates the tenant's
|
|
280
|
+
Commerce reservation. Node count defaults to the listing capacity; start,
|
|
281
|
+
end, and hourly rate default from the listing. Optional `--node` values pin
|
|
282
|
+
specific catalog ids. Start and end overrides must remain inside the
|
|
283
|
+
listing's allowed window; the hourly rate can also be overridden explicitly.
|
|
284
|
+
- `reservations commerce list --tenant <email-or-id> [--listing <listing-id>]`
|
|
285
|
+
lists active reservations in their live window, optionally filtered to one
|
|
286
|
+
listing.
|
|
324
287
|
|
|
325
288
|
Reservation lifecycle verbs also run under the operator surface:
|
|
326
289
|
|
|
327
290
|
- `ornn reservations commerce create|list` creates or discovers a validated
|
|
328
|
-
Commerce reservation
|
|
329
|
-
`ornn login
|
|
330
|
-
|
|
331
|
-
|
|
291
|
+
Commerce reservation from a listing. These actions require a staff
|
|
292
|
+
`ornn login` session; the gateway `/v1/cli/operator/*` allowlist enforces
|
|
293
|
+
staff authorization — there is no review-secret break-glass that bypasses
|
|
294
|
+
that gate.
|
|
332
295
|
- `ornn reservations transfer <reservation-id> --target-tenant <id>
|
|
333
296
|
[--target-user <id>] [--node <id>] [--strategy reject|park] [--confirm]`
|
|
334
297
|
transfers a reservation to another tenant.
|
|
335
298
|
- `ornn reservations deploy <node-id> --target-tenant <id>
|
|
336
299
|
--commerce-reservation <id> [--target-user <id>] [--network public|private]`
|
|
337
|
-
deploys one node only after
|
|
338
|
-
reservation and listing match that node.
|
|
300
|
+
deploys one node only after the gateway operator contract verifies that the
|
|
301
|
+
live tenant-owned Commerce reservation and listing match that node.
|
|
339
302
|
|
|
340
|
-
The tenant `ornn reservations list|show|checkout` verbs
|
|
341
|
-
login and `/
|
|
342
|
-
`
|
|
303
|
+
The tenant `ornn reservations list|show|checkout` verbs use the tenant CLI
|
|
304
|
+
login and `/v1/cli/compute` gateway contract. Staff Commerce actions use the
|
|
305
|
+
gateway operator contract; `transfer|deploy` retain the operator path above.
|
|
343
306
|
|
|
344
307
|
Staff happy path:
|
|
345
308
|
|
|
346
|
-
- `ORNN_AUTH_BASE_URL` — web/
|
|
309
|
+
- `ORNN_AUTH_BASE_URL` — web/browser handoff origin
|
|
310
|
+
- `ORNN_API_BASE_URL` — API gateway origin
|
|
347
311
|
- `ornn login` as a user allowed by `INTERNAL_ALLOWED_*` on that environment
|
|
348
312
|
|
|
349
|
-
Optional
|
|
313
|
+
Optional installer gateway base for `ornn tokens create` install one-liners:
|
|
350
314
|
|
|
351
|
-
- `
|
|
352
|
-
|
|
315
|
+
- `ORNN_INSTALLER_URL` - base serving `enrollment/install` (for deployed
|
|
316
|
+
gateways, `https://<gateway>/v1/orchestrator`), falling back to
|
|
317
|
+
`NEXT_PUBLIC_INSTALLER_URL`. Unset prints the token without an install command.
|
|
353
318
|
|
|
354
|
-
Without a staff login session
|
|
355
|
-
|
|
319
|
+
Without a staff login session, operator commands fail with a clear error before
|
|
320
|
+
making a network request.
|
|
356
321
|
|
|
357
322
|
Commands print concise human-readable output by default. Use `--json` on
|
|
358
323
|
read/show/list commands and transaction handoffs when you need structured
|
|
@@ -365,7 +330,7 @@ cannot open a browser, copy the printed URL into any browser and sign in there;
|
|
|
365
330
|
the terminal keeps polling until the login is approved or expires.
|
|
366
331
|
|
|
367
332
|
Run `ornn --help` for the full command list and `ornn api` for the
|
|
368
|
-
allowlisted
|
|
333
|
+
allowlisted gateway API escape hatch.
|
|
369
334
|
|
|
370
335
|
WireGuard client configs use the current tenant-scoped `/nodes` routes:
|
|
371
336
|
|
|
@@ -376,10 +341,21 @@ ornn api post /nodes/reservations/<reservation-id>/vpn/peers \
|
|
|
376
341
|
ornn api delete /nodes/reservations/<reservation-id>/vpn/peers/<peer-id> --raw
|
|
377
342
|
```
|
|
378
343
|
|
|
379
|
-
The legacy `/standalone-vms/*` prefix is not exposed through the
|
|
344
|
+
The legacy `/standalone-vms/*` prefix is not exposed through the gateway
|
|
345
|
+
`/v1/cli/*` allowlist.
|
|
380
346
|
Deleting a peer is the supported way to replace its key; switching a node
|
|
381
347
|
between Public and Private VPN preserves the peer.
|
|
382
348
|
|
|
383
349
|
## Updating
|
|
384
350
|
|
|
385
351
|
The CLI checks the npm registry for a newer version at most once per day and prints a one-line notice on stderr when one exists. Run `ornn update` to install it (the command detects npm, pnpm, yarn, or bun installs). The check is skipped in CI and non-interactive shells.
|
|
352
|
+
|
|
353
|
+
## Deployment
|
|
354
|
+
|
|
355
|
+
`deploy-cli-pipeline.yml` publishes `@ornncompute/cli` from `main`. Staging
|
|
356
|
+
publishes the package.json version to the npm `next` dist-tag; production then
|
|
357
|
+
promotes that same version to `latest`. Manual rolls use
|
|
358
|
+
`deploy-cli-service.yml`. Runtime changes under `apps/cli` or
|
|
359
|
+
`packages/capabilities` must bump `apps/cli/package.json` so npm receives a
|
|
360
|
+
new release. Re-running the pipeline is idempotent when that version is
|
|
361
|
+
already published.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ornncompute/cli",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Command-line interface for Ornn compute access workflows.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
"files": [
|
|
10
10
|
"bin",
|
|
11
11
|
"src",
|
|
12
|
+
"vendor",
|
|
12
13
|
"README.md"
|
|
13
14
|
],
|
|
14
15
|
"homepage": "https://compute.ornn.com",
|
|
@@ -26,7 +27,11 @@
|
|
|
26
27
|
"registry": "https://registry.npmjs.org/"
|
|
27
28
|
},
|
|
28
29
|
"scripts": {
|
|
29
|
-
"test": "node --test"
|
|
30
|
+
"test": "node --test",
|
|
31
|
+
"prepack": "node scripts/vendor-capabilities.mjs"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@ornn/capabilities": "0.1.0"
|
|
30
35
|
},
|
|
31
36
|
"engines": {
|
|
32
37
|
"node": ">=20"
|