Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@grahamc
Created March 16, 2019 00:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save grahamc/4fe4ae6cb74674b81dd32bcca1900ebf to your computer and use it in GitHub Desktop.
Save grahamc/4fe4ae6cb74674b81dd32bcca1900ebf to your computer and use it in GitHub Desktop.
# Ordering Services
#
# Given a set of services, make them run one at a time in a specific
# order, on a timer.
let
lib = import <nixpkgs/lib>;
servicePrefix = "ordering-test-";
mkService = name: {
name = "${servicePrefix}${name}";
value = {
description = "Ordering test named ${name}";
script = ''
sleep 10
'';
serviceConfig = {
Type = "oneshot";
RemainAfterExit = false;
};
unitConfig = {
After = [];
};
};
};
nameList = [ "a" "b" "c" "d" "e" ];
services = builtins.map mkService nameList;
# Given a list of systemd service, give each one an After
# attribute, so they start in a specific order. The returned
# list can be converted in to a systemd.services attrset with
# `lib.listToAttrs`.
#
# Example:
#
# mkOrderedChain [
# { name = "foo"; value = { script = "true"; }; }
# { name = "bar"; value = { script = "true"; }; }
# ]
#
# => [
# {
# name = "foo";
# value = {
# script = "true";
# unitConfig = { After = []; };
# };
# }
# {
# name = "bar";
# value = {
# script = "true";
# unitConfig = { After = [ "bar" ]; };
# };
# }
#
mkOrderedChain = jobs: let
unitConfigFrom = job: job.unitConfig or {};
afterFrom = job: (unitConfigFrom job).After or [];
previousFrom = collector:
if collector ? previous
then [collector.previous]
else [];
ordered = builtins.foldl'
(collector: item: {
services = collector.services
++ [{
inherit (item) name;
value = item.value // {
unitConfig = (unitConfigFrom item.value) //
{
After = (afterFrom item.value) ++
(previousFrom collector);
};
};
}];
previous = item.name;
})
{ services = []; }
jobs;
in ordered.services;
in {
systemd.services = (lib.listToAttrs (mkOrderedChain services)) // {
"${servicePrefix}all" = {
description = "Start all ordered tests";
unitConfig = {
After = builtins.map
(service: "${service.name}.service")
services;
Wants = builtins.map
(service: "${service.name}.service")
services;
};
script = "true";
};
};
systemd.timers."${servicePrefix}all" = {
description = "Start all ordered tests";
wantedBy = [ "timers.target" ];
timerConfig = {
OnUnitInactiveSec = 30;
OnBootSec = 900;
AccuracySec = 10;
Unit = "${servicePrefix}all.service";
};
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment