@microck/raft 0.5.0 → 0.7.0
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 +27 -15
- package/deploy/build-image.py +4 -2
- package/deploy/raft-expire.py +109 -31
- package/deploy/verify-controls.py +6 -6
- package/deploy/verify-features.py +329 -19
- package/deploy/verify-jobs.py +264 -0
- package/deploy/verify-limits.py +22 -3
- package/deploy/verify-live.py +31 -6
- package/deploy/verify-output.py +208 -0
- package/deploy/verify-release.py +33 -4
- package/deploy/verify-run.py +571 -0
- package/deploy/verify-self-update.py +9 -1
- package/deploy/verify-sync.py +122 -0
- package/docs/benchmarks/read-latency-2026-10-29.json +70 -0
- package/docs/boat-capabilities.md +60 -7
- package/docs/boat-parity-design.md +1 -0
- package/docs/boot-performance.mdx +21 -0
- package/docs/contract.md +88 -13
- package/docs/first-box.mdx +22 -19
- package/docs/guides/background-jobs.mdx +38 -31
- package/docs/guides/backup-recovery.mdx +4 -3
- package/docs/guides/ci-jobs.mdx +209 -0
- package/docs/guides/config-policy.mdx +109 -35
- package/docs/guides/files.mdx +2 -2
- package/docs/guides/index.mdx +31 -0
- package/docs/guides/long-running-services.mdx +9 -3
- package/docs/guides/meta.json +7 -2
- package/docs/guides/project-setup.mdx +1 -1
- package/docs/guides/scripting-ci.mdx +36 -14
- package/docs/guides/snapshots-forks.mdx +4 -2
- package/docs/guides/troubleshooting.mdx +19 -2
- package/docs/guides/upgrades.mdx +11 -9
- package/docs/index.mdx +26 -28
- package/docs/maintainers/index.mdx +18 -0
- package/docs/maintainers/meta.json +12 -0
- package/docs/meta.json +5 -9
- package/docs/operations.mdx +17 -10
- package/docs/publishing.md +14 -4
- package/docs/reference/capacity.mdx +2 -1
- package/docs/reference/cli.md +135 -43
- package/docs/reference/configuration.mdx +10 -6
- package/docs/reference/meta.json +3 -1
- package/docs/releases/0.2.0.md +1 -0
- package/docs/releases/0.2.1.md +1 -0
- package/docs/releases/0.3.0.md +1 -0
- package/docs/releases/0.4.0.md +1 -0
- package/docs/releases/0.5.0.md +1 -0
- package/docs/releases/0.6.0.md +17 -0
- package/docs/releases/0.7.0.md +23 -0
- package/docs/releases/index.mdx +21 -0
- package/docs/releases/meta.json +15 -0
- package/docs/requirements.mdx +1 -1
- package/docs/reviews/docs-audit-2026-10-24.md +92 -0
- package/docs/reviews/performance-audit-2026-10-29.md +90 -0
- package/docs/site-development.md +1 -0
- package/docs/verification.mdx +22 -4
- package/package.json +3 -1
- package/raft.py +526 -193
- package/raft_files.py +13 -1
- package/raft_jobs.py +390 -0
- package/raft_output.py +166 -0
- package/raft_run.py +330 -0
- package/skills/raft-cli/SKILL.md +78 -182
package/docs/guides/meta.json
CHANGED
|
@@ -3,16 +3,21 @@
|
|
|
3
3
|
"collapsible": true,
|
|
4
4
|
"defaultOpen": false,
|
|
5
5
|
"pages": [
|
|
6
|
+
"index",
|
|
7
|
+
"---Develop---",
|
|
6
8
|
"project-setup",
|
|
7
9
|
"docker",
|
|
8
10
|
"files",
|
|
11
|
+
"desktop-services",
|
|
12
|
+
"---Automate---",
|
|
9
13
|
"background-jobs",
|
|
10
14
|
"long-running-services",
|
|
11
15
|
"scripting-ci",
|
|
12
|
-
"
|
|
13
|
-
"
|
|
16
|
+
"ci-jobs",
|
|
17
|
+
"---Operate---",
|
|
14
18
|
"snapshots-forks",
|
|
15
19
|
"backup-recovery",
|
|
20
|
+
"config-policy",
|
|
16
21
|
"upgrades",
|
|
17
22
|
"troubleshooting"
|
|
18
23
|
]
|
|
@@ -15,7 +15,7 @@ service. Commands run as guest root in `/workspace` unless you choose another us
|
|
|
15
15
|
Create a persistent box after [host setup](../operations.mdx):
|
|
16
16
|
|
|
17
17
|
```sh title="CONTROLLER: Create a project box"
|
|
18
|
-
box=$(raft new --location lab --ttl 3600)
|
|
18
|
+
box=$(raft new --location lab --ttl 3600 --persistent)
|
|
19
19
|
```
|
|
20
20
|
|
|
21
21
|
Upload a local project, excluding credentials and files you do not want copied.
|
|
@@ -11,15 +11,34 @@ authentication, and hosts with passwordless sudo. No Raft HTTP API, SDK, or API
|
|
|
11
11
|
exists. Give access only to trusted jobs: the configured SSH account has host sudo
|
|
12
12
|
and controls all boxes on that host.
|
|
13
13
|
|
|
14
|
+
For one-shot builds, [`raft run`](./ci-jobs.mdx) combines allocation, source upload,
|
|
15
|
+
foreground execution, artifact collection and disposable cleanup. It is an
|
|
16
|
+
orchestration command, not a registered CI runner. The manual lifecycle examples
|
|
17
|
+
below remain useful for persistent debugging workflows.
|
|
18
|
+
|
|
14
19
|
## Output formats
|
|
15
20
|
|
|
16
|
-
|
|
21
|
+
The development CLI supports `raft --json COMMAND ...` for JSON Lines output.
|
|
22
|
+
Each event has a `type`: `data` carries a structured `value`; `stdout` and
|
|
23
|
+
`stderr` carry base64-encoded bytes in `data`; `error` carries `code` and
|
|
24
|
+
`message`; the final `exit` carries the process exit `code`. Decode stream events
|
|
25
|
+
in order within each channel. Chunks need not end at line boundaries. This keeps
|
|
26
|
+
binary output intact and streams long-running command output without buffering
|
|
27
|
+
it all. Interactive `ssh`, `forward` and `desktop` reject JSON mode before acting.
|
|
28
|
+
Help/version work without configuration. JSON mode suppresses release notices.
|
|
29
|
+
|
|
30
|
+
```sh
|
|
31
|
+
raft --json list --location lab | jq 'select(.type == "data") | .value'
|
|
32
|
+
raft --json exec "$BOX" -- sh -c 'echo hello; exit 7'
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Without global `--json`, parse each command's format:
|
|
17
36
|
|
|
18
37
|
| Command | stdout |
|
|
19
38
|
| --- | --- |
|
|
20
39
|
| `new`, `fork`, `recover` | One location-qualified handle |
|
|
21
40
|
| `exec --detach` | One `rfcmd-` job ID |
|
|
22
|
-
| `list` | JSONL: one object per box, with `box`, `state`, `stopAt`, `disk`, `note` |
|
|
41
|
+
| `list` | JSONL: one object per box, with `box`, `state`, `stopAt`, `deleteAt`, `disk`, `note` |
|
|
23
42
|
| `info` | One pretty-printed native Incus metadata JSON object |
|
|
24
43
|
| `usage` | One JSON object containing running resource counters |
|
|
25
44
|
| `capacity --json` | One JSON object per location (JSONL across multiple hosts) |
|
|
@@ -27,13 +46,15 @@ Raft does not have a global `--json` option. Parse each command's actual format:
|
|
|
27
46
|
| `config` | One pretty-printed JSON object with `file`, `defaults`, `policy` |
|
|
28
47
|
| `config set/unset`, `policy` | One line describing the change |
|
|
29
48
|
| `prune` | JSONL candidates or deleted records with `box`, `action` |
|
|
30
|
-
| `status` |
|
|
31
|
-
| `logs` |
|
|
32
|
-
| `exec` | Payload stdout/stderr |
|
|
49
|
+
| `status` | Retained JSON record with `state`, `exitCode`, timestamps and `droppedBytes` |
|
|
50
|
+
| `logs` | First 1 MiB of retained combined output |
|
|
51
|
+
| `exec`, `run` | Payload stdout/stderr; `run` lifecycle diagnostics use stderr |
|
|
33
52
|
| Other inspection/maintenance commands | Human-readable text or no output |
|
|
34
53
|
|
|
35
54
|
`list` emits nothing when there are no boxes. `stopAt` is the host Unix deadline
|
|
36
|
-
as a string, or an empty string when absent. `
|
|
55
|
+
as a string, or an empty string when absent. `deleteAt` is the Unix time the
|
|
56
|
+
location's retention policy deletes a stopped box, in the same form, or an empty
|
|
57
|
+
string. `disk` is `"shared"` or the box's
|
|
37
58
|
own disk size, such as `"20GiB"`. `note` is the box note object with
|
|
38
59
|
`purpose` and optional `owner` and `next`, or `null`. `info` uses native Incus keys rather
|
|
39
60
|
than a normalized Raft schema. `usage` includes `memoryBytes`, `memoryLimit`,
|
|
@@ -52,10 +73,11 @@ raft prune --location lab --older-than 7 | jq -r '.box'
|
|
|
52
73
|
|
|
53
74
|
`raft new` fills omitted options from the controller's
|
|
54
75
|
`~/.config/raft/config.json`, so the same script can create different boxes on
|
|
55
|
-
different controllers. Pass `--location`, `--ttl`, `--cpu`, `--memory
|
|
56
|
-
`--disk` in CI.
|
|
76
|
+
different controllers. Pass `--location`, `--ttl`, `--cpu`, `--memory`,
|
|
77
|
+
`--disk` and `--disposable` or `--persistent` in CI.
|
|
57
78
|
Hosts can also require box note fields; give `--purpose`, `--owner` and `--next`
|
|
58
|
-
so a policy cannot fail the job.
|
|
79
|
+
so a policy cannot fail the job. A host retention policy can delete a box left
|
|
80
|
+
stopped between jobs; see [Defaults and host policies](./config-policy.mdx).
|
|
59
81
|
|
|
60
82
|
Do not redirect `2>&1` into machine-readable output. Recovery reports its allocated
|
|
61
83
|
handle on stderr before import finishes; only a successful completion prints the
|
|
@@ -76,10 +98,10 @@ stderr.
|
|
|
76
98
|
|
|
77
99
|
SSH transport failures may return SSH's status rather than the payload's result.
|
|
78
100
|
The foreground tunnel replaces the CLI process with SSH and uses SSH's exit code.
|
|
79
|
-
A zero exit from `status` means the query succeeded
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
[Background jobs](./background-jobs.mdx).
|
|
101
|
+
A zero exit from `status` means the query succeeded. Wait for a terminal `state`
|
|
102
|
+
and read `exitCode`; running, cancelled and interrupted jobs have no confirmed
|
|
103
|
+
payload exit code. Results remain readable after stop or deletion for seven days.
|
|
104
|
+
See [Background jobs](./background-jobs.mdx).
|
|
83
105
|
|
|
84
106
|
## Create, wait, run, and stop
|
|
85
107
|
|
|
@@ -105,7 +127,7 @@ cleanup() {
|
|
|
105
127
|
}
|
|
106
128
|
trap cleanup EXIT
|
|
107
129
|
|
|
108
|
-
box=$(raft new --location lab --ttl 3600)
|
|
130
|
+
box=$(raft new --location lab --ttl 3600 --persistent)
|
|
109
131
|
printf 'Created %s\n' "$box" >&2
|
|
110
132
|
ready=false
|
|
111
133
|
for attempt in {1..30}; do
|
|
@@ -9,7 +9,8 @@ Raft captures filesystem snapshots, rolls back changes, and clones workspaces on
|
|
|
9
9
|
|
|
10
10
|
## Target workspace handle
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
Use a **persistent** workspace and stop it first. Stopping a disposable box deletes
|
|
13
|
+
it and its snapshots; do not use one as the source for this walkthrough.
|
|
13
14
|
|
|
14
15
|
```sh title="CONTROLLER: Select and stop target workspace"
|
|
15
16
|
raft list
|
|
@@ -66,6 +67,7 @@ raft resume "$box" --ttl 600
|
|
|
66
67
|
Forking creates an independent clone on the same host:
|
|
67
68
|
|
|
68
69
|
```sh title="CONTROLLER: Fork workspace into a new clone"
|
|
70
|
+
raft stop "$box" # Use a persistent box; stop deletes disposable boxes
|
|
69
71
|
copy=$(raft fork "$box" --ttl 600)
|
|
70
72
|
echo "Created fork: $copy"
|
|
71
73
|
```
|
|
@@ -110,4 +112,4 @@ copy=$(raft fork "$box" --ttl 600 --cpu 2 --memory 4GiB)
|
|
|
110
112
|
raft resume "$box" --ttl 600 --memory 2GiB
|
|
111
113
|
```
|
|
112
114
|
|
|
113
|
-
Omitted CPU and RAM values keep the source limits; the disk never changes on fork or resume. Forks are persistent by default
|
|
115
|
+
Omitted CPU and RAM values keep the source limits; the disk never changes on fork or resume. Forks are persistent by default, even when `raft config` sets `disposable true`; add `--disposable` to delete a clone when it stops or expires.
|
|
@@ -33,8 +33,8 @@ raft doctor
|
|
|
33
33
|
|
|
34
34
|
An active expiration timer can still run an older worker. Installing or updating
|
|
35
35
|
the controller CLI does not deploy host code. `doctor` checks the same worker
|
|
36
|
-
protocol as disposable creation and retention
|
|
37
|
-
changing any boxes. It exits nonzero and names the location on a mismatch.
|
|
36
|
+
protocol as disposable creation, prune and setting a retention policy, without
|
|
37
|
+
running expiry or changing any boxes. It exits nonzero and names the location on a mismatch.
|
|
38
38
|
|
|
39
39
|
Review the host deployment changes, then deploy from the checkout matching your
|
|
40
40
|
CLI. Replace `lab` with the location reported by the diagnostic:
|
|
@@ -106,6 +106,23 @@ files and snapshots. Expired disposable containers are deleted, including their
|
|
|
106
106
|
snapshots. Use `raft gc --location lab` to check only one host. The timer normally
|
|
107
107
|
checks every 15 seconds; host outages, graceful shutdown and long locked
|
|
108
108
|
operations can delay expiry. See [Lifetime and persistent services](./long-running-services.mdx).
|
|
109
|
+
`raft gc` also applies the location's stopped-box retention.
|
|
110
|
+
|
|
111
|
+
### A stopped box disappeared
|
|
112
|
+
|
|
113
|
+
A host retention policy deletes boxes left stopped for its hours. Check the
|
|
114
|
+
policy and the host journal, which records every deletion:
|
|
115
|
+
|
|
116
|
+
```sh title="CONTROLLER: Check retention"
|
|
117
|
+
raft config | jq '.policy'
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
```sh title="HOST: Find the deletion"
|
|
121
|
+
sudo journalctl -t raft | grep 'Deleted box'
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Deleted boxes cannot be recovered except from a `raft backup` archive. See
|
|
125
|
+
[Defaults and host policies](./config-policy.mdx#delete-boxes-left-stopped).
|
|
109
126
|
|
|
110
127
|
## Common error scenarios
|
|
111
128
|
|
package/docs/guides/upgrades.mdx
CHANGED
|
@@ -17,7 +17,7 @@ parts of Raft. Updating one does not automatically update the others.
|
|
|
17
17
|
## Choose a release and prepare
|
|
18
18
|
|
|
19
19
|
Review [release notes](https://github.com/Microck/raft/releases) and use matching
|
|
20
|
-
CLI and deployment sources. The examples below pin `v0.
|
|
20
|
+
CLI and deployment sources. The examples below pin `v0.6.0`; replace that version
|
|
21
21
|
consistently when adopting another release.
|
|
22
22
|
|
|
23
23
|
```sh title="CONTROLLER: Inspect the current installation"
|
|
@@ -34,7 +34,7 @@ stopping one. Schedule redeployment when interruptions are acceptable.
|
|
|
34
34
|
## Update the controller
|
|
35
35
|
|
|
36
36
|
`raft self-update` installs the latest release through the channel that
|
|
37
|
-
installed the CLI, and `raft self-update --version 0.
|
|
37
|
+
installed the CLI, and `raft self-update --version 0.6.0` installs a chosen
|
|
38
38
|
one. `raft self-update --check` only reports. For npm installs, npm checks the
|
|
39
39
|
registry integrity hash of a package published with provenance. For uv tools,
|
|
40
40
|
Raft downloads the release wheel and refuses it unless its SHA-256 matches the
|
|
@@ -43,7 +43,7 @@ release `SHA256SUMS`. See [`self-update`](../reference/cli.md#self-update).
|
|
|
43
43
|
To install a release by hand instead, for an npm installation:
|
|
44
44
|
|
|
45
45
|
```sh title="CONTROLLER: Install a pinned CLI release"
|
|
46
|
-
npm install -g @microck/raft@0.
|
|
46
|
+
npm install -g @microck/raft@0.6.0
|
|
47
47
|
raft --version
|
|
48
48
|
```
|
|
49
49
|
|
|
@@ -52,7 +52,7 @@ release, verify the checksum, then install it with `uv`:
|
|
|
52
52
|
|
|
53
53
|
```sh title="CONTROLLER: Install a verified release wheel instead of npm"
|
|
54
54
|
sha256sum --ignore-missing -c SHA256SUMS
|
|
55
|
-
uv tool install --force ./raft-0.
|
|
55
|
+
uv tool install --force ./raft-0.6.0-py3-none-any.whl
|
|
56
56
|
raft --version
|
|
57
57
|
```
|
|
58
58
|
|
|
@@ -71,8 +71,8 @@ reports each host whose worker differs from the new CLI.
|
|
|
71
71
|
Obtain a separate checkout of the matching release:
|
|
72
72
|
|
|
73
73
|
```sh title="CONTROLLER: Obtain and deploy matching host code"
|
|
74
|
-
git clone --branch v0.
|
|
75
|
-
cd raft-v0.
|
|
74
|
+
git clone --branch v0.6.0 https://github.com/Microck/raft.git raft-v0.6.0
|
|
75
|
+
cd raft-v0.6.0
|
|
76
76
|
python3 deploy/deploy.py --location lab
|
|
77
77
|
raft doctor
|
|
78
78
|
```
|
|
@@ -84,8 +84,10 @@ timer. It does not import an image or migrate guest files.
|
|
|
84
84
|
|
|
85
85
|
Do not bypass a conflicting-resource or storage-size error. Inspect the host and
|
|
86
86
|
preserve backups before explicit recovery; redeployment does not repair arbitrary
|
|
87
|
-
infrastructure drift. Disposable creation/fork
|
|
88
|
-
and fail if it differs from the CLI. That check
|
|
87
|
+
infrastructure drift. Disposable creation/fork, prune and setting a retention
|
|
88
|
+
policy check the worker protocol and fail if it differs from the CLI. That check
|
|
89
|
+
is not an automatic upgrade. Raft 0.6.0 raised the protocol for stopped-box
|
|
90
|
+
retention, so hosts deployed by an earlier release need this redeploy.
|
|
89
91
|
|
|
90
92
|
## Replace the image pin
|
|
91
93
|
|
|
@@ -103,7 +105,7 @@ backup's guest filesystem rather than rebuilding it from the new image.
|
|
|
103
105
|
## Verify the update
|
|
104
106
|
|
|
105
107
|
```sh title="CONTROLLER: Smoke-check a new persistent box"
|
|
106
|
-
box=$(raft new --location lab --ttl 600)
|
|
108
|
+
box=$(raft new --location lab --ttl 600 --persistent)
|
|
107
109
|
raft exec "$box" -- node --version
|
|
108
110
|
raft exec "$box" -- docker info
|
|
109
111
|
raft stop "$box"
|
package/docs/index.mdx
CHANGED
|
@@ -1,41 +1,39 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Overview
|
|
3
|
-
description:
|
|
3
|
+
description: Create persistent Linux development boxes on Ubuntu hosts you control.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Raft
|
|
7
7
|
|
|
8
|
-
Raft
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
Raft creates **persistent Linux boxes on your own Ubuntu hosts**. Run commands,
|
|
9
|
+
Docker builds and development services; copy files; save snapshots; or open a
|
|
10
|
+
private desktop. A box is an unprivileged Incus container that shares its host's
|
|
11
|
+
kernel, not a virtual machine.
|
|
12
12
|
|
|
13
|
-
##
|
|
13
|
+
## Start here
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
1. [Check requirements](./requirements.mdx): a Linux controller and a dedicated Ubuntu host.
|
|
16
|
+
2. [Set up a host](./operations.mdx): install the CLI and run guided onboarding.
|
|
17
|
+
3. [Create your first box](./first-box.mdx): run a command, stop it and resume it.
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
+
Already have a configured host? Run these commands on your **controller**
|
|
20
|
+
(the machine where you installed `raft`). Replace `lab` with your location:
|
|
21
|
+
|
|
22
|
+
```sh
|
|
23
|
+
box=$(raft new --location lab --ttl 600 --persistent)
|
|
19
24
|
raft exec "$box" -- node --version
|
|
20
25
|
raft ssh "$box"
|
|
21
|
-
raft stop "$box"
|
|
22
26
|
```
|
|
23
27
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
| Set defaults for new boxes or require box note fields | [Defaults and note policies](./guides/config-policy.mdx) |
|
|
37
|
-
| Forward guest ports or open noVNC desktop | [Desktop and private services](./guides/desktop-services.mdx) |
|
|
38
|
-
| Capture disk state or clone workspaces | [Snapshots and forks](./guides/snapshots-forks.mdx) |
|
|
39
|
-
| Export portable backups across hosts | [Backup and recovery](./guides/backup-recovery.mdx) |
|
|
40
|
-
| Update the CLI, host worker, and workspace image | [Upgrades and image changes](./guides/upgrades.mdx) |
|
|
41
|
-
| Inspect host services and diagnose errors | [Troubleshooting](./guides/troubleshooting.mdx) |
|
|
28
|
+
Exit the guest shell, then run `raft stop "$box"` on the controller. Files remain;
|
|
29
|
+
processes stop. Host retention policies can later delete stopped boxes.
|
|
30
|
+
|
|
31
|
+
## Find a task
|
|
32
|
+
|
|
33
|
+
- [Work with a project](./guides/project-setup.mdx) or [copy files](./guides/files.mdx).
|
|
34
|
+
- [Run Docker](./guides/docker.mdx), [background jobs](./guides/background-jobs.mdx), or [open a desktop](./guides/desktop-services.mdx).
|
|
35
|
+
- [Browse all guides](./guides/index.mdx), [look up a command](./reference/cli.md), or [troubleshoot](./guides/troubleshooting.mdx).
|
|
36
|
+
|
|
37
|
+
Raft is an independent open-source alternative to Boat, not affiliated with it.
|
|
38
|
+
[Compare the trade-offs](./boat-capabilities.md). Setup examples target published
|
|
39
|
+
**0.6.0**; [0.7.0 features](./releases/0.7.0.md) are marked unreleased.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Maintain Raft
|
|
3
|
+
description: Design, verification, release and documentation work for Raft contributors.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Maintain Raft
|
|
7
|
+
|
|
8
|
+
These pages are for changing or releasing Raft, not for creating your first box.
|
|
9
|
+
For everyday use, start with [host setup](../operations.mdx) or the [task guides](../guides/index.mdx).
|
|
10
|
+
|
|
11
|
+
- [Design decisions](../boat-parity-design.md): why Raft uses Incus and host SSH.
|
|
12
|
+
- [Runtime contract](../contract.md): behavior that implementations must preserve.
|
|
13
|
+
- [Verification](../verification.mdx): test commands, evidence and unverified boundaries.
|
|
14
|
+
- [Publishing](../publishing.md): package and image release gates.
|
|
15
|
+
- [Documentation site](../site-development.md): edit, preview and check these docs.
|
|
16
|
+
|
|
17
|
+
Host tests create and delete real workspaces. Read each suite's effects before
|
|
18
|
+
running it, and use dedicated infrastructure you are authorized to change.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"title": "Maintainers",
|
|
3
|
+
"collapsible": true,
|
|
4
|
+
"defaultOpen": false,
|
|
5
|
+
"pages": [
|
|
6
|
+
"index",
|
|
7
|
+
"[Design decisions](/docs/boat-parity-design/)",
|
|
8
|
+
"[Verification](/docs/verification/)",
|
|
9
|
+
"[Publishing](/docs/publishing/)",
|
|
10
|
+
"[Documentation site](/docs/site-development/)"
|
|
11
|
+
]
|
|
12
|
+
}
|
package/docs/meta.json
CHANGED
|
@@ -2,20 +2,16 @@
|
|
|
2
2
|
"title": "Raft",
|
|
3
3
|
"pages": [
|
|
4
4
|
"index",
|
|
5
|
-
"---
|
|
5
|
+
"---Get started---",
|
|
6
6
|
"requirements",
|
|
7
7
|
"operations",
|
|
8
8
|
"first-box",
|
|
9
|
+
"---Use Raft---",
|
|
9
10
|
"guides",
|
|
10
11
|
"reference",
|
|
11
|
-
"
|
|
12
|
-
"---Comparison---",
|
|
12
|
+
"---About---",
|
|
13
13
|
"boat-capabilities",
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
"boat-parity-design",
|
|
17
|
-
"verification",
|
|
18
|
-
"publishing",
|
|
19
|
-
"site-development"
|
|
14
|
+
"maintainers",
|
|
15
|
+
"releases"
|
|
20
16
|
]
|
|
21
17
|
}
|
package/docs/operations.mdx
CHANGED
|
@@ -7,6 +7,8 @@ description: Install the Raft controller CLI, provision a dedicated host, and ac
|
|
|
7
7
|
|
|
8
8
|
Set up a dedicated Ubuntu host, install the Raft CLI, provision Incus, acquire a workspace image, and verify readiness.
|
|
9
9
|
|
|
10
|
+
Examples pin published **0.6.0**. Use matching CLI, deployment scripts and image assets.
|
|
11
|
+
|
|
10
12
|
Review prerequisites in [System requirements](./requirements.mdx) before starting.
|
|
11
13
|
|
|
12
14
|
## Guided onboarding
|
|
@@ -15,7 +17,7 @@ Install the CLI from npm on your Linux controller, confirm key-based SSH to the
|
|
|
15
17
|
host, then let `raft host add` do the remaining steps:
|
|
16
18
|
|
|
17
19
|
```sh title="CONTROLLER: Onboard a host"
|
|
18
|
-
npm install -g @microck/raft@0.
|
|
20
|
+
npm install -g @microck/raft@0.6.0
|
|
19
21
|
ssh ubuntu@192.0.2.10 true
|
|
20
22
|
raft host add lab --ssh ubuntu@192.0.2.10 --dry-run
|
|
21
23
|
raft host add lab --ssh ubuntu@192.0.2.10
|
|
@@ -30,6 +32,9 @@ that instead. See [`host add`](./reference/cli.md#host-add) for image options.
|
|
|
30
32
|
|
|
31
33
|
## Manual setup
|
|
32
34
|
|
|
35
|
+
<details>
|
|
36
|
+
<summary>Advanced: provision each component yourself instead of using host add</summary>
|
|
37
|
+
|
|
33
38
|
The steps below are what `raft host add` automates. Follow them to inspect or
|
|
34
39
|
customize each stage.
|
|
35
40
|
|
|
@@ -62,7 +67,7 @@ sudo -n true && echo "Passwordless sudo is functional"
|
|
|
62
67
|
On your Linux controller with Python 3.11.8+, install the published CLI:
|
|
63
68
|
|
|
64
69
|
```sh title="CONTROLLER: Install published CLI"
|
|
65
|
-
npm install -g @microck/raft@0.
|
|
70
|
+
npm install -g @microck/raft@0.6.0
|
|
66
71
|
raft --version
|
|
67
72
|
```
|
|
68
73
|
|
|
@@ -70,7 +75,7 @@ Installation does not configure hosts or download images. Clone the matching
|
|
|
70
75
|
release to obtain the deployment scripts and example configuration:
|
|
71
76
|
|
|
72
77
|
```sh title="CONTROLLER: Obtain deployment scripts"
|
|
73
|
-
git clone --branch v0.
|
|
78
|
+
git clone --branch v0.6.0 https://github.com/Microck/raft.git raft
|
|
74
79
|
cd raft
|
|
75
80
|
```
|
|
76
81
|
|
|
@@ -161,16 +166,16 @@ Workspaces require an unprivileged Debian 13 development image matching the host
|
|
|
161
166
|
|
|
162
167
|
<Tab value="Download release image">
|
|
163
168
|
|
|
164
|
-
Download the release archive, checksum, and manifest from [Raft releases](https://github.com/Microck/raft/releases). These examples pin `v0.
|
|
169
|
+
Download the release archive, checksum, and manifest from [Raft releases](https://github.com/Microck/raft/releases). These examples pin `v0.6.0`, matching the CLI and deployment checkout above. The `sha256sum` check gates import so corrupted archives are rejected:
|
|
165
170
|
|
|
166
171
|
<Tabs items={["ARM64", "AMD64"]}>
|
|
167
172
|
|
|
168
173
|
<Tab value="ARM64">
|
|
169
174
|
|
|
170
175
|
```sh title="HOST (ARM64): Download, verify, and import release image"
|
|
171
|
-
curl -fsSL -O https://github.com/Microck/raft/releases/download/v0.
|
|
172
|
-
curl -fsSL -O https://github.com/Microck/raft/releases/download/v0.
|
|
173
|
-
curl -fsSL -O https://github.com/Microck/raft/releases/download/v0.
|
|
176
|
+
curl -fsSL -O https://github.com/Microck/raft/releases/download/v0.6.0/raft-dev-arm64.tar.gz
|
|
177
|
+
curl -fsSL -O https://github.com/Microck/raft/releases/download/v0.6.0/SHA256SUMS
|
|
178
|
+
curl -fsSL -O https://github.com/Microck/raft/releases/download/v0.6.0/manifest-arm64.json
|
|
174
179
|
|
|
175
180
|
sha256sum --ignore-missing -c SHA256SUMS && \
|
|
176
181
|
sudo incus --project raft image import ./raft-dev-arm64.tar.gz --alias raft-dev
|
|
@@ -181,9 +186,9 @@ sha256sum --ignore-missing -c SHA256SUMS && \
|
|
|
181
186
|
<Tab value="AMD64">
|
|
182
187
|
|
|
183
188
|
```sh title="HOST (AMD64): Download, verify, and import release image"
|
|
184
|
-
curl -fsSL -O https://github.com/Microck/raft/releases/download/v0.
|
|
185
|
-
curl -fsSL -O https://github.com/Microck/raft/releases/download/v0.
|
|
186
|
-
curl -fsSL -O https://github.com/Microck/raft/releases/download/v0.
|
|
189
|
+
curl -fsSL -O https://github.com/Microck/raft/releases/download/v0.6.0/raft-dev-amd64.tar.gz
|
|
190
|
+
curl -fsSL -O https://github.com/Microck/raft/releases/download/v0.6.0/SHA256SUMS
|
|
191
|
+
curl -fsSL -O https://github.com/Microck/raft/releases/download/v0.6.0/manifest-amd64.json
|
|
187
192
|
|
|
188
193
|
sha256sum --ignore-missing -c SHA256SUMS && \
|
|
189
194
|
sudo incus --project raft image import ./raft-dev-amd64.tar.gz --alias raft-dev
|
|
@@ -258,6 +263,8 @@ Check that Incus, the network service, and the expiration timer are active. For
|
|
|
258
263
|
|
|
259
264
|
</Steps>
|
|
260
265
|
|
|
266
|
+
</details>
|
|
267
|
+
|
|
261
268
|
## Next step
|
|
262
269
|
|
|
263
270
|
Proceed to [First working box](./first-box.mdx) to launch, verify, and manage your first workspace.
|
package/docs/publishing.md
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Publishing
|
|
3
|
+
description: Release packages and native images through verified publication gates.
|
|
3
4
|
---
|
|
4
5
|
|
|
5
6
|
# Publishing a clean source release
|
|
@@ -8,12 +9,12 @@ Public releases must contain only reusable code, examples, and documentation. Ke
|
|
|
8
9
|
|
|
9
10
|
## Release assets and image publishing
|
|
10
11
|
|
|
11
|
-
Release `main` through the `native images` workflow with a semantic `release_tag`, such as `v0.
|
|
12
|
+
Release `main` through the `native images` workflow with a semantic `release_tag`, such as `v0.7.0`. The tag must match both Python and npm versions. Clean upstream Debian bases provide the images.
|
|
12
13
|
|
|
13
14
|
The workflow builds and inspects Python and npm packages, tests their installed executables outside the checkout, and publishes `@microck/raft` using the repository's `NPM_TOKEN` secret with npm provenance. Only then does it create the GitHub release with the wheel, source archive, npm tarball and verified image assets. Published versions are immutable; after partial publication, fix the failure and use a new patch version.
|
|
14
15
|
|
|
15
16
|
```sh
|
|
16
|
-
gh workflow run images.yml --ref main -f release_tag=v0.
|
|
17
|
+
gh workflow run images.yml --ref main -f release_tag=v0.7.0
|
|
17
18
|
```
|
|
18
19
|
|
|
19
20
|
- **Validation gating**: Publication requires native lifecycle and full-image recovery jobs alongside fresh AMD64 KVM provisioning and reboot verification.
|
|
@@ -30,15 +31,24 @@ Scan **all Git history**, branches, and tags before changing repository visibili
|
|
|
30
31
|
|
|
31
32
|
## Release verification commands
|
|
32
33
|
|
|
34
|
+
Install `gitleaks`, `uv`, Node.js with `npm`, and the OpenSSH client providing `ssh-keygen` before running these checks. Ensure they are available on `PATH`; `uv sync --locked` does not install these tools.
|
|
35
|
+
|
|
33
36
|
Run security scanning, linting, formatting checks, and package builds before tagging:
|
|
34
37
|
|
|
35
38
|
```sh
|
|
36
39
|
gitleaks dir --redact --no-banner .
|
|
37
40
|
gitleaks git --redact --no-banner .
|
|
38
41
|
uv sync --locked
|
|
39
|
-
uvx ruff check raft.py deploy/*.py
|
|
40
|
-
uvx ruff format --check raft.py deploy/*.py
|
|
42
|
+
uvx ruff check raft.py raft_files.py raft_run.py deploy/*.py
|
|
43
|
+
uvx ruff format --check raft.py raft_files.py raft_run.py deploy/*.py
|
|
44
|
+
uv run python -m compileall -q raft.py raft_files.py raft_run.py deploy
|
|
45
|
+
uv run python deploy/verify-limits.py
|
|
46
|
+
uv run python deploy/verify-image-tests.py
|
|
47
|
+
uv run python deploy/verify-run.py
|
|
48
|
+
uv run python deploy/verify-features.py
|
|
49
|
+
uv run python deploy/verify-self-update.py
|
|
41
50
|
uv build
|
|
51
|
+
uv run python deploy/verify-release.py
|
|
42
52
|
```
|
|
43
53
|
|
|
44
54
|
## Image distribution rules
|
|
@@ -23,7 +23,7 @@ A box from a snapshot (`new --from`) or a fork keeps the source's CPU, RAM and
|
|
|
23
23
|
disk instead of any default, and each flag you pass overrides only its own value.
|
|
24
24
|
|
|
25
25
|
```sh
|
|
26
|
-
box=$(raft new --cpu 4 --memory 16GiB --disk 40GiB --ttl 3600 --purpose "Large build")
|
|
26
|
+
box=$(raft new --cpu 4 --memory 16GiB --disk 40GiB --ttl 3600 --persistent --purpose "Large build")
|
|
27
27
|
```
|
|
28
28
|
|
|
29
29
|
A CPU or RAM request larger than the whole host fails before anything is
|
|
@@ -37,6 +37,7 @@ Change CPU and RAM when you resume a stopped box or fork one:
|
|
|
37
37
|
|
|
38
38
|
```sh
|
|
39
39
|
raft resume "$box" --ttl 1800 --cpu 2 --memory 4GiB
|
|
40
|
+
raft stop "$box" # Fork requires a stopped persistent source
|
|
40
41
|
copy=$(raft fork "$box" --ttl 1800 --memory 2GiB)
|
|
41
42
|
```
|
|
42
43
|
|