Merge pull request #249211 from oddlama/feat-influxdb-provision

nixos/influxdb2: automatic initial setup and nixos tests

authored by Nick Cao and committed by GitHub 2dadab48 fea0315e

+157 -7
+117 -7
nixos/modules/services/databases/influxdb2.nix
··· 1 1 { config, lib, pkgs, ... }: 2 2 3 - with lib; 3 + let 4 + inherit 5 + (lib) 6 + escapeShellArg 7 + hasAttr 8 + literalExpression 9 + mkEnableOption 10 + mkIf 11 + mkOption 12 + types 13 + ; 4 14 5 - let 6 15 format = pkgs.formats.json { }; 7 16 cfg = config.services.influxdb2; 8 17 configFile = format.generate "config.json" cfg.settings; ··· 24 33 description = lib.mdDoc ''configuration options for influxdb2, see <https://docs.influxdata.com/influxdb/v2.0/reference/config-options> for details.''; 25 34 type = format.type; 26 35 }; 36 + 37 + provision = { 38 + enable = mkEnableOption "initial database setup and provisioning"; 39 + 40 + initialSetup = { 41 + organization = mkOption { 42 + type = types.str; 43 + example = "main"; 44 + description = "Primary organization name"; 45 + }; 46 + 47 + bucket = mkOption { 48 + type = types.str; 49 + example = "example"; 50 + description = "Primary bucket name"; 51 + }; 52 + 53 + username = mkOption { 54 + type = types.str; 55 + default = "admin"; 56 + description = "Primary username"; 57 + }; 58 + 59 + retention = mkOption { 60 + type = types.str; 61 + default = "0"; 62 + description = '' 63 + The duration for which the bucket will retain data (0 is infinite). 64 + Accepted units are `ns` (nanoseconds), `us` or `µs` (microseconds), `ms` (milliseconds), 65 + `s` (seconds), `m` (minutes), `h` (hours), `d` (days) and `w` (weeks). 66 + ''; 67 + }; 68 + 69 + passwordFile = mkOption { 70 + type = types.path; 71 + description = "Password for primary user. Don't use a file from the nix store!"; 72 + }; 73 + 74 + tokenFile = mkOption { 75 + type = types.path; 76 + description = "API Token to set for the admin user. Don't use a file from the nix store!"; 77 + }; 78 + }; 79 + }; 27 80 }; 28 81 }; 29 82 30 83 config = mkIf cfg.enable { 31 - assertions = [{ 32 - assertion = !(builtins.hasAttr "bolt-path" cfg.settings) && !(builtins.hasAttr "engine-path" cfg.settings); 33 - message = "services.influxdb2.config: bolt-path and engine-path should not be set as they are managed by systemd"; 34 - }]; 84 + assertions = [ 85 + { 86 + assertion = !(hasAttr "bolt-path" cfg.settings) && !(hasAttr "engine-path" cfg.settings); 87 + message = "services.influxdb2.config: bolt-path and engine-path should not be set as they are managed by systemd"; 88 + } 89 + ]; 35 90 36 91 systemd.services.influxdb2 = { 37 92 description = "InfluxDB is an open-source, distributed, time series database"; ··· 52 107 LimitNOFILE = 65536; 53 108 KillMode = "control-group"; 54 109 Restart = "on-failure"; 110 + LoadCredential = [ 111 + "admin-password:${cfg.provision.initialSetup.passwordFile}" 112 + "admin-token:${cfg.provision.initialSetup.tokenFile}" 113 + ]; 55 114 }; 115 + 116 + path = [pkgs.influxdb2-cli]; 117 + 118 + # Mark if this is the first startup so postStart can do the initial setup 119 + preStart = mkIf cfg.provision.enable '' 120 + if ! test -e "$STATE_DIRECTORY/influxd.bolt"; then 121 + touch "$STATE_DIRECTORY/.first_startup" 122 + fi 123 + ''; 124 + 125 + postStart = let 126 + initCfg = cfg.provision.initialSetup; 127 + in mkIf cfg.provision.enable ( 128 + '' 129 + set -euo pipefail 130 + export INFLUX_HOST="http://"${escapeShellArg (cfg.settings.http-bind-address or "localhost:8086")} 131 + 132 + # Wait for the influxdb server to come online 133 + count=0 134 + while ! influx ping &>/dev/null; do 135 + if [ "$count" -eq 300 ]; then 136 + echo "Tried for 30 seconds, giving up..." 137 + exit 1 138 + fi 139 + 140 + if ! kill -0 "$MAINPID"; then 141 + echo "Main server died, giving up..." 142 + exit 1 143 + fi 144 + 145 + sleep 0.1 146 + count=$((count++)) 147 + done 148 + 149 + # Do the initial database setup. Pass /dev/null as configs-path to 150 + # avoid saving the token as the active config. 151 + if test -e "$STATE_DIRECTORY/.first_startup"; then 152 + influx setup \ 153 + --configs-path /dev/null \ 154 + --org ${escapeShellArg initCfg.organization} \ 155 + --bucket ${escapeShellArg initCfg.bucket} \ 156 + --username ${escapeShellArg initCfg.username} \ 157 + --password "$(< "$CREDENTIALS_DIRECTORY/admin-password")" \ 158 + --token "$(< "$CREDENTIALS_DIRECTORY/admin-token")" \ 159 + --retention ${escapeShellArg initCfg.retention} \ 160 + --force >/dev/null 161 + 162 + rm -f "$STATE_DIRECTORY/.first_startup" 163 + fi 164 + '' 165 + ); 56 166 }; 57 167 58 168 users.extraUsers.influxdb2 = { ··· 63 173 users.extraGroups.influxdb2 = {}; 64 174 }; 65 175 66 - meta.maintainers = with lib.maintainers; [ nickcao ]; 176 + meta.maintainers = with lib.maintainers; [ nickcao oddlama ]; 67 177 }
+1
nixos/tests/all-tests.nix
··· 367 367 iftop = handleTest ./iftop.nix {}; 368 368 incron = handleTest ./incron.nix {}; 369 369 influxdb = handleTest ./influxdb.nix {}; 370 + influxdb2 = handleTest ./influxdb2.nix {}; 370 371 initrd-network-openvpn = handleTest ./initrd-network-openvpn {}; 371 372 initrd-network-ssh = handleTest ./initrd-network-ssh {}; 372 373 initrd-luks-empty-passphrase = handleTest ./initrd-luks-empty-passphrase.nix {};
+36
nixos/tests/influxdb2.nix
··· 1 + import ./make-test-python.nix ({ pkgs, ...} : { 2 + name = "influxdb2"; 3 + meta = with pkgs.lib.maintainers; { 4 + maintainers = [ offline ]; 5 + }; 6 + 7 + nodes.machine = { lib, ... }: { 8 + environment.systemPackages = [ pkgs.influxdb2-cli ]; 9 + services.influxdb2.enable = true; 10 + services.influxdb2.provision = { 11 + enable = true; 12 + initialSetup = { 13 + organization = "default"; 14 + bucket = "default"; 15 + passwordFile = pkgs.writeText "admin-pw" "ExAmPl3PA55W0rD"; 16 + tokenFile = pkgs.writeText "admin-token" "verysecureadmintoken"; 17 + }; 18 + }; 19 + }; 20 + 21 + testScript = { nodes, ... }: 22 + let 23 + tokenArg = "--token verysecureadmintoken"; 24 + in '' 25 + machine.wait_for_unit("influxdb2.service") 26 + 27 + machine.fail("curl --fail -X POST 'http://localhost:8086/api/v2/signin' -u admin:wrongpassword") 28 + machine.succeed("curl --fail -X POST 'http://localhost:8086/api/v2/signin' -u admin:ExAmPl3PA55W0rD") 29 + 30 + out = machine.succeed("influx org list ${tokenArg}") 31 + assert "default" in out 32 + 33 + out = machine.succeed("influx bucket list ${tokenArg} --org default") 34 + assert "default" in out 35 + ''; 36 + })
+3
pkgs/servers/nosql/influxdb2/default.nix
··· 8 8 , rustPlatform 9 9 , stdenv 10 10 , libiconv 11 + , nixosTests 11 12 }: 12 13 13 14 let ··· 106 107 tags = [ "assets" ]; 107 108 108 109 ldflags = [ "-X main.commit=v${version}" "-X main.version=${version}" ]; 110 + 111 + passthru.tests = { inherit (nixosTests) influxdb2; }; 109 112 110 113 meta = with lib; { 111 114 description = "An open-source distributed time series database";