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 "running as root";
15
16 autoRetirement = mkEnableOption ''
17 retiring the host upon OS shutdown
18 '';
19
20 apiKeyFile = mkOption {
21 type = types.path;
22 example = "/run/keys/mackerel-api-key";
23 description = ''
24 Path to file containing the Mackerel API key. The file should contain a
25 single line of the following form:
26
27 `apikey = "EXAMPLE_API_KEY"`
28 '';
29 };
30
31 settings = mkOption {
32 description = ''
33 Options for mackerel-agent.conf.
34
35 Documentation:
36 <https://mackerel.io/docs/entry/spec/agent>
37 '';
38
39 default = {};
40 example = {
41 verbose = false;
42 silent = false;
43 };
44
45 type = types.submodule {
46 freeformType = settingsFmt.type;
47
48 options.host_status = {
49 on_start = mkOption {
50 type = types.enum [ "working" "standby" "maintenance" "poweroff" ];
51 description = "Host status after agent startup.";
52 default = "working";
53 };
54 on_stop = mkOption {
55 type = types.enum [ "working" "standby" "maintenance" "poweroff" ];
56 description = "Host status after agent shutdown.";
57 default = "poweroff";
58 };
59 };
60
61 options.diagnostic =
62 mkEnableOption "collecting memory usage for the agent itself";
63 };
64 };
65 };
66
67 config = mkIf cfg.enable {
68 environment.systemPackages = with pkgs; [ mackerel-agent ];
69
70 environment.etc = {
71 "mackerel-agent/mackerel-agent.conf".source =
72 settingsFmt.generate "mackerel-agent.conf" cfg.settings;
73 "mackerel-agent/conf.d/api-key.conf".source = cfg.apiKeyFile;
74 };
75
76 services.mackerel-agent.settings = {
77 root = mkDefault "/var/lib/mackerel-agent";
78 pidfile = mkDefault "/run/mackerel-agent/mackerel-agent.pid";
79
80 # conf.d stores the symlink to cfg.apiKeyFile
81 include = mkDefault "/etc/mackerel-agent/conf.d/*.conf";
82 };
83
84 # upstream service file in https://github.com/mackerelio/mackerel-agent/blob/master/packaging/rpm/src/mackerel-agent.service
85 systemd.services.mackerel-agent = {
86 description = "mackerel.io agent";
87 wants = [ "network-online.target" ];
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}