1{
2 lib,
3 config,
4 pkgs,
5 ...
6}:
7let
8 cfg = config.services.sitespeed-io;
9 format = pkgs.formats.json { };
10in
11{
12 options.services.sitespeed-io = {
13 enable = lib.mkEnableOption "Sitespeed.io";
14
15 user = lib.mkOption {
16 type = lib.types.str;
17 default = "sitespeed-io";
18 description = "User account under which sitespeed-io runs.";
19 };
20
21 package = lib.mkPackageOption pkgs "sitespeed-io" { };
22
23 dataDir = lib.mkOption {
24 default = "/var/lib/sitespeed-io";
25 type = lib.types.str;
26 description = "The base sitespeed-io data directory.";
27 };
28
29 period = lib.mkOption {
30 type = lib.types.str;
31 default = "hourly";
32 description = ''
33 Systemd calendar expression when to run. See {manpage}`systemd.time(7)`.
34 '';
35 };
36
37 runs = lib.mkOption {
38 default = [ ];
39 description = ''
40 A list of run configurations. The service will call sitespeed-io once
41 for every run listed here. This lets you examine different websites
42 with different sitespeed-io settings.
43 '';
44 type = lib.types.listOf (
45 lib.types.submodule {
46 options = {
47 urls = lib.mkOption {
48 type = with lib.types; listOf str;
49 default = [ ];
50 description = ''
51 URLs the service should monitor.
52 '';
53 };
54
55 settings = lib.mkOption {
56 type = lib.types.submodule {
57 freeformType = format.type;
58 options = { };
59 };
60 default = { };
61 description = ''
62 Configuration for sitespeed-io, see
63 <https://www.sitespeed.io/documentation/sitespeed.io/configuration/>
64 for available options. The value here will be directly transformed to
65 JSON and passed as `--config` to the program.
66 '';
67 };
68
69 extraArgs = lib.mkOption {
70 type = with lib.types; listOf str;
71 default = [ ];
72 description = ''
73 Extra command line arguments to pass to the program.
74 '';
75 };
76 };
77 }
78 );
79 };
80 };
81
82 config = lib.mkIf cfg.enable {
83 assertions = [
84 {
85 assertion = cfg.runs != [ ];
86 message = "At least one run must be configured.";
87 }
88 {
89 assertion = lib.all (run: run.urls != [ ]) cfg.runs;
90 message = "All runs must have at least one url configured.";
91 }
92 ];
93
94 systemd.services.sitespeed-io = {
95 description = "Check website status";
96 startAt = cfg.period;
97 serviceConfig = {
98 WorkingDirectory = cfg.dataDir;
99 User = cfg.user;
100 };
101 preStart = "chmod u+w -R ${cfg.dataDir}"; # Make sure things are writable
102 script =
103 (lib.concatMapStrings (run: ''
104 ${lib.getExe cfg.package} \
105 --config ${format.generate "sitespeed.json" run.settings} \
106 ${lib.escapeShellArgs run.extraArgs} \
107 ${builtins.toFile "urls.txt" (lib.concatLines run.urls)} &
108 '') cfg.runs)
109 + ''
110 wait
111 '';
112 };
113
114 users = {
115 extraUsers.${cfg.user} = {
116 isSystemUser = true;
117 group = cfg.user;
118 home = cfg.dataDir;
119 createHome = true;
120 homeMode = "755";
121 };
122 extraGroups.${cfg.user} = { };
123 };
124 };
125}