@orchestraworks/worker 0.0.139 → 0.0.141
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 +186 -0
- package/docs/REFERENCE.md +68 -12
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -27,6 +27,192 @@ docker run --rm --entrypoint worker <image> check --harness claude
|
|
|
27
27
|
|
|
28
28
|
`worker version` prints the version and the protocol versions this build speaks.
|
|
29
29
|
|
|
30
|
+
## Make a machine image
|
|
31
|
+
|
|
32
|
+
`worker install-machine` makes the host it runs on into a machine image that a cloud starts machines from.
|
|
33
|
+
Use it for your own image under a Launcher on Azure, the program you run in your own cloud. A machine you
|
|
34
|
+
enroll yourself is not an image: run `orchestra install`, or `worker install --role worker`.
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
worker install-machine --cloud azure|aws [--harness <families>|none] [--egress-redirect] [--docker] [--node]
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Run it once, as root on Linux or as an administrator on Windows, on a host that has never run the worker.
|
|
41
|
+
Each step reads what is there, changes only what is different, and prints `ok: <step>` or
|
|
42
|
+
`changed: <step>`. The first failure stops the run and names the step. You can run it again.
|
|
43
|
+
|
|
44
|
+
`<root>` is the machine-wide root: `/var/lib/sfdk/worker` on Linux, `%ProgramData%\sfdk\worker` on Windows.
|
|
45
|
+
|
|
46
|
+
| Step | When | What it does |
|
|
47
|
+
|---|---|---|
|
|
48
|
+
| preconditions | always | Refuses a host it is not written for. Refuses a host that has booted as a machine: a boot file or `<root>/state` is there. Refuses a running worker service. |
|
|
49
|
+
| directories | Windows | Creates `<root>`, `C:\software-factory` and its `etc` folder for SYSTEM and Administrators only. Users can also read and run `C:\software-factory`, which holds the programs on the machine path. A folder that is already there is kept as it is. |
|
|
50
|
+
| package | always | Copies this release package to `<root>/package`. The service runs from there, because a self-update replaces the package directory. |
|
|
51
|
+
| agent account | Linux | Creates the `agent` account, uid and gid 1000, home `/home`, and gives `/home` to it. Another account at uid 1000 is kept. |
|
|
52
|
+
| harnesses | `--harness` | Installs the named harness families and their Node under the root. `none` or no flag installs none: a family installs itself on its first turn, in about a minute. |
|
|
53
|
+
| service | always | Defines the service, `SfdkWorker` on Windows and `sfdk-worker.service` on Linux. It restarts after a failure. The step does not start it. |
|
|
54
|
+
| cloud | always | `azure`: at each boot, the start-up task runs `worker boot-files --cloud azure`, which writes the boot files from the VM's userData, and then the worker starts. `aws`: the worker starts at each boot, after the platform's user data, and an Azure start-up task or unit from an earlier run is removed. |
|
|
55
|
+
| egress redirect | `--egress-redirect` | WinDivert and its inbound firewall rule on Windows, `iptables` on Linux. A Launcher machine does not need it. |
|
|
56
|
+
| Docker | `--docker` | Windows containers, or rootless Docker for the `agent` account. |
|
|
57
|
+
| Node | `--node` | The agent's own Node, on the machine path. On Windows a new Node keeps the packages that `npm install -g` put in its folder. |
|
|
58
|
+
| check | always | Runs `worker check --profile launcher` for `azure`, and `--profile enrolled` for `aws`. |
|
|
59
|
+
|
|
60
|
+
The hosts:
|
|
61
|
+
|
|
62
|
+
- Windows Server 2025 x64, Core or Desktop, Generation 2, and Ubuntu 22.04 and 24.04, amd64 and arm64:
|
|
63
|
+
every step.
|
|
64
|
+
- Another Windows Server, or another Linux with systemd and glibc: the required steps, `--harness` and
|
|
65
|
+
`--node`. `--docker` and `--egress-redirect` are refused, and on Linux `--cloud azure` is refused too.
|
|
66
|
+
- Windows 11, another client edition of Windows, and a Linux without systemd: refused.
|
|
67
|
+
|
|
68
|
+
The machine must reach these hosts. The command does not test them:
|
|
69
|
+
|
|
70
|
+
- the platform, and its object store;
|
|
71
|
+
- while you build the image: `registry.npmjs.org` and `nodejs.org`, and with `--docker`,
|
|
72
|
+
`download.docker.com`; on Windows with `--egress-redirect`, `github.com`; on Linux, the Ubuntu package
|
|
73
|
+
mirror.
|
|
74
|
+
|
|
75
|
+
### Windows Server 2025 for a Launcher on Azure
|
|
76
|
+
|
|
77
|
+
1. Create the build VM from Microsoft's Windows Server 2025 image, Generation 2, with
|
|
78
|
+
`--security-type Standard`. A Trusted Launch VM cannot be captured into the image definition of step 7.
|
|
79
|
+
2. Install your toolchain.
|
|
80
|
+
3. Download the worker package and check it against the digest npm publishes. In PowerShell, as an
|
|
81
|
+
administrator:
|
|
82
|
+
|
|
83
|
+
```powershell
|
|
84
|
+
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
|
85
|
+
$version = '<worker version>'
|
|
86
|
+
$meta = Invoke-RestMethod "https://registry.npmjs.org/@orchestraworks%2Fworker-win32-x64/$version"
|
|
87
|
+
$tarball = Join-Path $env:TEMP 'worker.tgz'
|
|
88
|
+
Invoke-WebRequest -UseBasicParsing -Uri $meta.dist.tarball -OutFile $tarball
|
|
89
|
+
$digest = [Security.Cryptography.SHA512]::Create().ComputeHash([IO.File]::ReadAllBytes($tarball))
|
|
90
|
+
if (('sha512-' + [Convert]::ToBase64String($digest)) -ne $meta.dist.integrity) { throw 'the download does not match the digest npm publishes' }
|
|
91
|
+
$unpacked = Join-Path $env:TEMP 'worker'
|
|
92
|
+
New-Item -ItemType Directory -Force -Path $unpacked | Out-Null
|
|
93
|
+
tar.exe -xzf $tarball -C $unpacked
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
4. Make the machine. Add `--harness claude` or another family to preinstall it:
|
|
97
|
+
|
|
98
|
+
```powershell
|
|
99
|
+
& "$unpacked\package\worker.exe" install-machine --cloud azure
|
|
100
|
+
if ($LASTEXITCODE -ne 0) { throw "install-machine exited $LASTEXITCODE; the line above names the step that failed" }
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
5. Restart the VM until no restart is pending. Sysprep refuses to run, or stops, while one is pending.
|
|
104
|
+
This command shows `"restartPending":false` when none is:
|
|
105
|
+
|
|
106
|
+
```powershell
|
|
107
|
+
& "$env:ProgramData\sfdk\worker\package\worker.exe" check --profile launcher --output json
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
6. Generalize with Sysprep:
|
|
111
|
+
|
|
112
|
+
```powershell
|
|
113
|
+
& "$env:SystemRoot\System32\Sysprep\Sysprep.exe" /oobe /generalize /mode:vm /shutdown
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
- Do not remove the built-in Administrator account. Azure renames it, so `Remove-LocalUser` fails, and
|
|
117
|
+
Sysprep resets it.
|
|
118
|
+
- An installed SQL Server is generalized only through SQL Server's own image preparation, as Microsoft
|
|
119
|
+
documents for SQL Server and Sysprep.
|
|
120
|
+
|
|
121
|
+
7. Capture the VM into an image definition in your Azure Compute Gallery. The Launcher creates Standard
|
|
122
|
+
security VMs, and on the `Dsv6` sizes it uses the NVMe disk controller, so the definition declares both:
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
az vm deallocate --resource-group <rg> --name <vm>
|
|
126
|
+
az vm generalize --resource-group <rg> --name <vm>
|
|
127
|
+
az sig image-definition create --resource-group <rg> --gallery-name <gallery> \
|
|
128
|
+
--gallery-image-definition <definition> --publisher <publisher> --offer <offer> --sku <sku> \
|
|
129
|
+
--os-type Windows --os-state Generalized --hyper-v-generation V2 \
|
|
130
|
+
--features "SecurityType=TrustedLaunchSupported DiskControllerTypes=SCSI,NVMe"
|
|
131
|
+
az sig image-version create --resource-group <rg> --gallery-name <gallery> \
|
|
132
|
+
--gallery-image-definition <definition> --gallery-image-version 1.0.0 \
|
|
133
|
+
--virtual-machine "$(az vm show --resource-group <rg> --name <vm> --query id --output tsv)"
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Keep the quotes around `--features`: without them the Azure CLI refuses the second feature as an
|
|
137
|
+
unrecognized argument.
|
|
138
|
+
|
|
139
|
+
8. Name the image version's resource id in the environment's `image`.
|
|
140
|
+
|
|
141
|
+
### Ubuntu for a Launcher on Azure
|
|
142
|
+
|
|
143
|
+
1. Create the build VM from Canonical's Ubuntu 22.04 or 24.04 image, Generation 2, with
|
|
144
|
+
`--security-type Standard`.
|
|
145
|
+
2. Install your toolchain.
|
|
146
|
+
3. Download the worker package and check it against the digest npm publishes. On arm64 the package is
|
|
147
|
+
`worker-linux-arm64`:
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
version='<worker version>'
|
|
151
|
+
curl -fsSL "https://registry.npmjs.org/@orchestraworks%2Fworker-linux-x64/${version}" -o worker.json
|
|
152
|
+
tarball="$(python3 -c 'import json; print(json.load(open("worker.json"))["dist"]["tarball"])')"
|
|
153
|
+
integrity="$(python3 -c 'import json; print(json.load(open("worker.json"))["dist"]["integrity"])')"
|
|
154
|
+
curl -fsSL "${tarball}" -o worker.tgz
|
|
155
|
+
[ "sha512-$(openssl dgst -sha512 -binary worker.tgz | base64 -w0)" = "${integrity}" ] ||
|
|
156
|
+
{ echo "the download does not match the digest npm publishes" >&2; exit 1; }
|
|
157
|
+
mkdir -p worker && tar -xzf worker.tgz -C worker
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
4. Make the machine:
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
sudo ./worker/package/worker install-machine --cloud azure
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
5. Generalize. This removes the account you built with, so no machine made from the image carries it.
|
|
167
|
+
Run it from `/`, because it deletes your home directory, and the Azure agent stops with an error
|
|
168
|
+
when its working directory is gone:
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
cd / && sudo waagent -force -deprovision+user && export HISTSIZE=0 && sync
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
6. Capture as in the Windows steps, with `--os-type Linux`.
|
|
175
|
+
7. Name the image version's resource id in the environment's `image`.
|
|
176
|
+
|
|
177
|
+
If the image serves an app, end your own boot step with one request to the app. The first request after
|
|
178
|
+
a boot is slow, so this request takes that delay instead of the first user.
|
|
179
|
+
|
|
180
|
+
### The model key and other tokens
|
|
181
|
+
|
|
182
|
+
Give the agent its model key in one of three ways. Each works on every machine, with or without our
|
|
183
|
+
egress edge. The edge and its Secrets are an addition, never needed for your own key.
|
|
184
|
+
|
|
185
|
+
1. **The environment's `env`** (`provisionSpec.env`). The worker reads it when it starts. A declared value
|
|
186
|
+
replaces our image's placeholder, never a real value. The platform stores `env` values in plain text,
|
|
187
|
+
an environment read returns them, and the VM's startup data carries them. If that is not acceptable,
|
|
188
|
+
use route 2 or 3, or a Secret at our egress edge where one stands in front.
|
|
189
|
+
2. **Baked into the image**, at machine scope, before Sysprep or generalizing. On Windows, that is the
|
|
190
|
+
`Environment` value (a multi-string) of `HKLM\SYSTEM\CurrentControlSet\Services\SfdkWorker`. Keep
|
|
191
|
+
the entries that are there, and add or replace only yours. On Linux, it is a drop-in on
|
|
192
|
+
`sfdk-worker.service`.
|
|
193
|
+
3. **The `onStartAgent` hook** writes the harness's own key file in the agent's home:
|
|
194
|
+
`.claude/.credentials.json` for a Claude sign-in, `.codex/auth.json` for `codex`, or
|
|
195
|
+
`.pi/agent/auth.json` for `pi`. The worker keeps a real value it finds there. A raw Claude API key has
|
|
196
|
+
no file, so use route 1 or 2 for it.
|
|
197
|
+
|
|
198
|
+
The names:
|
|
199
|
+
|
|
200
|
+
- `claude` with an Anthropic API key or an Orchestra gateway key: `ANTHROPIC_API_KEY`. With a gateway
|
|
201
|
+
key, keep the agent's model gateway on. The platform sets the gateway address.
|
|
202
|
+
- `claude` with a Claude subscription token: `ORCHESTRA_WORKER_CLAUDE_OAUTH_TOKEN`. A renewing sign-in:
|
|
203
|
+
`ORCHESTRA_WORKER_CLAUDE_ACCESS_TOKEN` and `ORCHESTRA_WORKER_CLAUDE_REFRESH_TOKEN`.
|
|
204
|
+
- `codex`: `ORCHESTRA_WORKER_OPENAI_API_KEY`, or `ORCHESTRA_WORKER_CODEX_PERSONAL_ACCESS_TOKEN`.
|
|
205
|
+
- `pi`: `ORCHESTRA_WORKER_OPENAI_API_KEY` or `ORCHESTRA_WORKER_CLAUDE_OAUTH_TOKEN`.
|
|
206
|
+
`ORCHESTRA_WORKER_PI_PROVIDER` chooses the provider.
|
|
207
|
+
|
|
208
|
+
Never restart `SfdkWorker` or `sfdk-worker.service` to load a key. A restart after the worker registered
|
|
209
|
+
stops the machine's work, and the platform parks the VM. The next message starts it again, 1 to 2
|
|
210
|
+
minutes later.
|
|
211
|
+
|
|
212
|
+
- A gateway key's `monthlyCreditCap` stops the key when it is reached. One short turn can cost about 30
|
|
213
|
+
credits, so a low cap fails the next turn with `budget_exceeded`.
|
|
214
|
+
- If you restart a machine's VM yourself, the platform stops the VM. The next message starts it again.
|
|
215
|
+
|
|
30
216
|
## For coding agents
|
|
31
217
|
|
|
32
218
|
- `orchestra worker --help` lists the worker commands. `orchestra worker <command> --help` gives their flags.
|
package/docs/REFERENCE.md
CHANGED
|
@@ -12,11 +12,11 @@ The worker exposes no API of its own. Every route it calls is the platform's.
|
|
|
12
12
|
|
|
13
13
|
| path | what it holds |
|
|
14
14
|
|---|---|
|
|
15
|
-
| `cmd/worker/` | the one binary: `run`, `install`, `enroll`, `check`, `version` |
|
|
15
|
+
| `cmd/worker/` | the one binary: `run`, `install`, `install-machine`, `boot-files`, `enroll`, `check`, `trust-nested`, `screen`, `version` |
|
|
16
16
|
| `identity/` | the four identity exchanges — claim, refresh, reattach-challenge, reattach — the holder key, and the loop that keeps the machine token alive |
|
|
17
17
|
| `broker/` | the protocol on the message broker: the connection, the register on every connect, the heartbeat and the status cadence, the pull of this machine's own work consumer, and the publisher every other package sends through |
|
|
18
18
|
| `env/` | the machine-side environment the platform composes onto a launch, read from the names the contract declares |
|
|
19
|
-
| `facts/` | what this build knows about the four harness families: the program to install and the digest that authenticates it, the environment each family is handed, the templates it seeds, and every location its content lands in — embedded in the binary, so one release digest covers the facts and the program that reads them |
|
|
19
|
+
| `facts/` | what this build knows about the four harness families: the program to install and the digest that authenticates it, the environment each family is handed, the templates it seeds, and every location its content lands in; and, in `machine.json`, the pins of what `install-machine` puts on a machine beside the worker — Docker, WinDivert and the agent's Node — and where a launch's certificate files land. Both are embedded in the binary, so one release digest covers the facts and the program that reads them |
|
|
20
20
|
| `harness/` | the only place family-specific knowledge lives: the launch plan, the content layout, the store lookup, the mid-turn message each family accepts, and the installer that puts the pinned Node and a family's programs under the worker root |
|
|
21
21
|
| `process/` | the agent's setup and the harness process behind each session placement: the start, the stop and the last save a remove asks for, the startup fence over what a previous run left, and the stop of everything when the worker is told to stop |
|
|
22
22
|
| `stream/` | the queue: every placement message and every prompt, steer and cancel pulled off this machine's work consumer, the ACP client that opens a session's harness conversation and runs its turns, each turn's events batched to the platform and published live, and the answer every placement message is owed |
|
|
@@ -94,10 +94,12 @@ shapes the schema ships, and nothing here re-declares one.
|
|
|
94
94
|
**The machine-wide service is the image role's, and the role is the whole of what asks for it.** An
|
|
95
95
|
`image` gets it — a property list under `/Library/LaunchDaemons`, a unit under `/etc/systemd/system`,
|
|
96
96
|
a Windows service — because the platform builds the image with nobody logged in to it and nobody
|
|
97
|
-
typing the command, and the builder is already root. No flag selects that scope, on any role.
|
|
97
|
+
typing the command, and the builder is already root. No flag selects that scope, on any role. A
|
|
98
|
+
virtual-machine image is made by `worker install-machine` below, which our bakes run; the `image` role
|
|
99
|
+
stays for a container image, whose own command is the worker.
|
|
98
100
|
|
|
99
101
|
`--root` follows the scope the same way: `~/.sfdk/worker` (`%LOCALAPPDATA%\sfdk\worker` on Windows) for
|
|
100
|
-
a `user` install, `/var/lib/sfdk/worker` (`%ProgramData%\
|
|
102
|
+
a `user` install, `/var/lib/sfdk/worker` (`%ProgramData%\sfdk\worker`) for the other two. A `user`
|
|
101
103
|
install writes its log under that root, at `log/worker.log`, because no service manager in that scope
|
|
102
104
|
keeps one a person can read.
|
|
103
105
|
|
|
@@ -137,10 +139,51 @@ shapes the schema ships, and nothing here re-declares one.
|
|
|
137
139
|
family's programs, and `workspaces/<family>`, the directory that family's harness runs in — one
|
|
138
140
|
create at install covers all three, and a worker enrolled on somebody's own machine can take no
|
|
139
141
|
second one.
|
|
142
|
+
- **`worker install-machine --cloud azure|aws [--os windows|linux] [--harness <families>|none]
|
|
143
|
+
[--egress-redirect] [--docker] [--node]`** makes the host it runs on into a machine image, in eleven steps
|
|
144
|
+
the package [README](../README.md) lists with the hosts each one runs on. It runs elevated, takes no
|
|
145
|
+
`--root` and installs under the machine-wide root. Each step reads the current state, changes only what
|
|
146
|
+
differs, reads the result back and prints `ok: <step>` or `changed: <step>`; the first failure stops the
|
|
147
|
+
run. So a second run on a converged host changes nothing, and a run that stopped part way is repaired by
|
|
148
|
+
running it again. It refuses a host that has already booted as a machine — a boot file or `<root>/state`
|
|
149
|
+
is there — because removing one is not a repair, and it refuses a running worker service. On Windows it
|
|
150
|
+
creates `<root>`, the install root `C:\software-factory` and its `etc` folder for SYSTEM and
|
|
151
|
+
Administrators alone, with Users also reading and running the install root, whose `bin` and `node` are
|
|
152
|
+
on the machine path; a folder already there is kept, so a host that made one first keeps its
|
|
153
|
+
permissions.
|
|
154
|
+
|
|
155
|
+
The service runs from a copy of the release package at `<root>/package`, because the self-update
|
|
156
|
+
replaces the directory the running binary sits in; the step compares that copy's `worker version`
|
|
157
|
+
with its own, and it refuses a package unpacked under `<root>/package` or holding it. The cloud step
|
|
158
|
+
owns the start type. `aws` starts the service at every boot, after the
|
|
159
|
+
platform's user data. `azure` cannot order the worker after its boot file on Windows, so there the
|
|
160
|
+
service is demand-start and the scheduled task `orchestra-azure-userdata` runs `<root>\package\worker.exe
|
|
161
|
+
boot-files --cloud azure` as SYSTEM at startup, with a 10-minute limit and three restarts a minute
|
|
162
|
+
apart; on Linux the oneshot unit `orchestra-azure-userdata.service` runs the same command, ordered before
|
|
163
|
+
the worker's unit, which requires it. Azure on Linux also installs WALinuxAgent's and azure-vm-utils'
|
|
164
|
+
udev rules, which name a data disk by its LUN. `aws` removes the Azure task, or the Azure unit and the
|
|
165
|
+
worker unit's link to it, that an earlier `azure` run left. The optional steps fetch what they install from the pins
|
|
166
|
+
in `facts/machine.json` and check each archive's SHA-256 — Node against `nodejs.org`'s published
|
|
167
|
+
`SHASUMS256.txt` — before anything is unpacked. A new Node on Windows replaces only the archive's own
|
|
168
|
+
files, `node.exe` last, so npm's global packages in its folder and their commands stay. The last step runs `worker check` in-process with the
|
|
169
|
+
profile that holds only what this command installs: `launcher` for `azure`, `enrolled` for `aws`. A
|
|
170
|
+
machine a person enrolls is not an image and keeps `worker install --role worker`; `--cloud none` is
|
|
171
|
+
refused and says so.
|
|
172
|
+
- **`worker boot-files --cloud azure`** is the start-up task of an Azure image. It reads the VM's
|
|
173
|
+
`compute/userData` from the instance metadata service at `169.254.169.254` with the `Metadata: true`
|
|
174
|
+
header and no proxy, sixty times two seconds apart. The text is base64 of one JSON object of strings
|
|
175
|
+
with the keys `machine.env`, `transport-trust-roots.pem` and `egress-ca.pem`; an unknown key, a value
|
|
176
|
+
that is not a string or a missing `machine.env` fails the boot. `machine.env` goes where the EC2 lanes
|
|
177
|
+
put the boot file, the two certificates to the guest paths in `facts/machine.json`, and a known file
|
|
178
|
+
this boot does not carry is removed, so a resumed VM never reads its previous launch's file. Each file
|
|
179
|
+
is written under a staged name of its own, created new with its permissions before any byte, and
|
|
180
|
+
renamed into place: on Linux at modes `0600`, `0600` and `0644`, the egress authority being the one the
|
|
181
|
+
agent's programs read, and on Windows readable by SYSTEM and Administrators alone. On Windows it starts `SfdkWorker` last; on Linux systemd starts the worker's unit after this one ends.
|
|
140
182
|
- **`worker enroll`** redeems the enrollment token this machine was given, prints the row it was
|
|
141
183
|
issued, and then serves that machine. It does not stop at the redemption, because the holder key
|
|
142
184
|
the redemption bound lives in this process.
|
|
143
|
-
- **`worker check [--harness <families
|
|
185
|
+
- **`worker check [--harness <families>|none] [--root <dir>] [--profile hosted|launcher|enrolled]
|
|
186
|
+
[--output json]`** reads the runtime image contract from
|
|
144
187
|
inside an image, which is where the rest of that contract cannot be read. An inspection from the
|
|
145
188
|
container runtime sees the command, the account it starts as, the platform it was built for and the
|
|
146
189
|
version label; whether a family's programs are there at the versions this build's facts pin, whether
|
|
@@ -156,6 +199,18 @@ shapes the schema ships, and nothing here re-declares one.
|
|
|
156
199
|
it is used. With no `--harness` it checks the rows that belong to no family and says so — a customer
|
|
157
200
|
image installs the families it needs, so holding one to every family this build can host would
|
|
158
201
|
refuse it for lacking programs nothing on it was ever going to run.
|
|
202
|
+
|
|
203
|
+
`--profile` names the machine the image is for, and each profile holds the image only to what that
|
|
204
|
+
machine runs. `hosted` is our own images: every row above, and on Linux `/home` owned by uid 1000
|
|
205
|
+
where it is not a mount point. `launcher` is a customer's image their Launcher starts, which has no
|
|
206
|
+
egress edge in front of it: no WinDivert and no CLI, and the `/home` row. `enrolled` is a customer's
|
|
207
|
+
image the platform's EC2 lane starts: no WinDivert, no CLI and no `/home` row. With no `--profile` the
|
|
208
|
+
check reads the `hosted` rows without `/home`, which is how the local environment runs it inside a
|
|
209
|
+
container whose `/home` nobody prepared, and reports no profile. `--output json` answers the rows as a
|
|
210
|
+
document with `held`, `missed`, `families` and, when a profile was named, `profile`; on Windows it
|
|
211
|
+
also carries `restartPending`, set while Component Based Servicing's `RebootPending` key, Windows
|
|
212
|
+
Update's `RebootRequired` key or the Session Manager's `PendingFileRenameOperations` value is there.
|
|
213
|
+
A pending restart is reported and never refused: Sysprep refuses to generalize while one is pending.
|
|
159
214
|
- **`worker trust-nested [--registry <host>]... [--root <dir>]`** lets the containers this machine
|
|
160
215
|
runs trust the egress edge, which nothing does by default. It reads the authority from
|
|
161
216
|
`SFDK_EGRESS_CA_FILE`, which the worker sets on every harness process and on the setup script;
|
|
@@ -204,7 +259,7 @@ set is a concern this machine does not have.
|
|
|
204
259
|
| `SFDK_EGRESS_LISTEN_PORT` | where the redirect lands, which is the shim's own listen port |
|
|
205
260
|
| `SFDK_EGRESS_IPV6` | `true` mirrors the redirect through `ip6tables` |
|
|
206
261
|
| `SFDK_EGRESS_PROXY` | `on`, the default, or `off`; `off` tells each harness that no edge of ours stands in front of this machine, as on an enrolled one. The platform writes `off` into every Launcher machine's boot file, because no proxy entrance of ours stands in front of one yet |
|
|
207
|
-
| `SFDK_RUNTIME_ENVIRONMENT` | a whole environment folded into one JSON object of string values, for a boot file whose lines cannot carry a line break; each pair is placed unless already set, except that
|
|
262
|
+
| `SFDK_RUNTIME_ENVIRONMENT` | a whole environment folded into one JSON object of string values, for a boot file whose lines cannot carry a line break; each pair is placed unless already set, except that a non-blank pair replaces a name that holds exactly the image's placeholder |
|
|
208
263
|
| `SFDK_VOLUME_MOUNTS` | the volumes this launch declares, as one JSON document |
|
|
209
264
|
| `SFDK_MACHINE_SLUG` | the machine's platform-minted slug: the leading label of its preview hostnames, and what the tunnel's upgrade signs |
|
|
210
265
|
| `SFDK_TUNNEL_ENDPOINT_URL` | where the preview gateway serves its tunnel listener; its scheme is the whole TLS statement for that hop |
|
|
@@ -214,10 +269,10 @@ set is a concern this machine does not have.
|
|
|
214
269
|
**The worker reads that file itself, on every operating system, and no service manager is handed it.**
|
|
215
270
|
Every `worker run` places each pair into its own environment before it serves, leaving alone any name
|
|
216
271
|
that is already set, so a person's own foreground run still wins over the file. One name already set
|
|
217
|
-
is replaced
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
272
|
+
is replaced, on every machine: a non-blank value the launch declared replaces a name that holds exactly
|
|
273
|
+
a placeholder the family facts list, whether or not an egress edge stands in front. That is how a
|
|
274
|
+
customer's own token in `provisionSpec.env` reaches the harness; it rides the machine's startup data in
|
|
275
|
+
plain text. systemd's
|
|
221
276
|
`EnvironmentFile=` is deliberately not used: it processes backslash escapes in an unquoted value, so
|
|
222
277
|
the two characters `\n` that carry a line break inside `SFDK_RUNTIME_ENVIRONMENT` would arrive as a bare
|
|
223
278
|
`n` and the certificate folded in there would hold no certificate at all. A machine with no file
|
|
@@ -226,7 +281,8 @@ stops the start and is named.
|
|
|
226
281
|
|
|
227
282
|
Where the file sits is the one thing that differs, and only because of who may write it. On a Linux
|
|
228
283
|
machine the platform launched, cloud-init writes `/etc/sfdk/machine.env` from the user data and the run
|
|
229
|
-
reads it;
|
|
284
|
+
reads it; on an Azure machine `worker boot-files` writes the same file from the VM's userData, and
|
|
285
|
+
`<root>\machine.env` on Windows. No install by a person writes there. A `worker` install that registers a service writes
|
|
230
286
|
`<root>/machine.env` under the worker's own root — `C:\ProgramData\sfdk\worker\machine.env` on a default
|
|
231
287
|
machine-wide Windows install — because an install that registers the worker in one person's own session
|
|
232
288
|
cannot write under `/etc`. A Linux run reads both, the machine-wide one first. The platform's user data writes that file on a machine
|
|
@@ -260,7 +316,7 @@ things in place in one order that is not interchangeable:
|
|
|
260
316
|
nothing behind it. On Windows an inbound firewall rule is written first as well: the rewritten
|
|
261
317
|
packet arrives as an inbound connection, which Windows Server blocks by default.
|
|
262
318
|
3. **The redirect** — `iptables` on Ubuntu, WinDivert on Windows. The two WinDivert files are loaded
|
|
263
|
-
by absolute path from `<root>\bin`, where
|
|
319
|
+
by absolute path from `<root>\bin`, where `install-machine --egress-redirect` places them, and never through the
|
|
264
320
|
operating system's own search order: opening the driver installs and starts a kernel service.
|
|
265
321
|
|
|
266
322
|
Each accepted connection's original destination is recovered (`SO_ORIGINAL_DST` on Linux, the
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orchestraworks/worker",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.141",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "The Orchestra worker.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -22,10 +22,10 @@
|
|
|
22
22
|
"docs/REFERENCE.md"
|
|
23
23
|
],
|
|
24
24
|
"optionalDependencies": {
|
|
25
|
-
"@orchestraworks/worker-linux-x64": "0.0.
|
|
26
|
-
"@orchestraworks/worker-linux-arm64": "0.0.
|
|
27
|
-
"@orchestraworks/worker-darwin-x64": "0.0.
|
|
28
|
-
"@orchestraworks/worker-darwin-arm64": "0.0.
|
|
29
|
-
"@orchestraworks/worker-win32-x64": "0.0.
|
|
25
|
+
"@orchestraworks/worker-linux-x64": "0.0.141",
|
|
26
|
+
"@orchestraworks/worker-linux-arm64": "0.0.141",
|
|
27
|
+
"@orchestraworks/worker-darwin-x64": "0.0.141",
|
|
28
|
+
"@orchestraworks/worker-darwin-arm64": "0.0.141",
|
|
29
|
+
"@orchestraworks/worker-win32-x64": "0.0.141"
|
|
30
30
|
}
|
|
31
31
|
}
|