https://github.com/NixOS/nixpkgs/pull/480686 made getty unconditional, fixing
several bugs and bad interactions. This imposes no runtime costs due to lazy
systemd-based activation, but it does drag getty and its closure in to images.
For many NixOS installations, this is fine - they want console login and such
anyway - but it's a burden on lights-out containers aiming for minimal image
sizes.
This change adds a new configuration knob to totally disable getty for these
sorts of headless/lights-out/appliance-style set-ups. The option's description
is deliberately made stern to hopefully dissuade anyone from toggling it if
their system isn't in that class. As the option defaults to enabling getty,
there should be no behaviour change for anyone not explicitly opting themselves
in - hopefully with full knowledge of the consequences.
My local testing chopped a whole 15% off one of my images by being able to
remove getty (the big contributor being util-linux and its friends), and that's
just for one random image - others might be even bigger relative gains. I think
that's more than enough to justify this configuration knob.
I had a look for uses of getty in NixOS to see if anywhere wanted to either
have a hard dependency on getty and hence explicitly enable it (so that weird
configurations get picked up at evaluation time rather than runtime) or disable
it. The use sites fall into two categories:
0. Virtualised set-ups that wire up units to getty listening on ttyS0. These
probably don't want a hard dependency: it's reasonable to run these lights-out,
and just disabling getty will DTRT here.
1. `modules/profiles/headless.nix`, which disables some of the getty units.
This _could_ instead disable getty as a whole, but that might break e.g.
`machinectl shell`, and I can imagine set-ups where you want that even without
console login, so I have left it alone. Maybe someone else feels differently
and more strongly, and then that someone else can put together a PR and argue
their case.
util-linux 2.42 switched agetty's default issue-file lookup from a
hardcoded "/etc/issue" to ${sysconfdir}, which is $out/etc in nixpkgs,
so the greeting is no longer found.
Point agetty at the real paths explicitly. The list matches what 2.41
searched. Placed before extraArgs so users can still override it.
This is a non-mass-rebuild stopgap until util-linux is built with
--sysconfdir=/etc on staging.
Fixes#514060
## What this fixes:
Currently ; logging in to nixos containers is broken as they do not get spawned a login shell at all. This was noticed in https://github.com/NixOS/nixpkgs/pull/470248. Also no login shell is spawned when the bashless profile is enabled.
## How it fixes this
It makes it so that `console.enable` really just controls whether virtual console setup is done or not.
all the tty units are just unconditionally included as before instead of masked.
Systemd already takes care of not starting them up when they're not needed through `Condition` clauses and through the `systemd-getty-generator`. There is no reason to manually mask (what is what `enable = false; does) getty units. systemd already does the right thing.
## How we got here:
We have `modules/config/console.nix` . This module is what sets up the **virtual console**. That is; the graphical console that Linux ships with that by default is on `/dev/tty1` (and thus on `/dev/console` on single-user instances).
This module used to disable `systemd-vconsole-setup` when `isContainer` was `true` as nspawn containers do not have a virtual console; instead `/dev/console` is a PTS device that gets mounted into the container.
https://github.com/NixOS/nixpkgs/pull/197867/changes was then merged that made it so that the entire module gets disabled in containers. This is nice because this means we don't install `kbd` package etc in container profile which reduces the footprint.
Somebody commented that they expected this module to also disable TTY services when set to disable due to the wording being `enable virtual console`.
However, getty services and virtual console have nothing to do with eachother. This module is to configure the virtual console fonts; not to configure gettys!
It's perfectly possible to have TTYs without having a virtual console! Namely serial consoles and hypervisors consoles `ttyS0`, `ttyAMA0`, `hvc0` .
A comment was made by rnhmjoj correctly pointing this out
> > Tried out false, does not disable the getty target/services.
>
> It's not mean to: this module solely takes care of configuring the console (keymap, font, colors, ...), not providing one. That's why I say the "enable virtual console" description is misleading.
https://github.com/NixOS/nixpkgs/pull/197867#issuecomment-1294204444
However, instead of thus just merging as is; a change was made to start disabling _some_ getty services. However (probably by accident); `console-getty.service` and `container-getty@.service` were *not* disabled. So nixos-containers kept working.
> Ok, that makes sense.
>
> I think if this goes in it either needs a doc change like you asked for, or to also toggle the getty service so it does what the current docs imply.
https://github.com/NixOS/nixpkgs/pull/197867#issuecomment-1294383386
At this point; disabling the virtual console module would break setups that don't have a virtual console in the first place! This includes: servers, containers, anything without a graphical display. However; because the tty list was incomplete and `console-getty.service` was *not* disabled; containers kept working.
A follow-up PR was then made (even though the original code was not correct) that added the remaining gettys https://github.com/NixOS/nixpkgs/pull/363533 . This meant all the use-cases where there is no virtual console and disable the virtual console are now properly broken.
To date that is the [bashless profile](https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/profiles/bashless.nix) and the [container profile](https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/virtualisation/container-config.nix)
This then got noticed by https://github.com/NixOS/nixpkgs/pull/470248 as it uncovered that login shells are not being spawned anymore inside nspawn containers.
I then started looking into the PRs and backtracked how we got here.
Changes:
- autovt@.service moved from a static meson-installed symlink to an
[Install] Alias= on getty@.service upstream. We do not process
[Install] sections, and logind still hardcodes spawning
autovt@ttyN.service on VT switch, so recreate the alias.
- kmscon: suppress getty@.service instead of autovt@.service.
Add static pull-in of kmsconvt@tty1 via getty.target since logind
does not spawn autovt on tty1 by design.
- modprobe@.service: upstream switched ExecStart from /sbin/modprobe to
a bare 'modprobe' relying on PATH. Update the substitution to match
the new form, since DEFAULT_PATH on NixOS is systemd's own bindir
which has no modprobe.
- Remove stale substituteInPlace patterns for paths removed upstream
(/bin/echo in test-fileio.c, /bin/cat in cat.c, /usr/bin/getent in
nspawn-setuid.c)
- Remove dead CFLAGS overrides for POLKIT_AGENT_BINARY_PATH (replaced
by runtime find_executable) and SYSTEMD_CGROUP_AGENTS_PATH (cgroup-v1
leftover, gone before v259). Use --replace-fail for the remaining
config.h substitution so future removals fail loudly.
- Remove deprecated meson options (sysvinit-path, sysvrcnd-path, libidn)
- Handle new pull-oci.c tar references
- Drop upstreamed patch 0017-meson.build-do-not-create-systemdstatedir.patch
This makes it so that the getty units are only included if
`config.console.enable` is set to `true`. Previously, they would be
included, but disabled in that case, which is unnecessary.
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 https://github.com/infinisil/treewide-nixpkgs-reformat-script/archive/a08b3a4d199c6124ac5b36a889d9099b4383463f.tar.gz \
--argstr baseRev b32a094368
result/bin/apply-formatting $NIXPKGS_PATH
Currently, the `kmscon.conf` file that is generated is missing a
trailing newline. This breaks `kmscon`, since its parser assumes
well-formedness.
I noticed this while trying to specify a font, whose spec ended up on
the last line, but without the trailing newline, `kmscon` would not honor it.
- rename hardware.opengl to hardware.graphics
- remove hardware.opengl.driSupport, which does nothing
- remove hardware.opengl.setLdLibraryPath, which should never be done
- rename hardware.opengl.driSupport32Bit to hardware.graphics.enable32Bit
- lost of small docs / formatting cleanups
these changes were generated with nixq 0.0.2, by running
nixq ">> lib.mdDoc[remove] Argument[keep]" --batchmode nixos/**.nix
nixq ">> mdDoc[remove] Argument[keep]" --batchmode nixos/**.nix
nixq ">> Inherit >> mdDoc[remove]" --batchmode nixos/**.nix
two mentions of the mdDoc function remain in nixos/, both of which
are inside of comments.
Since lib.mdDoc is already defined as just id, this commit is a no-op as
far as Nix (and the built manual) is concerned.
now nix-doc-munge will not introduce whitespace changes when it replaces
manpage references with the MD equivalent.
no change to the manpage, changes to the HTML manual are whitespace only.
the conversion procedure is simple:
- find all things that look like options, ie calls to either `mkOption`
or `lib.mkOption` that take an attrset. remember the attrset as the
option
- for all options, find a `description` attribute who's value is not a
call to `mdDoc` or `lib.mdDoc`
- textually convert the entire value of the attribute to MD with a few
simple regexes (the set from mdize-module.sh)
- if the change produced a change in the manual output, discard
- if the change kept the manual unchanged, add some text to the
description to make sure we've actually found an option. if the
manual changes this time, keep the converted description
this procedure converts 80% of nixos options to markdown. around 2000
options remain to be inspected, but most of those fail the "does not
change the manual output check": currently the MD conversion process
does not faithfully convert docbook tags like <code> and <package>, so
any option using such tags will not be converted at all.
This updates systemd to version v249.4 from version v247.6.
Besides the many new features that can be found in the upstream
repository they also introduced a bunch of cleanup which ended up
requiring a few more patches on our side.
a) 0022-core-Handle-lookup-paths-being-symlinks.patch:
The way symlinked units were handled was changed in such that the last
name of a unit file within one of the unit directories
(/run/systemd/system, /etc/systemd/system, ...) is used as the name
for the unit. Unfortunately that code didn't take into account that
the unit directories themselves could already be symlinks and thus
caused all our units to be recognized slightly different.
There is an upstream PR for this new patch:
https://github.com/systemd/systemd/pull/20479
b) The way the APIVFS is setup has been changed in such a way that we
now always have /run. This required a few changes to the
confinement tests which did assert that they didn't exist. Instead of
adding another patch we can just adopt the upstream behavior. An
empty /run doesn't seem harmful.
As part of this work I refactored the confinement test just a little
bit to allow better debugging of test failures. Previously it would
just fail at some point and it wasn't obvious which of the many
commands failed or what the unexpected string was. This should now be
more obvious.
c) Again related to the confinement tests the way a file was tested for
being accessible was optimized. Previously systemd would in some
situations open a file twice during that check. This was reduced to
one operation but required the procfs to be mounted in a units
namespace.
An upstream bug was filed and fixed. We are now carrying the
essential patch to fix that issue until it is backported to a new
release (likely only version 250). The good part about this story is
that upstream systemd now has a test case that looks very similar to
one of our confinement tests. Hopefully that will lead to less
friction in the long run.
https://github.com/systemd/systemd/issues/20514https://github.com/systemd/systemd/pull/20515
d) Previously we could grep for dlopen( somewhat reliably but now
upstream started using a wrapper around dlopen that is most of the
time used with linebreaks. This makes using grep not ergonomic
anymore.
With this bump we are grepping for anything that looks like a
dynamic library name (in contrast to a dlopen(3) call) and replace
those instead. That seems more robust. Time will tell if this holds.
I tried using coccinelle to patch all those call sites using its
tooling but unfornately it does stumble upon the _cleanup_
annotations that are very common in the systemd code.
e) We now have some machinery for libbpf support in our systemd build.
That being said it doesn't actually work as generating some skeletons
doesn't work just yet. It fails with the below error message and is
disabled by default (in both minimal and the regular build).
> FAILED: src/core/bpf/socket_bind/socket-bind.skel.h
> /build/source/tools/build-bpf-skel.py --clang_exec /nix/store/x1bi2mkapk1m0zq2g02nr018qyjkdn7a-clang-wrapper-12.0.1/bin/clang --llvm_strip_exec /nix/store/zm0kqan9qc77x219yihmmisi9g3sg8ns-llvm-12.0.1/bin/llvm-strip --bpftool_exec /nix/store/l6dg8jlbh8qnqa58mshh3d8r6999dk0p-bpftools-5.13.11/bin/bpftool --arch x86_64 ../src/core/bpf/socket_bind/socket-bind.bpf.c src/core/bpf/socket_bind/socket-bind.skel.h
> libbpf: elf: socket_bind_bpf is not a valid eBPF object file
> Error: failed to open BPF object file: BPF object format invalid
> Traceback (most recent call last):
> File "/build/source/tools/build-bpf-skel.py", line 128, in <module>
> bpf_build(args)
> File "/build/source/tools/build-bpf-skel.py", line 92, in bpf_build
> gen_bpf_skeleton(bpftool_exec=args.bpftool_exec,
> File "/build/source/tools/build-bpf-skel.py", line 63, in gen_bpf_skeleton
> skel = subprocess.check_output(bpftool_args, universal_newlines=True)
> File "/nix/store/81lwy2hfqj4c1943b1x8a0qsivjhdhw9-python3-3.9.6/lib/python3.9/subprocess.py", line 424, in check_output
> return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
> File "/nix/store/81lwy2hfqj4c1943b1x8a0qsivjhdhw9-python3-3.9.6/lib/python3.9/subprocess.py", line 528, in run
> raise CalledProcessError(retcode, process.args,
> subprocess.CalledProcessError: Command '['/nix/store/l6dg8jlbh8qnqa58mshh3d8r6999dk0p-bpftools-5.13.11/bin/bpftool', 'g', 's', '../src/core/bpf/socket_bind/socket-bind.bpf.o']' returned non-zero exit status 255.
> [102/1457] Compiling C object src/journal/libjournal-core.a.p/journald-server.c.oapture output)put)ut)
> ninja: build stopped: subcommand failed.
f) We do now have support for TPM2 based disk encryption in our
systemd build. The actual bits and pieces to make use of that are
missing but there are various ongoing efforts in that direction.
There is also the story about systemd in our initrd to enable this
being used for root volumes. None of this will yet work out of the
box but we can start improving on that front.
g) FIDO2 support was added systemd and consequently we can now use
that. Just with TPM2 there hasn't been any integration work with
NixOS and instead this just adds that capability to work on that.
Co-Authored-By: Jörg Thalheim <joerg@thalheim.io>