summary refs log tree commit diff
path: root/nixos/modules/services
diff options
context:
space:
mode:
authorCorbin <cds@corbinsimpson.com>2016-03-22 23:40:35 -0700
committerCorbin <cds@corbinsimpson.com>2016-03-31 14:01:09 -0700
commite3e563330798723a8991f0d7011e5c1b74a36e5d (patch)
tree9c499a757fad78102438929ac5b1174ad22fc3a1 /nixos/modules/services
parent3f31284e9b0cf0a302797b546105728db18b04e9 (diff)
downloadnixlib-e3e563330798723a8991f0d7011e5c1b74a36e5d.tar
nixlib-e3e563330798723a8991f0d7011e5c1b74a36e5d.tar.gz
nixlib-e3e563330798723a8991f0d7011e5c1b74a36e5d.tar.bz2
nixlib-e3e563330798723a8991f0d7011e5c1b74a36e5d.tar.lz
nixlib-e3e563330798723a8991f0d7011e5c1b74a36e5d.tar.xz
nixlib-e3e563330798723a8991f0d7011e5c1b74a36e5d.tar.zst
nixlib-e3e563330798723a8991f0d7011e5c1b74a36e5d.zip
services: Add Tahoe-LAFS service.
Including systemd configuration and much of the standard storage node and
introducer configuration.
Diffstat (limited to 'nixos/modules/services')
-rw-r--r--nixos/modules/services/network-filesystems/tahoe.nix286
1 files changed, 286 insertions, 0 deletions
diff --git a/nixos/modules/services/network-filesystems/tahoe.nix b/nixos/modules/services/network-filesystems/tahoe.nix
new file mode 100644
index 000000000000..ab441339a560
--- /dev/null
+++ b/nixos/modules/services/network-filesystems/tahoe.nix
@@ -0,0 +1,286 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+let
+  cfg = config.services.tahoe;
+in
+  {
+    options.services.tahoe = {
+      introducers = mkOption {
+        default = {};
+        type = types.loaOf types.optionSet;
+        description = ''
+          The Tahoe introducers.
+        '';
+        options = {
+          nickname = mkOption {
+            type = types.str;
+            description = ''
+              The nickname of this Tahoe introducer.
+            '';
+          };
+          tub.port = mkOption {
+            default = 3458;
+            type = types.int;
+            description = ''
+              The port on which the introducer will listen.
+            '';
+          };
+          package = mkOption {
+            default = pkgs.tahoelafs;
+            defaultText = "pkgs.tahoelafs";
+            type = types.package;
+            example = literalExample "pkgs.tahoelafs";
+            description = ''
+              The package to use for the Tahoe LAFS daemon.
+            '';
+          };
+        };
+      };
+      nodes = mkOption {
+        default = {};
+        type = types.loaOf types.optionSet;
+        description = ''
+          The Tahoe nodes.
+        '';
+        options = {
+          nickname = mkOption {
+            type = types.str;
+            description = ''
+              The nickname of this Tahoe node.
+            '';
+          };
+          tub.port = mkOption {
+            default = 3457;
+            type = types.int;
+            description = ''
+              The port on which the tub will listen.
+
+              This is the correct setting to tweak if you want Tahoe's storage
+              system to listen on a different port.
+            '';
+          };
+          web.port = mkOption {
+            default = 3456;
+            type = types.int;
+            description = ''
+              The port on which the Web server will listen.
+
+              This is the correct setting to tweak if you want Tahoe's WUI to
+              listen on a different port.
+            '';
+          };
+          client.introducer = mkOption {
+            default = null;
+            type = types.nullOr types.str;
+            description = ''
+              The furl for a Tahoe introducer node.
+
+              Like all furls, keep this safe and don't share it.
+            '';
+          };
+          client.helper = mkOption {
+            default = null;
+            type = types.nullOr types.str;
+            description = ''
+              The furl for a Tahoe helper node.
+
+              Like all furls, keep this safe and don't share it.
+            '';
+          };
+          client.shares.needed = mkOption {
+            default = 3;
+            type = types.int;
+            description = ''
+              The number of shares required to reconstitute a file.
+            '';
+          };
+          client.shares.happy = mkOption {
+            default = 7;
+            type = types.int;
+            description = ''
+              The number of distinct storage nodes required to store
+              a file.
+            '';
+          };
+          client.shares.total = mkOption {
+            default = 10;
+            type = types.int;
+            description = ''
+              The number of shares required to store a file.
+            '';
+          };
+          storage.enable = mkEnableOption "storage service";
+          storage.reservedSpace = mkOption {
+            default = "1G";
+            type = types.str;
+            description = ''
+              The amount of filesystem space to not use for storage.
+            '';
+          };
+          helper.enable = mkEnableOption "helper service";
+          package = mkOption {
+            default = pkgs.tahoelafs;
+            defaultText = "pkgs.tahoelafs";
+            type = types.package;
+            example = literalExample "pkgs.tahoelafs";
+            description = ''
+              The package to use for the Tahoe LAFS daemon.
+            '';
+          };
+        };
+      };
+    };
+    config = mkMerge [
+      (mkIf (cfg.introducers != {}) {
+        environment = {
+          etc = flip mapAttrs' cfg.introducers (node: settings:
+            nameValuePair "tahoe-lafs/introducer-${node}.cfg" {
+              mode = "0444";
+              text = ''
+                # This configuration is generated by Nix. Edit at your own
+                # peril; here be dragons.
+
+                [node]
+                nickname = ${settings.nickname}
+                tub.port = ${toString settings.tub.port}
+              '';
+            });
+          # Actually require Tahoe, so that we will have it installed.
+          systemPackages = flip mapAttrsToList cfg.introducers (node: settings:
+            settings.package
+          );
+        };
+        # Open up the firewall.
+        # networking.firewall.allowedTCPPorts = flip mapAttrsToList cfg.introducers
+        #   (node: settings: settings.tub.port);
+        systemd.services = flip mapAttrs' cfg.introducers (node: settings:
+          let
+            pidfile = "/run/tahoe.introducer-${node}.pid";
+            # This is a directory, but it has no trailing slash. Tahoe commands
+            # get antsy when there's a trailing slash.
+            nodedir = "/var/db/tahoe-lafs/introducer-${node}";
+          in nameValuePair "tahoe.introducer-${node}" {
+            description = "Tahoe LAFS node ${node}";
+            wantedBy = [ "multi-user.target" ];
+            path = [ settings.package ];
+            restartTriggers = [
+              config.environment.etc."tahoe-lafs/introducer-${node}.cfg".source ];
+            serviceConfig = {
+              Type = "simple";
+              PIDFile = pidfile;
+            };
+            preStart = ''
+              if [ \! -d ${nodedir} ]; then
+                mkdir -p /var/db/tahoe-lafs
+                tahoe create-introducer ${nodedir}
+              fi
+
+              # Tahoe has created a predefined tahoe.cfg which we must now
+              # scribble over.
+              # XXX I thought that a symlink would work here, but it doesn't, so
+              # we must do this on every prestart. Fixes welcome.
+              # rm ${nodedir}/tahoe.cfg
+              # ln -s /etc/tahoe-lafs/introducer-${node}.cfg ${nodedir}/tahoe.cfg
+              cp /etc/tahoe-lafs/introducer-${node}.cfg ${nodedir}/tahoe.cfg
+            '';
+            # Believe it or not, Tahoe is very brittle about the order of
+            # arguments to $(tahoe start). The node directory must come first,
+            # and arguments which alter Twisted's behavior come afterwards.
+            script = ''
+              tahoe start ${nodedir} -n -l- --pidfile=${pidfile}
+            '';
+          });
+        users.extraUsers = flip mapAttrs' cfg.introducers (node: _:
+          nameValuePair "tahoe.introducer-${node}" {
+            description = "Tahoe node user for introducer ${node}";
+            isSystemUser = true;
+          });
+      })
+      (mkIf (cfg.nodes != {}) {
+        environment = {
+          etc = flip mapAttrs' cfg.nodes (node: settings:
+            nameValuePair "tahoe-lafs/${node}.cfg" {
+              mode = "0444";
+              text = ''
+                # This configuration is generated by Nix. Edit at your own
+                # peril; here be dragons.
+
+                [node]
+                nickname = ${settings.nickname}
+                tub.port = ${toString settings.tub.port}
+                # This is a Twisted endpoint. Twisted Web doesn't work on
+                # non-TCP. ~ C.
+                web.port = tcp:${toString settings.web.port}
+
+                [client]
+                ${optionalString (settings.client.introducer != null)
+                  "introducer.furl = ${settings.client.introducer}"}
+                ${optionalString (settings.client.helper != null)
+                  "helper.furl = ${settings.client.helper}"}
+
+                shares.needed = ${toString settings.client.shares.needed}
+                shares.happy = ${toString settings.client.shares.happy}
+                shares.total = ${toString settings.client.shares.total}
+
+                [storage]
+                enabled = ${if settings.storage.enable then "true" else "false"}
+                reserved_space = ${settings.storage.reservedSpace}
+
+                [helper]
+                enabled = ${if settings.helper.enable then "true" else "false"}
+              '';
+            });
+          # Actually require Tahoe, so that we will have it installed.
+          systemPackages = flip mapAttrsToList cfg.nodes (node: settings:
+            settings.package
+          );
+        };
+        # Open up the firewall.
+        # networking.firewall.allowedTCPPorts = flip mapAttrsToList cfg.nodes
+        #   (node: settings: settings.tub.port);
+        systemd.services = flip mapAttrs' cfg.nodes (node: settings:
+          let
+            pidfile = "/run/tahoe.${node}.pid";
+            # This is a directory, but it has no trailing slash. Tahoe commands
+            # get antsy when there's a trailing slash.
+            nodedir = "/var/db/tahoe-lafs/${node}";
+          in nameValuePair "tahoe.${node}" {
+            description = "Tahoe LAFS node ${node}";
+            wantedBy = [ "multi-user.target" ];
+            path = [ settings.package ];
+            restartTriggers = [
+              config.environment.etc."tahoe-lafs/${node}.cfg".source ];
+            serviceConfig = {
+              Type = "simple";
+              PIDFile = pidfile;
+            };
+            preStart = ''
+              if [ \! -d ${nodedir} ]; then
+                mkdir -p /var/db/tahoe-lafs
+                tahoe create-node ${nodedir}
+              fi
+
+              # Tahoe has created a predefined tahoe.cfg which we must now
+              # scribble over.
+              # XXX I thought that a symlink would work here, but it doesn't, so
+              # we must do this on every prestart. Fixes welcome.
+              # rm ${nodedir}/tahoe.cfg
+              # ln -s /etc/tahoe-lafs/${node}.cfg ${nodedir}/tahoe.cfg
+              cp /etc/tahoe-lafs/${node}.cfg ${nodedir}/tahoe.cfg
+            '';
+            # Believe it or not, Tahoe is very brittle about the order of
+            # arguments to $(tahoe start). The node directory must come first,
+            # and arguments which alter Twisted's behavior come afterwards.
+            script = ''
+              tahoe start ${nodedir} -n -l- --pidfile=${pidfile}
+            '';
+          });
+        users.extraUsers = flip mapAttrs' cfg.nodes (node: _:
+          nameValuePair "tahoe.${node}" {
+            description = "Tahoe node user for node ${node}";
+            isSystemUser = true;
+          });
+      })
+    ];
+  }