1 # This runs to two scenarios but in one tests:
2 # - A post-sysinit service needs to be restarted AFTER tmpfiles was restarted.
3 # - A service needs to be restarted BEFORE tmpfiles is restarted
8 makeGeneration = generation: {
9 "${generation}".configuration = {
10 systemd.services.pre-sysinit-before-tmpfiles.environment.USER =
11 lib.mkForce "${generation}-tmpfiles-user";
13 systemd.services.pre-sysinit-after-tmpfiles.environment = {
14 NEEDED_PATH = lib.mkForce "/run/${generation}-needed-by-pre-sysinit-after-tmpfiles";
15 PATH_TO_CREATE = lib.mkForce "/run/${generation}-needed-by-post-sysinit";
18 systemd.services.post-sysinit.environment = {
19 NEEDED_PATH = lib.mkForce "/run/${generation}-needed-by-post-sysinit";
20 PATH_TO_CREATE = lib.mkForce "/run/${generation}-created-by-post-sysinit";
23 systemd.tmpfiles.settings.test = lib.mkForce {
24 "/run/${generation}-needed-by-pre-sysinit-after-tmpfiles".f.user =
25 "${generation}-tmpfiles-user";
33 name = "sysinit-reactivation";
35 meta.maintainers = with lib.maintainers; [ nikstur ];
37 nodes.machine = { config, lib, pkgs, ... }: {
38 systemd.services.pre-sysinit-before-tmpfiles = {
39 wantedBy = [ "sysinit.target" ];
40 requiredBy = [ "sysinit-reactivation.target" ];
41 before = [ "systemd-tmpfiles-setup.service" "systemd-tmpfiles-resetup.service" ];
42 unitConfig.DefaultDependencies = false;
43 serviceConfig.Type = "oneshot";
44 serviceConfig.RemainAfterExit = true;
45 environment.USER = "tmpfiles-user";
46 script = "${pkgs.shadow}/bin/useradd $USER";
49 systemd.services.pre-sysinit-after-tmpfiles = {
50 wantedBy = [ "sysinit.target" ];
51 requiredBy = [ "sysinit-reactivation.target" ];
52 after = [ "systemd-tmpfiles-setup.service" "systemd-tmpfiles-resetup.service" ];
53 unitConfig.DefaultDependencies = false;
54 serviceConfig.Type = "oneshot";
55 serviceConfig.RemainAfterExit = true;
57 NEEDED_PATH = "/run/needed-by-pre-sysinit-after-tmpfiles";
58 PATH_TO_CREATE = "/run/needed-by-post-sysinit";
61 if [[ -e $NEEDED_PATH ]]; then
67 systemd.services.post-sysinit = {
68 wantedBy = [ "default.target" ];
69 serviceConfig.Type = "oneshot";
70 serviceConfig.RemainAfterExit = true;
72 NEEDED_PATH = "/run/needed-by-post-sysinit";
73 PATH_TO_CREATE = "/run/created-by-post-sysinit";
76 if [[ -e $NEEDED_PATH ]]; then
82 systemd.tmpfiles.settings.test = {
83 "/run/needed-by-pre-sysinit-after-tmpfiles".f.user =
87 specialisation = lib.mkMerge [
88 (makeGeneration "second")
89 (makeGeneration "third")
93 testScript = { nodes, ... }: ''
94 def switch(generation):
95 toplevel = "${nodes.machine.system.build.toplevel}";
96 machine.succeed(f"{toplevel}/specialisation/{generation}/bin/switch-to-configuration switch")
98 machine.wait_for_unit("default.target")
99 machine.succeed("test -e /run/created-by-post-sysinit")
102 machine.succeed("test -e /run/second-created-by-post-sysinit")
105 machine.succeed("test -e /run/third-created-by-post-sysinit")