diff --git a/nixos/modules/private-storage.nix b/nixos/modules/private-storage.nix index 39972965909f6566051ecd3cd39e8dbe00e7fb45..d2db7dd661a8a923c04e245e45cad30305ebfe68 100644 --- a/nixos/modules/private-storage.nix +++ b/nixos/modules/private-storage.nix @@ -48,6 +48,14 @@ in An IPv4 address to advertise for this storage service. ''; }; + services.private-storage.introducerFURL = lib.mkOption + { default = null; + type = lib.types.nullOr lib.types.str; + example = lib.literalExample "pb://<tubid>@<location hint>/<swissnum>"; + description = '' + A Tahoe-LAFS introducer node fURL at which this storage node should announce itself. + ''; + }; services.private-storage.publicStoragePort = lib.mkOption { default = 8898; type = lib.types.int; @@ -78,7 +86,10 @@ in # We just populate this according to policy/preference of Private # Storage. sections = - { node = + { client = if cfg.introducerFURL == null then {} else + { "introducer.furl" = cfg.introducerFURL; + }; + node = # XXX Should try to name that is unique across the grid. { nickname = "storage"; # We have the web port active because the CLI uses it. We may diff --git a/nixos/modules/tests/private-storage.nix b/nixos/modules/tests/private-storage.nix index 0838de10b1e794824a3cfea63e1c75ac81776286..89e63a858728722c006297e024facde686dd74e5 100644 --- a/nixos/modules/tests/private-storage.nix +++ b/nixos/modules/tests/private-storage.nix @@ -1,31 +1,136 @@ +let + pkgs = import <nixpkgs> { }; + # Here are the preconstructed secrets which we can assign to the introducer. + # This is a lot easier than having the introducer generate them and then + # discovering and configuring the other nodes with them. + pemFile = pkgs.writeTextFile { + name = "node.pem"; + text = '' +-----BEGIN CERTIFICATE----- +MIICojCCAYoCAQEwDQYJKoZIhvcNAQELBQAwFzEVMBMGA1UEAwwMbmV3cGJfdGhp +bmd5MB4XDTE5MDkyMDE4NDkzNloXDTIwMDkxOTE4NDkzNlowFzEVMBMGA1UEAwwM +bmV3cGJfdGhpbmd5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1zK4 +wH0ZvjFCnFo+PvT/ANBJ2H7pZQDRHFHmhW28VeQ4nCqlifjxJ/MOWpqKYK6rxHOK +DNTDR5MbkFO7l0yquB0/FArP9RErezKakXz8qSLhipDZk7y+0fKWMPxcgdSzm28Z +817Yzp1naXPHQRcno3M3eo58FyoTDAOXP3hiS+bFm8RGVINLSBJtILKoplvgSdyD +/1Xg4zbh2FK+gS0f92jel5JyAaebt3EQPiIxwUrvi5a1w5EQKi13sJ22RK5H6sch +Xg76GMMBCckLs+g8xza5uHLbotMnWb7ddW+pC0SQsrihUxz902lQoUuxq2aJig6o +Ti6wsetUcxtOErfy6wIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQC7ciESyktDoAus +ni6zW30AXnoTxD/LNCf2HMUFcyFF57p5dcaTsAUhUd+aKX/iJyhy6bfgo8GGI5xN +LvhvNQ6Cb6Z9qiCWDvEll+nbfuJNEanEd6bkR06/TX5bK5iDMYZD4Z+SSHsNDNEF +DXJ96zp42UfQTdimxXHmZidAYvtYeLe4EDoJGhpuryEAIUwPdTvsPX+pLfCdtdyP +595zbHkUPPnA3feWckcmN0FWiXisaE4ERXdPrcBnMB5TqY7KI0j2TjW59l1TnNFD +dEKMyBD89ndBXvZq8JO8nzdM0WF32jSM/Yb+clS6PHoypHGo4jBTE3AEIXMUe//x +MSwj51gz +-----END CERTIFICATE----- +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDXMrjAfRm+MUKc +Wj4+9P8A0EnYfullANEcUeaFbbxV5DicKqWJ+PEn8w5amopgrqvEc4oM1MNHkxuQ +U7uXTKq4HT8UCs/1ESt7MpqRfPypIuGKkNmTvL7R8pYw/FyB1LObbxnzXtjOnWdp +c8dBFyejczd6jnwXKhMMA5c/eGJL5sWbxEZUg0tIEm0gsqimW+BJ3IP/VeDjNuHY +Ur6BLR/3aN6XknIBp5u3cRA+IjHBSu+LlrXDkRAqLXewnbZErkfqxyFeDvoYwwEJ +yQuz6DzHNrm4ctui0ydZvt11b6kLRJCyuKFTHP3TaVChS7GrZomKDqhOLrCx61Rz +G04St/LrAgMBAAECggEAfRKjwmxzK9Fhj5H7n4exNf3ZDZUlfWiuILGRM3eGAL22 +ET3QHJKtRrTDYPF0/6BFgNZOJAr8vHrJiGbCHruWdY+5+6IVH7As/1t37psgFgWJ +5Ikvi+glV8yQckQaV/MRuIMoKAS2Kc/eLLH32uLkTOFIG1j40lXH4DGuFFuZddbH +Ie2TsgUmI3LXTSGSq4qSgXyB46uGuGOn4WKIAKp7O4kN2jBB5y3q9C2YltQ+Dv+k +T64wBNK3ZnHHNKli0A86kzPLVQJfHgjzC76QRlC+guKgRoV9Kut3LLfoi6ep5yJr +RT6Pr/hTNKCluIZUTPhmB0u3xGr9gj6vDsMCanvrsQKBgQD5y7ZJqFvgh9MlhSLN +20p7jlyu+cYSDWktUjA4109ior8oaCVUXziSuPsr9JfwYRaYsJTUpCYKECFYLibA +qI+Jj/auJljuCmrfWuS9Z08sAmVoU+O4FZt2UVbui5l5spU41Ze09f81DpzkHhZ0 +SEVH2SgChdy7KdPPhxcVhJHqJQKBgQDciwameP0WaazTY77ZRE4Yt+dPyPFkpSer +bibeMmss5d+QVo4B4YEL20CrmaJq+FB9u99nL1d6VsvtWuovvHKMmoM//D8Si7PW +ieAm9mN0L+2Xf25UVFBewQkzNuJJG+z1OtHFfIDDGnNzL2yx//3YFJnR/ehftsK7 +lIlXUElzzwKBgGUW1cx1P8lb7k0u1ejtJ/VcpZGCL3A60SewLSezqsLGDgoyK3k7 +l8944Nzm/V4gTF66h2COlX5ZDMV819372SrYggH0LuUWfi2pwQwNdPLgfV19JZjn +1aRKQp4DDLc9WDpJ5j0rmH5GTaPbsUaZwL/U1+Y9ehicUsWXa/YfUlWpAoGBAJCZ +7yBTj82UOCbZ7ZZS/MmkOtvLKssMpnf2XzGs6SylA/KFbdK54ny9oydgMmfkrBHk +jtP+7GJgapET3RyzeH/MB2Z6o3grdRyjhf7F6euSSTvd558PMSsPclLMF45L6w/X +IxdTTLGftDa/z4reB7gXucs/qY6oLAIFoA9Jqv9tAoGAIpw4GDw5IQFZhcHuHCOZ +Xrq9L1fR5rYBQa6xcPHkMbWzigcNJz7FnLg0tB1SvF23egpmj5VAcnWyjyj883pn +h2wuwJUFy8LALtjJwqhjUtQfv5LLiT5061/CUrhD3GEBNlYbOO4FA1Z0SIhFYn40 +VzowmHAqdxYvlfJsWe91UI0= +-----END PRIVATE KEY----- +''; + }; + tubID = "rr7y46ixsg6qmck4jkkc7hke6xe4sv5f"; + swissnum = "2k6p3wrabat5jrj7otcih4cjdema4q3m"; + introducerPort = 35151; + location = "tcp:introducer:${toString introducerPort}"; + introducerFURL = "pb://${tubID}@${location}/${swissnum}"; + introducerFURLFile = pkgs.writeTextFile { + name = "introducer.furl"; + text = introducerFURL; + }; +in # https://nixos.org/nixos/manual/index.html#sec-nixos-tests import <nixpkgs/nixos/tests/make-test.nix> { - # Configure a single machine as a PrivateStorage storage node. - machine = - { config, pkgs, ... }: - { imports = - [ ../private-storage.nix - ]; - services.private-storage.enable = true; - }; + nodes = rec { + # Get a machine where we can run a Tahoe-LAFS client node. + client = + { config, pkgs, ... }: + { environment.systemPackages = [ + pkgs.tahoe-lafs + pkgs.daemonize + ]; + }; + + # Get another machine where we can run a Tahoe-LAFS introducer node. It has the same configuration as the client. + introducer = client; + + # Configure a single machine as a PrivateStorage storage node. + storage = + { config, pkgs, ... }: + { imports = + [ ../private-storage.nix + ]; + services.private-storage.enable = true; + services.private-storage.publicIPv4 = "storage"; + services.private-storage.introducerFURL = introducerFURL; + }; + }; # Test the machine with a Perl program (sobbing). testScript = '' - # Boot the VM. - $machine->start; + # + # Set up a Tahoe-LAFS introducer. + # + $introducer->start; + $introducer->succeed('tahoe create-introducer --hostname introducer /tmp/introducer'); + $introducer->copyFileFromHost('${pemFile}', '/tmp/introducer/private/node.pem'); + $introducer->copyFileFromHost('${introducerFURLFile}', '/tmp/introducer/private/introducer.furl'); + $introducer->succeed('daemonize $(type -p tahoe) run /tmp/introducer'); + $introducer->waitForOpenPort(${toString introducerPort}); + + # + # Get a Tahoe-LAFS storage server up. + # + + # Boot the storage VM. + $storage->start; # The systemd unit should reach the running state. - $machine->waitForUnit("tahoe.storage.service"); + $storage->waitForUnit('tahoe.storage.service'); # Some while after that the Tahoe-LAFS node should listen on the web API # port. The port number here has to agree with the port number set in # the private-storage.nix module. - $machine->waitForOpenPort(3456); + $storage->waitForOpenPort(3456); # Once the web API is listening it should be possible to scrape some # status from the node if it is really working. - $machine->succeed("tahoe -d /var/db/tahoe-lafs/storage status"); + $storage->succeed('tahoe -d /var/db/tahoe-lafs/storage status'); + + # + # Storage appears to be working so try to get a client to speak with it. + # + + # Boot another VM. + $client->start; + + # Create a Tahoe-LAFS client on it. + $client->succeed('tahoe create-client --shares-needed 1 --shares-happy 1 --shares-total 1 --introducer ${introducerFURL}'); ''; }