Skip to content

Commit 9d85765

Browse files
author
linux_name2
committed
docs: document --separate-home/--copy-files as experimental home isolation
1 parent 7a65663 commit 9d85765

7 files changed

Lines changed: 184 additions & 10 deletions

File tree

‎README.md‎

Lines changed: 60 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,13 +92,14 @@ sudo atomic-rebuild-uki 20250208-134725 # rebuild UKI for specifi
9292

9393
### Shell completion
9494

95-
Tab completion is available for `atomic-gc` and `atomic-rebuild-uki` in both zsh and bash:
95+
Tab completion is available for `atomic-gc`, `atomic-rebuild-uki`, and `atomic-upgrade` in both zsh and bash:
9696

9797
```bash
9898
atomic-gc <TAB> # → list rm
9999
atomic-gc rm <TAB> # → generation IDs from ESP
100100
atomic-rebuild-uki <TAB> # → generation IDs from ESP
101101
atomic-rebuild-uki -<TAB> # → --help --list -h -l
102+
atomic-upgrade -<TAB> # → --dry-run --tag --no-gc --separate-home ...
102103
```
103104

104105
Completions are installed automatically. For bash, the `bash-completion` package must
@@ -159,6 +160,7 @@ Edit `/etc/atomic.conf`:
159160
| `KERNEL_PARAMS` | *(security defaults)* | Kernel command line parameters |
160161
| `SBCTL_SIGN` | `0` | Sign UKI files with sbctl for Secure Boot (`0`=off, `1`=on) |
161162
| `UPGRADE_GUARD` | `1` | Upgrade guard: block direct `pacman -Syu` (`0`=off, `1`=on) |
163+
| `HOME_COPY_FILES` | *(empty)* | Files to copy into isolated home subvolumes (see [Experimental home isolation](#experimental-home-isolation)) |
162164

163165
Default `KERNEL_PARAMS`: `rw slab_nomerge init_on_alloc=1 page_alloc.shuffle=1 pti=on vsyscall=none randomize_kstack_offset=on debugfs=off`
164166

@@ -240,6 +242,59 @@ sudo atomic-upgrade -- bash -c '/usr/bin/pacman -Syu && sudo -u YOUR_USER yay -S
240242
> upgrade applies to the live system and is **not atomic**. The next
241243
> `atomic-upgrade` will snapshot whatever state the live system is in.
242244
245+
## Experimental home isolation
246+
247+
> **This feature is for throwaway experiments, not permanent environments.**
248+
> Permanent setups should use regular generations with the shared `/home` subvolume.
249+
250+
`--separate-home` creates an isolated `/home` subvolume for the generation — so
251+
experiments with dotfiles, DE configs, or user-level packages don't pollute your
252+
main home. If something goes wrong, delete the generation and the home subvolume
253+
is orphaned; GC will warn you about it.
254+
255+
```bash
256+
# Try KDE without touching your current home
257+
sudo atomic-upgrade --separate-home -t kde -- pacman -S plasma-meta
258+
259+
# Experiment with dev tooling, bring specific dotfiles
260+
sudo atomic-upgrade --separate-home -t dev --copy-files ".bashrc .ssh .gitconfig" -- pacman -S base-devel
261+
262+
# Dry run to preview
263+
sudo atomic-upgrade --dry-run --separate-home -t test
264+
```
265+
266+
**How it works:**
267+
268+
1. A new Btrfs subvolume `home-TAG` is created (or reused if it already exists)
269+
2. User directories are created with correct ownership (users with UID ≥ 1000)
270+
3. Files listed in `--copy-files` (or `HOME_COPY_FILES` from config) are copied from
271+
current `/home/<user>/` into the new home
272+
4. The generation's fstab is updated so `/home` points to the new subvolume
273+
274+
**Constraints:**
275+
276+
- Requires `--tag` (the home subvolume is named `home-TAG`)
277+
- `--copy-files` requires `--separate-home`
278+
- File paths with spaces are not supported
279+
- Absolute paths and `..` traversal are rejected for safety
280+
281+
**Cleanup:** GC never auto-deletes home subvolumes (they contain user data). When
282+
all generations referencing a tag are gone, GC reports the orphan:
283+
284+
```
285+
Orphan home: home-kde (no generations with tag 'kde')
286+
To remove: btrfs subvolume delete /run/atomic/temp_root/home-kde
287+
```
288+
289+
A default set of files to copy can be configured:
290+
291+
```bash
292+
# /etc/atomic.conf
293+
HOME_COPY_FILES=".bashrc .bash_profile .ssh .gnupg .gitconfig"
294+
```
295+
296+
The `--copy-files` flag overrides `HOME_COPY_FILES` per invocation.
297+
243298
## Disk space checks
244299

245300
Before creating a snapshot, `atomic-upgrade` checks available disk space on both the Btrfs filesystem and the ESP:
@@ -255,6 +310,8 @@ If disk space cannot be determined (e.g. `btrfs` and `df` both fail), a warning
255310
- `root-*` subvolumes that have no matching UKI on the ESP
256311
- UKI files on the ESP that have no matching subvolume
257312

313+
Orphan `home-*` subvolumes (where no generation with that tag exists) are **reported but never auto-deleted** — they may contain user data. Use `btrfs subvolume delete` to remove them manually.
314+
258315
If the ESP is not mounted during the orphan sweep phase, it is skipped with a warning — orphans will be cleaned up on the next run.
259316

260317
## Components
@@ -265,11 +322,11 @@ If the ESP is not mounted during the orphan sweep phase, it is skipped with a wa
265322
| `atomic-gc` | Generation management — garbage collection, list, manual delete |
266323
| `atomic-guard` | Pacman hook — blocks direct `-Syu`, allows installs/removes |
267324
| `atomic-rebuild-uki` | Rebuild UKI for existing snapshot |
268-
| `common.sh` | Shared library (config, locking, btrfs, UKI build, GC) |
325+
| `common.sh` | Shared library (config, locking, btrfs, UKI build, GC, home skeleton) |
269326
| `fstab.py` | Safe fstab editing (atomic write + verification + rollback) |
270327
| `rootdev.py` | Auto-detect root device type (LUKS/LVM/plain) and build kernel cmdline |
271328
| `pacman-wrapper` | Optional `/usr/local/bin/pacman` wrapper |
272-
| `completions/` | Zsh and bash tab completions for `atomic-gc` and `atomic-rebuild-uki` |
329+
| `completions/` | Zsh and bash tab completions for `atomic-gc`, `atomic-rebuild-uki`, and `atomic-upgrade` |
273330

274331
## Troubleshooting
275332

‎man/atomic-gc.8‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ Subvolumes that have no matching UKI on the ESP.
2727
.IP \[bu] 2
2828
UKI files that have no matching subvolume.
2929
.PP
30+
Orphan \f[I]home\-*\f[R] subvolumes (created by
31+
\f[B]\-\-separate\-home\f[R]) are \f[B]reported but never
32+
auto\-deleted\f[R] \[em] they may contain user data.
33+
A message with the manual deletion command is printed for each orphan.
34+
.PP
3035
If the ESP is not mounted during the orphan sweep, it is skipped with a
3136
warning.
3237
.SH SUBCOMMANDS

‎man/atomic-gc.8.md‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ sweep removes:
3131
- Subvolumes that have no matching UKI on the ESP.
3232
- UKI files that have no matching subvolume.
3333

34+
Orphan *home-\** subvolumes (created by **\--separate-home**) are **reported
35+
but never auto-deleted** — they may contain user data. A message with the
36+
manual deletion command is printed for each orphan.
37+
3438
If the ESP is not mounted during the orphan sweep, it is skipped with a
3539
warning.
3640

‎man/atomic-upgrade.8‎

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
.\" Automatically generated by Pandoc 3.5
22
.\"
3-
.TH "" "" "" ""
4-
.SS \[ga]\[ga]\[ga]markdown
5-
title: ATOMIC\-UPGRADE section: 8 header: System Administration footer:
6-
atomic\-upgrade \[em]
3+
.TH "ATOMIC\-UPGRADE" "8" "" "atomic\-upgrade" "System Administration"
74
.SH NAME
85
atomic\-upgrade \[em] atomic system upgrades for Arch Linux on Btrfs
96
.SH SYNOPSIS
107
\f[B]atomic\-upgrade\f[R] [\f[B]\-n\f[R]|\f[B]\-\-dry\-run\f[R]]
118
[\f[B]\-t\f[R]|\f[B]\-\-tag\f[R] \f[I]TAG\f[R]] [\f[B]\-\-no\-gc\f[R]]
12-
[\f[B]\-\-\f[R] \f[I]COMMAND\f[R]\&...]
9+
[\f[B]\-\-separate\-home\f[R]] [\f[B]\-\-copy\-files\f[R] \f[I]\[lq]FILE
10+
\&...\[rq]\f[R]] [\f[B]\-\-\f[R] \f[I]COMMAND\f[R]\&...]
1311
.PP
1412
\f[B]atomic\-rebuild\-uki\f[R] [\f[B]\-l\f[R]|\f[B]\-\-list\f[R]]
1513
\f[I]GEN_ID\f[R]
@@ -52,6 +50,21 @@ Example: \f[B]\-t pre\-nvidia\f[R] creates
5250
\f[B]\-\-no\-gc\f[R]
5351
Skip garbage collection after a successful upgrade.
5452
.TP
53+
\f[B]\-\-separate\-home\f[R]
54+
Create an isolated \f[I]/home\f[R] Btrfs subvolume for this generation.
55+
The subvolume is named \f[I]home\-TAG\f[R], so \f[B]\-\-tag\f[R] is
56+
required.
57+
If a subvolume with that name already exists, it is reused.
58+
See \f[B]EXPERIMENTAL HOME ISOLATION\f[R] below.
59+
.TP
60+
\f[B]\-\-copy\-files\f[R] \f[I]\[lq]FILE \&...\[rq]\f[R]
61+
Space\-separated list of files to copy from the current
62+
\f[I]/home//\f[R] into the new home subvolume.
63+
Paths are relative to the user\[cq]s home directory.
64+
Requires \f[B]\-\-separate\-home\f[R].
65+
Overrides \f[B]HOME_COPY_FILES\f[R] from \f[B]atomic.conf\f[R](5).
66+
Paths with spaces are not supported.
67+
.TP
5568
\f[B]\-\-\f[R] \f[I]COMMAND\f[R]\&...
5669
Run \f[I]COMMAND\f[R] in the snapshot chroot instead of the default
5770
\f[B]pacman \-Syu\f[R].
@@ -61,6 +74,26 @@ Show usage summary and exit.
6174
.TP
6275
\f[B]\-V\f[R], \f[B]\-\-version\f[R]
6376
Show version and exit.
77+
.SH EXPERIMENTAL HOME ISOLATION
78+
\f[B]This feature is for throwaway experiments, not permanent
79+
environments.\f[R] Permanent setups should use regular generations with
80+
the shared \f[I]/home\f[R] subvolume.
81+
.PP
82+
When \f[B]\-\-separate\-home\f[R] is used, the generation gets its own
83+
\f[I]/home\f[R] subvolume so that experiments with dotfiles, desktop
84+
environment configs, or user\-level packages do not affect the main
85+
home.
86+
If the experiment fails, delete the generation; garbage collection will
87+
report the orphan home subvolume but will \f[B]never auto\-delete
88+
it\f[R] (it may contain user data).
89+
.PP
90+
The home subvolume is populated with empty user directories (matching
91+
users with UID >= 1000) and, optionally, specific files copied from the
92+
current home via \f[B]\-\-copy\-files\f[R] or the
93+
\f[B]HOME_COPY_FILES\f[R] config option.
94+
.PP
95+
Safety: absolute paths and \f[B]..\f[R] traversal in file lists are
96+
rejected.
6497
.SH UPGRADE GUARD
6598
Two guard layers prevent accidental direct system upgrades, controlled
6699
by the \f[B]UPGRADE_GUARD\f[R] option in \f[B]atomic.conf\f[R](5)
@@ -176,6 +209,18 @@ Upgrade with a custom tag:
176209
sudo atomic\-upgrade \-t pre\-nvidia
177210
.EE
178211
.PP
212+
Experiment with KDE in isolated home (throwaway):
213+
.IP
214+
.EX
215+
sudo atomic\-upgrade \-\-separate\-home \-t kde \-\- pacman \-S plasma\-meta
216+
.EE
217+
.PP
218+
Experiment with dev tools, copying dotfiles:
219+
.IP
220+
.EX
221+
sudo atomic\-upgrade \-\-separate\-home \-t dev \-\-copy\-files \[dq].bashrc .ssh\[dq] \-\- pacman \-S base\-devel
222+
.EE
223+
.PP
179224
Rebuild a missing UKI:
180225
.IP
181226
.EX

‎man/atomic-upgrade.8.md‎

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
```markdown
21
---
32
title: ATOMIC-UPGRADE
43
section: 8
@@ -12,7 +11,7 @@ atomic-upgrade — atomic system upgrades for Arch Linux on Btrfs
1211

1312
# SYNOPSIS
1413

15-
**atomic-upgrade** [**-n**|**\--dry-run**] [**-t**|**\--tag** *TAG*] [**\--no-gc**] [**\--** *COMMAND*...]
14+
**atomic-upgrade** [**-n**|**\--dry-run**] [**-t**|**\--tag** *TAG*] [**\--no-gc**] [**\--separate-home**] [**\--copy-files** *"FILE ..."*] [**\--** *COMMAND*...]
1615

1716
**atomic-rebuild-uki** [**-l**|**\--list**] *GEN_ID*
1817

@@ -50,6 +49,18 @@ Use it to recover an accidentally deleted *.efi* file.
5049
**\--no-gc**
5150
: Skip garbage collection after a successful upgrade.
5251

52+
**\--separate-home**
53+
: Create an isolated */home* Btrfs subvolume for this generation. The
54+
subvolume is named *home-TAG*, so **\--tag** is required. If a subvolume
55+
with that name already exists, it is reused. See **EXPERIMENTAL HOME
56+
ISOLATION** below.
57+
58+
**\--copy-files** *"FILE ..."*
59+
: Space-separated list of files to copy from the current */home/<user>/*
60+
into the new home subvolume. Paths are relative to the user's home
61+
directory. Requires **\--separate-home**. Overrides **HOME_COPY_FILES**
62+
from **atomic.conf**(5). Paths with spaces are not supported.
63+
5364
**\--** *COMMAND*...
5465
: Run *COMMAND* in the snapshot chroot instead of the default
5566
**pacman -Syu**.
@@ -60,6 +71,24 @@ Use it to recover an accidentally deleted *.efi* file.
6071
**-V**, **\--version**
6172
: Show version and exit.
6273

74+
# EXPERIMENTAL HOME ISOLATION
75+
76+
**This feature is for throwaway experiments, not permanent environments.**
77+
Permanent setups should use regular generations with the shared */home*
78+
subvolume.
79+
80+
When **\--separate-home** is used, the generation gets its own */home*
81+
subvolume so that experiments with dotfiles, desktop environment configs,
82+
or user-level packages do not affect the main home. If the experiment fails,
83+
delete the generation; garbage collection will report the orphan home
84+
subvolume but will **never auto-delete it** (it may contain user data).
85+
86+
The home subvolume is populated with empty user directories (matching users
87+
with UID >= 1000) and, optionally, specific files copied from the current
88+
home via **\--copy-files** or the **HOME_COPY_FILES** config option.
89+
90+
Safety: absolute paths and **..** traversal in file lists are rejected.
91+
6392
# UPGRADE GUARD
6493

6594
Two guard layers prevent accidental direct system upgrades, controlled by the
@@ -161,6 +190,14 @@ Upgrade with a custom tag:
161190

162191
sudo atomic-upgrade -t pre-nvidia
163192

193+
Experiment with KDE in isolated home (throwaway):
194+
195+
sudo atomic-upgrade --separate-home -t kde -- pacman -S plasma-meta
196+
197+
Experiment with dev tools, copying dotfiles:
198+
199+
sudo atomic-upgrade --separate-home -t dev --copy-files ".bashrc .ssh" -- pacman -S base-devel
200+
164201
Rebuild a missing UKI:
165202

166203
sudo atomic-rebuild-uki 20250208-134725

‎man/atomic.conf.5‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,15 @@ Enable the upgrade guard (pacman hook and wrapper).
7474
Set to \f[B]1\f[R] to block direct \f[B]pacman \-Syu\f[R], \f[B]0\f[R]
7575
to allow it.
7676
Default: \f[B]1\f[R].
77+
.TP
78+
\f[B]HOME_COPY_FILES\f[R]
79+
Space\-separated list of files to copy from \f[I]/home//\f[R] into
80+
isolated home subvolumes created with \f[B]\-\-separate\-home\f[R].
81+
Paths are relative to the user\[cq]s home directory.
82+
The \f[B]\-\-copy\-files\f[R] flag on the command line overrides this
83+
value per invocation.
84+
Paths with spaces are not supported.
85+
Default: \f[I](empty)\f[R].
7786
.SH SECURITY
7887
The configuration file must be owned by root.
7988
If the file is owned by another user, it is rejected and no values are
@@ -122,6 +131,12 @@ Keep more generations:
122131
.EX
123132
KEEP_GENERATIONS=5
124133
.EE
134+
.PP
135+
Default files for isolated homes:
136+
.IP
137+
.EX
138+
HOME_COPY_FILES=\[dq].bashrc .bash_profile .ssh .gnupg .gitconfig\[dq]
139+
.EE
125140
.SH SEE ALSO
126141
\f[B]atomic\-upgrade\f[R](8), \f[B]atomic\-gc\f[R](8),
127142
\f[B]sbctl\f[R](8), \f[B]pacman.conf\f[R](5)

‎man/atomic.conf.5.md‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,13 @@ rejected entirely.
7070
: Enable the upgrade guard (pacman hook and wrapper). Set to **1** to
7171
block direct **pacman -Syu**, **0** to allow it. Default: **1**.
7272

73+
**HOME_COPY_FILES**
74+
: Space-separated list of files to copy from */home/<user>/* into isolated
75+
home subvolumes created with **\--separate-home**. Paths are relative to
76+
the user's home directory. The **\--copy-files** flag on the command line
77+
overrides this value per invocation. Paths with spaces are not supported.
78+
Default: *(empty)*.
79+
7380
# SECURITY
7481

7582
The configuration file must be owned by root. If the file is owned by
@@ -108,6 +115,10 @@ Keep more generations:
108115

109116
KEEP_GENERATIONS=5
110117

118+
Default files for isolated homes:
119+
120+
HOME_COPY_FILES=".bashrc .bash_profile .ssh .gnupg .gitconfig"
121+
111122
# SEE ALSO
112123

113124
**atomic-upgrade**(8), **atomic-gc**(8), **sbctl**(8), **pacman.conf**(5)

0 commit comments

Comments
 (0)