| 160 |
160 |
|
earlier note about moving users off `bootc upgrade` is a permanent condition
|
| 161 |
161 |
|
rather than a step in a migration.
|
| 162 |
162 |
|
|
|
163 |
+ |
## `bootc switch` is not `bootc upgrade`, measured 2026-08-15
|
|
164 |
+ |
|
|
165 |
+ |
The paragraph above is about `upgrade`, and reads as though the whole bootc
|
|
166 |
+ |
path were closed to a layered machine. It is not, and the difference matters
|
|
167 |
+ |
because **`bootc switch` is the command Alloy actually prints**: it is the
|
|
168 |
+ |
middle line of `Staleness::REMEDY` in `crates/alloy/src/stale.rs` and the
|
|
169 |
+ |
adoption step in docs/IMAGE.md.
|
|
170 |
+ |
|
|
171 |
+ |
Measured on the same versions, from a `c1` machine holding a layered
|
|
172 |
+ |
`alloy-demo`, switching to `c2`:
|
|
173 |
+ |
|
|
174 |
+ |
# bootc upgrade
|
|
175 |
+ |
error: Upgrading: Deployment contains local rpm-ostree modifications;
|
|
176 |
+ |
cannot upgrade via bootc.
|
|
177 |
+ |
|
|
178 |
+ |
# bootc switch --transport registry 10.0.2.2:5000/alloy-layertest:c2
|
|
179 |
+ |
Queued for next boot: 10.0.2.2:5000/alloy-layertest:c2
|
|
180 |
+ |
|
|
181 |
+ |
**`switch` succeeds where `upgrade` refuses.** So the rebuild-and-adopt loop
|
|
182 |
+ |
the console prints is not broken by the component flip, which is the thing
|
|
183 |
+ |
worth knowing before anyone "fixes" that screen.
|
|
184 |
+ |
|
|
185 |
+ |
**It discards the layer, silently.** After the reboot the request is gone
|
|
186 |
+ |
outright rather than left inactive, and the binary with it:
|
|
187 |
+ |
|
|
188 |
+ |
0 booted ...alloy-layertest:c2
|
|
189 |
+ |
packages: [] requested: []
|
|
190 |
+ |
1 ...alloy-layertest:latest
|
|
191 |
+ |
packages: ['alloy-demo'] requested: ['alloy-demo']
|
|
192 |
+ |
|
|
193 |
+ |
# alloy-demo
|
|
194 |
+ |
alloy-demo ABSENT
|
|
195 |
+ |
|
|
196 |
+ |
The rollback deployment keeps the layered state, so nothing is lost that a
|
|
197 |
+ |
rollback would not restore.
|
|
198 |
+ |
|
|
199 |
+ |
**On a real machine that self-heals, and it is the drain rule for free.**
|
|
200 |
+ |
`etc/systemd/system/alloy-layer-components.service` gates on
|
|
201 |
+ |
`ConditionPathExists=!/usr/bin/alloy`, read off the filesystem rather than off
|
|
202 |
+ |
a stamp, which is exactly the case its comment says it was written for. The
|
|
203 |
+ |
switch makes that condition true again, so the unit re-fires and lays the
|
|
204 |
+ |
components down from the **new** image's carried repo. Confirmed by re-running
|
|
205 |
+ |
the install on the switched machine with the network repo disabled: it
|
|
206 |
+ |
resolves `0.0.3` out of `/usr/share/alloy-demo/rpm`, which is `c2`'s copy and
|
|
207 |
+ |
not the version that was layered before.
|
|
208 |
+ |
|
|
209 |
+ |
That answers, for the rebuild path, the problem recorded above as "the layer
|
|
210 |
+ |
does not follow the image". On the `rpm-ostree upgrade` path a satisfied
|
|
211 |
+ |
request is not re-resolved and `alloy update` has to drop and re-add. On the
|
|
212 |
+ |
`bootc switch` path the drop happens on its own and the unit does the re-add,
|
|
213 |
+ |
so the component tracks the image with nothing owning it.
|
|
214 |
+ |
|
|
215 |
+ |
**The cost is a second reboot, and it is silent.** The user types the three
|
|
216 |
+ |
commands, reboots, and lands on a machine with no console and no terminal
|
|
217 |
+ |
while the unit lays them down and reboots again. That is the same silent
|
|
218 |
+ |
double boot already recorded against the first-install path in GO alloy
|
|
219 |
+ |
`d866e125` subtask 7 — this measurement widens it from "the first boot after
|
|
220 |
+ |
an install" to "every rebuild anyone adopts", which is the more common case
|
|
221 |
+ |
and the one where the user has no reason to expect it.
|
|
222 |
+ |
|
| 163 |
223 |
|
## How an installed machine gets the components, 2026-08-14
|
| 164 |
224 |
|
|
| 165 |
225 |
|
Decided by Max: **they travel on the ISO**, not over the network. That is the
|