2015-08-14 06:05:03 +01:00
|
|
|
{ config, pkgs, lib, ... }:
|
|
|
|
|
|
|
|
with lib;
|
|
|
|
|
|
|
|
let
|
|
|
|
|
|
|
|
cfg = config.services.netatalk;
|
|
|
|
|
|
|
|
extmapFile = pkgs.writeText "extmap.conf" cfg.extmap;
|
|
|
|
|
|
|
|
afpToString = x: if builtins.typeOf x == "bool"
|
2017-04-11 17:08:51 +01:00
|
|
|
then boolToString x
|
2015-08-14 06:05:03 +01:00
|
|
|
else toString x;
|
|
|
|
|
|
|
|
volumeConfig = name:
|
|
|
|
let vol = getAttr name cfg.volumes; in
|
|
|
|
"[${name}]\n " + (toString (
|
|
|
|
map
|
|
|
|
(key: "${key} = ${afpToString (getAttr key vol)}\n")
|
|
|
|
(attrNames vol)
|
|
|
|
));
|
|
|
|
|
|
|
|
afpConf = ''[Global]
|
|
|
|
extmap file = ${extmapFile}
|
|
|
|
afp port = ${toString cfg.port}
|
|
|
|
|
|
|
|
${cfg.extraConfig}
|
|
|
|
|
|
|
|
${if cfg.homes.enable then ''[Homes]
|
|
|
|
${optionalString (cfg.homes.path != "") "path = ${cfg.homes.path}"}
|
|
|
|
basedir regex = ${cfg.homes.basedirRegex}
|
|
|
|
${cfg.homes.extraConfig}
|
|
|
|
'' else ""}
|
|
|
|
|
|
|
|
${toString (map volumeConfig (attrNames cfg.volumes))}
|
|
|
|
'';
|
|
|
|
|
|
|
|
afpConfFile = pkgs.writeText "afp.conf" afpConf;
|
|
|
|
|
|
|
|
in
|
|
|
|
|
|
|
|
{
|
|
|
|
options = {
|
|
|
|
services.netatalk = {
|
|
|
|
|
2020-04-20 19:05:26 +01:00
|
|
|
enable = mkEnableOption "the Netatalk AFP fileserver";
|
2015-08-14 06:05:03 +01:00
|
|
|
|
|
|
|
port = mkOption {
|
2021-01-31 10:31:24 +00:00
|
|
|
type = types.port;
|
2015-08-14 06:05:03 +01:00
|
|
|
default = 548;
|
|
|
|
description = "TCP port to be used for AFP.";
|
|
|
|
};
|
|
|
|
|
|
|
|
extraConfig = mkOption {
|
|
|
|
type = types.lines;
|
|
|
|
default = "";
|
|
|
|
example = "uam list = uams_guest.so";
|
|
|
|
description = ''
|
|
|
|
Lines of configuration to add to the <literal>[Global]</literal> section.
|
|
|
|
See <literal>man apf.conf</literal> for more information.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
homes = {
|
|
|
|
enable = mkOption {
|
2020-04-20 19:05:26 +01:00
|
|
|
type = types.bool;
|
2015-08-14 06:05:03 +01:00
|
|
|
default = false;
|
|
|
|
description = "Enable sharing of the UNIX server user home directories.";
|
|
|
|
};
|
|
|
|
|
|
|
|
path = mkOption {
|
2021-01-31 10:31:24 +00:00
|
|
|
type = types.str;
|
2015-08-14 06:05:03 +01:00
|
|
|
default = "";
|
|
|
|
example = "afp-data";
|
|
|
|
description = "Share not the whole user home but this subdirectory path.";
|
|
|
|
};
|
|
|
|
|
|
|
|
basedirRegex = mkOption {
|
|
|
|
example = "/home";
|
2021-01-31 10:31:24 +00:00
|
|
|
type = types.str;
|
2015-08-14 06:05:03 +01:00
|
|
|
description = "Regex which matches the parent directory of the user homes.";
|
|
|
|
};
|
|
|
|
|
|
|
|
extraConfig = mkOption {
|
|
|
|
type = types.lines;
|
|
|
|
default = "";
|
|
|
|
description = ''
|
|
|
|
Lines of configuration to add to the <literal>[Homes]</literal> section.
|
|
|
|
See <literal>man apf.conf</literal> for more information.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
volumes = mkOption {
|
|
|
|
default = { };
|
|
|
|
type = types.attrsOf (types.attrsOf types.unspecified);
|
|
|
|
description =
|
|
|
|
''
|
|
|
|
Set of AFP volumes to export.
|
|
|
|
See <literal>man apf.conf</literal> for more information.
|
|
|
|
'';
|
2020-04-02 06:39:04 +01:00
|
|
|
example = literalExample ''
|
2015-08-14 06:05:03 +01:00
|
|
|
{ srv =
|
|
|
|
{ path = "/srv";
|
|
|
|
"read only" = true;
|
|
|
|
"hosts allow" = "10.1.0.0/16 10.2.1.100 2001:0db8:1234::/48";
|
|
|
|
};
|
2020-04-02 06:39:04 +01:00
|
|
|
}
|
|
|
|
'';
|
2015-08-14 06:05:03 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
extmap = mkOption {
|
|
|
|
type = types.lines;
|
2020-11-22 07:23:53 +00:00
|
|
|
default = "";
|
|
|
|
description = ''
|
|
|
|
File name extension mappings.
|
|
|
|
See <literal>man extmap.conf</literal> for more information.
|
2015-08-14 06:05:03 +01:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
config = mkIf cfg.enable {
|
|
|
|
|
|
|
|
systemd.services.netatalk = {
|
|
|
|
description = "Netatalk AFP fileserver for Macintosh clients";
|
|
|
|
unitConfig.Documentation = "man:afp.conf(5) man:netatalk(8) man:afpd(8) man:cnid_metad(8) man:cnid_dbd(8)";
|
|
|
|
after = [ "network.target" "avahi-daemon.service" ];
|
|
|
|
wantedBy = [ "multi-user.target" ];
|
|
|
|
|
|
|
|
path = [ pkgs.netatalk ];
|
|
|
|
|
|
|
|
serviceConfig = {
|
|
|
|
Type = "forking";
|
|
|
|
GuessMainPID = "no";
|
|
|
|
PIDFile = "/run/lock/netatalk";
|
2020-11-22 07:23:53 +00:00
|
|
|
ExecStartPre = "${pkgs.coreutils}/bin/mkdir -m 0755 -p /var/lib/netatalk/CNID";
|
2015-08-14 06:05:03 +01:00
|
|
|
ExecStart = "${pkgs.netatalk}/sbin/netatalk -F ${afpConfFile}";
|
|
|
|
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
|
2020-11-22 07:23:53 +00:00
|
|
|
ExecStop = "${pkgs.coreutils}/bin/kill -TERM $MAINPID";
|
2015-08-14 06:05:03 +01:00
|
|
|
Restart = "always";
|
|
|
|
RestartSec = 1;
|
|
|
|
};
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
security.pam.services.netatalk.unixAuth = true;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|