nixos/influxdb2: add initial setup automation and nixos tests
This commit is contained in:
parent
fd91dcf310
commit
b4d718f14a
4 changed files with 157 additions and 7 deletions
|
@ -1,8 +1,17 @@
|
||||||
{ config, lib, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
with lib;
|
|
||||||
|
|
||||||
let
|
let
|
||||||
|
inherit
|
||||||
|
(lib)
|
||||||
|
escapeShellArg
|
||||||
|
hasAttr
|
||||||
|
literalExpression
|
||||||
|
mkEnableOption
|
||||||
|
mkIf
|
||||||
|
mkOption
|
||||||
|
types
|
||||||
|
;
|
||||||
|
|
||||||
format = pkgs.formats.json { };
|
format = pkgs.formats.json { };
|
||||||
cfg = config.services.influxdb2;
|
cfg = config.services.influxdb2;
|
||||||
configFile = format.generate "config.json" cfg.settings;
|
configFile = format.generate "config.json" cfg.settings;
|
||||||
|
@ -24,14 +33,60 @@ in
|
||||||
description = lib.mdDoc ''configuration options for influxdb2, see <https://docs.influxdata.com/influxdb/v2.0/reference/config-options> for details.'';
|
description = lib.mdDoc ''configuration options for influxdb2, see <https://docs.influxdata.com/influxdb/v2.0/reference/config-options> for details.'';
|
||||||
type = format.type;
|
type = format.type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
provision = {
|
||||||
|
enable = mkEnableOption "initial database setup and provisioning";
|
||||||
|
|
||||||
|
initialSetup = {
|
||||||
|
organization = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
example = "main";
|
||||||
|
description = "Primary organization name";
|
||||||
|
};
|
||||||
|
|
||||||
|
bucket = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
example = "example";
|
||||||
|
description = "Primary bucket name";
|
||||||
|
};
|
||||||
|
|
||||||
|
username = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "admin";
|
||||||
|
description = "Primary username";
|
||||||
|
};
|
||||||
|
|
||||||
|
retention = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "0";
|
||||||
|
description = ''
|
||||||
|
The duration for which the bucket will retain data (0 is infinite).
|
||||||
|
Accepted units are `ns` (nanoseconds), `us` or `µs` (microseconds), `ms` (milliseconds),
|
||||||
|
`s` (seconds), `m` (minutes), `h` (hours), `d` (days) and `w` (weeks).
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
passwordFile = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
description = "Password for primary user. Don't use a file from the nix store!";
|
||||||
|
};
|
||||||
|
|
||||||
|
tokenFile = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
description = "API Token to set for the admin user. Don't use a file from the nix store!";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
assertions = [{
|
assertions = [
|
||||||
assertion = !(builtins.hasAttr "bolt-path" cfg.settings) && !(builtins.hasAttr "engine-path" cfg.settings);
|
{
|
||||||
message = "services.influxdb2.config: bolt-path and engine-path should not be set as they are managed by systemd";
|
assertion = !(hasAttr "bolt-path" cfg.settings) && !(hasAttr "engine-path" cfg.settings);
|
||||||
}];
|
message = "services.influxdb2.config: bolt-path and engine-path should not be set as they are managed by systemd";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
systemd.services.influxdb2 = {
|
systemd.services.influxdb2 = {
|
||||||
description = "InfluxDB is an open-source, distributed, time series database";
|
description = "InfluxDB is an open-source, distributed, time series database";
|
||||||
|
@ -52,7 +107,62 @@ in
|
||||||
LimitNOFILE = 65536;
|
LimitNOFILE = 65536;
|
||||||
KillMode = "control-group";
|
KillMode = "control-group";
|
||||||
Restart = "on-failure";
|
Restart = "on-failure";
|
||||||
|
LoadCredential = [
|
||||||
|
"admin-password:${cfg.provision.initialSetup.passwordFile}"
|
||||||
|
"admin-token:${cfg.provision.initialSetup.tokenFile}"
|
||||||
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
path = [pkgs.influxdb2-cli];
|
||||||
|
|
||||||
|
# Mark if this is the first startup so postStart can do the initial setup
|
||||||
|
preStart = mkIf cfg.provision.enable ''
|
||||||
|
if ! test -e "$STATE_DIRECTORY/influxd.bolt"; then
|
||||||
|
touch "$STATE_DIRECTORY/.first_startup"
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
|
||||||
|
postStart = let
|
||||||
|
initCfg = cfg.provision.initialSetup;
|
||||||
|
in mkIf cfg.provision.enable (
|
||||||
|
''
|
||||||
|
set -euo pipefail
|
||||||
|
export INFLUX_HOST="http://"${escapeShellArg (cfg.settings.http-bind-address or "localhost:8086")}
|
||||||
|
|
||||||
|
# Wait for the influxdb server to come online
|
||||||
|
count=0
|
||||||
|
while ! influx ping &>/dev/null; do
|
||||||
|
if [ "$count" -eq 300 ]; then
|
||||||
|
echo "Tried for 30 seconds, giving up..."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! kill -0 "$MAINPID"; then
|
||||||
|
echo "Main server died, giving up..."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
sleep 0.1
|
||||||
|
count=$((count++))
|
||||||
|
done
|
||||||
|
|
||||||
|
# Do the initial database setup. Pass /dev/null as configs-path to
|
||||||
|
# avoid saving the token as the active config.
|
||||||
|
if test -e "$STATE_DIRECTORY/.first_startup"; then
|
||||||
|
influx setup \
|
||||||
|
--configs-path /dev/null \
|
||||||
|
--org ${escapeShellArg initCfg.organization} \
|
||||||
|
--bucket ${escapeShellArg initCfg.bucket} \
|
||||||
|
--username ${escapeShellArg initCfg.username} \
|
||||||
|
--password "$(< "$CREDENTIALS_DIRECTORY/admin-password")" \
|
||||||
|
--token "$(< "$CREDENTIALS_DIRECTORY/admin-token")" \
|
||||||
|
--retention ${escapeShellArg initCfg.retention} \
|
||||||
|
--force >/dev/null
|
||||||
|
|
||||||
|
rm -f "$STATE_DIRECTORY/.first_startup"
|
||||||
|
fi
|
||||||
|
''
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
users.extraUsers.influxdb2 = {
|
users.extraUsers.influxdb2 = {
|
||||||
|
@ -63,5 +173,5 @@ in
|
||||||
users.extraGroups.influxdb2 = {};
|
users.extraGroups.influxdb2 = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
meta.maintainers = with lib.maintainers; [ nickcao ];
|
meta.maintainers = with lib.maintainers; [ nickcao oddlama ];
|
||||||
}
|
}
|
||||||
|
|
|
@ -367,6 +367,7 @@ in {
|
||||||
iftop = handleTest ./iftop.nix {};
|
iftop = handleTest ./iftop.nix {};
|
||||||
incron = handleTest ./incron.nix {};
|
incron = handleTest ./incron.nix {};
|
||||||
influxdb = handleTest ./influxdb.nix {};
|
influxdb = handleTest ./influxdb.nix {};
|
||||||
|
influxdb2 = handleTest ./influxdb2.nix {};
|
||||||
initrd-network-openvpn = handleTest ./initrd-network-openvpn {};
|
initrd-network-openvpn = handleTest ./initrd-network-openvpn {};
|
||||||
initrd-network-ssh = handleTest ./initrd-network-ssh {};
|
initrd-network-ssh = handleTest ./initrd-network-ssh {};
|
||||||
initrd-luks-empty-passphrase = handleTest ./initrd-luks-empty-passphrase.nix {};
|
initrd-luks-empty-passphrase = handleTest ./initrd-luks-empty-passphrase.nix {};
|
||||||
|
|
36
nixos/tests/influxdb2.nix
Normal file
36
nixos/tests/influxdb2.nix
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
import ./make-test-python.nix ({ pkgs, ...} : {
|
||||||
|
name = "influxdb2";
|
||||||
|
meta = with pkgs.lib.maintainers; {
|
||||||
|
maintainers = [ offline ];
|
||||||
|
};
|
||||||
|
|
||||||
|
nodes.machine = { lib, ... }: {
|
||||||
|
environment.systemPackages = [ pkgs.influxdb2-cli ];
|
||||||
|
services.influxdb2.enable = true;
|
||||||
|
services.influxdb2.provision = {
|
||||||
|
enable = true;
|
||||||
|
initialSetup = {
|
||||||
|
organization = "default";
|
||||||
|
bucket = "default";
|
||||||
|
passwordFile = pkgs.writeText "admin-pw" "ExAmPl3PA55W0rD";
|
||||||
|
tokenFile = pkgs.writeText "admin-token" "verysecureadmintoken";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
testScript = { nodes, ... }:
|
||||||
|
let
|
||||||
|
tokenArg = "--token verysecureadmintoken";
|
||||||
|
in ''
|
||||||
|
machine.wait_for_unit("influxdb2.service")
|
||||||
|
|
||||||
|
machine.fail("curl --fail -X POST 'http://localhost:8086/api/v2/signin' -u admin:wrongpassword")
|
||||||
|
machine.succeed("curl --fail -X POST 'http://localhost:8086/api/v2/signin' -u admin:ExAmPl3PA55W0rD")
|
||||||
|
|
||||||
|
out = machine.succeed("influx org list ${tokenArg}")
|
||||||
|
assert "default" in out
|
||||||
|
|
||||||
|
out = machine.succeed("influx bucket list ${tokenArg} --org default")
|
||||||
|
assert "default" in out
|
||||||
|
'';
|
||||||
|
})
|
|
@ -8,6 +8,7 @@
|
||||||
, rustPlatform
|
, rustPlatform
|
||||||
, stdenv
|
, stdenv
|
||||||
, libiconv
|
, libiconv
|
||||||
|
, nixosTests
|
||||||
}:
|
}:
|
||||||
|
|
||||||
let
|
let
|
||||||
|
@ -107,6 +108,8 @@ in buildGoModule {
|
||||||
|
|
||||||
ldflags = [ "-X main.commit=v${version}" "-X main.version=${version}" ];
|
ldflags = [ "-X main.commit=v${version}" "-X main.version=${version}" ];
|
||||||
|
|
||||||
|
passthru.tests = { inherit (nixosTests) influxdb2; };
|
||||||
|
|
||||||
meta = with lib; {
|
meta = with lib; {
|
||||||
description = "An open-source distributed time series database";
|
description = "An open-source distributed time series database";
|
||||||
license = licenses.mit;
|
license = licenses.mit;
|
||||||
|
|
Loading…
Reference in a new issue