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; \ +