Something went wrong. Try again.
What happens if I push all of nixpkgs
Something went wrong. Try again.
Nix
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268{ lib, ... }:
let # Settings for both servers and agents webUi = true; retry_interval = "1s"; raft_multiplier = 1;
defaultExtraConfig = { inherit retry_interval; performance = { inherit raft_multiplier; }; };
allConsensusServerHosts = [ "192.168.1.1" "192.168.1.2" "192.168.1.3" ];
allConsensusClientHosts = [ "192.168.2.1" "192.168.2.2" ];
firewallSettings = { # See https://www.consul.io/docs/install/ports.html allowedTCPPorts = [ 8301 8302 8600 8500 8300 ]; allowedUDPPorts = [ 8301 8302 8600 ]; };
client = index: { pkgs, ... }: let ip = builtins.elemAt allConsensusClientHosts index; in { environment.systemPackages = [ pkgs.consul ];
networking.interfaces.eth1.ipv4.addresses = pkgs.lib.mkOverride 0 [ { address = ip; prefixLength = 16; } ]; networking.firewall = firewallSettings;
nixpkgs.config.allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) [ "consul" ];
services.consul = { enable = true; inherit webUi; extraConfig = defaultExtraConfig // { server = false; retry_join = allConsensusServerHosts; bind_addr = ip; }; }; };
server = index: { pkgs, ... }: let numConsensusServers = builtins.length allConsensusServerHosts; thisConsensusServerHost = builtins.elemAt allConsensusServerHosts index; ip = thisConsensusServerHost; # since we already use IPs to identify servers in { networking.interfaces.eth1.ipv4.addresses = pkgs.lib.mkOverride 0 [ { address = ip; prefixLength = 16; } ]; networking.firewall = firewallSettings;
nixpkgs.config.allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) [ "consul" ];
services.consul = assert builtins.elem thisConsensusServerHost allConsensusServerHosts; { enable = true; inherit webUi; extraConfig = defaultExtraConfig // { server = true; bootstrap_expect = numConsensusServers; # Tell Consul that we never intend to drop below this many servers. # Ensures to not permanently lose consensus after temporary loss. # See https://github.com/hashicorp/consul/issues/8118#issuecomment-645330040 autopilot.min_quorum = numConsensusServers; retry_join = # If there's only 1 node in the network, we allow self-join; # otherwise, the node must not try to join itself, and join only the other servers. # See https://github.com/hashicorp/consul/issues/2868 if numConsensusServers == 1 then allConsensusServerHosts else builtins.filter (h: h != thisConsensusServerHost) allConsensusServerHosts; bind_addr = ip; }; }; };in{ name = "consul";
node.pkgsReadOnly = false;
nodes = { server1 = server 0; server2 = server 1; server3 = server 2;
client1 = client 0; client2 = client 1; };
testScript = '' servers = [server1, server2, server3] machines = [server1, server2, server3, client1, client2]
for m in machines: m.wait_for_unit("consul.service")
def wait_for_healthy_servers(): # See https://github.com/hashicorp/consul/issues/8118#issuecomment-645330040 # for why the `Voter` column of `list-peers` has that info. # TODO: The `grep true` relies on the fact that currently in # the output like # # consul operator raft list-peers # Node ID Address State Voter RaftProtocol # server3 ... 192.168.1.3:8300 leader true 3 # server2 ... 192.168.1.2:8300 follower true 3 # server1 ... 192.168.1.1:8300 follower false 3 # `Voter`is the only boolean column. # Change this to the more reliable way to be defined by # https://github.com/hashicorp/consul/issues/8118 # once that ticket is closed. for m in machines: m.wait_until_succeeds( "[ $(consul operator raft list-peers | grep true | wc -l) == 3 ]" )
def wait_for_all_machines_alive(): """ Note that Serf-"alive" does not mean "Raft"-healthy; see `wait_for_healthy_servers()` for that instead. """ for m in machines: m.wait_until_succeeds("[ $(consul members | grep -o alive | wc -l) == 5 ]")
wait_for_healthy_servers() # Also wait for clients to be alive. wait_for_all_machines_alive()
client1.succeed("consul kv put testkey 42") client2.succeed("[ $(consul kv get testkey) == 42 ]")
def rolling_restart_test(proper_rolling_procedure=True): """ Tests that the cluster can tolearate failures of any single server, following the recommended rolling upgrade procedure from https://www.consul.io/docs/upgrading#standard-upgrades.
Optionally, `proper_rolling_procedure=False` can be given to wait only for each server to be back `Healthy`, not `Stable` in the Raft consensus, see Consul setting `ServerStabilizationTime` and https://github.com/hashicorp/consul/issues/8118#issuecomment-645330040. """
for server in servers: server.block() server.systemctl("stop consul")
# Make sure the stopped peer is recognized as being down client1.wait_until_succeeds( f"[ $(consul members | grep {server.name} | grep -o -E 'failed|left' | wc -l) == 1 ]" )
# For each client, wait until they have connection again # using `kv get -recurse` before issuing commands. client1.wait_until_succeeds("consul kv get -recurse") client2.wait_until_succeeds("consul kv get -recurse")
# Do some consul actions while one server is down. client1.succeed("consul kv put testkey 43") client2.succeed("[ $(consul kv get testkey) == 43 ]") client2.succeed("consul kv delete testkey")
server.unblock() server.systemctl("start consul")
if proper_rolling_procedure: # Wait for recovery. wait_for_healthy_servers() else: # NOT proper rolling upgrade procedure, see above. wait_for_all_machines_alive()
# Wait for client connections. client1.wait_until_succeeds("consul kv get -recurse") client2.wait_until_succeeds("consul kv get -recurse")
# Do some consul actions with server back up. client1.succeed("consul kv put testkey 44") client2.succeed("[ $(consul kv get testkey) == 44 ]") client2.succeed("consul kv delete testkey")
def all_servers_crash_simultaneously_test(): """ Tests that the cluster will eventually come back after all servers crash simultaneously. """
for server in servers: server.block() server.systemctl("stop --no-block consul")
for server in servers: # --no-block is async, so ensure it has been stopped by now server.wait_until_fails("systemctl is-active --quiet consul") server.unblock() server.systemctl("start consul")
# Wait for recovery. wait_for_healthy_servers()
# Wait for client connections. client1.wait_until_succeeds("consul kv get -recurse") client2.wait_until_succeeds("consul kv get -recurse")
# Do some consul actions with servers back up. client1.succeed("consul kv put testkey 44") client2.succeed("[ $(consul kv get testkey) == 44 ]") client2.succeed("consul kv delete testkey")
# Run the tests.
print("rolling_restart_test()") rolling_restart_test()
print("all_servers_crash_simultaneously_test()") all_servers_crash_simultaneously_test()
print("rolling_restart_test(proper_rolling_procedure=False)") rolling_restart_test(proper_rolling_procedure=False) '';}