The symlink to /var/lib/nixos/machine-id never persists the ID,
systemd-machine-id-commit.service requires a writable /etc, and
machine_id_commit() does not follow symlinks for its mountpoint check.
So the backing file stays "uninitialized", every boot is
ConditionFirstBoot=yes, and the machine-id is random per boot.
Ship an empty regular file instead, systemd then overlays /run/machine-id
for the session, ConditionFirstBoot is correctly "no", commit is
cleanly condition-skipped, and the file is a usable bind target for
users that want persistence.
Fixes#523878
Regular (non-symlink) /etc entries with an explicit mode are currently
written to the metadata erofs image as stubs that redirect to a
separate basedir layer. Every open() of such a file makes overlayfs open
two real files (the metadata stub and the basedir target).
composefs-dump supports embedding file content directly via the CONTENT
field (raw size limit LCFS_INLINE_CONTENT_MAX = 5000 bytes). Use it for
files up to 4096 bytes so they are served straight from erofs with a
single underlying open. Files above the threshold keep the existing basedir
redirect.
Basedir entries that are provably inlineable are filtered at eval time
(text-backed entries) so changing a small /etc file no longer rebuilds
etc-lowerdir. Other entries are filtered at build time using the
same size check as the dump generator.
On a minimal config the basedir becomes empty and an open+read+close of
/etc/sudoers drops from ~46k to ~12k kernel instructions (-73%).
The metadata image size is unchanged (content fits in erofs block slack).
As the test shows, stc-ng previously did not correctly account for the
removal of template instances defined with overrideStrategy "asDropin".
A real use case does exist: Defining systemd-nspawn container units
which inherit the settings from the vendored systemd-nspawn@.service.
I tried to find the least intrusvie but stable solution here. The
globbing is technically unnecessary but it mimics the behaviour and
implementation in parse_unit.
Fix by walking the newly-mounted metadata layer before the overlay is
(re)mounted and removing trusted.overlay.opaque from any upperdir
directory that now has a counterpart in the lowerdir. This turns those
directories back into merged views: user-placed files and individual
whiteouts are preserved, only the blanket hiding of lowerdir content
is undone.
Applied in both the activation script (switch-to-configuration) and
the initrd rw-etc service (boot), since the upperdir persists across
reboots. Uses the new clear-etc-opaque entrypoint of nixos-init so the
initrd stays bash-free.
Fixes#505475
When a directory is created in /etc that does not yet exist in the
overlay's lowerdir, overlayfs marks it opaque in the upperdir. This is
correct at creation time, but becomes stale when a later generation
adds entries under that directory: the opaque marker hides them.
stage-2-init.sh runs `install -d /etc/nixos` on every boot. When
/nixos is absent from the metadata layer, /.rw-etc/upper/nixos becomes
opaque. Switching to a generation that adds environment.etc."nixos/*"
then silently fails to expose those entries in /etc.
Add a failing regression test that exercises both the
switch-to-configuration path and the initrd/boot path.
Reproduces #505475
This is a follow-up for #460057 to completely remove all mentions of nixos.org/channels/.
The following command was used to generate this change:
```
find . -type f -exec sed -i 's|nixos.org/channels/|channels.nixos.org/|g' {} +
```
After final improvements to the official formatter implementation,
this commit now performs the first treewide reformat of Nix files using it.
This is part of the implementation of RFC 166.
Only "inactive" files are reformatted, meaning only files that
aren't being touched by any PR with activity in the past 2 months.
This is to avoid conflicts for PRs that might soon be merged.
Later we can do a full treewide reformat to get the rest,
which should not cause as many conflicts.
A CI check has already been running for some time to ensure that new and
already-formatted files are formatted, so the files being reformatted here
should also stay formatted.
This commit was automatically created and can be verified using
nix-build a08b3a4d19.tar.gz \
--argstr baseRev b32a094368
result/bin/apply-formatting $NIXPKGS_PATH
Before this change, the hash of the etc metadata image was included in
the mount unit that's responsible for mounting this metadata image in the
initrd.
And because this metadata image changes with every change to the etc
contents, the initrd would be rebuild every time as well.
This can lead to a lot of rebuilds (especially when revision info is
included in /etc/os-release) and all these initrd archives use up a lot of
space on the ESP.
With this change, we instead include a symlink to the metadata image in the
top-level directory, in the same way as we already do for things like init and
prepare-root, and we deduce the store path from the init= kernel parameter,
in the same way as we already do to find the path to init and prepare-root.
Doing so avoids rebuilding the initrd all the time.
On Linux we cannot feasbibly generate users statically because we need
to take care to not change or re-use UIDs over the lifetime of a machine
(i.e. over multiple generations). This means we need the context of the
running machine.
Thus, stop creating users statically and instead generate them at
runtime irrespective of mutableUsers.
When /etc is immutable, the password files (e.g. /etc/passwd etc.) are
created in a separate directory (/var/lib/nixos/etc). /etc will be
pre-populated with symlinks to this separate directory.
Immutable users are now implemented by bind-mounting the password files
read-only onto themselves and only briefly re-mounting them writable to
re-execute sysusers. The biggest limitation of this design is that you
now need to manually unmount this bind mount to change passwords because
sysusers cannot change passwords for you. This shouldn't be too much of
an issue because system users should only rarely need to change their
passwords.
The activation script that remounts the /etc overlay now handles other
mount points on top of /etc by bind mounting them to the new temporary
/etc overlay and then atomically revealing it.