From 6d313530993cd791c6870ddfec68872bb301daed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6gler?= Date: Sat, 6 Aug 2022 22:29:56 +0200 Subject: [PATCH 1/2] nixos: Add unit option overrideStrategy --- nixos/lib/systemd-lib.nix | 35 ++++++++++++++++++++---------- nixos/lib/systemd-unit-options.nix | 16 ++++++++++++++ 2 files changed, 40 insertions(+), 11 deletions(-) diff --git a/nixos/lib/systemd-lib.nix b/nixos/lib/systemd-lib.nix index 65356634655d..4c52643446ed 100644 --- a/nixos/lib/systemd-lib.nix +++ b/nixos/lib/systemd-lib.nix @@ -187,11 +187,14 @@ in rec { done done - # Symlink all units defined by systemd.units. If these are also - # provided by systemd or systemd.packages, then add them as + # Symlink units defined by systemd.units where override strategy + # shall be automatically detected. If these are also provided by + # systemd or systemd.packages, then add them as # .d/overrides.conf, which makes them extend the # upstream unit. - for i in ${toString (mapAttrsToList (n: v: v.unit) units)}; do + for i in ${toString (mapAttrsToList + (n: v: v.unit) + (lib.filterAttrs (n: v: (attrByPath [ "overrideStrategy" ] "asDropinIfExists" v) == "asDropinIfExists") units))}; do fn=$(basename $i/*) if [ -e $out/$fn ]; then if [ "$(readlink -f $i/$fn)" = /dev/null ]; then @@ -210,6 +213,16 @@ in rec { fi done + # Symlink units defined by systemd.units which shall be + # treated as drop-in file. + for i in ${toString (mapAttrsToList + (n: v: v.unit) + (lib.filterAttrs (n: v: v ? overrideStrategy && v.overrideStrategy == "asDropin") units))}; do + fn=$(basename $i/*) + mkdir -p $out/$fn.d + ln -s $i/$fn $out/$fn.d/overrides.conf + done + # Create service aliases from aliases option. ${concatStrings (mapAttrsToList (name: unit: concatMapStrings (name2: '' @@ -340,7 +353,7 @@ in rec { ''; targetToUnit = name: def: - { inherit (def) aliases wantedBy requiredBy enable; + { inherit (def) aliases wantedBy requiredBy enable overrideStrategy; text = '' [Unit] @@ -349,7 +362,7 @@ in rec { }; serviceToUnit = name: def: - { inherit (def) aliases wantedBy requiredBy enable; + { inherit (def) aliases wantedBy requiredBy enable overrideStrategy; text = commonUnitText def + '' [Service] @@ -371,7 +384,7 @@ in rec { }; socketToUnit = name: def: - { inherit (def) aliases wantedBy requiredBy enable; + { inherit (def) aliases wantedBy requiredBy enable overrideStrategy; text = commonUnitText def + '' [Socket] @@ -382,7 +395,7 @@ in rec { }; timerToUnit = name: def: - { inherit (def) aliases wantedBy requiredBy enable; + { inherit (def) aliases wantedBy requiredBy enable overrideStrategy; text = commonUnitText def + '' [Timer] @@ -391,7 +404,7 @@ in rec { }; pathToUnit = name: def: - { inherit (def) aliases wantedBy requiredBy enable; + { inherit (def) aliases wantedBy requiredBy enable overrideStrategy; text = commonUnitText def + '' [Path] @@ -400,7 +413,7 @@ in rec { }; mountToUnit = name: def: - { inherit (def) aliases wantedBy requiredBy enable; + { inherit (def) aliases wantedBy requiredBy enable overrideStrategy; text = commonUnitText def + '' [Mount] @@ -409,7 +422,7 @@ in rec { }; automountToUnit = name: def: - { inherit (def) aliases wantedBy requiredBy enable; + { inherit (def) aliases wantedBy requiredBy enable overrideStrategy; text = commonUnitText def + '' [Automount] @@ -418,7 +431,7 @@ in rec { }; sliceToUnit = name: def: - { inherit (def) aliases wantedBy requiredBy enable; + { inherit (def) aliases wantedBy requiredBy enable overrideStrategy; text = commonUnitText def + '' [Slice] diff --git a/nixos/lib/systemd-unit-options.nix b/nixos/lib/systemd-unit-options.nix index 1c56b1b9aa04..79c019217814 100644 --- a/nixos/lib/systemd-unit-options.nix +++ b/nixos/lib/systemd-unit-options.nix @@ -48,6 +48,22 @@ in rec { ''; }; + overrideStrategy = mkOption { + default = "asDropinIfExists"; + type = types.enum [ "asDropinIfExists" "asDropin" ]; + description = lib.mdDoc '' + Defines how unit configuration is provided for systemd: + + `asDropinIfExists` creates a unit file when no unit file is provided by the package + otherwise a drop-in file name `overrides.conf`. + + `asDropin` creates a drop-in file named `overrides.conf`. + Mainly needed to define instances for systemd template units (e.g. `systemd-nspawn@mycontainer.service`). + + See also systemd.unit(1). + ''; + }; + requiredBy = mkOption { default = []; type = types.listOf unitNameType; From 9bb2a979d4cc690e424c1cc292f99ac895b5dd18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6gler?= Date: Sat, 22 Oct 2022 13:07:09 +0200 Subject: [PATCH 2/2] nixos/tests/machinectl: Disable tmpfs for /tmp --- nixos/tests/systemd-machinectl.nix | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/nixos/tests/systemd-machinectl.nix b/nixos/tests/systemd-machinectl.nix index fa5c81599eb0..b8ed0c33e8e4 100644 --- a/nixos/tests/systemd-machinectl.nix +++ b/nixos/tests/systemd-machinectl.nix @@ -44,6 +44,14 @@ import ./make-test-python.nix ({ pkgs, ... }: # not needed, but we want to test the nspawn file generation systemd.nspawn.${containerName} = { }; + + systemd.services."systemd-nspawn@${containerName}" = { + serviceConfig.Environment = [ + # Disable tmpfs for /tmp + "SYSTEMD_NSPAWN_TMPFS_TMP=0" + ]; + overrideStrategy = "asDropin"; + }; }; testScript = '' @@ -95,6 +103,9 @@ import ./make-test-python.nix ({ pkgs, ... }: machine.succeed("machinectl stop ${containerName}"); machine.wait_until_succeeds("test $(systemctl is-active systemd-nspawn@${containerName}) = inactive"); + # Test tmpfs for /tmp + machine.fail("mountpoint /tmp"); + # Show to to delete the container machine.succeed("chattr -i ${containerRoot}/var/empty"); machine.succeed("rm -rf ${containerRoot}");