1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6 cfg = config.services.mackerel-agent;
7 settingsFmt = pkgs.formats.toml {};
8in {
9 options.services.mackerel-agent = {
10 enable = mkEnableOption "mackerel.io agent";
11
12 # the upstream package runs as root, but doesn't seem to be strictly
13 # necessary for basic functionality
14 runAsRoot = mkEnableOption "Whether to run as root.";
15
16 autoRetirement = mkEnableOption ''
17 Whether to automatically retire the host upon OS shutdown.
18 '';
19
20 apiKeyFile = mkOption {
21 type = types.path;
22 default = "";
23 example = "/run/keys/mackerel-api-key";
24 description = ''
25 Path to file containing the Mackerel API key. The file should contain a
26 single line of the following form:
27
28 <literallayout>apikey = "EXAMPLE_API_KEY"</literallayout>
29 '';
30 };
31
32 settings = mkOption {
33 description = ''
34 Options for mackerel-agent.conf.
35
36 Documentation:
37 <link xlink:href="https://mackerel.io/docs/entry/spec/agent"/>
38 '';
39
40 default = {};
41 example = {
42 verbose = false;
43 silent = false;
44 };
45
46 type = types.submodule {
47 freeformType = settingsFmt.type;
48
49 options.host_status = {
50 on_start = mkOption {
51 type = types.enum [ "working" "standby" "maintenance" "poweroff" ];
52 description = "Host status after agent startup.";
53 default = "working";
54 };
55 on_stop = mkOption {
56 type = types.enum [ "working" "standby" "maintenance" "poweroff" ];
57 description = "Host status after agent shutdown.";
58 default = "poweroff";
59 };
60 };
61
62 options.diagnostic =
63 mkEnableOption "Collect memory usage for the agent itself";
64 };
65 };
66 };
67
68 config = mkIf cfg.enable {
69 environment.systemPackages = with pkgs; [ mackerel-agent ];
70
71 environment.etc = {
72 "mackerel-agent/mackerel-agent.conf".source =
73 settingsFmt.generate "mackerel-agent.conf" cfg.settings;
74 "mackerel-agent/conf.d/api-key.conf".source = cfg.apiKeyFile;
75 };
76
77 services.mackerel-agent.settings = {
78 root = mkDefault "/var/lib/mackerel-agent";
79 pidfile = mkDefault "/run/mackerel-agent/mackerel-agent.pid";
80
81 # conf.d stores the symlink to cfg.apiKeyFile
82 include = mkDefault "/etc/mackerel-agent/conf.d/*.conf";
83 };
84
85 # upstream service file in https://git.io/JUt4Q
86 systemd.services.mackerel-agent = {
87 description = "mackerel.io agent";
88 after = [ "network-online.target" "nss-lookup.target" ];
89 wantedBy = [ "multi-user.target" ];
90 environment = {
91 MACKEREL_PLUGIN_WORKDIR = mkDefault "%C/mackerel-agent";
92 };
93 serviceConfig = {
94 DynamicUser = !cfg.runAsRoot;
95 PrivateTmp = mkDefault true;
96 CacheDirectory = "mackerel-agent";
97 ConfigurationDirectory = "mackerel-agent";
98 RuntimeDirectory = "mackerel-agent";
99 StateDirectory = "mackerel-agent";
100 ExecStart = "${pkgs.mackerel-agent}/bin/mackerel-agent supervise";
101 ExecStopPost = mkIf cfg.autoRetirement "${pkg.mackerel-agent}/bin/mackerel-agent retire -force";
102 ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
103 LimitNOFILE = mkDefault 65536;
104 LimitNPROC = mkDefault 65536;
105 };
106 restartTriggers = [
107 config.environment.etc."mackerel-agent/mackerel-agent.conf".source
108 ];
109 };
110 };
111}