308 lines
7.2 KiB
Markdown
308 lines
7.2 KiB
Markdown
# Omarchy migrations
|
|
|
|
Omarchy migrations are one-time repair scripts for existing installs. They are
|
|
used when a package update needs to change state that pacman cannot safely own by
|
|
itself.
|
|
|
|
They are for both humans and agents:
|
|
|
|
- Users should know when migrations run, where state is stored, and how to retry
|
|
or inspect pending work.
|
|
- Agents should know which migration scope to use, how to write safe migration
|
|
scripts, and what should **not** be a migration.
|
|
|
|
## The two migration scopes
|
|
|
|
Omarchy migrations are split by execution context:
|
|
|
|
```text
|
|
migrations/system/*.sh
|
|
migrations/user/*.sh
|
|
```
|
|
|
|
### System migrations
|
|
|
|
System migrations run as root and must be noninteractive.
|
|
|
|
Use system migrations for machine-wide state, for example:
|
|
|
|
- `/etc` drop-ins or legacy config cleanup
|
|
- `/boot` / bootloader cleanup
|
|
- systemd system units or service state
|
|
- hardware quirks
|
|
- package-owned layout transitions
|
|
|
|
State lives in:
|
|
|
|
```text
|
|
/var/lib/omarchy/migrations/system/<migration filename>
|
|
```
|
|
|
|
### User migrations
|
|
|
|
User migrations run as the current graphical/login user and may be interactive.
|
|
|
|
Use user migrations for per-user or session-aware state, for example:
|
|
|
|
- `~/.config` changes
|
|
- `~/.local` state
|
|
- user systemd units
|
|
- browser/editor preferences
|
|
- DBus/session-dependent updates
|
|
- prompts that need to happen in a visible terminal
|
|
|
|
State lives in:
|
|
|
|
```text
|
|
~/.local/state/omarchy/migrations/user/<migration filename>
|
|
```
|
|
|
|
A user migration is pending for a given user only when the script exists under
|
|
`/usr/share/omarchy/migrations/user/` and that user's matching state file is
|
|
missing.
|
|
|
|
There is no global root-owned “user migrations required” queue.
|
|
|
|
## When migrations run
|
|
|
|
### During `omarchy update`
|
|
|
|
`omarchy update` is the normal update path. It runs package updates, then:
|
|
|
|
```bash
|
|
omarchy-migrate
|
|
omarchy-hook post-update
|
|
```
|
|
|
|
`omarchy-migrate`:
|
|
|
|
1. waits for any active pacman transaction to finish
|
|
2. runs pending system migrations
|
|
3. runs pending user migrations for the current user
|
|
|
|
System migrations usually already ran during the pacman transaction via the
|
|
`omarchy` package `post_upgrade()`, but the second check is intentional and
|
|
idempotent.
|
|
|
|
### During direct pacman updates
|
|
|
|
Raw `sudo pacman -Syu` is guarded. Users should normally run:
|
|
|
|
```bash
|
|
omarchy update
|
|
```
|
|
|
|
If a user explicitly bypasses the guard, the `omarchy` package still runs system
|
|
migrations from `post_upgrade()`:
|
|
|
|
```bash
|
|
omarchy-migrate-system
|
|
```
|
|
|
|
User migrations are never run by pacman. Instead, the user session watches the
|
|
packaged user migration directory and runs a notifier. The notifier checks:
|
|
|
|
```bash
|
|
omarchy-migrate --pending user
|
|
```
|
|
|
|
If that user has pending user migrations, it shows a notification that opens a
|
|
terminal for:
|
|
|
|
```bash
|
|
omarchy-migrate
|
|
```
|
|
|
|
The notifier never runs user migrations silently in the background.
|
|
|
|
### Manually
|
|
|
|
Users can safely run:
|
|
|
|
```bash
|
|
omarchy-migrate
|
|
```
|
|
|
|
at any time. Already-completed migrations are skipped.
|
|
|
|
## Inspecting pending migrations
|
|
|
|
Use:
|
|
|
|
```bash
|
|
omarchy-migrate --pending
|
|
omarchy-migrate --pending system
|
|
omarchy-migrate --pending user
|
|
```
|
|
|
|
Exit behavior:
|
|
|
|
- `0` — one or more matching migrations are pending
|
|
- non-zero — no matching migrations are pending
|
|
|
|
Output is scope-prefixed:
|
|
|
|
```text
|
|
system/100-system.sh
|
|
user/200-user.sh
|
|
```
|
|
|
|
The lower-level runners also support `--pending` and print filenames without the
|
|
scope prefix:
|
|
|
|
```bash
|
|
omarchy-migrate-system --pending
|
|
omarchy-migrate-user --pending
|
|
```
|
|
|
|
Prefer `omarchy-migrate --pending ...` in user-facing tools and watchers.
|
|
|
|
## Writing migrations
|
|
|
|
Create a migration with:
|
|
|
|
```bash
|
|
omarchy-dev-add-migration system --no-edit
|
|
omarchy-dev-add-migration user --no-edit
|
|
```
|
|
|
|
Choose the scope based on the state being changed, not on convenience.
|
|
|
|
### File format
|
|
|
|
Migrations are plain shell files:
|
|
|
|
- filename: unix timestamp, generated by `omarchy-dev-add-migration`
|
|
- mode: `0644`
|
|
- no shebang
|
|
- start with an `echo` describing the migration
|
|
- use `$OMARCHY_PATH` for Omarchy-owned files
|
|
|
|
Example system migration:
|
|
|
|
```bash
|
|
echo "Remove legacy Limine config"
|
|
|
|
rm -f /boot/EFI/limine/limine.conf
|
|
```
|
|
|
|
Example user migration:
|
|
|
|
```bash
|
|
echo "Refresh user app launchers"
|
|
|
|
omarchy-refresh-applications
|
|
```
|
|
|
|
### Execution model
|
|
|
|
Migration runners execute scripts with strict shell settings:
|
|
|
|
```bash
|
|
bash -euo pipefail <migration>
|
|
```
|
|
|
|
`$OMARCHY_PATH` is exported into the migration process.
|
|
|
|
A migration is marked complete only after the script exits successfully. If it
|
|
fails, the marker is not written and the migration will be retried later.
|
|
|
|
Because failed migrations can be retried after doing partial work, migrations
|
|
must be idempotent. Prefer operations that are safe to run more than once:
|
|
|
|
```bash
|
|
mkdir -p ~/.config/example
|
|
rm -f ~/.config/example/legacy.conf
|
|
install -Dm644 "$OMARCHY_PATH/default/example.conf" ~/.config/example/example.conf
|
|
systemctl --user enable --now some-unit.service || true
|
|
```
|
|
|
|
Use `|| true` only when a failure is genuinely acceptable.
|
|
|
|
## What belongs in a migration?
|
|
|
|
Good migration uses:
|
|
|
|
- deleting or moving legacy files that block the packaged layout
|
|
- marking or enabling new service state
|
|
- migrating old config paths to new config paths
|
|
- repairing known bad state from an earlier Omarchy release
|
|
- one-time compatibility for existing installs
|
|
|
|
Bad migration uses:
|
|
|
|
- fresh-install setup that belongs in `install/` or `/etc/skel`
|
|
- package installation that belongs in package dependencies or package lists
|
|
- recurring maintenance
|
|
- arbitrary cleanup that should be a user command
|
|
- pre-4 upgrade work that belongs in `omarchy-upgrade-to-4`
|
|
- hidden user/session work from pacman
|
|
|
|
## Fresh installs and new users
|
|
|
|
Fresh users created from the packaged layout should not have to run historical
|
|
user migrations. The package seeds user migration markers into `/etc/skel` so
|
|
new users start with shipped user migrations marked complete.
|
|
|
|
The ISO/finalization path also marks shipped user migrations complete for the
|
|
freshly-created install user when running:
|
|
|
|
```bash
|
|
omarchy-finalize-user --first-install
|
|
```
|
|
|
|
Existing users keep their own migration state and run only migrations whose
|
|
state files are missing.
|
|
|
|
## Troubleshooting
|
|
|
|
### See what is pending
|
|
|
|
```bash
|
|
omarchy-migrate --pending
|
|
```
|
|
|
|
### Retry failed migrations
|
|
|
|
Fix the underlying problem, then run:
|
|
|
|
```bash
|
|
omarchy-migrate
|
|
```
|
|
|
|
A failed migration is not marked complete, so it will retry.
|
|
|
|
### Re-run a completed migration manually
|
|
|
|
Remove its marker, then run the migration command again:
|
|
|
|
```bash
|
|
rm ~/.local/state/omarchy/migrations/user/<migration>.sh
|
|
omarchy-migrate
|
|
```
|
|
|
|
For system migrations:
|
|
|
|
```bash
|
|
sudo rm /var/lib/omarchy/migrations/system/<migration>.sh
|
|
omarchy-migrate
|
|
```
|
|
|
|
Be careful: migrations should be idempotent, but manually removing markers is an
|
|
advanced troubleshooting step.
|
|
|
|
## Agent checklist
|
|
|
|
Before adding a migration:
|
|
|
|
1. Is this a one-time repair for existing installs?
|
|
2. Is it system state or user/session state?
|
|
3. Can it run safely more than once?
|
|
4. Will it fail loudly if the important work fails?
|
|
5. Does it avoid hidden interactive work from pacman?
|
|
6. Does it belong in `omarchy-upgrade-to-4` instead?
|
|
7. Did you add or update tests if behavior changed?
|
|
|
|
If the answer to any of these is unclear, stop and ask before adding the
|
|
migration.
|