Commit cbfa8722 authored by Will Fancher's avatar Will Fancher
Browse files

nixos/terminfo: Fix less in systemd stage 1

Since `less` 691, we get `terminals database is inaccessible` in
initrd. This is a problem because ordinary systemd commands like
systemctl and journalctl often try to use the pager.

Bisected to: https://github.com/gwsw/less/commit/7bf5441da53139e834024cd4157915f4ebc0ee9e

Fedora only adds these few terminfos to their initramfs, see dracut:
https://github.com/dracutdevs/dracut/blob/5d2bda46f4e75e85445ee4d3bd3f68bf966287b9/modules.d/95terminfo/module-setup.sh#L12
parent a08b6de8
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -66,6 +66,17 @@
      source = "${config.system.path}/share/terminfo";
    };

    boot.initrd.systemd.contents = lib.listToAttrs (
      lib.map
        (ti: lib.nameValuePair "/etc/terminfo/${ti}" { source = "${pkgs.ncurses}/share/terminfo/${ti}"; })
        [
          "l/linux"
          "v/vt100"
          "v/vt102"
          "v/vt220"
        ]
    );

    environment.profileRelativeSessionVariables = {
      TERMINFO_DIRS = [ "/share/terminfo" ];
    };
+1 −0
Original line number Diff line number Diff line
@@ -1560,6 +1560,7 @@ in
  };
  systemd-initrd-simple = runTest ./systemd-initrd-simple.nix;
  systemd-initrd-swraid = runTest ./systemd-initrd-swraid.nix;
  systemd-initrd-terminfo = runTest ./systemd-initrd-terminfo.nix;
  systemd-initrd-vconsole = runTest ./systemd-initrd-vconsole.nix;
  systemd-initrd-vlan = runTest ./systemd-initrd-vlan.nix;
  systemd-journal = runTest ./systemd-journal.nix;
+22 −0
Original line number Diff line number Diff line
{ lib, ... }:
{
  name = "systemd-initrd-terminfo";

  meta.maintainers = [ lib.maintainers.elvishjerricco ];

  nodes.machine =
    { config, ... }:
    {
      boot.initrd.systemd = {
        enable = true;
        extraBin.script = "${config.boot.initrd.systemd.package.util-linux}/bin/script";
      };
      testing.initrdBackdoor = true;
    };

  testScript = ''
    machine.wait_for_unit("initrd.target")
    rc, out = machine.execute("echo q | script -q -e -c 'yes | less' /dev/null")
    assert "terminals database is inaccessible" not in out
  '';
}