users/services: s6-rc: implement readiness polling
This commit is contained in:
@@ -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
|
||||||
|
Reference in New Issue
Block a user