Declarative configuration

The idea

A file describes the machine. A command makes the machine match the file. That is the whole model, and it is the same one NixOS uses — built on top of an ordinary package manager rather than replacing it.

/etc/arctic/system.conf     what the machine is
arctic-rebuild              make it so

You do not alpm ins things onto a configured Arctic system. You add a line and rebuild. The difference matters: the file stays a complete, accurate description of the machine, which is what makes rebuilding it elsewhere — or rolling it back — possible at all.

system.conf

SYS_PACKAGES="
	git
	tmux
	ripgrep
	neovim
"

SYS_SERVICES="
	dbus
	iwd
	sshd
"

SYS_PACKAGES is the complete list, not a list of things to add. Deleting a name removes that package on the next rebuild, along with anything that was only installed as its dependency.

Only explicitly installed packages belong here. Dependencies are alpm's business — listing them yourself is wrong and unnecessary.

SYS_SERVICES is the same for what runs at boot.

arctic-rebuild

arctic-rebuild            make the system match the config
arctic-rebuild --dry-run  show what would change, change nothing

A rebuild diffs the file against reality and closes the gap:

:: recorded generation 4
:: reconciling against /etc/arctic/system.conf
  + install: ripgrep fd
  - remove: tmux
  + enable services: sshd
:: now on generation 5
:: rebuild complete

Removals go through alpm del+deps, so orphaned dependencies go too — while alpm's own protected-package list still refuses to remove the base system no matter what the file says.

The first rebuild does not remove everything

An empty system.conf read literally would mean "this machine should have no packages". Instead, the first rebuild on a machine where the file is empty seeds it from what is actually installed and changes nothing. You get an accurate file to start editing from.

After an install this has already happened — arctic-strap writes system.conf from the install itself.

Every rebuild is undoable

A rebuild records a generation before it changes anything and another after it succeeds. If an edit was wrong:

arctic rollback          go back one generation
arctic rollback 3        go back to a specific one
arctic diff 3 5          see what changed between two

And if the result will not boot, the recent generations are in the boot menu. See generations and rollback.

Services

Services are declared once, in SYS_SERVICES, regardless of which init is running. Arctic's own service definitions live in /etc/rc.d as a handful of variables, and are translated into OpenRC scripts, runit run files, dinit services, s6 directories or systemd units as needed — see init systems.

Directly, without editing the file:

service list
service enable sshd
service disable sshd
service start sshd
service status sshd

service enable and the config are the same thing — enabling a service adds it to what the next rebuild considers correct only if you also list it. If you enable something by hand and then rebuild, the rebuild will turn it back off, because the file did not mention it. That is the point of a declarative system, and it is worth knowing before it surprises you.

What is not declarative yet

Honestly: system.conf covers packages and services. Hostname, locale, timezone, users and the network are set at install time from install.conf and are not currently reconciled by arctic-rebuild. Changing them means editing the system directly. That gap is known and is the next thing to close.

More: arctic linux docs · install · generations and rollback · init systems · kernels · packages (alpm) · desktops and audio · ephemeral shells · musl · building from source