summary refs log tree commit diff
path: root/nixos/modules/services/networking/consul.nix
diff options
context:
space:
mode:
authorWilliam A. Kennington III <william@wkennington.com>2014-09-15 01:26:26 -0700
committerWilliam A. Kennington III <william@wkennington.com>2014-09-26 03:25:14 -0700
commit36f9b9c284342574ce178571195c313fc1874cca (patch)
tree1f623595b9509f814f989a0ccfcd42ba02051702 /nixos/modules/services/networking/consul.nix
parent413b00f23fe327cac3b2981d5dca6008c1e80698 (diff)
downloadnixpkgs-36f9b9c284342574ce178571195c313fc1874cca.tar
nixpkgs-36f9b9c284342574ce178571195c313fc1874cca.tar.gz
nixpkgs-36f9b9c284342574ce178571195c313fc1874cca.tar.bz2
nixpkgs-36f9b9c284342574ce178571195c313fc1874cca.tar.lz
nixpkgs-36f9b9c284342574ce178571195c313fc1874cca.tar.xz
nixpkgs-36f9b9c284342574ce178571195c313fc1874cca.tar.zst
nixpkgs-36f9b9c284342574ce178571195c313fc1874cca.zip
nixos/consul: Add module
Diffstat (limited to 'nixos/modules/services/networking/consul.nix')
-rw-r--r--nixos/modules/services/networking/consul.nix166
1 files changed, 166 insertions, 0 deletions
diff --git a/nixos/modules/services/networking/consul.nix b/nixos/modules/services/networking/consul.nix
new file mode 100644
index 00000000000..ebc83681408
--- /dev/null
+++ b/nixos/modules/services/networking/consul.nix
@@ -0,0 +1,166 @@
+{ config, lib, pkgs, utils, ... }:
+
+with lib;
+let
+
+  dataDir = "/var/lib/consul";
+  cfg = config.services.consul;
+
+  configOptions = {
+    data_dir = dataDir;
+    rejoin_after_leave = true;
+  }
+  // (if cfg.webUi then { ui_dir = "${pkgs.consul.ui}"; } else { })
+  // cfg.extraConfig;
+
+  configFiles = [ "/etc/consul.json" "/etc/consul-addrs.json" ]
+    ++ cfg.extraConfigFiles;
+
+  devices = attrValues (filterAttrs (_: i: i != null) cfg.interface);
+  systemdDevices = flip map devices
+    (i: "sys-subsystem-net-devices-${utils.escapeSystemdPath i}.device");
+in
+{
+  options = {
+
+    services.consul = {
+
+      enable = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          Enables the consul daemon.
+        '';
+      };
+
+      webUi = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          Enables the web interface on the consul http port.
+        '';
+      };
+
+      interface = {
+
+        advertise = mkOption {
+          type = types.nullOr types.str;
+          default = null;
+          description = ''
+            The name of the interface to pull the advertise_addr from.
+          '';
+        };
+
+        bind = mkOption {
+          type = types.nullOr types.str;
+          default = null;
+          description = ''
+            The name of the interface to pull the bind_addr from.
+          '';
+        };
+
+      };
+
+      forceIpv4 = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          Whether we should force the interfaces to only pull ipv4 addresses.
+        '';
+      };
+
+      dropPrivileges = mkOption {
+        type = types.bool;
+        default = true;
+        description = ''
+          Whether the consul agent should be run as a non-root consul user.
+        '';
+      };
+
+      extraConfig = mkOption {
+        default = { };
+        description = ''
+          Extra configuration options which are serialized to json and added
+          to the config.json file.
+        '';
+      };
+
+      extraConfigFiles = mkOption {
+        default = [ ];
+        type = types.listOf types.str;
+        description = ''
+          Additional configuration files to pass to consul
+          NOTE: These will not trigger the service to be restarted when altered.
+        '';
+      };
+
+    };
+
+  };
+
+  config = mkIf cfg.enable {
+
+    users.extraUsers."consul" = {
+      description = "Consul agent daemon user";
+      uid = config.ids.uids.consul;
+    };
+
+    environment = {
+      etc."consul.json".text = builtins.toJSON configOptions;
+      systemPackages = with pkgs; [ consul ];
+    };
+
+    systemd.services.consul = {
+      wantedBy = [ "multi-user.target" ];
+      after = [ "network.target" ] ++ systemdDevices;
+      bindsTo = systemdDevices;
+      restartTriggers = [ config.environment.etc."consul.json".source ];
+
+      serviceConfig = {
+        ExecStart = "@${pkgs.consul}/bin/consul consul agent"
+          + concatMapStrings (n: " -config-file ${n}") configFiles;
+        ExecStop = "${pkgs.consul}/bin/consul leave";
+        ExecReload = "${pkgs.consul}/bin/consul reload";
+        PermissionsStartOnly = true;
+        User = if cfg.dropPrivileges then "consul" else null;
+      };
+
+      path = with pkgs; [ iproute gnugrep gawk ];
+      preStart = ''
+        mkdir -m 0700 -p ${dataDir}
+        chown -R consul ${dataDir}
+
+        # Determine interface addresses
+        getAddrOnce () {
+          ip addr show dev "$1" \
+            | grep 'inet${optionalString (cfg.forceIpv4) " "}.*scope global' \
+            | awk -F '[ /\t]*' '{print $3}' | head -n 1
+        }
+        getAddr () {
+          ADDR="$(getAddrOnce $1)"
+          LEFT=60 # Die after 1 minute
+          while [ -z "$ADDR" ]; do
+            sleep 1
+            LEFT=$(expr $LEFT - 1)
+            if [ "$LEFT" -eq "0" ]; then
+              echo "Address lookup timed out"
+              exit 1
+            fi
+            ADDR="$(getAddrOnce $1)"
+          done
+          echo "$ADDR"
+        }
+        echo "{" > /etc/consul-addrs.json
+      ''
+      + concatStrings (flip mapAttrsToList cfg.interface (name: i:
+        optionalString (i != null) ''
+          echo "    \"${name}_addr\": \"$(getAddr "${i}")\"," >> /etc/consul-addrs.json
+        ''))
+      + ''
+        echo "    \"\": \"\"" >> /etc/consul-addrs.json
+        echo "}" >> /etc/consul-addrs.json
+      '';
+    };
+
+  };
+}