Skip to content

Commit 99123ba

Browse files
committed
docs: Document finding deployments in install-to-existing-root
Users doing `bootc install to-existing-root` previously had no easy way to find the ostree deployment before rebooting in order to inject configuration files. This addresses that gap. Key changes: - Document using `ostree admin --print-current-dir` to find the newly created deployment path before rebooting - Clarify the two distinct scenarios: injecting new configuration before reboot vs. migrating old data after reboot - Add examples for both file-based configuration and kernel arguments (via `systemd.mount-extra`) - Cross-link documentation between general install docs and the to-existing-root man page - Fix typo in path structure documentation Related: #531 Assisted-by: Claude Code (Sonnet 4.5) Signed-off-by: Colin Walters <[email protected]>
1 parent eee1e67 commit 99123ba

File tree

2 files changed

+210
-9
lines changed

2 files changed

+210
-9
lines changed

docs/src/bootc-install.md

Lines changed: 102 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,11 @@ an `/etc/hostname` into the target root. At the current time, bootc does
166166
not offer a direct API to do this. However, the backend for bootc is
167167
ostree, and it is possible to enumerate the deployments via ostree APIs.
168168

169+
You can use `ostree admin --sysroot=/path/to/target --print-current-dir` to
170+
find the newly created deployment directory. For detailed examples and usage,
171+
see the [Injecting configuration before first boot](#before-reboot-injecting-new-configuration)
172+
section under `to-existing-root` documentation below.
173+
169174
We hope to provide a bootc-supported method to find the deployment in
170175
the future.
171176

@@ -216,22 +221,106 @@ It is assumed in this command that the target rootfs is pased via `-v /:/target`
216221

217222
As noted above, the data in `/boot` will be wiped, but everything else in the existing
218223
operating `/` is **NOT** automatically cleaned up. This can
219-
be useful, because it allows the new image to automatically import data from the previous
220-
host system! For example, container images, database, user home directory data, config
221-
files in `/etc` are all available after the subsequent reboot in `/sysroot` (which
224+
be useful, because it allows the new image to access data from the previous
225+
host system. For example, container images, database, user home directory data, and
226+
config files in `/etc` are all available after the subsequent reboot in `/sysroot` (which
222227
is the "physical root").
223228

224229
However, previous mount points or subvolumes will not be automatically
225230
mounted in the new system, e.g. a btrfs subvolume for /home will not be automatically mounted to
226231
/sysroot/home. These filesystems will persist and can be handled any way you want like manually
227232
mounting them or defining the mount points as part of the bootc image.
228233

229-
A special case of this trick is using the `--root-ssh-authorized-keys` flag to inherit
230-
root's SSH keys (which may have been injected from e.g. cloud instance userdata
231-
via a tool like `cloud-init`). To do this, just add
232-
`--root-ssh-authorized-keys /target/root/.ssh/authorized_keys`
233-
to the above.
234+
#### Managing configuration: before and after reboot
235+
236+
There are two distinct scenarios for managing configuration with `to-existing-root`:
237+
238+
**Before rebooting (injecting new configuration):** You can inject new configuration
239+
files into the newly installed deployment before the first boot. This is useful for
240+
adding custom `/etc/fstab` entries, systemd mount units, or other fresh configuration
241+
that the new system should have from the start.
242+
243+
**After rebooting (migrating old configuration):** You can copy or migrate configuration
244+
and data from the old system (now accessible at `/sysroot`) to the new system. This is
245+
useful for preserving network settings, user accounts, or application data from the
246+
previous installation.
247+
248+
##### Before reboot: Injecting new configuration
249+
250+
After running `bootc install to-existing-root`, you may want to inject
251+
configuration files (such as `/etc/fstab`, systemd units, or other configuration)
252+
into the newly installed system before rebooting. The new deployment is located
253+
in the ostree repository structure at:
254+
255+
`/target/ostree/deploy/<stateroot>/deploy/<checksum>.<serial>/`
256+
257+
Where `<stateroot>` defaults to `default` unless specified via `--stateroot`.
234258

259+
To find and modify the newly installed deployment:
260+
261+
```bash
262+
# Get the deployment path
263+
DEPLOY_PATH=$(ostree admin --sysroot=/target --print-current-dir)
264+
265+
# Add a systemd mount unit
266+
cat > ${DEPLOY_PATH}/etc/systemd/system/data.mount <<EOF
267+
[Unit]
268+
Description=Data partition
269+
270+
[Mount]
271+
What=UUID=...
272+
Where=/data
273+
Type=xfs
274+
275+
[Install]
276+
WantedBy=local-fs.target
277+
EOF
278+
```
279+
280+
###### Injecting kernel arguments for local state
281+
282+
An alternative approach is to key machine-local configuration from kernel arguments
283+
via the `--karg` option to `bootc install to-existing-root`.
284+
285+
For example with filesystem mounts, systemd offers a `systemd.mount-extra` that
286+
can be used instead of `/etc/fstab`:
287+
288+
```bash
289+
bootc install to-existing-root \
290+
--karg="systemd.mount-extra=UUID=<uuid>:/data:xfs:defaults"
291+
```
292+
293+
The `systemd.mount-extra` syntax is: `source:path:type:options`
294+
295+
##### After reboot: Migrating data from the old system
296+
297+
After rebooting into the new bootc system, the previous root filesystem is
298+
mounted at `/sysroot`. You can then migrate configuration and data from the
299+
old system to the new one.
300+
301+
**Important:** Any data from `/etc` that you want to use in the new system must be
302+
manually copied from `/sysroot/etc` to `/etc` after rebooting into the new system.
303+
There is currently no automated mechanism for migrating this configuration data.
304+
This applies to network configurations, user accounts, application settings, and other
305+
system configuration stored in `/etc`.
306+
307+
For example, after rebooting:
308+
309+
```bash
310+
# Copy network configuration from the old system
311+
cp /sysroot/etc/sysconfig/network-scripts/ifcfg-eth0 /etc/sysconfig/network-scripts/
312+
313+
# Copy application configuration
314+
cp -r /sysroot/etc/myapp /etc/
315+
```
316+
317+
A special case is using the `--root-ssh-authorized-keys` flag during installation
318+
to automatically inherit root's SSH keys (which may have been injected from e.g.
319+
cloud instance userdata via a tool like `cloud-init`). To do this, add
320+
`--root-ssh-authorized-keys /target/root/.ssh/authorized_keys` to the install command.
321+
322+
See also the [bootc-install-to-existing-root(8)](man/bootc-install-to-existing-root.8.md)
323+
man page for more details.
235324

236325
### Using `system-reinstall-bootc`
237326

@@ -294,7 +383,11 @@ for legacy `/etc/fstab` references for `/` to use
294383
Per the [filesystem](filesystem.md) section, `/etc` and `/var` are machine-local
295384
state by default. If you want to inject additional content after the installation
296385
process, at the current time this can be done by manually finding the
297-
target "deployment root" which will be underneath `/ostree/deploy/<stateroot/deploy/`.
386+
target "deployment root" which will be underneath `/ostree/deploy/<stateroot>/deploy/`.
387+
388+
You can use `ostree admin --sysroot=/path/to/target --print-current-dir` to find
389+
the deployment directory. For detailed examples, see
390+
[Injecting configuration before first boot](#before-reboot-injecting-new-configuration).
298391

299392
Installation software such as [Anaconda](https://github.com/rhinstaller/anaconda)
300393
do this today to implement generic `%post` scripts and the like.

docs/src/man/bootc-install-to-existing-root.8.md

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,114 @@ host root filesystem\'s `/boot` partition will be wiped, but the
1616
content of the existing root will otherwise be retained, and will need
1717
to be cleaned up if desired when rebooted into the new root.
1818

19+
## Managing configuration: before and after reboot
20+
21+
When using `to-existing-root`, there are two distinct scenarios for managing
22+
configuration files:
23+
24+
1. **Before rebooting**: Injecting new configuration into the newly installed system
25+
2. **After rebooting**: Migrating configuration from the old system to the new system
26+
27+
### Before reboot: Injecting new configuration
28+
29+
If you need to inject new configuration files (such as custom `/etc/fstab` entries,
30+
systemd mount units, or other configuration) into the newly installed system before
31+
rebooting, you can find the deployment directory in the ostree repository structure.
32+
The new deployment is located at:
33+
34+
```
35+
/ostree/deploy/<stateroot>/deploy/<checksum>.<serial>/
36+
```
37+
38+
Where `<stateroot>` defaults to `default` unless you specified a different
39+
value with `--stateroot`.
40+
41+
To find the path to the newly installed deployment:
42+
43+
```bash
44+
# Get the full deployment path directly
45+
DEPLOY_PATH=$(ostree admin --sysroot=/target --print-current-dir)
46+
```
47+
48+
This will return the full path, for example:
49+
`/target/ostree/deploy/default/deploy/807f233831a03d315289a4ba29c1670d8bd326d4569eabee7a84f25327997307.0`
50+
51+
You can then modify files in that deployment. For example, to add systemd mount units:
52+
53+
```bash
54+
# Get deployment path
55+
DEPLOY_PATH=$(ostree admin --sysroot=/target --print-current-dir)
56+
# Add a systemd mount unit
57+
vi ${DEPLOY_PATH}/etc/systemd/system/data.mount
58+
```
59+
60+
#### Injecting kernel arguments for local state
61+
62+
A better approach for machine-local configuration like filesystem mounts is to
63+
inject kernel arguments during installation. Kernel arguments are ideal for
64+
local/machine-specific state in a bootc system.
65+
66+
For filesystem mounts, use `systemd.mount-extra` instead of `/etc/fstab`:
67+
68+
```bash
69+
# Add a mount via kernel argument (preferred over /etc/fstab)
70+
bootc install to-existing-root \
71+
--karg="systemd.mount-extra=UUID=<uuid>:/data:xfs:defaults"
72+
```
73+
74+
The `systemd.mount-extra` syntax is: `source:path:type:options`
75+
76+
You can also inject other local kernel arguments for machine-specific configuration:
77+
78+
```bash
79+
# Add console settings for serial access
80+
bootc install to-existing-root --karg="console=ttyS0,115200"
81+
82+
# Add storage-specific options
83+
bootc install to-existing-root --karg="rootflags=subvol=root"
84+
```
85+
86+
This approach is cleaner than editing configuration files because kernel arguments
87+
are explicitly designed for local/machine-specific state in a bootc system.
88+
89+
**Note:** In the future, this functionality will be provided via a dedicated
90+
bootc API to make finding and modifying the deployment more straightforward.
91+
92+
### After reboot: Migrating data from the old system
93+
94+
After rebooting into the new bootc system, the previous root filesystem data
95+
is accessible at `/sysroot` (the "physical root"). This allows you to migrate
96+
data from the old system to the new one.
97+
98+
**Important:** Any configuration data from `/etc` that you want to use in the
99+
new system must be **manually copied** from `/sysroot/etc` to `/etc` after
100+
rebooting. There is currently no automated mechanism for migrating this data.
101+
102+
For example, to migrate configuration after rebooting:
103+
104+
```bash
105+
# After rebooting into the new system
106+
# Copy network configuration from the old system
107+
cp /sysroot/etc/sysconfig/network-scripts/ifcfg-eth0 /etc/sysconfig/network-scripts/
108+
109+
# Copy application configuration
110+
cp -r /sysroot/etc/myapp /etc/
111+
112+
# Selectively merge configuration files
113+
vi /etc/resolv.conf # Add nameservers from /sysroot/etc/resolv.conf
114+
115+
# For user accounts, use proper tools
116+
vipw # Carefully review and merge users from /sysroot/etc/passwd
117+
```
118+
119+
This applies to network configurations, user accounts, application settings,
120+
and other system configuration stored in `/etc`. Review files in `/sysroot/etc`
121+
and manually copy or merge what you need into `/etc`.
122+
123+
**Note:** For filesystem mounts from `/etc/fstab` in the old system, consider
124+
using kernel arguments (via `systemd.mount-extra`) injected before reboot instead
125+
of migrating the fstab entries. See the "Injecting kernel arguments" section above.
126+
19127
# OPTIONS
20128

21129
<!-- BEGIN GENERATED OPTIONS -->

0 commit comments

Comments
 (0)