1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
import ./make-test-python.nix ({ pkgs, lib, ...} :
let
addrShared = "192.168.0.1";
addrHostA = "192.168.0.10";
addrHostB = "192.168.0.11";
mkUcarpHost = addr: { config, pkgs, lib, ... }: {
networking.interfaces.eth1.ipv4.addresses = lib.mkForce [
{ address = addr; prefixLength = 24; }
];
networking.ucarp = {
enable = true;
interface = "eth1";
srcIp = addr;
vhId = 1;
passwordFile = "${pkgs.writeText "ucarp-pass" "secure"}";
addr = addrShared;
upscript = pkgs.writeScript "upscript" ''
#!/bin/sh
${pkgs.iproute2}/bin/ip addr add "$2"/24 dev "$1"
'';
downscript = pkgs.writeScript "downscript" ''
#!/bin/sh
${pkgs.iproute2}/bin/ip addr del "$2"/24 dev "$1"
'';
};
};
in {
name = "ucarp";
meta.maintainers = with lib.maintainers; [ oxzi ];
nodes = {
hostA = mkUcarpHost addrHostA;
hostB = mkUcarpHost addrHostB;
};
testScript = ''
def is_master(host):
ipOutput = host.succeed("ip addr show dev eth1")
return "inet ${addrShared}/24" in ipOutput
start_all()
# First, let both hosts start and let a master node be selected
for host, peer in [(hostA, "${addrHostB}"), (hostB, "${addrHostA}")]:
host.wait_for_unit("ucarp.service")
host.succeed(f"ping -c 1 {peer}")
hostA.sleep(5)
hostA_master, hostB_master = is_master(hostA), is_master(hostB)
assert hostA_master != hostB_master, "only one master node is allowed"
master_host = hostA if hostA_master else hostB
backup_host = hostB if hostA_master else hostA
# Let's crash the master host and let the backup take over
master_host.crash()
backup_host.sleep(5)
assert is_master(backup_host), "backup did not take over"
'';
})
|