users/services: s6-rc: implement readiness polling

This commit is contained in:
Colin 2024-03-21 16:37:57 +00:00
parent 4fa7e6113d
commit fff9d69e3e
1 changed files with 26 additions and 10 deletions

View File

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