diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index 30e716c2ef4b..585da96c32e0 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -275,6 +275,7 @@
./services/monitoring/zabbix-agent.nix
./services/monitoring/zabbix-server.nix
./services/network-filesystems/drbd.nix
+ ./services/network-filesystems/netatalk.nix
./services/network-filesystems/nfsd.nix
./services/network-filesystems/openafs-client/default.nix
./services/network-filesystems/rsyncd.nix
diff --git a/nixos/modules/services/network-filesystems/netatalk.nix b/nixos/modules/services/network-filesystems/netatalk.nix
new file mode 100644
index 000000000000..bff54406a2b0
--- /dev/null
+++ b/nixos/modules/services/network-filesystems/netatalk.nix
@@ -0,0 +1,150 @@
+{ config, pkgs, lib, ... }:
+
+with lib;
+
+let
+
+ cfg = config.services.netatalk;
+
+ extmapFile = pkgs.writeText "extmap.conf" cfg.extmap;
+
+ afpToString = x: if builtins.typeOf x == "bool"
+ then (if x then "true" else "false")
+ 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 = {
+
+ enable = mkOption {
+ default = false;
+ description = "Whether to enable the Netatalk AFP fileserver.";
+ };
+
+ port = mkOption {
+ 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 [Global] section.
+ See man apf.conf for more information.
+ '';
+ };
+
+ homes = {
+ enable = mkOption {
+ default = false;
+ description = "Enable sharing of the UNIX server user home directories.";
+ };
+
+ path = mkOption {
+ default = "";
+ example = "afp-data";
+ description = "Share not the whole user home but this subdirectory path.";
+ };
+
+ basedirRegex = mkOption {
+ example = "/home";
+ 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 [Homes] section.
+ See man apf.conf for more information.
+ '';
+ };
+ };
+
+ volumes = mkOption {
+ default = { };
+ type = types.attrsOf (types.attrsOf types.unspecified);
+ description =
+ ''
+ Set of AFP volumes to export.
+ See man apf.conf for more information.
+ '';
+ example =
+ { srv =
+ { path = "/srv";
+ "read only" = true;
+ "hosts allow" = "10.1.0.0/16 10.2.1.100 2001:0db8:1234::/48";
+ };
+ };
+ };
+
+ extmap = mkOption {
+ type = types.lines;
+ default = "";
+ description = ''
+ File name extension mappings.
+ See man extmap.conf for more information.
+ '';
+ };
+
+ };
+ };
+
+ 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";
+ ExecStartPre = "${pkgs.coreutils}/bin/mkdir -m 0755 -p /var/lib/netatalk/CNID";
+ ExecStart = "${pkgs.netatalk}/sbin/netatalk -F ${afpConfFile}";
+ ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
+ ExecStop = "${pkgs.coreutils}/bin/kill -TERM $MAINPID";
+ Restart = "always";
+ RestartSec = 1;
+ };
+
+ };
+
+ security.pam.services.netatalk.unixAuth = true;
+
+ };
+
+}
diff --git a/pkgs/tools/filesystems/netatalk/default.nix b/pkgs/tools/filesystems/netatalk/default.nix
index d5a0cbbc4190..7e4ea032bb39 100644
--- a/pkgs/tools/filesystems/netatalk/default.nix
+++ b/pkgs/tools/filesystems/netatalk/default.nix
@@ -1,24 +1,28 @@
-{ fetchurl, stdenv, pkgconfig, db, libgcrypt, avahi, libiconv, pam, openssl }:
+{ fetchurl, stdenv, pkgconfig, db, libgcrypt, avahi, libiconv, pam, openssl, acl }:
-stdenv.mkDerivation rec {
- name = "netatalk-3.1.0";
+stdenv.mkDerivation rec{
+ name = "netatalk-3.1.7";
src = fetchurl {
url = "mirror://sourceforge/netatalk/netatalk/${name}.tar.bz2";
- sha256 = "1d8dc8ysslkis4yl1xab1w9p0pz7a1kg0i6fds4wxsp4fhb6wqhq";
+ sha256 = "0wf09fyqzza024qr1s26z5x7rsvh9zb4pv598gw7gm77wjcr6174";
};
- buildInputs = [ pkgconfig db libgcrypt avahi pam openssl libiconv ];
+ buildInputs = [ pkgconfig db libgcrypt avahi libiconv pam openssl acl ];
+
+ patches = ./omitLocalstatedirCreation.patch;
configureFlags = [
"--with-bdb=${db}"
"--with-openssl=${openssl}"
+ "--with-lockfile=/run/lock/netatalk"
+ "--localstatedir=/var/lib"
];
enableParallelBuild = true;
meta = {
- description = "Apple File Protocl Server";
+ description = "Apple Filing Protocol Server";
homepage = http://netatalk.sourceforge.net/;
license = stdenv.lib.licenses.gpl3;
platforms = stdenv.lib.platforms.linux;
diff --git a/pkgs/tools/filesystems/netatalk/omitLocalstatedirCreation.patch b/pkgs/tools/filesystems/netatalk/omitLocalstatedirCreation.patch
new file mode 100644
index 000000000000..d1a9dcb0b3bf
--- /dev/null
+++ b/pkgs/tools/filesystems/netatalk/omitLocalstatedirCreation.patch
@@ -0,0 +1,35 @@
+diff -ur netatalk-3.1.7-old/config/Makefile.in netatalk-3.1.7-new/config/Makefile.in
+--- netatalk-3.1.7-old/config/Makefile.in 2014-08-29 03:33:35.000000000 -0700
++++ netatalk-3.1.7-new/config/Makefile.in 2015-08-13 20:52:35.000000000 -0700
+@@ -699,7 +699,7 @@
+
+ info-am:
+
+-install-data-am: install-data-local install-dbusserviceDATA
++install-data-am: install-dbusserviceDATA
+
+ install-dvi: install-dvi-recursive
+
+@@ -754,7 +754,7 @@
+ cscopelist cscopelist-recursive ctags ctags-recursive \
+ distclean distclean-generic distclean-libtool distclean-tags \
+ distdir dvi dvi-am html html-am info info-am install \
+- install-am install-data install-data-am install-data-local \
++ install-am install-data install-data-am \
+ install-dbusserviceDATA install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-man install-pdf \
+@@ -782,12 +782,6 @@
+ # install configuration files
+ #
+
+-install-data-local: install-config-files
+- mkdir -pm 0755 $(DESTDIR)$(localstatedir)/netatalk/
+- mkdir -pm 0755 $(DESTDIR)$(localstatedir)/netatalk/CNID/
+- $(INSTALL_DATA) $(srcdir)/README $(DESTDIR)$(localstatedir)/netatalk/
+- $(INSTALL_DATA) $(srcdir)/README $(DESTDIR)$(localstatedir)/netatalk/CNID/
+-
+ uninstall-local:
+ @for f in $(CONFFILES) $(GENFILES); do \
+ echo rm -f $(DESTDIR)$(pkgconfdir)/$$f; \
+