summary refs log tree commit diff
path: root/nixos/modules/services/monitoring/grafana-image-renderer.nix
blob: b8b95d846c6afe6ff13d47a28f20c1e412081cf8 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
{ lib, pkgs, config, ... }:

with lib;

let
  cfg = config.services.grafana-image-renderer;

  format = pkgs.formats.json { };

  configFile = format.generate "grafana-image-renderer-config.json" cfg.settings;
in {
  options.services.grafana-image-renderer = {
    enable = mkEnableOption "grafana-image-renderer";

    chromium = mkOption {
      type = types.package;
      description = ''
        The chromium to use for image rendering.
      '';
    };

    verbose = mkEnableOption "verbosity for the service";

    provisionGrafana = mkEnableOption "Grafana configuration for grafana-image-renderer";

    settings = mkOption {
      type = types.submodule {
        freeformType = format.type;

        options = {
          service = {
            port = mkOption {
              type = types.port;
              default = 8081;
              description = ''
                The TCP port to use for the rendering server.
              '';
            };
            logging.level = mkOption {
              type = types.enum [ "error" "warning" "info" "debug" ];
              default = "info";
              description = ''
                The log-level of the <filename>grafana-image-renderer.service</filename>-unit.
              '';
            };
          };
          rendering = {
            width = mkOption {
              default = 1000;
              type = types.ints.positive;
              description = ''
                Width of the PNG used to display the alerting graph.
              '';
            };
            height = mkOption {
              default = 500;
              type = types.ints.positive;
              description = ''
                Height of the PNG used to display the alerting graph.
              '';
            };
            mode = mkOption {
              default = "default";
              type = types.enum [ "default" "reusable" "clustered" ];
              description = ''
                Rendering mode of <package>grafana-image-renderer</package>:
                <itemizedlist>
                <listitem><para><literal>default:</literal> Creates on browser-instance
                  per rendering request.</para></listitem>
                <listitem><para><literal>reusable:</literal> One browser instance
                  will be started and reused for each rendering request.</para></listitem>
                <listitem><para><literal>clustered:</literal> allows to precisely
                  configure how many browser-instances are supposed to be used. The values
                  for that mode can be declared in <literal>rendering.clustering</literal>.
                  </para></listitem>
                </itemizedlist>
              '';
            };
            args = mkOption {
              type = types.listOf types.str;
              default = [ "--no-sandbox" ];
              description = ''
                List of CLI flags passed to <package>chromium</package>.
              '';
            };
          };
        };
      };

      default = {};

      description = ''
        Configuration attributes for <package>grafana-image-renderer</package>.

        See <link xlink:href="https://github.com/grafana/grafana-image-renderer/blob/ce1f81438e5f69c7fd7c73ce08bab624c4c92e25/default.json" />
        for supported values.
      '';
    };
  };

  config = mkIf cfg.enable {
    assertions = [
      { assertion = cfg.provisionGrafana -> config.services.grafana.enable;
        message = ''
          To provision a Grafana instance to use grafana-image-renderer,
          `services.grafana.enable` must be set to `true`!
        '';
      }
    ];

    services.grafana.extraOptions = mkIf cfg.provisionGrafana {
      RENDERING_SERVER_URL = "http://localhost:${toString cfg.settings.service.port}/render";
      RENDERING_CALLBACK_URL = "http://localhost:${toString config.services.grafana.port}";
    };

    services.grafana-image-renderer.chromium = mkDefault pkgs.chromium;

    services.grafana-image-renderer.settings = {
      rendering = mapAttrs (const mkDefault) {
        chromeBin = "${cfg.chromium}/bin/chromium";
        verboseLogging = cfg.verbose;
        timezone = config.time.timeZone;
      };

      service = {
        logging.level = mkIf cfg.verbose (mkDefault "debug");
        metrics.enabled = mkDefault false;
      };
    };

    systemd.services.grafana-image-renderer = {
      wantedBy = [ "multi-user.target" ];
      after = [ "network.target" ];
      description = " A Grafana backend plugin that handles rendering of panels & dashboards to PNGs using headless browser (Chromium/Chrome)";

      environment = {
        PUPPETEER_SKIP_CHROMIUM_DOWNLOAD = "true";
      };

      serviceConfig = {
        DynamicUser = true;
        PrivateTmp = true;
        ExecStart = "${pkgs.grafana-image-renderer}/bin/grafana-image-renderer server --config=${configFile}";
        Restart = "always";
      };
    };
  };

  meta.maintainers = with maintainers; [ ma27 ];
}