{ pkgs, serverPkg, clientPkg }: let serverModule = import ../nixos/modules/lightscale-server.nix { defaultPackage = serverPkg; }; clientModule = import ../nixos/modules/lightscale-client.nix { defaultPackage = clientPkg; }; in { name = "lightscale-lab-services"; nodes = { server = { ... }: { imports = [ serverModule ]; networking.hostName = "server"; networking.usePredictableInterfaceNames = false; virtualisation.vlans = [ 1 ]; networking.interfaces.eth1.useDHCP = false; networking.interfaces.eth1.ipv4.addresses = [ { address = "10.0.0.1"; prefixLength = 24; } ]; networking.firewall.enable = false; boot.kernelModules = [ "wireguard" ]; services.lightscale-server = { enable = true; listen = "10.0.0.1:8080"; stateFile = "/var/lib/lightscale-server/state.json"; adminToken = "lab-admin-token"; }; environment.systemPackages = [ clientPkg pkgs.curl pkgs.iputils ]; }; client1 = { ... }: { imports = [ clientModule ]; networking.hostName = "client1"; networking.usePredictableInterfaceNames = false; virtualisation.vlans = [ 1 ]; networking.interfaces.eth1.useDHCP = false; networking.interfaces.eth1.ipv4.addresses = [ { address = "10.0.0.2"; prefixLength = 24; } ]; networking.firewall.enable = false; boot.kernelModules = [ "wireguard" ]; services.lightscale-client = { enable = true; profile = "svc"; stateDir = "/var/lib/lightscale-client"; controlUrls = [ "http://10.0.0.1:8080" ]; listenPort = 51820; applyRoutes = true; heartbeatInterval = 5; longpollTimeout = 5; }; environment.systemPackages = [ clientPkg pkgs.iputils ]; }; client2 = { ... }: { imports = [ clientModule ]; networking.hostName = "client2"; networking.usePredictableInterfaceNames = false; virtualisation.vlans = [ 1 ]; networking.interfaces.eth1.useDHCP = false; networking.interfaces.eth1.ipv4.addresses = [ { address = "10.0.0.3"; prefixLength = 24; } ]; networking.firewall.enable = false; boot.kernelModules = [ "wireguard" ]; services.lightscale-client = { enable = true; profile = "svc"; stateDir = "/var/lib/lightscale-client"; controlUrls = [ "http://10.0.0.1:8080" ]; listenPort = 51820; applyRoutes = true; heartbeatInterval = 5; longpollTimeout = 5; }; environment.systemPackages = [ clientPkg pkgs.iputils ]; }; }; testScript = '' import json start_all() server.wait_for_unit("lightscale-server.service") server.wait_for_open_port(8080, addr="10.0.0.1", timeout=120) client1.wait_for_unit("multi-user.target") client2.wait_for_unit("multi-user.target") net = json.loads(server.succeed( "curl -sSf -X POST http://10.0.0.1:8080/v1/networks " "-H 'authorization: Bearer lab-admin-token' " "-H 'content-type: application/json' " "-d '{\"name\":\"svc-net\",\"bootstrap_token_ttl_seconds\":1200,\"bootstrap_token_uses\":10}'" )) token = net["bootstrap_token"]["token"] network_id = net["network"]["id"] def register(node, name): node.succeed( "lightscale-client --profile svc " "--state-dir /var/lib/lightscale-client/svc " "--control-url http://10.0.0.1:8080 " f"register --node-name {name} -- {token}" ) node.wait_until_succeeds("test -s /var/lib/lightscale-client/svc/state.json") node.succeed("systemctl start lightscale-client.service") node.wait_for_unit("lightscale-client.service") node.wait_until_succeeds("ip link show ls-svc", timeout=120) register(client1, "client1") register(client2, "client2") server.wait_until_succeeds( f"curl -sSf -H 'authorization: Bearer lab-admin-token' " f"http://10.0.0.1:8080/v1/admin/networks/{network_id}/nodes | grep -q '\"nodes\"'", timeout=120, ) state1 = json.loads(client1.succeed("cat /var/lib/lightscale-client/svc/state.json")) state2 = json.loads(client2.succeed("cat /var/lib/lightscale-client/svc/state.json")) ip1 = state1["ipv4"] ip2 = state2["ipv4"] client1.wait_until_succeeds(f"ping -c 3 {ip2}", timeout=180) client2.wait_until_succeeds(f"ping -c 3 {ip1}", timeout=180) client1.succeed("systemctl restart lightscale-client.service") client1.wait_for_unit("lightscale-client.service") client1.wait_until_succeeds(f"ping -c 3 {ip2}", timeout=180) server.succeed("systemctl restart lightscale-server.service") server.wait_for_unit("lightscale-server.service") client1.wait_until_succeeds( "lightscale-client --profile svc --state-dir /var/lib/lightscale-client/svc " "--control-url http://10.0.0.1:8080 netmap | grep -q 'approved: true'", timeout=180, ) ''; }