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