From e6e4665a180b38ef4225d85b63fb8ed1101a77cc Mon Sep 17 00:00:00 2001 From: Daniel Barlow Date: Sun, 9 Jun 2024 22:37:45 +0100 Subject: [PATCH] flip dependencies for triggered/controlled services Instead of treating the trigger as the "main" service and the triggered service as subsidary, now we treat the triggered service as the service and the trigger as "subsidary". This needs some special handling when we work out which services go in the default bundle, but it works better for declaring dependencies on triggered services because it means the dependency runs after the triggered service comes up, not just when the watcher-for-events starts --- modules/mount/service.nix | 26 +++++++++++++------------ modules/s6/default.nix | 5 ++++- modules/service-trigger/default.nix | 6 +++--- modules/service-trigger/rule.nix | 7 +++---- pkgs/liminix-tools/services/builder.sh | 2 +- pkgs/liminix-tools/services/default.nix | 5 ++++- 6 files changed, 29 insertions(+), 22 deletions(-) diff --git a/modules/mount/service.nix b/modules/mount/service.nix index ab0b91bd..54cd2c2a 100644 --- a/modules/mount/service.nix +++ b/modules/mount/service.nix @@ -7,19 +7,21 @@ let inherit (liminix.services) longrun oneshot; device = "/dev/disk/by-partlabel/${partlabel}"; + name = "mount.${lib.strings.sanitizeDerivationName (lib.escapeURL mountpoint)}"; options_string = if options == [] then "" else "-o ${lib.concatStringsSep "," options}"; - mount_service = oneshot { - name = "mount.${lib.escapeURL mountpoint}"; - timeout-up = 3600; - up = "mount -t ${fstype} ${options_string} ${device} ${mountpoint}"; - down = "umount ${mountpoint}"; - }; -in svc.uevent-rule.build { - service = mount_service; - symlink = device; - terms = { - partname = partlabel; - devtype = "partition"; + controller = svc.uevent-rule.build { + serviceName = name; + symlink = device; + terms = { + partname = partlabel; + devtype = "partition"; + }; }; +in oneshot { + inherit name; + timeout-up = 3600; + up = "mount -t ${fstype} ${options_string} ${device} ${mountpoint}"; + down = "umount ${mountpoint}"; + inherit controller; } diff --git a/modules/s6/default.nix b/modules/s6/default.nix index cd05de76..256ee73c 100644 --- a/modules/s6/default.nix +++ b/modules/s6/default.nix @@ -13,7 +13,10 @@ let let defaultDefaultTarget = bundle { name = "default"; - contents = builtins.attrValues config.services; + contents = + builtins.map + (s: if (s ? controller && s.controller != null) then s.controller else s) + (builtins.attrValues config.services)); }; servicesAttrs = { default = defaultDefaultTarget; diff --git a/modules/service-trigger/default.nix b/modules/service-trigger/default.nix index eb3f7bd5..3bed214b 100644 --- a/modules/service-trigger/default.nix +++ b/modules/service-trigger/default.nix @@ -15,9 +15,9 @@ in { }; config = { system.service.uevent-rule = liminix.callService ./rule.nix { - service = mkOption { - description = "the service to run when the rule matches"; - type = liminix.lib.types.service; + serviceName = mkOption { + description = "name of the service to run when the rule matches"; + type = types.str; }; terms = mkOption { type = types.attrs; diff --git a/modules/service-trigger/rule.nix b/modules/service-trigger/rule.nix index a0d7578e..a851e529 100644 --- a/modules/service-trigger/rule.nix +++ b/modules/service-trigger/rule.nix @@ -4,7 +4,7 @@ , serviceFns , lib }: { - service, terms, symlink + serviceName, terms, symlink }: let inherit (liminix.services) longrun; @@ -18,8 +18,7 @@ let attrs)); termsString = stringify terms; in longrun { - name = "watch-for-${service.name}"; + name = "watch-for-${serviceName}"; isTrigger = true; - buildInputs = [ service ]; - run = "${uevent-watch}/bin/uevent-watch ${if symlink != null then "-n ${symlink}" else ""} -s ${service.name} ${termsString}"; + run = "${uevent-watch}/bin/uevent-watch ${if symlink != null then "-n ${symlink}" else ""} -s ${serviceName} ${termsString}"; } diff --git a/pkgs/liminix-tools/services/builder.sh b/pkgs/liminix-tools/services/builder.sh index e163fe07..5f1ecb68 100644 --- a/pkgs/liminix-tools/services/builder.sh +++ b/pkgs/liminix-tools/services/builder.sh @@ -11,7 +11,7 @@ test -n "$contents" && for d in $contents; do touch $out/${name}/contents.d/$d done -for i in timeout-up timeout-down run notification-fd up down finish consumer-for producer-for pipeline-name restart-on-upgrade; do +for i in controllerName timeout-up timeout-down run notification-fd up down finish consumer-for producer-for pipeline-name restart-on-upgrade; do test -n "$(printenv $i)" && (echo "$(printenv $i)" > $out/${name}/$i) done diff --git a/pkgs/liminix-tools/services/default.nix b/pkgs/liminix-tools/services/default.nix index 9a09963e..2a466030 100644 --- a/pkgs/liminix-tools/services/default.nix +++ b/pkgs/liminix-tools/services/default.nix @@ -39,6 +39,7 @@ let , contents ? [] , buildInputs ? [] , isTrigger ? false + , controller ? null } @ args: stdenvNoCC.mkDerivation { # we use stdenvNoCC to avoid generating derivations with names @@ -46,9 +47,11 @@ let inherit name serviceType up down run finish notification-fd producer-for consumer-for pipeline-name timeout-up timeout-down; restart-on-upgrade = isTrigger; - buildInputs = buildInputs ++ dependencies ++ contents; + buildInputs = buildInputs ++ dependencies ++ contents ++ lib.optional (controller != null) controller; dependencies = map (d: d.name) dependencies; contents = map (d: d.name) contents; + inherit controller; + controllerName = if controller ? name then controller.name else null; builder = ./builder.sh; };