nixpkgs/nixos/modules/services/network-filesystems/tahoe.nix

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

351 lines
14 KiB
Nix
Raw Normal View History

{ config, lib, pkgs, ... }:
let
cfg = config.services.tahoe;
in
{
options.services.tahoe = {
introducers = lib.mkOption {
default = {};
type = with lib.types; attrsOf (submodule {
2016-09-11 09:02:15 +00:00
options = {
nickname = lib.mkOption {
type = lib.types.str;
2016-09-11 09:02:15 +00:00
description = ''
The nickname of this Tahoe introducer.
'';
};
tub.port = lib.mkOption {
2016-09-11 09:02:15 +00:00
default = 3458;
type = lib.types.port;
2016-09-11 09:02:15 +00:00
description = ''
The port on which the introducer will listen.
'';
};
tub.location = lib.mkOption {
2016-09-11 09:02:15 +00:00
default = null;
type = lib.types.nullOr lib.types.str;
2016-09-11 09:02:15 +00:00
description = ''
The external location that the introducer should listen on.
If specified, the port should be included.
'';
};
package = lib.mkPackageOption pkgs "tahoelafs" { };
2016-09-11 09:02:15 +00:00
};
});
description = ''
The Tahoe introducers.
'';
};
nodes = lib.mkOption {
default = {};
type = with lib.types; attrsOf (submodule {
2016-09-11 09:02:15 +00:00
options = {
nickname = lib.mkOption {
type = lib.types.str;
2016-09-11 09:02:15 +00:00
description = ''
The nickname of this Tahoe node.
'';
};
tub.port = lib.mkOption {
2016-09-11 09:02:15 +00:00
default = 3457;
type = lib.types.port;
2016-09-11 09:02:15 +00:00
description = ''
The port on which the tub will listen.
2016-09-11 09:02:15 +00:00
This is the correct setting to tweak if you want Tahoe's storage
system to listen on a different port.
'';
};
tub.location = lib.mkOption {
2016-09-11 09:02:15 +00:00
default = null;
type = lib.types.nullOr lib.types.str;
2016-09-11 09:02:15 +00:00
description = ''
The external location that the node should listen on.
2016-09-11 09:02:15 +00:00
This is the setting to tweak if there are multiple interfaces
and you want to alter which interface Tahoe is advertising.
2016-09-11 09:02:15 +00:00
If specified, the port should be included.
'';
};
web.port = lib.mkOption {
2016-09-11 09:02:15 +00:00
default = 3456;
type = lib.types.port;
2016-09-11 09:02:15 +00:00
description = ''
The port on which the Web server will listen.
2016-09-11 09:02:15 +00:00
This is the correct setting to tweak if you want Tahoe's WUI to
listen on a different port.
'';
};
client.introducer = lib.mkOption {
2016-09-11 09:02:15 +00:00
default = null;
type = lib.types.nullOr lib.types.str;
2016-09-11 09:02:15 +00:00
description = ''
The furl for a Tahoe introducer node.
2016-09-11 09:02:15 +00:00
Like all furls, keep this safe and don't share it.
'';
};
client.helper = lib.mkOption {
2016-09-11 09:02:15 +00:00
default = null;
type = lib.types.nullOr lib.types.str;
2016-09-11 09:02:15 +00:00
description = ''
The furl for a Tahoe helper node.
2016-09-11 09:02:15 +00:00
Like all furls, keep this safe and don't share it.
'';
};
client.shares.needed = lib.mkOption {
2016-09-11 09:02:15 +00:00
default = 3;
type = lib.types.int;
2016-09-11 09:02:15 +00:00
description = ''
The number of shares required to reconstitute a file.
'';
};
client.shares.happy = lib.mkOption {
2016-09-11 09:02:15 +00:00
default = 7;
type = lib.types.int;
2016-09-11 09:02:15 +00:00
description = ''
The number of distinct storage nodes required to store
a file.
'';
};
client.shares.total = lib.mkOption {
2016-09-11 09:02:15 +00:00
default = 10;
type = lib.types.int;
2016-09-11 09:02:15 +00:00
description = ''
The number of shares required to store a file.
'';
};
storage.enable = lib.mkEnableOption "storage service";
storage.reservedSpace = lib.mkOption {
2016-09-11 09:02:15 +00:00
default = "1G";
type = lib.types.str;
2016-09-11 09:02:15 +00:00
description = ''
The amount of filesystem space to not use for storage.
'';
};
helper.enable = lib.mkEnableOption "helper service";
sftpd.enable = lib.mkEnableOption "SFTP service";
sftpd.port = lib.mkOption {
2016-10-29 05:23:53 +00:00
default = null;
type = lib.types.nullOr lib.types.int;
2016-10-29 05:23:53 +00:00
description = ''
The port on which the SFTP server will listen.
This is the correct setting to tweak if you want Tahoe's SFTP
daemon to listen on a different port.
'';
};
sftpd.hostPublicKeyFile = lib.mkOption {
2016-10-29 05:23:53 +00:00
default = null;
type = lib.types.nullOr lib.types.path;
2016-10-29 05:23:53 +00:00
description = ''
Path to the SSH host public key.
'';
};
sftpd.hostPrivateKeyFile = lib.mkOption {
2016-10-29 05:23:53 +00:00
default = null;
type = lib.types.nullOr lib.types.path;
2016-10-29 05:23:53 +00:00
description = ''
Path to the SSH host private key.
'';
};
sftpd.accounts.file = lib.mkOption {
2016-10-29 05:23:53 +00:00
default = null;
type = lib.types.nullOr lib.types.path;
2016-10-29 05:23:53 +00:00
description = ''
Path to the accounts file.
'';
};
sftpd.accounts.url = lib.mkOption {
2016-10-29 05:23:53 +00:00
default = null;
type = lib.types.nullOr lib.types.str;
2016-10-29 05:23:53 +00:00
description = ''
URL of the accounts server.
'';
};
package = lib.mkPackageOption pkgs "tahoelafs" { };
};
2016-09-11 09:02:15 +00:00
});
description = ''
The Tahoe nodes.
'';
};
};
config = lib.mkMerge [
(lib.mkIf (cfg.introducers != {}) {
environment = {
etc = lib.flip lib.mapAttrs' cfg.introducers (node: settings:
lib.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}
${lib.optionalString (settings.tub.location != null)
"tub.location = ${settings.tub.location}"}
'';
});
# Actually require Tahoe, so that we will have it installed.
systemPackages = lib.flip lib.mapAttrsToList cfg.introducers (node: settings:
settings.package
);
};
# Open up the firewall.
# networking.firewall.allowedTCPPorts = lib.flip lib.mapAttrsToList cfg.introducers
# (node: settings: settings.tub.port);
systemd.services = lib.flip lib.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 lib.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;
# Believe it or not, Tahoe is very brittle about the order of
# arguments to $(tahoe run). The node directory must come first,
# and arguments which alter Twisted's behavior come afterwards.
ExecStart = ''
${settings.package}/bin/tahoe run ${lib.escapeShellArg nodedir} --pidfile=${lib.escapeShellArg pidfile}
'';
};
preStart = ''
if [ ! -d ${lib.escapeShellArg nodedir} ]; then
mkdir -p /var/db/tahoe-lafs
# See https://github.com/NixOS/nixpkgs/issues/25273
tahoe create-introducer \
--hostname="${config.networking.hostName}" \
${lib.escapeShellArg 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 ${lib.escapeShellArg nodedir}/tahoe.cfg
'';
});
users.users = lib.flip lib.mapAttrs' cfg.introducers (node: _:
lib.nameValuePair "tahoe.introducer-${node}" {
description = "Tahoe node user for introducer ${node}";
isSystemUser = true;
});
})
(lib.mkIf (cfg.nodes != {}) {
environment = {
etc = lib.flip lib.mapAttrs' cfg.nodes (node: settings:
lib.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}
${lib.optionalString (settings.tub.location != null)
"tub.location = ${settings.tub.location}"}
# This is a Twisted endpoint. Twisted Web doesn't work on
# non-TCP. ~ C.
web.port = tcp:${toString settings.web.port}
[client]
${lib.optionalString (settings.client.introducer != null)
"introducer.furl = ${settings.client.introducer}"}
${lib.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 = ${lib.boolToString settings.storage.enable}
reserved_space = ${settings.storage.reservedSpace}
[helper]
enabled = ${lib.boolToString settings.helper.enable}
2016-10-29 05:23:53 +00:00
[sftpd]
enabled = ${lib.boolToString settings.sftpd.enable}
${lib.optionalString (settings.sftpd.port != null)
2016-10-29 05:23:53 +00:00
"port = ${toString settings.sftpd.port}"}
${lib.optionalString (settings.sftpd.hostPublicKeyFile != null)
2016-10-29 05:23:53 +00:00
"host_pubkey_file = ${settings.sftpd.hostPublicKeyFile}"}
${lib.optionalString (settings.sftpd.hostPrivateKeyFile != null)
2016-10-29 05:23:53 +00:00
"host_privkey_file = ${settings.sftpd.hostPrivateKeyFile}"}
${lib.optionalString (settings.sftpd.accounts.file != null)
2016-10-29 05:23:53 +00:00
"accounts.file = ${settings.sftpd.accounts.file}"}
${lib.optionalString (settings.sftpd.accounts.url != null)
2016-10-29 05:23:53 +00:00
"accounts.url = ${settings.sftpd.accounts.url}"}
'';
});
# Actually require Tahoe, so that we will have it installed.
systemPackages = lib.flip lib.mapAttrsToList cfg.nodes (node: settings:
settings.package
);
};
# Open up the firewall.
# networking.firewall.allowedTCPPorts = lib.flip lib.mapAttrsToList cfg.nodes
# (node: settings: settings.tub.port);
systemd.services = lib.flip lib.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 lib.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;
# Believe it or not, Tahoe is very brittle about the order of
# arguments to $(tahoe run). The node directory must come first,
# and arguments which alter Twisted's behavior come afterwards.
ExecStart = ''
${settings.package}/bin/tahoe run ${lib.escapeShellArg nodedir} --pidfile=${lib.escapeShellArg pidfile}
'';
};
preStart = ''
if [ ! -d ${lib.escapeShellArg nodedir} ]; then
mkdir -p /var/db/tahoe-lafs
tahoe create-node --hostname=localhost ${lib.escapeShellArg 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/${lib.escapeShellArg node}.cfg ${nodedir}/tahoe.cfg
cp /etc/tahoe-lafs/${lib.escapeShellArg node}.cfg ${lib.escapeShellArg nodedir}/tahoe.cfg
'';
});
users.users = lib.flip lib.mapAttrs' cfg.nodes (node: _:
lib.nameValuePair "tahoe.${node}" {
description = "Tahoe node user for node ${node}";
isSystemUser = true;
});
})
];
}