diff --git a/bin/copy-secrets b/bin/copy-secrets index 24685ede0..f40493599 100755 --- a/bin/copy-secrets +++ b/bin/copy-secrets @@ -32,6 +32,11 @@ case $(nixos-query services.ejabberd-cd.enable 2>/dev/null) in true) ejabberd_uid=$(nixos-query users.extraUsers.ejabberd.uid) esac +case $(nixos-query tv.consul.enable 2>/dev/null) in true) + consul_secret=$(nixos-query tv.consul.encrypt-file) + consul_uid=$(nixos-query users.extraUsers.consul.uid) +esac + (set -x rsync \ --rsync-path="mkdir -p \"$2\" && rsync" \ @@ -46,6 +51,8 @@ retiolum_secret=${retiolum_secret-} retiolum_uid=${retiolum_uid-} ejabberd_secret=${ejabberd_secret-} ejabberd_uid=${ejabberd_uid-} +consul_secret=${consul_secret-} +consul_uid=${consul_uid-} if test -n "\$retiolum_secret"; then chown -v "\$retiolum_uid:0" "\$retiolum_secret" @@ -55,4 +62,8 @@ if test -n "\$ejabberd_secret"; then chown -v "\$ejabberd_uid:0" "\$ejabberd_secret" fi +if test -n "\$consul_secret"; then + chown -v "\$consul_uid:0" "\$consul_secret" +fi + EOF diff --git a/modules/cd/default.nix b/modules/cd/default.nix index dcaea74b4..e3abd47ef 100644 --- a/modules/cd/default.nix +++ b/modules/cd/default.nix @@ -12,6 +12,7 @@ in ./users.nix ../tv/base.nix ../tv/base-cac-CentOS-7-64bit.nix + ../tv/config/consul-server.nix ../tv/ejabberd.nix # XXX echtes modul ../tv/exim-smarthost.nix ../tv/git/public.nix diff --git a/modules/mkdir/default.nix b/modules/mkdir/default.nix index e4c8343d3..76f0bb6bc 100644 --- a/modules/mkdir/default.nix +++ b/modules/mkdir/default.nix @@ -12,6 +12,7 @@ in ./users.nix ../tv/base.nix ../tv/base-cac-CentOS-7-64bit.nix + ../tv/config/consul-server.nix ../tv/exim-smarthost.nix ../tv/git/public.nix ../tv/sanitize.nix diff --git a/modules/nomic/default.nix b/modules/nomic/default.nix index 6f9c9e9fa..f61f97a89 100644 --- a/modules/nomic/default.nix +++ b/modules/nomic/default.nix @@ -9,6 +9,7 @@ in ./hardware-configuration.nix ./users.nix ../tv/base.nix + ../tv/config/consul-server.nix ../tv/environment.nix ../tv/exim-retiolum.nix ../tv/git/public.nix diff --git a/modules/rmdir/default.nix b/modules/rmdir/default.nix index e9b694de5..7279df778 100644 --- a/modules/rmdir/default.nix +++ b/modules/rmdir/default.nix @@ -12,6 +12,7 @@ in ./users.nix ../tv/base.nix ../tv/base-cac-CentOS-7-64bit.nix + ../tv/config/consul-server.nix ../tv/exim-smarthost.nix ../tv/git/public.nix ../tv/sanitize.nix diff --git a/modules/tv/config/consul-client.nix b/modules/tv/config/consul-client.nix new file mode 100644 index 000000000..0a8bf4d75 --- /dev/null +++ b/modules/tv/config/consul-client.nix @@ -0,0 +1,9 @@ +{ pkgs, ... }: + +{ + imports = [ ./consul-server.nix ]; + + tv.consul = { + server = pkgs.lib.mkForce false; + }; +} diff --git a/modules/tv/config/consul-server.nix b/modules/tv/config/consul-server.nix new file mode 100644 index 000000000..4cedbd349 --- /dev/null +++ b/modules/tv/config/consul-server.nix @@ -0,0 +1,22 @@ +{ config, ... }: + +{ + imports = [ ../../tv/consul ]; + tv.consul = rec { + enable = true; + + inherit (config.tv.identity) self; + inherit (self) dc; + + server = true; + + hosts = with config.tv.identity.hosts; [ + # TODO get this list automatically from each host where tv.consul.enable is true + cd + mkdir + nomic + rmdir + #wu + ]; + }; +} diff --git a/modules/tv/consul/default.nix b/modules/tv/consul/default.nix new file mode 100644 index 000000000..c7a3da2b7 --- /dev/null +++ b/modules/tv/consul/default.nix @@ -0,0 +1,123 @@ +{ config, lib, pkgs, ... }: + +# if quorum gets lost, then start any node with a config that doesn't contain bootstrap_expect +# but -bootstrap +# TODO consul-bootstrap HOST that actually does is +# TODO tools to inspect state of a cluster in outage state + +with builtins; +with lib; +let + service-name = "consul"; + + cfg = config.tv.consul; + + out = { + imports = [ ../../tv/iptables ]; + options.tv.consul = api; + config = mkIf cfg.enable (mkMerge [ + imp + { tv.iptables.input-retiolum-accept-new-tcp = [ "8300" "8301" ]; } + # TODO udp for 8301 + ]); + }; + + api = { + # TODO inherit (lib) api.options.enable; oder so + enable = mkOption { + type = types.bool; + default = false; + description = "enable tv.consul"; + }; + dc = mkOption { + type = types.unspecified; + }; + hosts = mkOption { + type = with types; listOf unspecified; + }; + encrypt-file = mkOption { + type = types.str; # TODO path (but not just into store) + default = "/etc/consul/encrypt.json"; + }; + data-dir = mkOption { + type = types.str; # TODO path (but not just into store) + default = "/var/lib/consul"; + }; + self = mkOption { + type = types.unspecified; + }; + server = mkOption { + type = types.bool; + default = false; + }; + GOMAXPROCS = mkOption { + type = types.int; + default = cfg.self.cores; + }; + }; + + consul-config = { + datacenter = cfg.dc; + data_dir = cfg.data-dir; + log_level = "INFO"; + #node_name = + server = cfg.server; + bind_addr = cfg.self.addr; # TODO cfg.addr + enable_syslog = true; + retry_join = map (getAttr "addr") (filter (host: host.fqdn != cfg.self.fqdn) cfg.hosts); + leave_on_terminate = true; + } // optionalAttrs cfg.server { + bootstrap_expect = length cfg.hosts; + leave_on_terminate = false; + }; + + imp = { + environment.systemPackages = with pkgs; [ + consul + ]; + + systemd.services.consul = { + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + path = with pkgs; [ + consul + ]; + environment = { + GOMAXPROCS = toString cfg.GOMAXPROCS; + }; + serviceConfig = { + PermissionsStartOnly = "true"; + SyslogIdentifier = "consul"; + User = user.name; + PrivateTmp = "true"; + Restart = "always"; + ExecStartPre = pkgs.writeScript "consul-init" '' + #! /bin/sh + mkdir -p ${cfg.data-dir} + chown consul: ${cfg.data-dir} + ''; + ExecStart = pkgs.writeScript "consul-service" '' + #! /bin/sh + set -euf + exec >/dev/null + exec consul agent \ + -config-file=${toFile "consul.json" (toJSON consul-config)} \ + -config-file=${cfg.encrypt-file} \ + ''; + #-node=${cfg.self.fqdn} \ + #ExecStart = "${tinc}/sbin/tincd -c ${confDir} -d 0 -U ${user} -D"; + }; + }; + + users.extraUsers = singleton { + inherit (user) name uid; + }; + }; + + user = { + name = "consul"; + uid = 2983239726; # genid consul + }; + +in +out diff --git a/modules/wu/default.nix b/modules/wu/default.nix index 10438bbc0..e55fbaf3f 100644 --- a/modules/wu/default.nix +++ b/modules/wu/default.nix @@ -8,6 +8,7 @@ in imports = [ ./hosts.nix ../tv/base.nix + ../tv/config/consul-client.nix ../tv/exim-retiolum.nix ../tv/environment.nix ../tv/sanitize.nix