@seeed-studio/solution-cli 0.3.2 → 0.4.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 +161 -113
- package/bin/cli.js +427 -34
- package/catalog/client-config.json +2 -2
- package/catalog/knowledge-core.json +75469 -639
- package/docs/cli-guide.md +195 -227
- package/lib/agent.js +132 -23
- package/lib/catalog-dto.js +14 -1
- package/lib/doctor.js +19 -1
- package/lib/downloader.js +24 -0
- package/lib/gotchas.js +126 -0
- package/lib/installer.js +75 -9
- package/lib/integration.js +265 -0
- package/lib/knowledge.js +1140 -103
- package/package.json +4 -3
- package/skills/solution-cli/SKILL.md +120 -28
- package/skills/solution-cli/references/consult-and-select.md +58 -14
- package/skills/solution-cli/references/deploy.md +60 -248
- package/skills/solution-cli/references/device-management.md +249 -77
- package/skills/solution-cli/references/diagnose.md +15 -0
- package/skills/solution-cli/references/edge-gotchas.md +205 -0
- package/skills/solution-cli/references/generic-rk3588.md +106 -0
- package/skills/solution-cli/references/hardware-bom.md +9 -3
- package/skills/solution-cli/references/sales-feasibility.md +65 -0
- package/skills/solution-cli/references/secondary-development.md +10 -7
|
@@ -1,89 +1,49 @@
|
|
|
1
1
|
# Deploy a solution
|
|
2
2
|
|
|
3
|
-
Run Step 0 in `SKILL.md` first
|
|
4
|
-
use `--lang en`; use `--lang zh` for a Chinese-speaking user.
|
|
3
|
+
Run Step 0 in `SKILL.md` first. Use `--lang zh` for a Chinese user and `--lang en` for an English user. The examples below use the absolute Engine path injected into the installed Skill; keep that path in place of `sensecraft-engine` when required.
|
|
5
4
|
|
|
6
5
|
## 1. Find the solution
|
|
7
6
|
|
|
8
|
-
```
|
|
7
|
+
```bash
|
|
8
|
+
solution-cli hub search "<user request>" --limit 5 --json
|
|
9
|
+
solution-cli hub get <reference-design-id> --locale <en|zh|ja> --section deployment --json
|
|
9
10
|
sensecraft-engine solution list --json
|
|
10
11
|
```
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
The Hub record identifies the business Scenario, its related Tech/RD records,
|
|
14
|
+
the deployment-document mapping, and production links. Match the request to a
|
|
15
|
+
Reference Design first; do not treat a Scenario or Tech page as an executable
|
|
16
|
+
solution. Then use the Engine's local list and `deploy-info` to confirm that
|
|
17
|
+
the mapped `solution_id` and presets are actually installed. If several RDs
|
|
18
|
+
fit, explain the difference and ask which one to use.
|
|
15
19
|
|
|
16
20
|
## 2. Read what the deployment needs
|
|
17
21
|
|
|
22
|
+
```bash
|
|
23
|
+
sensecraft-engine deploy-info <id> --lang zh
|
|
24
|
+
sensecraft-engine doctor --json
|
|
25
|
+
sensecraft-engine device ports
|
|
26
|
+
sensecraft-engine device scan --timeout 5
|
|
18
27
|
```
|
|
19
|
-
sensecraft-engine deploy-info <id> --lang en
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
- `presets[]` — deployment variants. If there is more than one, ask the user which
|
|
23
|
-
one, then run again with `--preset <preset>`. Without `--preset` the template
|
|
24
|
-
lists the steps of every preset.
|
|
25
|
-
- `steps[]` — each step's `device_id`, `type`, `required`, `connection_type`
|
|
26
|
-
(`ssh` / `serial` / `none` / ...), `parameters`, `category` (`deploy` or
|
|
27
|
-
`verify`) and `interactive`. Steps with `has_targets: true` (e.g.
|
|
28
|
-
`docker_deploy`) list `targets`: `local` = this computer's Docker, `remote` =
|
|
29
|
-
a device over SSH.
|
|
30
|
-
- Verify steps that need the user carry a ready command list:
|
|
31
|
-
`counting_cli`, `face_cli`, `wizard_cli` or `robot_cli` (see `verify.md`).
|
|
32
|
-
- `request_template` — a ready request body. Values shaped like
|
|
33
|
-
`<REQUIRED: ...>` must be filled in; everything else has a working default.
|
|
34
|
-
|
|
35
|
-
Never make up step or device IDs: the keys of `device_connections` and the
|
|
36
|
-
entries of `selected_devices` are exactly the ones in `request_template`.
|
|
37
|
-
|
|
38
|
-
Optional discovery, to pre-fill values:
|
|
39
|
-
|
|
40
|
-
```
|
|
41
|
-
sensecraft-engine device ports # serial ports (USB devices)
|
|
42
|
-
sensecraft-engine device scan --timeout 5 # SSH devices on the LAN (mDNS, IPv4)
|
|
43
|
-
sensecraft-engine device list # device catalog
|
|
44
|
-
sensecraft-engine doctor --json # this computer: serial permission, Docker, disk, network
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
## 3. Fill in and confirm
|
|
48
|
-
|
|
49
|
-
Ask the user for every `<REQUIRED: ...>` value (device IP, username, password,
|
|
50
|
-
serial port, and any user inputs). Serial steps carry both `port` and
|
|
51
|
-
`serial_port` placeholders; fill both with the port name from `device ports`.
|
|
52
28
|
|
|
53
|
-
|
|
54
|
-
set `"target_type"` to that target's own type** (`local` / `remote`) — or
|
|
55
|
-
remove `target_type`. Leaving the template's type while switching `target` is
|
|
56
|
-
rejected. Each deploy-info target carries `type` (`local` / `remote`) and,
|
|
57
|
-
when the target is tied to a board, `device` / `device_name` /
|
|
58
|
-
`device_class` (for example `rk3576`, `RK3576`): pick the target whose
|
|
59
|
-
`type` and device match the user's hardware, and copy its `type` into
|
|
60
|
-
`target_type`. `device` is null for targets that run on any Docker host. On
|
|
61
|
-
engine builds whose targets have no `type` yet, the target id suffix (for
|
|
62
|
-
example `_local`, `_remote`) is only a hint; confirm the type with `validate`
|
|
63
|
-
(§3, dry run) before starting. Remote targets need `host`, `username`
|
|
64
|
-
and either `password` or `key_file`:
|
|
29
|
+
Read `presets[]`, `steps[]`, `device_connections`, `selected_devices`, and `request_template` from `deploy-info`. A preset with more than one variant requires the user's choice. Fill every `<REQUIRED: ...>` value from the user or a read-only device check; never invent device IDs, connection keys, SSH credentials, serial ports, or Docker targets.
|
|
65
30
|
|
|
66
|
-
|
|
67
|
-
platform check failure; use a `remote` target over SSH to a Linux Docker host.
|
|
68
|
-
WSL must use the Linux engine binary and is Linux-host evidence, not Windows
|
|
69
|
-
native local Docker support. On macOS, the local target uses the literal
|
|
70
|
-
`docker` executable visible to the new engine process. If Docker Desktop's CLI
|
|
71
|
-
is only in its application bundle, provide that bundle's `bin` directory in a
|
|
72
|
-
temporary engine-process `PATH`; do not alter global shell configuration or
|
|
73
|
-
assume an already-running instance inherits the path. Docker Desktop being
|
|
74
|
-
running is a prerequisite check, not a deployment result.
|
|
31
|
+
For a `docker_deploy` step, use the target listed by `deploy-info` and copy its `type` into `target_type` (`local` or `remote`). Linux local and remote targets may declare `auto_install_docker`; the engine can install Docker/Compose when that option is enabled, but offline installation requires matching packages to be obtainable and usable permissions to already exist. Windows native local Docker is unsupported; use a Linux Docker host over SSH. macOS local Docker requires the user to install and start Docker Desktop first. The CLI does not install Docker Desktop or silently obtain `sudo`.
|
|
75
32
|
|
|
76
|
-
|
|
77
|
-
- SSH key: `"key_file": "~/.ssh/id_ed25519"` and no `password` field. The key
|
|
78
|
-
must be a regular file inside `~/.ssh` (or the engine's data directory); a
|
|
79
|
-
relative path is resolved under `~/.ssh`; other locations are refused.
|
|
33
|
+
## 3. Fill in and confirm (Zero-Plaintext-Password Protocol)
|
|
80
34
|
|
|
81
|
-
|
|
82
|
-
|
|
35
|
+
> [!IMPORTANT]
|
|
36
|
+
> **严禁在会话中索要、输出或接收用户的明文 SSH 密码!**(会触发主流大模型安全拒答拦截,且存在凭证泄露与历史污染风险)。
|
|
37
|
+
> - **标准且唯一支持认证方式**:采用 SSH 密钥免密认证 (`key_file: "~/.ssh/id_ed25519"` 或 `~/.ssh/id_rsa`)。
|
|
38
|
+
> - **若用户设备尚未配置免密公钥**:引导用户在其**本地终端**执行一次免密分发:
|
|
39
|
+
> ```bash
|
|
40
|
+
> ssh-copy-id -i ~/.ssh/id_ed25519.pub <user>@<device_ip>
|
|
41
|
+
> ```
|
|
42
|
+
> *(若本地尚无 Ed25519 密钥对,先执行 `ssh-keygen -t ed25519 -N ""` 一键创建)*。
|
|
43
|
+
> 输入密码的交互在用户独立本地终端完成,密码绝不流经大模型上下文,亦不留在会话与历史中。
|
|
44
|
+
> - **部署参数统一使用 `key_file`**:SenseCraft Engine 的部署请求格式要求远程目标通过 `key_file` 进行连接。严禁在聊天框索取明文密码。
|
|
83
45
|
|
|
84
|
-
Write the
|
|
85
|
-
directory, not `/tmp` (a file keeps the password out of the process list and
|
|
86
|
-
avoids shell quoting problems, notably in PowerShell):
|
|
46
|
+
Write the completed request to `./.sensecraft-work/body.json`, keeping credentials out of the command line:
|
|
87
47
|
|
|
88
48
|
```json
|
|
89
49
|
{
|
|
@@ -91,210 +51,62 @@ avoids shell quoting problems, notably in PowerShell):
|
|
|
91
51
|
"preset_id": "<preset>",
|
|
92
52
|
"selected_devices": ["<step_id>"],
|
|
93
53
|
"device_connections": {
|
|
94
|
-
"<step_id>": {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
Show the user the body with the password as `<REDACTED>` before starting.
|
|
102
|
-
|
|
103
|
-
On Windows PowerShell 5.1, write the JSON as UTF-8 **without a BOM**. The
|
|
104
|
-
default `Set-Content -Encoding UTF8` adds a BOM, which the Rust request reader
|
|
105
|
-
rejects. Keep the request file under the current workspace and do not print it
|
|
106
|
-
when it contains a password:
|
|
107
|
-
|
|
108
|
-
```powershell
|
|
109
|
-
$RequestPath = [System.IO.Path]::GetFullPath('.sensecraft-work/body.json')
|
|
110
|
-
$RequestDir = [System.IO.Path]::GetDirectoryName($RequestPath)
|
|
111
|
-
New-Item -ItemType Directory -Force -Path $RequestDir | Out-Null
|
|
112
|
-
$body = @{
|
|
113
|
-
solution_id = '<id>'
|
|
114
|
-
preset_id = '<preset>'
|
|
115
|
-
selected_devices = @('<step_id>')
|
|
116
|
-
device_connections = @{
|
|
117
|
-
'<step_id>' = @{
|
|
118
|
-
target = '<target_id>'
|
|
119
|
-
target_type = 'remote'
|
|
120
|
-
host = '192.168.1.50'
|
|
121
|
-
username = '<user>'
|
|
122
|
-
password = '<password>'
|
|
54
|
+
"<step_id>": {
|
|
55
|
+
"target": "<target_id>",
|
|
56
|
+
"target_type": "remote",
|
|
57
|
+
"host": "192.168.1.50",
|
|
58
|
+
"username": "<user>",
|
|
59
|
+
"key_file": "~/.ssh/id_ed25519"
|
|
123
60
|
}
|
|
124
61
|
}
|
|
125
62
|
}
|
|
126
|
-
$json = $body | ConvertTo-Json -Depth 50
|
|
127
|
-
[System.IO.File]::WriteAllText($RequestPath, $json, [System.Text.UTF8Encoding]::new($false))
|
|
128
63
|
```
|
|
129
64
|
|
|
130
|
-
|
|
131
|
-
of 2 is insufficient. Replace placeholders with user-provided values and keep
|
|
132
|
-
the file protected; never print the password.
|
|
65
|
+
Remote SSH uses a regular key under `~/.ssh` or the Engine data directory (`id_ed25519` / `id_rsa`). Serial steps need both `port` and `serial_port` when the template contains both. Add `auto_replace_containers: true` only after the user agrees to replace existing containers.
|
|
133
66
|
|
|
134
|
-
Before a remote
|
|
67
|
+
Before a remote deployment, run the no-change validation:
|
|
135
68
|
|
|
136
|
-
```
|
|
69
|
+
```bash
|
|
137
70
|
sensecraft-engine validate --params ./.sensecraft-work/body.json
|
|
138
71
|
```
|
|
139
72
|
|
|
140
|
-
|
|
141
|
-
(`verify_required`). It also lists the changes the deployment may make on each
|
|
142
|
-
target beyond the solution's own files and containers, as
|
|
143
|
-
`side_effects: {"<step_id>": [{"kind", "what", "when", "decided_in"}, ...]}`:
|
|
144
|
-
|
|
145
|
-
| `kind` | Change on the target |
|
|
146
|
-
|---|---|
|
|
147
|
-
| `sudo` | Commands run with `sudo` (Docker through `sudo docker`, actions marked `sudo`) |
|
|
148
|
-
| `daemon_json_write` | Merges `registry-mirrors` into `/etc/docker/daemon.json` (other keys kept) |
|
|
149
|
-
| `docker_daemon_restart` | Restarts the Docker daemon (all containers on the device restart with it) |
|
|
150
|
-
| `package_install` | Installs packages (Docker / Compose, `.deb`, apt / pip in an action) |
|
|
151
|
-
| `system_config` | Changes system settings (`usermod`, `update-alternatives`, services) |
|
|
152
|
-
| `reboot` | Reboots the device |
|
|
153
|
-
| `firmware_flash` | Flashes firmware |
|
|
154
|
-
| `local_script` | Runs a script on this computer |
|
|
155
|
-
|
|
156
|
-
`what` says what happens in plain words, `when` the condition: `always`, a
|
|
157
|
-
condition the engine checks during the deploy (for example "the device cannot
|
|
158
|
-
reach Docker Hub"), or "the action's script decides". `decided_in` points at
|
|
159
|
-
engine code; it is for bug reports, not something to read.
|
|
160
|
-
|
|
161
|
-
Tell the user what the list contains. If the user forbade a kind that is
|
|
162
|
-
listed (Docker restart, daemon.json changes, reboot, package installs) and
|
|
163
|
-
has not agreed to it, stop and ask before starting, also when `when` is a
|
|
164
|
-
condition: the deploy may meet it. Exception: when the action's script is in
|
|
165
|
-
the solution's step file (`devices/<x>.yaml` under `actions` or
|
|
166
|
-
`remote_overrides.actions` in `~/.sensecraft/content/solutions/<id>/`, or
|
|
167
|
-
`$SC_HOME/content/solutions/<id>/` when `SC_HOME` is set), read
|
|
168
|
-
it; if its condition can be checked read-only on the device and is not met,
|
|
169
|
-
say so and continue. Actions that come from the engine's built-in device
|
|
170
|
-
profile are not in that file: treat them as possible. Builds without a
|
|
171
|
-
`side_effects` field: assume a remote Docker deploy may write
|
|
172
|
-
`/etc/docker/daemon.json` and ask when the user restricted that.
|
|
173
|
-
|
|
174
|
-
Before the deploy, save the target's current Docker daemon config so changes
|
|
175
|
-
can be shown and restored:
|
|
176
|
-
|
|
177
|
-
```
|
|
178
|
-
ssh <user>@<ip> cat /etc/docker/daemon.json > ./.sensecraft-work/daemon.json.before
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
(a missing file is fine: note that it did not exist). After the deploy, `cat`
|
|
182
|
-
it again and show the user any difference; restoring it is a change on the
|
|
183
|
-
device and needs the user's OK.
|
|
73
|
+
Read `side_effects` and report any `sudo`, Docker daemon configuration or restart, package install, system configuration, reboot, firmware flash, or local script operation. Stop for user approval if a listed effect is outside the agreed scope. Save `/etc/docker/daemon.json` before a remote deployment when it exists so a later restoration can be reviewed separately.
|
|
184
74
|
|
|
185
75
|
## 4. Start and follow
|
|
186
76
|
|
|
77
|
+
```bash
|
|
78
|
+
sensecraft-engine deploy --params ./.sensecraft-work/body.json --yes --detach --lang zh
|
|
79
|
+
sensecraft-engine status <deployment-id> --json
|
|
80
|
+
sensecraft-engine logs <deployment-id> --since <N>
|
|
187
81
|
```
|
|
188
|
-
sensecraft-engine deploy --params ./.sensecraft-work/body.json --yes --detach --lang en
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
`--detach` prints `{"deployment_id": "...", "log": "..."}` and returns. Keep the
|
|
192
|
-
`deployment_id`. Exit code 2 means the request or arguments are invalid. When
|
|
193
|
-
the JSON error contains a `missing[]` list, ask for those fields
|
|
194
|
-
(`preset_id`, `device_connections.<id>.<key>`); for `bad_request` without
|
|
195
|
-
`missing[]`, inspect the solution ID, JSON shape, and parameter spelling before
|
|
196
|
-
asking for another value.
|
|
197
|
-
Exit code 3 with a 409 means the device is busy with another deployment.
|
|
198
|
-
|
|
199
|
-
Follow progress in one of two ways:
|
|
200
82
|
|
|
201
|
-
|
|
202
|
-
`sensecraft-engine status <deployment_id> --json`. `status` is `running`
|
|
203
|
-
while in progress and ends as `completed`, `failed`, `cancelled` or
|
|
204
|
-
`interrupted`; each device and step has its own `status` and `message`.
|
|
205
|
-
Exit code: 0 while running or completed, 1 for failed / cancelled /
|
|
206
|
-
interrupted.
|
|
207
|
-
- **Event stream:** `sensecraft-engine logs <deployment_id> --since <N>`
|
|
208
|
-
prints NDJSON events (`{seq, type, ...}`) with `seq > N` and exits; add
|
|
209
|
-
`--follow` to keep streaming until the deployment ends (run it in the
|
|
210
|
-
background if your command timeout is short). Remember the last `seq` and
|
|
211
|
-
pass it as `--since` next time, so you never read the same events twice.
|
|
83
|
+
Keep the returned `deployment_id`. Poll `status` until it is `completed`, `failed`, `cancelled`, or `interrupted`; read `logs` with the last event sequence. `--follow` can stream logs when the command timeout allows it. A request error (exit 2) needs corrected fields; a busy device (exit 3/409) needs the other deployment resolved first.
|
|
212
84
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
| `type` | Meaning |
|
|
216
|
-
|---|---|
|
|
217
|
-
| `log` | `level`, `message`; `error`-level lines are evidence for `diagnose.md` |
|
|
218
|
-
| `step_skipped` with `reason: verify_required` | The step needs the user — the `verify_required` event before it has the details |
|
|
219
|
-
| `verify_required` | Go to `verify.md` with this event |
|
|
220
|
-
| `device_completed` | One device finished |
|
|
221
|
-
| `deployment_completed` | Last event; `status` is the final result |
|
|
222
|
-
|
|
223
|
-
Read the JSON directly instead of grepping it (no interpreter, see `SKILL.md`
|
|
224
|
-
rule 5). Delete `./.sensecraft-work/` afterwards (`body.json` holds a
|
|
225
|
-
password).
|
|
226
|
-
|
|
227
|
-
Without `--detach`, `deploy --json` streams the same events on stdout and ends
|
|
228
|
-
with one `{"type": "result", "deployment_id", "status", "devices"}` line; the
|
|
229
|
-
exit code is the deployment's result. Ctrl-C or a killed agent command only
|
|
230
|
-
detaches: the deployment keeps running in the engine instance; continue with
|
|
231
|
-
`status` / `logs`.
|
|
232
|
-
|
|
233
|
-
If `--detach` prints `"backend": "python"`, the desktop app's backend is
|
|
234
|
-
running this deployment: `logs` then has `log` and `deployment_completed`
|
|
235
|
-
events only, no `verify_required`. Do the guide's verify steps with the user
|
|
236
|
-
as described in `verify.md` §1.
|
|
85
|
+
Without `--detach`, `deploy --json` waits for the final result. Interrupting the client only detaches from the running Engine deployment; continue with `status` and `logs`.
|
|
237
86
|
|
|
238
87
|
## 5. Verify
|
|
239
88
|
|
|
240
|
-
`completed` is not
|
|
89
|
+
`completed` is not by itself service verification. Handle every `verify_required` event with `verify.md`, then check the target:
|
|
241
90
|
|
|
242
|
-
- `
|
|
243
|
-
-
|
|
244
|
-
|
|
245
|
-
check):
|
|
246
|
-
`sensecraft-engine docker ps --json` (this computer),
|
|
247
|
-
`sensecraft-engine docker ps --host <ip> --username <user> --key-file ~/.ssh/id_ed25519 --json`
|
|
248
|
-
(remote with an SSH key; same path rules as `key_file` in §3), or
|
|
249
|
-
`SC_SSH_PASSWORD=<password> sensecraft-engine docker ps --host <ip> --username <user> --json`
|
|
250
|
-
(remote with a password; `--password-stdin` reads it from stdin instead).
|
|
251
|
-
`docker logs <container> --host ... --key-file ...` takes the same options.
|
|
252
|
-
Older engines without `--key-file` accept a password only; with a key-only
|
|
253
|
-
device use `ssh <user>@<ip> docker ps`.
|
|
254
|
-
- Services with a port: `curl -s -o /dev/null -w "%{http_code}" http://<host>:<port>/`
|
|
255
|
-
returns 2xx/3xx.
|
|
256
|
-
- Stay running: `completed` can precede a crash loop. CLI deploys already
|
|
257
|
-
watch each Docker service for about 60 seconds after its health check
|
|
258
|
-
answers and fail the step with `Service <name> is not healthy: ...` when a
|
|
259
|
-
container restarts, exits or disappears. Check once more yourself: run `docker ps` once,
|
|
260
|
-
wait about 60 seconds, then run it again and read the container restart
|
|
261
|
-
count (`docker inspect -f '{{.Name}} {{.RestartCount}} {{.State.Status}}' <container>`
|
|
262
|
-
over SSH, or the `Restarting` / `Up Less than a second` status in `docker ps`).
|
|
263
|
-
The counts must stay 0 and the verify endpoint (the step's `url`, or the
|
|
264
|
-
port check above) must still answer after the wait. If a container restarts
|
|
265
|
-
or the endpoint stops answering, report a crash loop, not success, and go to
|
|
266
|
-
`diagnose.md`.
|
|
267
|
-
- Tell the user the URL to open and anything the guide says to do next.
|
|
91
|
+
- Docker services remain `running` and healthy. Use `sensecraft-engine docker ps --json` locally or the remote form documented by the Engine help.
|
|
92
|
+
- Service endpoints return the expected 2xx/3xx response.
|
|
93
|
+
- For services with a health check, check once more after about 60 seconds and inspect restart counts for a crash loop.
|
|
268
94
|
|
|
269
|
-
|
|
95
|
+
Report the URL, device, deployed solution, and verification evidence. Do not report success when a container restarts, disappears, or its endpoint stops answering.
|
|
270
96
|
|
|
271
|
-
|
|
97
|
+
## 6. If anything failed
|
|
272
98
|
|
|
273
|
-
|
|
274
|
-
`device_connections` — with `selected_devices` listing only the device(s) that
|
|
275
|
-
failed (or `--device <step_id>` for one device); the others are already done.
|
|
276
|
-
Leaving manual steps in is harmless (they are skipped).
|
|
99
|
+
Go to `diagnose.md` with the `deployment_id`. Retry only after reading the error. Transient registry or network errors may be retried up to five times with increasing waits; deterministic credential, parameter, disk, port, or container errors require a fix before retry and at most three rounds.
|
|
277
100
|
|
|
278
|
-
|
|
101
|
+
To retry a partial deployment, reuse the same request body and list only failed devices. Do not change the preset or target values while diagnosing a failure. Keep the body file private and remove `./.sensecraft-work/` after the deployment workflow completes.
|
|
279
102
|
|
|
280
|
-
|
|
281
|
-
500 / 502 / 503 / 504, `TLS handshake timeout`, `i/o timeout`,
|
|
282
|
-
`connection reset`, a mirror that flaps): retry the same body without
|
|
283
|
-
asking, up to 5 times, waiting 15, 30, 60, 120, 240 seconds between tries.
|
|
284
|
-
These retries do not count as fix rounds. If the engine log shows the
|
|
285
|
-
mirror changing between tries, that is the same transient case. After the
|
|
286
|
-
5th failure, stop and report the error text, the waits and the registry host.
|
|
287
|
-
- **Deterministic failures** (bad parameter or credentials, port taken, disk
|
|
288
|
-
full, missing file, a container that exits on start, the same error with the
|
|
289
|
-
same text after a fix): stop retrying blindly. First retry after a fix
|
|
290
|
-
without asking; later retries need the user's OK; at most 3 rounds, then
|
|
291
|
-
report.
|
|
103
|
+
## Cancel
|
|
292
104
|
|
|
293
|
-
|
|
294
|
-
error after a wait as deterministic.
|
|
105
|
+
Only after the user approves cancellation:
|
|
295
106
|
|
|
296
|
-
|
|
107
|
+
```bash
|
|
108
|
+
sensecraft-engine cancel <deployment-id>
|
|
109
|
+
sensecraft-engine status <deployment-id> --json
|
|
110
|
+
```
|
|
297
111
|
|
|
298
|
-
|
|
299
|
-
`status` until it is `cancelled`, and tell the user which steps had already run:
|
|
300
|
-
the device may be half-configured.
|
|
112
|
+
Wait for `cancelled` and report which steps had already run; a cancelled deployment may leave a device partially configured.
|