users/services: s6-rc: implement readiness polling

This commit is contained in:
2024-03-21 16:37:57 +00:00
parent 4fa7e6113d
commit fff9d69e3e

View File

@@ -55,7 +55,7 @@ let
# infers the service type from the arguments and creates an attrset usable by `fsToDerivation`. # infers the service type from the arguments and creates an attrset usable by `fsToDerivation`.
# also configures the service for logging, if applicable. # also configures the service for logging, if applicable.
serviceToFs = { name, run, finish, depends, contents }: let serviceToFs = { name, check, contents, depends, finish, run }: let
type = if run != null then "longrun" else "bundle"; type = if run != null then "longrun" else "bundle";
logger = serviceToFs' { logger = serviceToFs' {
name = "logger:${name}"; name = "logger:${name}";
@@ -64,8 +64,7 @@ let
type = "longrun"; type = "longrun";
}; };
in (serviceToFs' { in (serviceToFs' {
inherit name type run finish; inherit name check depends finish run type;
depends = depends;
contents = maybe (type == "bundle") contents; contents = maybe (type == "bundle") contents;
producerFor = maybe (type == "longrun") "logger:${name}"; producerFor = maybe (type == "longrun") "logger:${name}";
}) // (lib.optionalAttrs (type == "longrun") logger); }) // (lib.optionalAttrs (type == "longrun") logger);
@@ -73,19 +72,28 @@ let
serviceToFs'= { serviceToFs'= {
name, name,
type, type,
check ? null, #< command to poll to check for service readiness
consumerFor ? null, consumerFor ? null,
contents ? null, #< bundle contents contents ? null, #< bundle contents
depends ? [], depends ? [],
finish ? null, finish ? null,
producerFor ? null, producerFor ? null,
run ? null, run ? null,
}: { }: let
maybe-notify = lib.optionalString (check != null) "s6-notifyoncheck -n 0 ";
in {
"${name}".dir = { "${name}".dir = {
"type".text = type; "type".text = type;
"contents".text = maybe (contents != null) ( "contents".text = maybe (contents != null) (
lib.concatStringsSep "\n" contents lib.concatStringsSep "\n" contents
); );
"consumer-for".text = maybe (consumerFor != null) consumerFor; "consumer-for".text = maybe (consumerFor != null) consumerFor;
"data".dir = {
"check".executable = maybe (check != null) ''
#!/bin/sh
exec ${check}
'';
};
"dependencies.d".dir = lib.genAttrs "dependencies.d".dir = lib.genAttrs
depends depends
(dep: { text = ""; }) (dep: { text = ""; })
@@ -94,11 +102,12 @@ let
#!/bin/sh #!/bin/sh
exec ${finish} exec ${finish}
''; '';
"notification-fd".text = maybe (check != null) "3";
"producer-for".text = maybe (producerFor != null) producerFor; "producer-for".text = maybe (producerFor != null) producerFor;
"run".executable = maybe (run != null) '' "run".executable = maybe (run != null) ''
#!/bin/sh #!/bin/sh
echo "starting: s6-${name}" echo "starting: s6-${name}"
exec ${run} 2>&1 exec ${maybe-notify}${run} 2>&1
''; '';
}; };
}; };
@@ -147,14 +156,15 @@ let
s6SvcsFromConfigServices = services: lib.mapAttrsToList s6SvcsFromConfigServices = services: lib.mapAttrsToList
(name: service: { (name: service: {
inherit name; inherit name;
run = service.command; check = service.pollReadyCommand;
finish = service.cleanupCommand;
depends = service.depends ++ builtins.attrNames (
lib.filterAttrs (_: cfg: lib.elem name cfg.dependencyOf) services
);
contents = builtins.attrNames ( contents = builtins.attrNames (
lib.filterAttrs (_: cfg: lib.elem name cfg.partOf) services lib.filterAttrs (_: cfg: lib.elem name cfg.partOf) services
); );
depends = service.depends ++ builtins.attrNames (
lib.filterAttrs (_: cfg: lib.elem name cfg.dependencyOf) services
);
finish = service.cleanupCommand;
run = service.command;
}) })
services services
; ;
@@ -165,24 +175,30 @@ let
implicitServices = { implicitServices = {
"default" = { "default" = {
command = null; command = null;
check = null;
cleanupCommand = null; cleanupCommand = null;
depends = []; depends = [];
dependencyOf = []; dependencyOf = [];
partOf = []; partOf = [];
pollReadyCommand = null;
}; };
"graphical-session" = { "graphical-session" = {
command = null; command = null;
check = null;
cleanupCommand = null; cleanupCommand = null;
depends = []; depends = [];
dependencyOf = []; dependencyOf = [];
partOf = []; partOf = [];
pollReadyCommand = null;
}; };
"sound" = { "sound" = {
command = null; command = null;
check = null;
cleanupCommand = null; cleanupCommand = null;
depends = []; depends = [];
dependencyOf = []; dependencyOf = [];
partOf = [ "default" ]; partOf = [ "default" ];
pollReadyCommand = null;
}; };
}; };
in in