at master 4.2 kB view raw
1{ pkgs, ... }: 2let 3 listenPort = 30123; 4 testString = "It works!"; 5 mkCreateSmallFileService = 6 { 7 path, 8 loop ? false, 9 }: 10 { 11 script = '' 12 ${pkgs.coreutils}/bin/dd if=/dev/zero of=${path} bs=1K count=100 13 ${pkgs.lib.optionalString loop "${pkgs.util-linux}/bin/losetup --find ${path}"} 14 ''; 15 serviceConfig = { 16 Type = "oneshot"; 17 }; 18 wantedBy = [ "multi-user.target" ]; 19 before = [ "nbd-server.service" ]; 20 }; 21in 22{ 23 name = "nbd"; 24 25 nodes = { 26 server = 27 { config, pkgs, ... }: 28 { 29 # Create some small files of zeros to use as the ndb disks 30 ## `vault-pub.disk` is accessible from any IP 31 systemd.services.create-pub-file = mkCreateSmallFileService { path = "/vault-pub.disk"; }; 32 ## `vault-priv.disk` is accessible only from localhost. 33 ## It's also a loopback device to test exporting /dev/... 34 systemd.services.create-priv-file = mkCreateSmallFileService { 35 path = "/vault-priv.disk"; 36 loop = true; 37 }; 38 ## `aaa.disk` is just here because "[aaa]" sorts before 39 ## "[generic]" lexicographically, and nbd-server breaks if 40 ## "[generic]" isn't the first section. 41 systemd.services.create-aaa-file = mkCreateSmallFileService { path = "/aaa.disk"; }; 42 43 # Needed only for nbd-client used in the tests. 44 environment.systemPackages = [ pkgs.nbd ]; 45 46 # Open the nbd port in the firewall 47 networking.firewall.allowedTCPPorts = [ listenPort ]; 48 49 # Run the nbd server and expose the small file created above 50 services.nbd.server = { 51 enable = true; 52 exports = { 53 aaa = { 54 path = "/aaa.disk"; 55 }; 56 vault-pub = { 57 path = "/vault-pub.disk"; 58 }; 59 vault-priv = { 60 path = "/dev/loop0"; 61 allowAddresses = [ 62 "127.0.0.1" 63 "::1" 64 ]; 65 }; 66 }; 67 listenAddress = "0.0.0.0"; 68 listenPort = listenPort; 69 }; 70 }; 71 72 client = 73 { config, pkgs, ... }: 74 { 75 programs.nbd.enable = true; 76 }; 77 }; 78 79 testScript = '' 80 testString = "${testString}" 81 82 start_all() 83 server.wait_for_open_port(${toString listenPort}) 84 85 # Client: Connect to the server, write a small string to the nbd disk, and cleanly disconnect 86 client.succeed("nbd-client server ${toString listenPort} /dev/nbd0 -name vault-pub -persist") 87 client.succeed(f"echo '{testString}' | dd of=/dev/nbd0 conv=notrunc") 88 client.succeed("nbd-client -d /dev/nbd0") 89 90 # Server: Check that the string written by the client is indeed in the file 91 foundString = server.succeed(f"dd status=none if=/vault-pub.disk count={len(testString)}")[:len(testString)] 92 if foundString != testString: 93 raise Exception(f"Read the wrong string from nbd disk. Expected: '{testString}'. Found: '{foundString}'") 94 95 # Client: Fail to connect to the private disk 96 client.fail("nbd-client server ${toString listenPort} /dev/nbd0 -name vault-priv -persist") 97 98 # Server: Successfully connect to the private disk 99 server.succeed("nbd-client localhost ${toString listenPort} /dev/nbd0 -name vault-priv -persist") 100 server.succeed(f"echo '{testString}' | dd of=/dev/nbd0 conv=notrunc") 101 foundString = server.succeed(f"dd status=none if=/dev/loop0 count={len(testString)}")[:len(testString)] 102 if foundString != testString: 103 raise Exception(f"Read the wrong string from nbd disk. Expected: '{testString}'. Found: '{foundString}'") 104 server.succeed("nbd-client -d /dev/nbd0") 105 106 # Server: Successfully connect to the aaa disk 107 server.succeed("nbd-client localhost ${toString listenPort} /dev/nbd0 -name aaa -persist") 108 server.succeed(f"echo '{testString}' | dd of=/dev/nbd0 conv=notrunc") 109 foundString = server.succeed(f"dd status=none if=/aaa.disk count={len(testString)}")[:len(testString)] 110 if foundString != testString: 111 raise Exception(f"Read the wrong string from nbd disk. Expected: '{testString}'. Found: '{foundString}'") 112 server.succeed("nbd-client -d /dev/nbd0") 113 ''; 114}