Unverified Commit 2dadab48 authored by Nick Cao's avatar Nick Cao Committed by GitHub
Browse files

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

nixos/influxdb2: automatic initial setup and nixos tests
parents fea0315e b4d718f1
Loading
Loading
Loading
Loading
+117 −7
Original line number Diff line number Diff line
{ config, lib, pkgs, ... }:

with lib;

let
  inherit
    (lib)
    escapeShellArg
    hasAttr
    literalExpression
    mkEnableOption
    mkIf
    mkOption
    types
    ;

  format = pkgs.formats.json { };
  cfg = config.services.influxdb2;
  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.'';
        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 {
    assertions = [{
      assertion = !(builtins.hasAttr "bolt-path" cfg.settings) && !(builtins.hasAttr "engine-path" cfg.settings);
    assertions = [
      {
        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 = {
      description = "InfluxDB is an open-source, distributed, time series database";
@@ -52,7 +107,62 @@ in
        LimitNOFILE = 65536;
        KillMode = "control-group";
        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 = {
@@ -63,5 +173,5 @@ in
    users.extraGroups.influxdb2 = {};
  };

  meta.maintainers = with lib.maintainers; [ nickcao ];
  meta.maintainers = with lib.maintainers; [ nickcao oddlama ];
}
+1 −0
Original line number Diff line number Diff line
@@ -367,6 +367,7 @@ in {
  iftop = handleTest ./iftop.nix {};
  incron = handleTest ./incron.nix {};
  influxdb = handleTest ./influxdb.nix {};
  influxdb2 = handleTest ./influxdb2.nix {};
  initrd-network-openvpn = handleTest ./initrd-network-openvpn {};
  initrd-network-ssh = handleTest ./initrd-network-ssh {};
  initrd-luks-empty-passphrase = handleTest ./initrd-luks-empty-passphrase.nix {};
+36 −0
Original line number Diff line number Diff line
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
    '';
})
+3 −0
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@
, rustPlatform
, stdenv
, libiconv
, nixosTests
}:

let
@@ -107,6 +108,8 @@ in buildGoModule {

  ldflags = [ "-X main.commit=v${version}" "-X main.version=${version}" ];

  passthru.tests = { inherit (nixosTests) influxdb2; };

  meta = with lib; {
    description = "An open-source distributed time series database";
    license = licenses.mit;