1{
2 config,
3 options,
4 pkgs,
5 lib,
6 ...
7}:
8let
9 inherit (lib)
10 literalExpression
11 mkOption
12 mkEnableOption
13 mkIf
14 mkMerge
15 types
16 optional
17 ;
18
19 cfg = config.services.uptime;
20 opt = options.services.uptime;
21
22 configDir = pkgs.runCommand "config" { preferLocalBuild = true; } (
23 if cfg.configFile != null then
24 ''
25 mkdir $out
26 ext=`echo ${cfg.configFile} | grep -o \\..*`
27 ln -sv ${cfg.configFile} $out/default$ext
28 ln -sv /var/lib/uptime/runtime.json $out/runtime.json
29 ''
30 else
31 ''
32 mkdir $out
33 cat ${pkgs.nodePackages.node-uptime}/lib/node_modules/node-uptime/config/default.yaml > $out/default.yaml
34 cat >> $out/default.yaml <<EOF
35
36 autoStartMonitor: false
37
38 mongodb:
39 connectionString: 'mongodb://localhost/uptime'
40 EOF
41 ln -sv /var/lib/uptime/runtime.json $out/runtime.json
42 ''
43 );
44in
45{
46 options.services.uptime = {
47 configFile = mkOption {
48 description = ''
49 The uptime configuration file
50
51 If mongodb: server != localhost, please set usesRemoteMongo = true
52
53 If you only want to run the monitor, please set enableWebService = false
54 and enableSeparateMonitoringService = true
55
56 If autoStartMonitor: false (recommended) and you want to run both
57 services, please set enableSeparateMonitoringService = true
58 '';
59
60 type = types.nullOr types.path;
61
62 default = null;
63 };
64
65 usesRemoteMongo = mkOption {
66 description = "Whether the configuration file specifies a remote mongo instance";
67
68 default = false;
69
70 type = types.bool;
71 };
72
73 enableWebService = mkEnableOption "the uptime monitoring program web service";
74
75 enableSeparateMonitoringService = mkEnableOption "the uptime monitoring service" // {
76 default = cfg.enableWebService;
77 defaultText = literalExpression "config.${opt.enableWebService}";
78 };
79
80 nodeEnv = mkOption {
81 description = "The node environment to run in (development, production, etc.)";
82
83 type = types.str;
84
85 default = "production";
86 };
87 };
88
89 config = mkMerge [
90 (mkIf cfg.enableWebService {
91 systemd.services.uptime = {
92 description = "uptime web service";
93 wantedBy = [ "multi-user.target" ];
94 environment = {
95 NODE_CONFIG_DIR = configDir;
96 NODE_ENV = cfg.nodeEnv;
97 NODE_PATH = "${pkgs.nodePackages.node-uptime}/lib/node_modules/node-uptime/node_modules";
98 };
99 preStart = "mkdir -p /var/lib/uptime";
100 serviceConfig.ExecStart = "${pkgs.nodejs}/bin/node ${pkgs.nodePackages.node-uptime}/lib/node_modules/node-uptime/app.js";
101 };
102
103 services.mongodb.enable = mkIf (!cfg.usesRemoteMongo) true;
104 })
105 (mkIf cfg.enableSeparateMonitoringService {
106 systemd.services.uptime-monitor = {
107 description = "uptime monitoring service";
108 wantedBy = [ "multi-user.target" ];
109 requires = optional cfg.enableWebService "uptime.service";
110 after = optional cfg.enableWebService "uptime.service";
111 environment = {
112 NODE_CONFIG_DIR = configDir;
113 NODE_ENV = cfg.nodeEnv;
114 NODE_PATH = "${pkgs.nodePackages.node-uptime}/lib/node_modules/node-uptime/node_modules";
115 };
116 # Ugh, need to wait for web service to be up
117 preStart = if cfg.enableWebService then "sleep 1s" else "mkdir -p /var/lib/uptime";
118 serviceConfig.ExecStart = "${pkgs.nodejs}/bin/node ${pkgs.nodePackages.node-uptime}/lib/node_modules/node-uptime/monitor.js";
119 };
120 })
121 ];
122}