Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

init grafana service #108

Merged
merged 11 commits into from
Feb 22, 2024
1 change: 1 addition & 0 deletions nix/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ in
./redis-cluster.nix
./redis.nix
./zookeeper.nix
./grafana
];
}
83 changes: 83 additions & 0 deletions nix/grafana/default.nix
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Usually we create folder for a service when there are more than just the service definition file and test file. We can preserve the flat hierarchy here.

Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
{ pkgs, lib, name, config, ... }:
let
inherit (lib) types;
iniFormat = pkgs.formats.ini { };
in
{
options = {
description = ''
Configure grafana.
'';
enable = lib.mkEnableOption name;

package = lib.mkPackageOption pkgs "grafana" { };

port = lib.mkOption {
type = types.int;
description = "Which port to run grafana on.";
default = 3000;
};

dataDir = lib.mkOption {
type = types.str;
description = "Directory where grafana stores its logs and data.";
default = "./data/${name}";
};

extraConf = lib.mkOption {
type = iniFormat.type;
description = "Extra configuration for grafana.";
default = { };
example = ''
{
security.admin_user = "patato";
security.admin_password = "potato";
}
'';
};

outputs.settings = lib.mkOption {
type = types.deferredModule;
internal = true;
readOnly = true;
default = {
processes."${name}" =
let
grafanaConfig =
{
server = {
protocol = "http";
http_port = config.port;
domain = "localhost";
};
} // config.extraConf;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if extraConfg = { server.http_port = 8080; }? Would it not end up removing protocol and domain? Shouldn't we do a deep merge?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i was not sure about this. i'll test this out

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i am using lib.recursiveUpdate now.

i have made this same error here. i'll create a PR to fix this

grafanaConfigIni = iniFormat.generate "defaults.ini" grafanaConfig;
startScript = pkgs.writeShellApplication {
name = "start-grafana";
runtimeInputs = [ config.package ];
text = ''
grafana server --config ${grafanaConfigIni} \
--homepath ${config.package}/share/grafana \
cfg:paths.data="$(readlink -m ${config.dataDir})"
'';
};
in
{
command = startScript;
readiness_probe = {
exec.command = "${pkgs.curl}/bin/curl -f ${grafanaConfig.server.protocol}://${grafanaConfig.server.domain}:${builtins.toString grafanaConfig.server.http_port}/api/health";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, perhaps make the whole ${grafanaConfig.server.protocol}://${grafanaConfig.server.domain}:${builtins.toString grafanaConfig.server.http_port}" a value of an internal option (grafanaUri?), so it can be re-used in other places, including by the user. It also makes the probe CLI here more readable.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@srid sure.

grafana has a config called root_url for this. i'll store the resulting value in this config

initial_delay_seconds = 15;
period_seconds = 10;
timeout_seconds = 2;
success_threshold = 1;
failure_threshold = 5;
};
namespace = name;

# https://github.com/F1bonacc1/process-compose#-auto-restart-if-not-healthy
availability.restart = "on_failure";
};
};
};
};
}
31 changes: 31 additions & 0 deletions nix/grafana/grafana_test.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{ pkgs, config, ... }: {
services.grafana."gf1" =
{
enable = true;
port = 3000;
extraConf = {
security.admin_user = "patato";
security.admin_password = "potato";
};
};

settings.processes.test =
let
cfg = config.services.grafana."gf1";
in
{
# Tests based on: https://github.com/NixOS/nixpkgs/blob/master/nixos/tests/grafana/basic.nix
command = pkgs.writeShellApplication {
runtimeInputs = [ cfg.package pkgs.gnugrep pkgs.curl pkgs.uutils-coreutils-noprefix ];
text =
''
ADMIN=${cfg.extraConf.security.admin_user}
PASSWORD=${cfg.extraConf.security.admin_password}
curl -sSfN -u $ADMIN:$PASSWORD http://127.0.0.1:3000/api/org/users -i
curl -sSfN -u $ADMIN:$PASSWORD http://127.0.0.1:3000/api/org/users | grep admin\@localhost
'';
name = "grafana-test";
};
depends_on."gf1".condition = "process_healthy";
};
}
1 change: 1 addition & 0 deletions test/flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
"${inputs.services-flake}/nix/redis_test.nix"
"${inputs.services-flake}/nix/redis-cluster_test.nix"
"${inputs.services-flake}/nix/zookeeper_test.nix"
"${inputs.services-flake}/nix/grafana/grafana_test.nix"
]);
};
};
Expand Down
Loading