amd-oneclick-sdk 1.0.0__tar.gz
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.
- amd_oneclick_sdk-1.0.0/PKG-INFO +651 -0
- amd_oneclick_sdk-1.0.0/README.md +635 -0
- amd_oneclick_sdk-1.0.0/amd_oneclick_sdk/__init__.py +45 -0
- amd_oneclick_sdk-1.0.0/amd_oneclick_sdk/_cli/__init__.py +7 -0
- amd_oneclick_sdk-1.0.0/amd_oneclick_sdk/_cli/auth_commands.py +225 -0
- amd_oneclick_sdk-1.0.0/amd_oneclick_sdk/_cli/catalog.py +541 -0
- amd_oneclick_sdk-1.0.0/amd_oneclick_sdk/_cli/common.py +51 -0
- amd_oneclick_sdk-1.0.0/amd_oneclick_sdk/_cli/completion.py +120 -0
- amd_oneclick_sdk-1.0.0/amd_oneclick_sdk/_cli/credits.py +22 -0
- amd_oneclick_sdk-1.0.0/amd_oneclick_sdk/_cli/dashboard.py +101 -0
- amd_oneclick_sdk-1.0.0/amd_oneclick_sdk/_cli/device_auth.py +103 -0
- amd_oneclick_sdk-1.0.0/amd_oneclick_sdk/_cli/instance_commands.py +378 -0
- amd_oneclick_sdk-1.0.0/amd_oneclick_sdk/_cli/instance_create.py +85 -0
- amd_oneclick_sdk-1.0.0/amd_oneclick_sdk/_cli/lifecycle.py +326 -0
- amd_oneclick_sdk-1.0.0/amd_oneclick_sdk/_cli/main.py +247 -0
- amd_oneclick_sdk-1.0.0/amd_oneclick_sdk/_cli/output.py +435 -0
- amd_oneclick_sdk-1.0.0/amd_oneclick_sdk/_cli/parser.py +363 -0
- amd_oneclick_sdk-1.0.0/amd_oneclick_sdk/_cli/profiles.py +152 -0
- amd_oneclick_sdk-1.0.0/amd_oneclick_sdk/_cli/registry.py +147 -0
- amd_oneclick_sdk-1.0.0/amd_oneclick_sdk/auth.py +204 -0
- amd_oneclick_sdk-1.0.0/amd_oneclick_sdk/cli.py +32 -0
- amd_oneclick_sdk-1.0.0/amd_oneclick_sdk/client.py +499 -0
- amd_oneclick_sdk-1.0.0/amd_oneclick_sdk/defaults.py +15 -0
- amd_oneclick_sdk-1.0.0/amd_oneclick_sdk/errors.py +96 -0
- amd_oneclick_sdk-1.0.0/amd_oneclick_sdk/keys.py +138 -0
- amd_oneclick_sdk-1.0.0/amd_oneclick_sdk/prompt.py +86 -0
- amd_oneclick_sdk-1.0.0/amd_oneclick_sdk/rcc_config.py +607 -0
- amd_oneclick_sdk-1.0.0/amd_oneclick_sdk/security.py +149 -0
- amd_oneclick_sdk-1.0.0/amd_oneclick_sdk.egg-info/PKG-INFO +651 -0
- amd_oneclick_sdk-1.0.0/amd_oneclick_sdk.egg-info/SOURCES.txt +34 -0
- amd_oneclick_sdk-1.0.0/amd_oneclick_sdk.egg-info/dependency_links.txt +1 -0
- amd_oneclick_sdk-1.0.0/amd_oneclick_sdk.egg-info/entry_points.txt +3 -0
- amd_oneclick_sdk-1.0.0/amd_oneclick_sdk.egg-info/requires.txt +3 -0
- amd_oneclick_sdk-1.0.0/amd_oneclick_sdk.egg-info/top_level.txt +1 -0
- amd_oneclick_sdk-1.0.0/pyproject.toml +32 -0
- amd_oneclick_sdk-1.0.0/setup.cfg +4 -0
|
@@ -0,0 +1,651 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: amd-oneclick-sdk
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Scoped command-line SDK for Radeon Cloud accounts and instances
|
|
5
|
+
License-Expression: MIT
|
|
6
|
+
Keywords: amd,gpu,rocm,jupyter,radeon-cloud
|
|
7
|
+
Classifier: Development Status :: 4 - Beta
|
|
8
|
+
Classifier: Environment :: Console
|
|
9
|
+
Classifier: Intended Audience :: Developers
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Topic :: System :: Distributed Computing
|
|
12
|
+
Requires-Python: >=3.9
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
Provides-Extra: dev
|
|
15
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
16
|
+
|
|
17
|
+
# Radeon Cloud CLI (RCC)
|
|
18
|
+
|
|
19
|
+
RCC is the command-line interface and Python SDK for connecting a local
|
|
20
|
+
workstation to an existing Radeon Cloud account and managing that account's
|
|
21
|
+
Jupyter instance. Browser authorization uses the existing GitHub, email, or SSO
|
|
22
|
+
login flow and returns a scoped, expiring `rcc_...` resource token to the CLI.
|
|
23
|
+
|
|
24
|
+
> **Integration status:** this package is version `1.0.0` and implements the
|
|
25
|
+
> first Radeon-Cloud-Internal integration. The server feature is disabled by
|
|
26
|
+
> default with `RCC_CLI_ENABLED=false`; operators must apply the RCC database
|
|
27
|
+
> migration and verify the public routes before enabling it. Use
|
|
28
|
+
> `rcc capabilities` to inspect the contract exposed by a deployment.
|
|
29
|
+
|
|
30
|
+
For the Chinese integration handoff, including interface ownership, token
|
|
31
|
+
scopes, implemented safeguards, current limitations, and the joint test
|
|
32
|
+
checklist, see [主项目接口对接与联调清单](../docs/ops/rcc-sdk-main-project-handoff-cn.md).
|
|
33
|
+
|
|
34
|
+
The built-in Manager endpoint is `https://radeon-global.anruicloud.com`.
|
|
35
|
+
Operators can select another deployment with a named profile, `--base-url`, or
|
|
36
|
+
the matched `RCC_URL` / `RCC_TOKEN` environment variables described below.
|
|
37
|
+
|
|
38
|
+
An RCC token is deliberately separate from the existing `rc-...` model
|
|
39
|
+
forwarding / Token Factory credential:
|
|
40
|
+
|
|
41
|
+
- `rcc_...` authorizes scoped account, Catalog, and Jupyter-instance actions.
|
|
42
|
+
- `rc-...` remains a model-forwarding credential and is rejected by this SDK
|
|
43
|
+
before a resource request is sent.
|
|
44
|
+
|
|
45
|
+
## Current capabilities
|
|
46
|
+
|
|
47
|
+
- **Browser-assisted account authorization:** approve one workstation through
|
|
48
|
+
the existing Radeon Cloud website without copying a web session or password
|
|
49
|
+
into the CLI.
|
|
50
|
+
- **Per-device credentials:** every login receives its own named, scoped,
|
|
51
|
+
expiring token; logout revokes only the selected token.
|
|
52
|
+
- **Multiple local accounts:** save named account profiles and select an
|
|
53
|
+
explicit identity for each command.
|
|
54
|
+
- **Read-only account and Credits status:** inspect the signed-in identity and
|
|
55
|
+
GPU-hour balance without exposing the legacy Token Factory credential.
|
|
56
|
+
- **Administrator Catalog discovery:** list and search approved environments,
|
|
57
|
+
resource pools, and resource templates.
|
|
58
|
+
- **Jupyter lifecycle:** create, inspect, watch, read logs from, open, and delete
|
|
59
|
+
the current account-owned instance.
|
|
60
|
+
- **Safe browser handoff:** open a ready Jupyter instance through a short-lived,
|
|
61
|
+
single-use URL.
|
|
62
|
+
- **Managed SSH:** reuse a matching local identity, append its public key only
|
|
63
|
+
when needed, and enter a ready instance with `rcc instance ssh`.
|
|
64
|
+
- **Automation output:** use versioned `human`, `json`, or `ndjson` output and
|
|
65
|
+
generate shell completion locally.
|
|
66
|
+
|
|
67
|
+
The Radeon Cloud service never receives a kubeconfig, Kubernetes
|
|
68
|
+
ServiceAccount token, SSH private key, internal Launch Job identifier,
|
|
69
|
+
workload API key, or OpenCode password.
|
|
70
|
+
|
|
71
|
+
## Installation
|
|
72
|
+
|
|
73
|
+
### Requirements
|
|
74
|
+
|
|
75
|
+
- Python 3.9 or newer.
|
|
76
|
+
- Linux, macOS, or Windows 10/11.
|
|
77
|
+
- A browser that can reach the configured Radeon Cloud login page. A browser is
|
|
78
|
+
not required on the CLI host when `--no-browser` is used.
|
|
79
|
+
- OpenSSH (`ssh` and `ssh-keygen`) when managed SSH is used.
|
|
80
|
+
|
|
81
|
+
The package has no third-party Python runtime dependencies.
|
|
82
|
+
|
|
83
|
+
### Install from the repository
|
|
84
|
+
|
|
85
|
+
From the Radeon-Cloud-Internal repository root:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
python3 -m pip install ./sdk
|
|
89
|
+
rcc --version
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
For SDK development:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
python3 -m pip install -e ./sdk
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Install a release wheel
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
pipx install ./amd_oneclick_sdk-1.0.0-py3-none-any.whl
|
|
102
|
+
rcc --version
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Packaged Linux and Windows bundles
|
|
106
|
+
|
|
107
|
+
A release bundle places exactly one RCC wheel beside its platform installer.
|
|
108
|
+
After extracting the bundle, run:
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
# Linux, from the extracted linux bundle
|
|
112
|
+
bash install-rcc.sh
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
```text
|
|
116
|
+
Windows: double-click install-rcc.cmd or run it from Command Prompt.
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Both installers create an isolated per-user Python environment and finish by
|
|
120
|
+
printing the installed RCC version. Administrator privileges are not required.
|
|
121
|
+
|
|
122
|
+
Both `rcc` and the compatibility executable `amd-oneclick` invoke the same CLI.
|
|
123
|
+
|
|
124
|
+
## Quick start
|
|
125
|
+
|
|
126
|
+
### 1. Sign in
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
rcc auth login --account work
|
|
130
|
+
rcc auth status
|
|
131
|
+
rcc doctor
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
RCC opens a one-time verification page on the configured Radeon Cloud site.
|
|
135
|
+
Sign in through the normal web flow, review the device name, and approve the
|
|
136
|
+
request. On a headless or remote workstation, print the link instead:
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
rcc auth login --account work --no-browser
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Open that link in a trusted browser before the transaction expires. The CLI
|
|
143
|
+
polls only the one-time authorization transaction; it never reads browser
|
|
144
|
+
cookies.
|
|
145
|
+
|
|
146
|
+
### 2. Inspect approved resources
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
rcc credits status
|
|
150
|
+
rcc catalog list
|
|
151
|
+
rcc catalog list --kind environment
|
|
152
|
+
rcc catalog list --kind resource_pool
|
|
153
|
+
rcc catalog list --kind resource_template
|
|
154
|
+
rcc capabilities
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Catalog `available` means the account is policy-eligible at read time. It does
|
|
158
|
+
not reserve a GPU or guarantee that capacity is currently schedulable.
|
|
159
|
+
|
|
160
|
+
### 3. Create a Jupyter instance
|
|
161
|
+
|
|
162
|
+
Configure the account's SSH key once before its first SSH-enabled launch:
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
rcc instance add-key
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
This validates an existing local identity or offers to generate Ed25519, then
|
|
169
|
+
appends only its public half. Instance creation enables SSH by default; use
|
|
170
|
+
`--no-ssh` only when SSH is not wanted.
|
|
171
|
+
Direct `--token` or `RCC_TOKEN` credentials must also pass `--identity-file`;
|
|
172
|
+
RCC never borrows the active named account's private key for another token.
|
|
173
|
+
|
|
174
|
+
Run the command in an interactive terminal to select Catalog values, or pass
|
|
175
|
+
all selectors explicitly for automation:
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
rcc instance create \
|
|
179
|
+
--env REVIEWED_ENVIRONMENT \
|
|
180
|
+
--pod-type RESOURCE_POOL \
|
|
181
|
+
--resource-template RESOURCE_TEMPLATE
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
By default, the command waits for readiness by polling the current-instance
|
|
185
|
+
endpoint directly. It does not read or expose an internal Launch Job. To return
|
|
186
|
+
as soon as creation is accepted:
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
rcc instance create \
|
|
190
|
+
--env REVIEWED_ENVIRONMENT \
|
|
191
|
+
--pod-type RESOURCE_POOL \
|
|
192
|
+
--resource-template RESOURCE_TEMPLATE \
|
|
193
|
+
--no-wait
|
|
194
|
+
|
|
195
|
+
rcc instance status --watch
|
|
196
|
+
rcc instance logs
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Use `--idempotency-key KEY` when retrying the same logical create operation
|
|
200
|
+
after a lost response. The same key must not be reused for a different launch.
|
|
201
|
+
|
|
202
|
+
### 4. Open the instance
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
rcc instance open
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
For a headless machine, print the short-lived URL and open it on another trusted
|
|
209
|
+
device:
|
|
210
|
+
|
|
211
|
+
```bash
|
|
212
|
+
rcc instance open --print
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
The URL is single-use and sensitive even though it contains neither the RCC
|
|
216
|
+
token nor an internal workload credential. Do not place it in logs or chat.
|
|
217
|
+
|
|
218
|
+
### 5. Release the GPU
|
|
219
|
+
|
|
220
|
+
```bash
|
|
221
|
+
rcc instance delete --yes
|
|
222
|
+
rcc instance status
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Deletion is explicit. Logging out or removing a local profile does not stop an
|
|
226
|
+
instance or GPU billing. A successful response that says the instance is
|
|
227
|
+
shutting down does not mean cleanup has completed; continue checking status
|
|
228
|
+
until no active instance is reported.
|
|
229
|
+
|
|
230
|
+
## Supported command surface
|
|
231
|
+
|
|
232
|
+
```text
|
|
233
|
+
rcc status
|
|
234
|
+
rcc auth login|status|logout
|
|
235
|
+
rcc account add|list|current|use|remove
|
|
236
|
+
rcc credits status
|
|
237
|
+
rcc catalog list|show|search
|
|
238
|
+
rcc doctor
|
|
239
|
+
rcc capabilities
|
|
240
|
+
rcc instance create|add-key|list|status|logs|open|ssh|delete
|
|
241
|
+
rcc completion bash|zsh|fish|powershell
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
The following table is the first-release command-to-API contract. Commands
|
|
245
|
+
marked **local** require no server endpoint.
|
|
246
|
+
|
|
247
|
+
| Command | RCC BFF request(s) | Required scope / behavior |
|
|
248
|
+
|---|---|---|
|
|
249
|
+
| `rcc auth login` | `POST /api/cli/auth/start`, browser `GET/POST /auth/cli/verify/{code}`, then `POST /api/cli/auth/poll` | Login start and poll are one-time, unauthenticated transactions; browser approval requires the existing web session. |
|
|
250
|
+
| `rcc auth status` | `GET /api/cli/auth/status` | `account:read`; `--all` checks `GET /api/cli/account` for each saved profile. |
|
|
251
|
+
| `rcc auth logout` | `POST /api/cli/auth/logout` | `account:read`; revokes the effective device token; removes a profile only when it supplied that token. |
|
|
252
|
+
| `rcc account add` | Same device-authorization flow as `auth login` | Saves a new named local profile after browser approval. |
|
|
253
|
+
| `rcc account list/current/use` | **Local** | Reads or updates `~/.radeon-cloud/config.json`; token values are never displayed. |
|
|
254
|
+
| `rcc account remove` | **Local** by default; `POST /api/cli/auth/logout` with `--revoke` | Removes only the named local profile unless `--revoke` is explicitly supplied. |
|
|
255
|
+
| `rcc status` | `GET /api/cli/account` and `GET /api/cli/instances/current` | `account:read`, `instance:read`; combines account, Credits, and current-instance state. |
|
|
256
|
+
| `rcc credits status` | `GET /api/cli/account` | `account:read`; Credits are read-only in RCC. |
|
|
257
|
+
| `rcc catalog list/show/search` | `GET /api/cli/catalog` | `catalog:read`; `show` and `search` filter the returned approved Catalog locally. |
|
|
258
|
+
| `rcc capabilities` | `GET /api/cli/capabilities` | `account:read`; reports enabled and deferred features. |
|
|
259
|
+
| `rcc doctor` | `GET /ready`, `GET /api/cli/auth/status`, and `GET /api/cli/capabilities` | Checks local configuration, transport, token validity, and server contract. |
|
|
260
|
+
| `rcc instance add-key` | `POST /api/cli/ssh-key` | `instance:create`; validates locally and appends only the public key. |
|
|
261
|
+
| `rcc instance create` | `POST /api/cli/instances`, then `GET /api/cli/instances/current` while waiting | `instance:create`, then `instance:read`; SSH is enabled unless `--no-ssh` is passed. |
|
|
262
|
+
| `rcc instance list/status` | `GET /api/cli/instances/current` | `instance:read`; `--all` performs the same account-isolated request for each local profile. |
|
|
263
|
+
| `rcc instance logs` | `GET /api/cli/instances/current/logs` | `logs:read`. |
|
|
264
|
+
| `rcc instance open` | `POST /api/cli/instances/current/open` | `instance:open`; returns a one-time browser handoff. |
|
|
265
|
+
| `rcc instance ssh` | `GET /api/cli/instances/current`, then **local** OpenSSH | `instance:read`; executes `ssh` with the selected account's local private-key path. |
|
|
266
|
+
| `rcc instance delete` | `GET /api/cli/account`, `GET /api/cli/instances/current`, then `DELETE /api/cli/instances/current` | `account:read`, `instance:read`, `instance:delete`; identity and current-instance context are checked before deletion. |
|
|
267
|
+
| `rcc completion SHELL` | **Local** | Generates completion from the same registry used by the parser. |
|
|
268
|
+
|
|
269
|
+
The default `rcc_...` token scopes are:
|
|
270
|
+
|
|
271
|
+
```text
|
|
272
|
+
account:read
|
|
273
|
+
catalog:read
|
|
274
|
+
instance:read
|
|
275
|
+
instance:create
|
|
276
|
+
instance:delete
|
|
277
|
+
instance:open
|
|
278
|
+
logs:read
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
The BFF enforces the required scope again for every request. Possessing a token
|
|
282
|
+
does not grant commands outside its recorded scopes.
|
|
283
|
+
|
|
284
|
+
## Accounts, authentication, and Credits
|
|
285
|
+
|
|
286
|
+
`account` manages local profiles; `auth` manages remote per-device tokens.
|
|
287
|
+
|
|
288
|
+
```bash
|
|
289
|
+
rcc auth login --account work
|
|
290
|
+
rcc account add personal
|
|
291
|
+
rcc account list
|
|
292
|
+
rcc account current
|
|
293
|
+
rcc account use work
|
|
294
|
+
rcc -A personal status
|
|
295
|
+
rcc -A work auth status
|
|
296
|
+
rcc -A work auth logout
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
`-A/--account` is an identity boundary. When a named profile is explicitly
|
|
300
|
+
selected, ambient `RCC_URL` and `RCC_TOKEN` credentials for another account are
|
|
301
|
+
ignored. Destructive commands should use `-A NAME` when multiple profiles are
|
|
302
|
+
configured.
|
|
303
|
+
|
|
304
|
+
Environment-based automation may provide a matched pair:
|
|
305
|
+
|
|
306
|
+
```bash
|
|
307
|
+
export RCC_URL=https://radeon.example.com
|
|
308
|
+
export RCC_TOKEN=rcc_REDACTED
|
|
309
|
+
rcc --output json status
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
`RCC_TOKEN` requires a matching `RCC_URL`; RCC refuses to guess which Manager
|
|
313
|
+
should receive an ambient token. Command-line `--base-url` and `--token`
|
|
314
|
+
overrides are also available, but passing secrets in command arguments may
|
|
315
|
+
expose them through process inspection or shell history.
|
|
316
|
+
|
|
317
|
+
`rcc auth logout` resolves the same URL/token pair as other commands. If the
|
|
318
|
+
token came from a saved profile, logout revokes it and removes that profile;
|
|
319
|
+
if it came from explicit arguments or the environment, local profiles are kept.
|
|
320
|
+
Environment-only automation can log out without a local profile. A concurrent
|
|
321
|
+
replacement login is preserved when an older token is revoked.
|
|
322
|
+
|
|
323
|
+
Logout does not stop resources, release a GPU, end web sessions, or revoke
|
|
324
|
+
tokens on other devices. `rcc auth logout --all` processes all saved profiles
|
|
325
|
+
and ignores ambient credentials. It cannot be combined with `--account`,
|
|
326
|
+
`--base-url`, or `--token`.
|
|
327
|
+
|
|
328
|
+
Credits are intentionally read-only:
|
|
329
|
+
|
|
330
|
+
```bash
|
|
331
|
+
rcc credits status
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
Credit requests and changes remain in the Radeon Cloud web or administrator
|
|
335
|
+
workflow.
|
|
336
|
+
|
|
337
|
+
## Instance options and behavior
|
|
338
|
+
|
|
339
|
+
Only Catalog-approved Jupyter instances are supported. Creation accepts:
|
|
340
|
+
|
|
341
|
+
- `--env`: approved environment ID, name, or image selector.
|
|
342
|
+
- `--pod-type`: exact resource-pool ID from the Catalog.
|
|
343
|
+
- `--resource-template`: exact resource-template ID from the Catalog.
|
|
344
|
+
- `--disk-size-gb`: optional requested workspace size.
|
|
345
|
+
- `--resource-profile`: optional reviewed resource profile; default `auto`.
|
|
346
|
+
- `--use-pvc` or `--no-pvc`: optional persistence preference.
|
|
347
|
+
- `instance add-key --identity-file`: existing local private key or matching `.pub` path.
|
|
348
|
+
- `--no-ssh`: create without managed SSH.
|
|
349
|
+
- `--idempotency-key`: stable retry key for one logical create operation.
|
|
350
|
+
- `--no-wait`: return after the request is accepted.
|
|
351
|
+
- `--timeout`: local readiness wait limit; default 1800 seconds.
|
|
352
|
+
|
|
353
|
+
The Manager reports a terminal launch failure through current-instance status,
|
|
354
|
+
including while failed gateway resources are being cleaned up. A waiting create
|
|
355
|
+
exits with code `1` and the failure classification. It also stops if the accepted
|
|
356
|
+
instance disappears, is being deleted, or a different instance becomes current.
|
|
357
|
+
Internal Launch Job IDs remain private.
|
|
358
|
+
|
|
359
|
+
A local timeout or Ctrl+C does not cancel server-side work. Recover with:
|
|
360
|
+
|
|
361
|
+
```bash
|
|
362
|
+
rcc instance status --watch
|
|
363
|
+
rcc instance logs
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
Use `--interval` and `--timeout` with `instance status --watch` to control local
|
|
367
|
+
polling. Status and logs are always resolved from the authenticated account;
|
|
368
|
+
the SDK cannot supply an arbitrary server-side user name.
|
|
369
|
+
|
|
370
|
+
## Python SDK
|
|
371
|
+
|
|
372
|
+
Python callers can use the same browser authorization and RCC BFF endpoints:
|
|
373
|
+
|
|
374
|
+
```python
|
|
375
|
+
from amd_oneclick_sdk import RadeonCloudClient, authenticate
|
|
376
|
+
|
|
377
|
+
manager_url = "https://radeon.example.com"
|
|
378
|
+
login = authenticate(base_url=manager_url, device_name="build-workstation")
|
|
379
|
+
client = RadeonCloudClient(base_url=manager_url, token=login.access_token)
|
|
380
|
+
|
|
381
|
+
print(client.account())
|
|
382
|
+
print(client.capabilities())
|
|
383
|
+
print(client.catalog())
|
|
384
|
+
|
|
385
|
+
created = client.create_instance(
|
|
386
|
+
idempotency_key="provision-notebook-001",
|
|
387
|
+
environment="REVIEWED_ENVIRONMENT",
|
|
388
|
+
pod_type="RESOURCE_POOL",
|
|
389
|
+
resource_template="RESOURCE_TEMPLATE",
|
|
390
|
+
)
|
|
391
|
+
print(created)
|
|
392
|
+
print(client.instance_current())
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
`OneClickClient` remains available as a compatibility alias.
|
|
396
|
+
|
|
397
|
+
The supported lower-level client methods are:
|
|
398
|
+
|
|
399
|
+
```text
|
|
400
|
+
start_cli_auth poll_cli_auth
|
|
401
|
+
auth_status auth_logout
|
|
402
|
+
account capabilities catalog
|
|
403
|
+
add_ssh_key create_instance instance_current
|
|
404
|
+
instance_logs
|
|
405
|
+
open_instance delete_instance
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
Do not print, commit, or embed `AuthResult.access_token` in source code.
|
|
409
|
+
|
|
410
|
+
The Python client uses explicit credentials or a matched `RCC_URL` / `RCC_TOKEN`
|
|
411
|
+
pair (legacy `AMD_ONECLICK_*` aliases also work). It does not load workstation
|
|
412
|
+
profiles automatically. An explicit URL cannot be paired with a token inherited
|
|
413
|
+
from a different environment URL. Passing `token="", require_token=False`
|
|
414
|
+
creates an anonymous client and never inherits an ambient token; browser login
|
|
415
|
+
uses this mode. Explicit named CLI profiles ignore ambient credentials.
|
|
416
|
+
|
|
417
|
+
## Machine-readable output
|
|
418
|
+
|
|
419
|
+
Put global output options before the command:
|
|
420
|
+
|
|
421
|
+
```bash
|
|
422
|
+
rcc --output json catalog list
|
|
423
|
+
rcc --output ndjson instance status --watch
|
|
424
|
+
rcc --quiet --output json instance status
|
|
425
|
+
rcc -vv doctor
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
- `json` writes one final result document to stdout; progress is written to
|
|
429
|
+
stderr.
|
|
430
|
+
- `ndjson` writes event, result, or error documents one per line.
|
|
431
|
+
- Structured documents use `schema_version: rcc.cli/v1` and expose stable
|
|
432
|
+
command fields under `data`.
|
|
433
|
+
- Sensitive fields are redacted. `instance open` is an explicit handoff action,
|
|
434
|
+
so its one-time URL must still be handled as a secret.
|
|
435
|
+
- `completion` is a raw-artifact exception and writes a shell script instead of
|
|
436
|
+
an RCC result envelope.
|
|
437
|
+
|
|
438
|
+
Exit codes:
|
|
439
|
+
|
|
440
|
+
| Code | Meaning |
|
|
441
|
+
|---|---|
|
|
442
|
+
| `0` | The local command completed successfully. |
|
|
443
|
+
| `1` | Manager, network, TLS, protocol, or unexpected local failure. |
|
|
444
|
+
| `2` | Usage, local configuration, or authentication failure. |
|
|
445
|
+
| `5` | Local wait timeout; server-side work may still continue. |
|
|
446
|
+
| `130` | Interrupted by the user; remote work is left unchanged. |
|
|
447
|
+
|
|
448
|
+
A status command can return `0` while reporting a remote lifecycle such as
|
|
449
|
+
`failed` or `none`. Automation must inspect the documented fields under `data`
|
|
450
|
+
as well as the process exit code.
|
|
451
|
+
|
|
452
|
+
`auth status --all` exposes `data.active_account` and `data.accounts` in both
|
|
453
|
+
JSON and NDJSON. `instance status` includes `data.error_code` and `data.detail`
|
|
454
|
+
when the server reports a failure.
|
|
455
|
+
|
|
456
|
+
`doctor` returns `0` with `data.ok=true` only after service health,
|
|
457
|
+
authentication, configuration permissions, and the RCC API v1 contract all
|
|
458
|
+
pass. It requires output schema version 1 and all first-release capabilities.
|
|
459
|
+
Missing tokens, skipped checks, capability errors, and old-server fallbacks
|
|
460
|
+
return `1`; inspect `data.capability_state`, `data.capability_detail`,
|
|
461
|
+
`data.diagnostics`, and `data.remediation`. A successful doctor result must
|
|
462
|
+
still be followed by the actual instance lifecycle validation for that deployment.
|
|
463
|
+
|
|
464
|
+
## Authentication and security model
|
|
465
|
+
|
|
466
|
+
```text
|
|
467
|
+
RCC / Python SDK
|
|
468
|
+
-> HTTPS + scoped rcc_ bearer token
|
|
469
|
+
-> Radeon-Cloud-Internal frontend BFF (/api/cli/*)
|
|
470
|
+
-> browser account lookup + derived tenant identity
|
|
471
|
+
-> internal Manager Service API
|
|
472
|
+
-> Kubernetes account-owned Jupyter instance
|
|
473
|
+
```
|
|
474
|
+
|
|
475
|
+
- The browser continues to use the existing Radeon Cloud login page. The only
|
|
476
|
+
added browser page is the isolated device-authorization confirmation page;
|
|
477
|
+
the existing business SPA, navigation, and pages are unchanged.
|
|
478
|
+
- Raw RCC tokens, polling secrets, and browser codes are not stored by the
|
|
479
|
+
server. Their SHA-256 hashes are stored with token prefix, device name,
|
|
480
|
+
scopes, expiry, and operational metadata.
|
|
481
|
+
- Each token is individually revocable. Account `token_version` changes can
|
|
482
|
+
invalidate all previously issued RCC tokens after a security event.
|
|
483
|
+
- The BFF derives the internal Manager user identity from the authenticated web
|
|
484
|
+
account. A CLI-supplied `user_name` is neither accepted nor trusted.
|
|
485
|
+
- RCC instance responses are allowlisted and exclude internal Launch Job and
|
|
486
|
+
status URLs, SSH public-key material, workload API keys, OpenCode passwords,
|
|
487
|
+
and internal browser-handoff fields. SSH host, port, username, and readiness
|
|
488
|
+
metadata are allowlisted.
|
|
489
|
+
- Authentication, token, and browser-handoff responses use
|
|
490
|
+
`Cache-Control: no-store` where credentials or one-time material may be
|
|
491
|
+
present.
|
|
492
|
+
- TLS verification cannot be disabled from the CLI. Plain HTTP is limited to
|
|
493
|
+
loopback development and the explicitly retained legacy validation endpoint;
|
|
494
|
+
never send a production token over that endpoint.
|
|
495
|
+
|
|
496
|
+
## Local state
|
|
497
|
+
|
|
498
|
+
| Path | Purpose |
|
|
499
|
+
|---|---|
|
|
500
|
+
| `~/.radeon-cloud/config.json` | Named account profiles, scoped tokens, endpoint, expiry metadata, and the last opaque instance lifecycle fence. |
|
|
501
|
+
| `~/.radeon-cloud/config.json.lock` | Cross-process lock used for atomic profile updates. |
|
|
502
|
+
| `~/.radeon-cloud/keys/NAME/id_ed25519` | Per-account local SSH private key; never uploaded. |
|
|
503
|
+
|
|
504
|
+
On POSIX systems, RCC creates the directory with mode `0700` and the config and
|
|
505
|
+
lock files with mode `0600`. On Windows, store the file in a user-restricted
|
|
506
|
+
directory and verify its ACL separately. Do not commit this configuration or
|
|
507
|
+
copy its token into logs.
|
|
508
|
+
|
|
509
|
+
## Deferred capabilities
|
|
510
|
+
|
|
511
|
+
The first Radeon-Cloud-Internal integration intentionally does **not** expose:
|
|
512
|
+
|
|
513
|
+
- Registration or registration status.
|
|
514
|
+
- Credit requests.
|
|
515
|
+
- Instance resource sampling over SSH.
|
|
516
|
+
- Launch File, Launch Plan, or public Launch Job commands.
|
|
517
|
+
- Recipe discovery or execution.
|
|
518
|
+
- Serve, ComfyUI, or workload process management.
|
|
519
|
+
- Custom images supplied by the SDK caller.
|
|
520
|
+
- Distill discovery, planning, submission, Runs, logs, artifacts, or cancel.
|
|
521
|
+
|
|
522
|
+
These commands are absent from `rcc --help`, the command registry, and shell
|
|
523
|
+
completion. Their implementation modules and Client HTTP methods are not part
|
|
524
|
+
of this release. The
|
|
525
|
+
Manager may use an internal Launch Job while creating a notebook, but its ID and
|
|
526
|
+
API are not exposed to RCC. `rcc capabilities` reports every deferred feature
|
|
527
|
+
as disabled.
|
|
528
|
+
|
|
529
|
+
## Server rollout
|
|
530
|
+
|
|
531
|
+
RCC is dark by default. Operators should follow the migration guide at
|
|
532
|
+
[`ops/migrations/rcc-cli/README.md`](../ops/migrations/rcc-cli/README.md):
|
|
533
|
+
|
|
534
|
+
1. Back up PostgreSQL.
|
|
535
|
+
2. Apply `001_expand.sql` as the schema owner.
|
|
536
|
+
3. Apply `002_grant_runtime.sql` as the owner for the frontend role, including
|
|
537
|
+
`SELECT` on `amd_oneclick_schema_versions` as well as the RCC table permissions.
|
|
538
|
+
4. Run `001_preflight.sql` **as the frontend database role** and require
|
|
539
|
+
`ready=true` with no missing privileges.
|
|
540
|
+
5. Deploy the frontend BFF and SDK with `RCC_CLI_ENABLED=false`. The Manager
|
|
541
|
+
needs no new configuration: RCC adds no Service API route, alters no frozen
|
|
542
|
+
Service API function or model, and sends no new protocol parameter.
|
|
543
|
+
6. Verify the edge routes `/api/cli/*` and `/auth/cli/*`.
|
|
544
|
+
7. Set `RCC_CLI_ENABLED=true` only after those checks succeed.
|
|
545
|
+
|
|
546
|
+
Merging the PR does not apply these manual migrations or enable the feature.
|
|
547
|
+
Then run `rcc doctor` and validate login → Credits/catalog → create/readiness →
|
|
548
|
+
logs → one-time browser opening → deletion/resource release → logout in the
|
|
549
|
+
test deployment before production enablement.
|
|
550
|
+
|
|
551
|
+
Rollback is feature-flag only: set `RCC_CLI_ENABLED=false` and retain the RCC
|
|
552
|
+
tables so issued tokens remain revocable and auditable.
|
|
553
|
+
|
|
554
|
+
## Troubleshooting
|
|
555
|
+
|
|
556
|
+
### The browser does not open
|
|
557
|
+
|
|
558
|
+
```bash
|
|
559
|
+
rcc auth login --no-browser
|
|
560
|
+
```
|
|
561
|
+
|
|
562
|
+
Open the printed short-lived URL in a trusted browser signed in to the intended
|
|
563
|
+
Radeon Cloud account.
|
|
564
|
+
|
|
565
|
+
### RCC routes return 404
|
|
566
|
+
|
|
567
|
+
Confirm that the migration is complete, the edge forwards `/api/cli/*` and
|
|
568
|
+
`/auth/cli/*`, and the frontend process has `RCC_CLI_ENABLED=true`.
|
|
569
|
+
|
|
570
|
+
### An `rc-...` token is rejected
|
|
571
|
+
|
|
572
|
+
This is expected. Run `rcc auth login` to obtain a scoped `rcc_...` resource
|
|
573
|
+
token. Keep the `rc-...` credential only for model forwarding / Token Factory.
|
|
574
|
+
|
|
575
|
+
### A token expired or was revoked
|
|
576
|
+
|
|
577
|
+
```bash
|
|
578
|
+
rcc auth login --account NAME
|
|
579
|
+
```
|
|
580
|
+
|
|
581
|
+
Browser authorization replaces the selected workstation profile with a newly
|
|
582
|
+
issued token.
|
|
583
|
+
|
|
584
|
+
### Instance creation needs selectors
|
|
585
|
+
|
|
586
|
+
Run `rcc catalog list` first. In a non-interactive shell, pass `--env`,
|
|
587
|
+
`--pod-type`, and `--resource-template` explicitly.
|
|
588
|
+
|
|
589
|
+
### A local launch wait timed out
|
|
590
|
+
|
|
591
|
+
```bash
|
|
592
|
+
rcc instance status --watch
|
|
593
|
+
rcc instance logs
|
|
594
|
+
```
|
|
595
|
+
|
|
596
|
+
The timeout does not cancel the server-side instance creation.
|
|
597
|
+
|
|
598
|
+
### A ready instance does not open automatically
|
|
599
|
+
|
|
600
|
+
```bash
|
|
601
|
+
rcc instance open --print
|
|
602
|
+
```
|
|
603
|
+
|
|
604
|
+
Open the returned URL promptly; it is short-lived and single-use.
|
|
605
|
+
|
|
606
|
+
## Local regression checks
|
|
607
|
+
|
|
608
|
+
From the repository root, with the repository's test dependencies installed:
|
|
609
|
+
|
|
610
|
+
```bash
|
|
611
|
+
python3 -m pytest -q tests/test_rcc_frontend.py \
|
|
612
|
+
tests/test_rcc_cli_schema.py tests/test_rcc_migrations.py \
|
|
613
|
+
tests/test_frontend_api_surface.py tests/test_service_api_baseline.py
|
|
614
|
+
```
|
|
615
|
+
|
|
616
|
+
These cover device authorization and token lifecycle, the RCC schema contract,
|
|
617
|
+
the applied migration under PostgreSQL, the frontend route inventory, and the
|
|
618
|
+
frozen Service API contract. The PostgreSQL check starts and stops an isolated
|
|
619
|
+
socket-only database and never uses an external database URL; it runs when
|
|
620
|
+
PostgreSQL server binaries and `psycopg2` are present and the test user is not
|
|
621
|
+
root, and otherwise reports a skip. The rest use temporary SQLite databases and
|
|
622
|
+
synthetic accounts. None of them allocate GPUs or contact real login providers.
|
|
623
|
+
|
|
624
|
+
## Project structure
|
|
625
|
+
|
|
626
|
+
```text
|
|
627
|
+
sdk/
|
|
628
|
+
amd_oneclick_sdk/
|
|
629
|
+
__init__.py # Supported public Python exports
|
|
630
|
+
auth.py # Browser-assisted device authorization
|
|
631
|
+
client.py # RCC BFF HTTP client
|
|
632
|
+
rcc_config.py # Secure local multi-account state
|
|
633
|
+
keys.py # Local SSH key validation and generation
|
|
634
|
+
security.py # URL, TLS, and handoff validation
|
|
635
|
+
cli.py # Public CLI facade
|
|
636
|
+
_cli/ # Command parser, registry, handlers, and output
|
|
637
|
+
linux/ # Linux installer scripts
|
|
638
|
+
windows/ # Windows installer scripts
|
|
639
|
+
pyproject.toml # Package metadata
|
|
640
|
+
README.md # This guide
|
|
641
|
+
|
|
642
|
+
frontend/rcc_routes.py # RCC authentication and resource BFF
|
|
643
|
+
app/cli_auth/ # RCC schema contract and credential persistence
|
|
644
|
+
templates/cli_auth.html # Standalone device-approval page
|
|
645
|
+
ops/migrations/rcc-cli/ # Additive database migration and rollout guide
|
|
646
|
+
```
|
|
647
|
+
|
|
648
|
+
## License
|
|
649
|
+
|
|
650
|
+
The SDK package is distributed under the MIT license declared in
|
|
651
|
+
[`pyproject.toml`](pyproject.toml).
|