@ornncompute/cli 0.1.3 → 0.1.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 +41 -0
- package/package.json +1 -1
- package/src/api-client.mjs +63 -0
- package/src/cli.mjs +911 -20
- package/src/update.mjs +388 -0
package/README.md
CHANGED
|
@@ -28,6 +28,7 @@ static.
|
|
|
28
28
|
```bash
|
|
29
29
|
ornn help [command]
|
|
30
30
|
ornn login [--auth-base <url>] [--no-browser] [--timeout <seconds>]
|
|
31
|
+
ornn update
|
|
31
32
|
ornn whoami [--json]
|
|
32
33
|
ornn status [--json]
|
|
33
34
|
ornn listings list [--gpu-type <type>] [--facility <name>] [--operator <name>] [--json]
|
|
@@ -52,6 +53,10 @@ ornn nodes revoke <node-id> [--json]
|
|
|
52
53
|
ornn nodes ssh-command <node-or-reservation-id> [--json]
|
|
53
54
|
ornn nodes keys attach <node-id> --key <path|id|label> [--json]
|
|
54
55
|
ornn nodes keys list <node-id> [--json]
|
|
56
|
+
ornn node health <node-id> [--json]
|
|
57
|
+
ornn node diagnose <node-id> [--json]
|
|
58
|
+
ornn node drain <node-id> [--reason <text>] [--json]
|
|
59
|
+
ornn node restore <node-id> [--reason <text>] [--json]
|
|
55
60
|
ornn ssh <node-or-reservation-id> [--print] [--identity-file <path>] [--user <name>] [--json]
|
|
56
61
|
ornn metrics nodes [--json]
|
|
57
62
|
ornn metrics node <node-id> [--json]
|
|
@@ -84,6 +89,14 @@ ornn storage volumes create --name <name> [--source <drive-id>] [--json]
|
|
|
84
89
|
ornn storage volumes refresh <drive-id> [--json]
|
|
85
90
|
ornn storage volumes clear <drive-id> [--json]
|
|
86
91
|
ornn storage volumes delete <drive-id> [--json]
|
|
92
|
+
ornn storage deploy <drive-id> --reservation <reservation-id> [--mount-path <path>] [--read-only|--read-write] [--json]
|
|
93
|
+
ornn storage deploy status --reservation <reservation-id> [--json]
|
|
94
|
+
ornn storage buckets list [--json]
|
|
95
|
+
ornn storage buckets show <drive-id> [--json]
|
|
96
|
+
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]
|
|
97
|
+
ornn storage buckets update-credentials <drive-id> --access-key-id <id> --secret-access-key-file <path> [--json]
|
|
98
|
+
ornn storage buckets verify <drive-id> [--json]
|
|
99
|
+
ornn storage buckets disconnect <drive-id> [--json]
|
|
87
100
|
ornn keys list [--json]
|
|
88
101
|
ornn keys add [<public-key-file>] [--public-key <key>] [--label <label>] [--json]
|
|
89
102
|
ornn keys delete <key-id> [--json]
|
|
@@ -111,6 +124,30 @@ UI aliases are first-class in the CLI: `listings` maps to the older
|
|
|
111
124
|
`availability` command, `exchange` maps to `bid`, and `gpus` maps to
|
|
112
125
|
`reservations`. The older command names remain available for scripts.
|
|
113
126
|
|
|
127
|
+
## Operator commands
|
|
128
|
+
|
|
129
|
+
The `ornn node` commands are for Ornn operators and reviewers, not tenants. They
|
|
130
|
+
strictly wrap the internal-reviewer-gated compute endpoints, so they do not use
|
|
131
|
+
the tenant CLI login. Instead they talk to the compute service directly and
|
|
132
|
+
authenticate with the shared reviewer secret:
|
|
133
|
+
|
|
134
|
+
- `ornn node health <node-id>` shows launch readiness (ready/blocked plus
|
|
135
|
+
reasons), passive fault reasons, and the last validation status.
|
|
136
|
+
- `ornn node diagnose <node-id>` queues an active health run for the node.
|
|
137
|
+
- `ornn node drain <node-id>` / `ornn node restore <node-id>` take the node out
|
|
138
|
+
of and back into service. Both accept an optional `--reason`.
|
|
139
|
+
|
|
140
|
+
Set these environment variables before running them:
|
|
141
|
+
|
|
142
|
+
- `ORNN_COMPUTE_BASE_URL` — origin of the internal compute service (for example
|
|
143
|
+
`http://localhost:8000`). The review secret travels as a request header, so
|
|
144
|
+
in any non-local deployment this should be an `https://` origin.
|
|
145
|
+
- `ORNN_INTERNAL_REVIEW_SECRET` — the reviewer secret, sent as the
|
|
146
|
+
`X-Internal-Review-Secret` header.
|
|
147
|
+
|
|
148
|
+
If either is missing the command fails with a clear error before making any
|
|
149
|
+
network request.
|
|
150
|
+
|
|
114
151
|
Commands print concise human-readable output by default. Use `--json` on
|
|
115
152
|
read/show/list commands and transaction handoffs when you need structured
|
|
116
153
|
stdout for scripts. Errors and login/browser progress go to stderr.
|
|
@@ -123,3 +160,7 @@ the terminal keeps polling until the login is approved or expires.
|
|
|
123
160
|
|
|
124
161
|
Run `ornn --help` for the full command list and `ornn api` for the
|
|
125
162
|
allowlisted compute API escape hatch.
|
|
163
|
+
|
|
164
|
+
## Updating
|
|
165
|
+
|
|
166
|
+
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.
|
package/package.json
CHANGED
package/src/api-client.mjs
CHANGED
|
@@ -94,6 +94,69 @@ export async function cliRequest({
|
|
|
94
94
|
return data;
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
+
export function resolveComputeBaseUrl({ env = process.env } = {}) {
|
|
98
|
+
const base = env.ORNN_COMPUTE_BASE_URL?.trim();
|
|
99
|
+
if (!base) {
|
|
100
|
+
throw new CliApiError(
|
|
101
|
+
"Set ORNN_COMPUTE_BASE_URL to the internal compute service origin to run operator commands.",
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
return base.replace(/\/+$/, "");
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export function resolveInternalReviewSecret({ env = process.env } = {}) {
|
|
108
|
+
const secret = env.ORNN_INTERNAL_REVIEW_SECRET?.trim();
|
|
109
|
+
if (!secret) {
|
|
110
|
+
throw new CliApiError(
|
|
111
|
+
"Set ORNN_INTERNAL_REVIEW_SECRET to authenticate operator commands.",
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
return secret;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export async function operatorRequest({
|
|
118
|
+
body,
|
|
119
|
+
endpoint,
|
|
120
|
+
env = process.env,
|
|
121
|
+
fetchImpl = fetch,
|
|
122
|
+
method = "GET",
|
|
123
|
+
} = {}) {
|
|
124
|
+
// Operator path: hit compute directly with the review secret (not the tenant /api/cli proxy).
|
|
125
|
+
const baseUrl = resolveComputeBaseUrl({ env });
|
|
126
|
+
const secret = resolveInternalReviewSecret({ env });
|
|
127
|
+
const url = new URL(endpoint, `${baseUrl}/`);
|
|
128
|
+
const headers = {
|
|
129
|
+
Accept: "application/json",
|
|
130
|
+
"X-Internal-Review-Secret": secret,
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
let requestBody;
|
|
134
|
+
if (body !== undefined) {
|
|
135
|
+
headers["Content-Type"] = "application/json";
|
|
136
|
+
requestBody = typeof body === "string" ? body : JSON.stringify(body);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
let response;
|
|
140
|
+
try {
|
|
141
|
+
response = await fetchImpl(url, { body: requestBody, headers, method });
|
|
142
|
+
} catch (error) {
|
|
143
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
144
|
+
throw new CliApiError(`Could not reach Ornn compute at ${baseUrl}: ${message}`);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const text = await response.text();
|
|
148
|
+
const data = text ? parseJson(text, url.toString(), response) : null;
|
|
149
|
+
if (!response.ok) {
|
|
150
|
+
const detail = data?.detail ?? data?.error ?? response.statusText;
|
|
151
|
+
const message = detailMessage(detail) || response.statusText;
|
|
152
|
+
throw new CliApiError(`Ornn request failed: ${message}`, {
|
|
153
|
+
detail: data,
|
|
154
|
+
status: response.status,
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
return data;
|
|
158
|
+
}
|
|
159
|
+
|
|
97
160
|
export function computeEndpoint(path) {
|
|
98
161
|
const normalized = normalizeComputePath(path);
|
|
99
162
|
return `/api/cli/compute${normalized}`;
|