@cryptotaxi247 / infra / commits / 5c3362dd

channel updates: make sequential

Create a sequential ordering with systemd After-relationships between each channel's update job. Then, remove individual timers and create one timer for all the jobs. Fixes #79

Graham Christensen committed Mar 15, 2019 at 22:57 UTC 5c3362dd5757ba1e7c0bf553b1d42de8420a2067
2 files changed +124 -39
lib/service-order.nix new
+61
@@ -0,0 +1,61 @@
1 +# Ordering Services
2 +#
3 +# Given a set of services, make them run one at a time in a specific
4 +# order, on a timer.
5 +{ lib }:
6 +{
7 + # Given a list of systemd service, give each one an After
8 + # attribute, so they start in a specific order. The returned
9 + # list can be converted in to a systemd.services attrset with
10 + # `lib.listToAttrs`.
11 + #
12 + # Example:
13 + #
14 + # mkOrderedChain [
15 + # { name = "foo"; value = { script = "true"; }; }
16 + # { name = "bar"; value = { script = "true"; }; }
17 + # ]
18 + #
19 + # => [
20 + # {
21 + # name = "foo";
22 + # value = {
23 + # script = "true";
24 + # unitConfig = { After = []; };
25 + # };
26 + # }
27 + # {
28 + # name = "bar";
29 + # value = {
30 + # script = "true";
31 + # unitConfig = { After = [ "bar" ]; };
32 + # };
33 + # }
34 + #
35 + mkOrderedChain = jobs: let
36 + unitConfigFrom = job: job.unitConfig or {};
37 + afterFrom = job: (unitConfigFrom job).After or [];
38 + previousFrom = collector:
39 + if collector ? previous
40 + then [collector.previous]
41 + else [];
42 +
43 + ordered = builtins.foldl'
44 + (collector: item: {
45 + services = collector.services
46 + ++ [{
47 + inherit (item) name;
48 + value = item.value // {
49 + unitConfig = (unitConfigFrom item.value) //
50 + {
51 + After = (afterFrom item.value) ++
52 + (previousFrom collector);
53 + };
54 + };
55 + }];
56 + previous = "${item.name}.service";
57 + })
58 + { services = []; }
59 + jobs;
60 + in ordered.services;
61 +}
modules/hydra-mirror.nix
+63 -39
@@ -1,54 +1,78 @@
1 -{ config, lib, pkgs, ... }:
2 -
3 -with lib;
1 +{ lib, pkgs, ... }:
2
3 let
4 + channels = {
5 + # Channel name https://hydra.nixos.org/job/<value>/latest-finished
6 + "nixos-unstable" = "nixos/trunk-combined/tested";
7 + "nixos-unstable-small" = "nixos/unstable-small/tested";
8 + "nixpkgs-unstable" = "nixpkgs/trunk/unstable";
9 +
10 + "nixos-19.03" = "nixos/release-19.03/tested";
11 + "nixos-19.03-small" = "nixos/release-19.03-small/tested";
12 + "nixpkgs-19.03-darwin" = "nixpkgs/nixpkgs-19.03-darwin/darwin-tested";
13 +
14 + "nixos-18.09" = "nixos/release-18.09/tested";
15 + "nixos-18.09-small" = "nixos/release-18.09-small/tested";
16 + "nixpkgs-18.09-darwin" = "nixpkgs/nixpkgs-18.09-darwin/darwin-tested";
17 +
18 + "nixos-18.03" = "nixos/release-18.03/tested";
19 + "nixos-18.03-small" = "nixos/release-18.03-small/tested";
20 + "nixpkgs-18.03-darwin" = "nixpkgs/nixpkgs-18.03-darwin/darwin-tested";
21 + };
22
23 channelScripts = import <nixos-channel-scripts> { inherit pkgs; };
24 + orderLib = import ../lib/service-order.nix { inherit lib; };
25
26 makeUpdateChannel = channelName: mainJob:
10 - { timers."update-${channelName}" =
11 - { wantedBy = [ "timers.target" ];
12 - timerConfig.OnUnitInactiveSec = 600;
13 - timerConfig.OnBootSec = 900;
14 - timerConfig.AccuracySec = 300;
15 - };
16 -
17 - services."update-${channelName}" =
18 - { description = "Update Channel ${channelName}";
19 - after = [ "networking.target" ];
20 - path = [ channelScripts ];
21 - script =
22 - ''
23 - # FIXME: use IAM role.
24 - export AWS_ACCESS_KEY_ID=$(sed 's/aws_access_key_id=\(.*\)/\1/ ; t; d' ~/.aws/credentials)
25 - export AWS_SECRET_ACCESS_KEY=$(sed 's/aws_secret_access_key=\(.*\)/\1/ ; t; d' ~/.aws/credentials)
26 - exec mirror-nixos-branch ${channelName} https://hydra.nixos.org/job/${mainJob}/latest-finished
27 - ''; # */
28 - serviceConfig.User = "hydra-mirror";
29 - environment.TMPDIR = "/scratch/hydra-mirror";
30 - environment.GC_INITIAL_HEAP_SIZE = "4g";
27 + {
28 + name = "update-${channelName}";
29 + value = {
30 + description = "Update Channel ${channelName}";
31 + path = [ channelScripts ];
32 + script =
33 + ''
34 + # FIXME: use IAM role.
35 + export AWS_ACCESS_KEY_ID=$(sed 's/aws_access_key_id=\(.*\)/\1/ ; t; d' ~/.aws/credentials)
36 + export AWS_SECRET_ACCESS_KEY=$(sed 's/aws_secret_access_key=\(.*\)/\1/ ; t; d' ~/.aws/credentials)
37 + exec mirror-nixos-branch ${channelName} https://hydra.nixos.org/job/${mainJob}/latest-finished
38 + '';
39 + serviceConfig.User = "hydra-mirror";
40 + unitConfig.After = [ "networking.target" ];
41 + environment.TMPDIR = "/scratch/hydra-mirror";
42 + environment.GC_INITIAL_HEAP_SIZE = "4g";
43 };
44 };
45
46 + updateJobs = orderLib.mkOrderedChain
47 + (lib.mapAttrsToList makeUpdateChannel channels);
48 +
49 in
50
51 {
52 imports = [ ./hydra-mirror-user.nix ];
53
39 - systemd =
40 - fold recursiveUpdate {} [
41 - (makeUpdateChannel "nixos-19.03" "nixos/release-19.03/tested")
42 - (makeUpdateChannel "nixos-19.03-small" "nixos/release-19.03-small/tested")
43 - (makeUpdateChannel "nixos-18.09" "nixos/release-18.09/tested")
44 - (makeUpdateChannel "nixos-18.09-small" "nixos/release-18.09-small/tested")
45 - (makeUpdateChannel "nixos-18.03" "nixos/release-18.03/tested")
46 - (makeUpdateChannel "nixos-18.03-small" "nixos/release-18.03-small/tested")
47 - (makeUpdateChannel "nixos-unstable" "nixos/trunk-combined/tested")
48 - (makeUpdateChannel "nixos-unstable-small" "nixos/unstable-small/tested")
49 - (makeUpdateChannel "nixpkgs-19.03-darwin" "nixpkgs/nixpkgs-19.03-darwin/darwin-tested")
50 - (makeUpdateChannel "nixpkgs-18.09-darwin" "nixpkgs/nixpkgs-18.09-darwin/darwin-tested")
51 - (makeUpdateChannel "nixpkgs-18.03-darwin" "nixpkgs/nixpkgs-18.03-darwin/darwin-tested")
52 - (makeUpdateChannel "nixpkgs-unstable" "nixpkgs/trunk/unstable")
53 - ];
54 + systemd.services = (lib.listToAttrs updateJobs) // {
55 + "update-all-channels" = {
56 + description = "Start all channel updates.";
57 + unitConfig = {
58 + After = builtins.map
59 + (service: "${service.name}.service")
60 + updateJobs;
61 + Wants = builtins.map
62 + (service: "${service.name}.service")
63 + updateJobs;
64 + };
65 + script = "true";
66 + };
67 + };
68 +
69 + systemd.timers."update-all-channels" = {
70 + description = "Start all channel updates.";
71 + wantedBy = [ "timers.target" ];
72 + timerConfig = {
73 + OnUnitInactiveSec = 600;
74 + OnBootSec = 900;
75 + AccuracySec = 300;
76 + };
77 + };
78 }