max / alloy
- Co-Authored-By
- Claude Opus 5 (1M context) <noreply@anthropic.com>
- Claude-Session
- https://claude.ai/code/session_01WFBzMprSmNCfvdj2cGZyka
1 file changed,
+65 insertions,
-0 deletions
| @@ -218,6 +218,71 @@ | |||
| 218 | 218 | an install" to "every rebuild anyone adopts", which is the more common case | |
| 219 | 219 | and the one where the user has no reason to expect it. | |
| 220 | 220 | ||
| 221 | + | ## The transport is not a variable: `containers-storage` behaves identically | |
| 222 | + | ||
| 223 | + | The section above switched over `--transport registry`. The update channel | |
| 224 | + | Alloy actually ships (wiki `alloy-update-channel`) has the machine build its | |
| 225 | + | own image, so the ref lives in that machine's local store and the verb is | |
| 226 | + | `--transport containers-storage`. Measured 2026-09-07 rather than assumed, | |
| 227 | + | because the transport is the one variable that design changes. | |
| 228 | + | ||
| 229 | + | Same versions, same `c1` -> `c2` shape. `c2` was copied into the **guest's** | |
| 230 | + | containers-storage with skopeo first, which is what a local rebuild leaves | |
| 231 | + | behind: | |
| 232 | + | ||
| 233 | + | # skopeo copy --src-tls-verify=false \ | |
| 234 | + | docker://10.0.2.2:5000/alloy-layertest:c2 \ | |
| 235 | + | containers-storage:localhost/alloy-layertest:c2 | |
| 236 | + | ||
| 237 | + | # bootc upgrade | |
| 238 | + | error: Upgrading: Deployment contains local rpm-ostree modifications; | |
| 239 | + | cannot upgrade via bootc. | |
| 240 | + | ||
| 241 | + | # bootc switch --transport containers-storage localhost/alloy-layertest:c2 | |
| 242 | + | layers already present: 69; layers needed: 4 (6.1 kB) | |
| 243 | + | Deploying...done (2 seconds) | |
| 244 | + | Queued for next boot: | |
| 245 | + | ostree-unverified-image:containers-storage:localhost/alloy-layertest:c2 | |
| 246 | + | ||
| 247 | + | Every result matches the registry leg: | |
| 248 | + | ||
| 249 | + | - **`switch` succeeds where `upgrade` refuses**, on the same layered deployment. | |
| 250 | + | - **The staged deployment reads `Diff: 1 removed`** before the reboot, so the | |
| 251 | + | discard is visible without waiting for it. | |
| 252 | + | - **The layer is gone after the reboot**, and the rollback keeps it: | |
| 253 | + | ||
| 254 | + | 0 booted ostree-unverified-image:containers-storage:...:c2 | |
| 255 | + | (no packages, no requested-packages) | |
| 256 | + | 1 ostree-unverified-registry:...:latest | |
| 257 | + | packages: ['alloy-demo'] requested: ['alloy-demo'] | |
| 258 | + | ||
| 259 | + | # alloy-demo | |
| 260 | + | alloy-demo ABSENT | |
| 261 | + | ||
| 262 | + | - **The re-layer resolves out of the new image's carried repo.** With the | |
| 263 | + | network repo still `enabled=0`, `rpm-ostree install -y --idempotent | |
| 264 | + | alloy-demo` on the switched machine adds `alloy-demo-0.0.3`, which is `c2`'s | |
| 265 | + | copy — not the `0.0.2` that had been layered. So the component tracks the | |
| 266 | + | image on this path too, and on a real machine | |
| 267 | + | `alloy-layer-components.service` does that re-add unprompted. | |
| 268 | + | ||
| 269 | + | **Cheaper than the registry leg, and worth knowing.** `layers needed: 4 | |
| 270 | + | (6.1 kB)` against 69 already present: adopting a locally built image moves | |
| 271 | + | almost nothing, because the ostree content store already holds what the two | |
| 272 | + | images share. The rebuild costs build time; the adopt costs seconds. | |
| 273 | + | ||
| 274 | + | ### One harness gotcha found doing it | |
| 275 | + | ||
| 276 | + | **`rpm-ostree install` over a non-tty ssh does not exit.** The transaction | |
| 277 | + | completes — the journal shows `Created new deployment` and the deployment | |
| 278 | + | appears with its `LayeredPackages` — and the CLI client stays connected, so | |
| 279 | + | `sshx 'rpm-ostree install ...'` hangs forever after the work is done. It looks | |
| 280 | + | exactly like a slow depsolve. `rpm-ostree status` from a second session says | |
| 281 | + | `State: busy` with the transaction still named, which is what distinguishes it | |
| 282 | + | from a real stall: read the journal, and if the deployment is there, kill the | |
| 283 | + | client. Anything scripting this wants `ssh -tt` or a `--` wrapper rather than | |
| 284 | + | a longer timeout. | |
| 285 | + | ||
| 221 | 286 | ## How an installed machine gets the components | |
| 222 | 287 | ||
| 223 | 288 | **They travel on the ISO**, not over the network. That is the only shape that survives an offline install, and it keeps the no-phone-home |