diff --git a/modules/module-list.nix b/modules/module-list.nix index 50f1bea75398..b2d94cff50d0 100644 --- a/modules/module-list.nix +++ b/modules/module-list.nix @@ -105,7 +105,7 @@ ./services/monitoring/zabbix-agent.nix ./services/monitoring/zabbix-server.nix ./services/network-filesystems/drbd.nix - ./services/network-filesystems/nfs-kernel.nix + ./services/network-filesystems/nfsd.nix ./services/network-filesystems/openafs-client/default.nix ./services/network-filesystems/samba.nix ./services/networking/amuled.nix diff --git a/modules/services/network-filesystems/nfs-kernel.nix b/modules/services/network-filesystems/nfs-kernel.nix deleted file mode 100644 index ccf147e2f4fc..000000000000 --- a/modules/services/network-filesystems/nfs-kernel.nix +++ /dev/null @@ -1,182 +0,0 @@ -{ config, pkgs, ... }: - -with pkgs.lib; - -let - - inherit (pkgs) writeText openssh; - - cfg = config.services.nfsKernel; - - exports = pkgs.writeText "exports" cfg.server.exports; - -in - -{ - - ###### interface - - options = { - - services.nfsKernel = { - - client.enable = mkOption { - default = any (fs: fs.fsType == "nfs" || fs.fsType == "nfs4") config.fileSystems; - description = '' - Whether to enable the kernel's NFS client daemons. - ''; - }; - - server = { - enable = mkOption { - default = false; - description = '' - Whether to enable the kernel's NFS server. - ''; - }; - - exports = mkOption { - default = ""; - description = '' - Contents of the /etc/exports file. See - exports - 5 for the format. - ''; - }; - - hostName = mkOption { - default = null; - description = '' - Hostname or address on which NFS requests will be accepted. - Default is all. See the option in - nfsd - 8. - ''; - }; - - nproc = mkOption { - default = 8; - description = '' - Number of NFS server threads. Defaults to the recommended value of 8. - ''; - }; - - createMountPoints = mkOption { - default = false; - description = "Whether to create the mount points in the exports file at startup time."; - }; - }; - - }; - - }; - - - ###### implementation - - config = { - - services.portmap.enable = cfg.client.enable || cfg.server.enable; - - environment.systemPackages = mkIf cfg.server.enable [ pkgs.nfsUtils ]; - - environment.etc = mkIf cfg.server.enable (singleton - { source = exports; - target = "exports"; - }); - - boot.kernelModules = mkIf cfg.server.enable [ "nfsd" ]; - - jobs = - optionalAttrs cfg.server.enable - { nfsd = - { description = "Kernel NFS server"; - - startOn = "started networking"; - - path = [ pkgs.nfsUtils ]; - - preStart = - '' - start portmap || true - start mountd || true - - # Create a state directory required by NFSv4. - mkdir -p /var/lib/nfs/v4recovery - - rpc.nfsd \ - ${if cfg.server.hostName != null then "-H ${cfg.server.hostName}" else ""} \ - ${builtins.toString cfg.server.nproc} - ''; - - postStop = "rpc.nfsd 0"; - - postStart = - '' - start statd || true - ''; - }; - } - - // optionalAttrs cfg.server.enable - { mountd = - { description = "Kernel NFS server - mount daemon"; - - path = [ pkgs.nfsUtils pkgs.sysvtools pkgs.utillinux ]; - - preStart = - '' - start portmap || true - - mkdir -p /var/lib/nfs - touch /var/lib/nfs/rmtab - - mountpoint -q /proc/fs/nfsd || mount -t nfsd none /proc/fs/nfsd - - ${optionalString cfg.server.createMountPoints - '' - # create export directories: - # skip comments, take first col which may either be a quoted - # "foo bar" or just foo (-> man export) - sed '/^#.*/d;s/^"\([^"]*\)".*/\1/;t;s/[ ].*//' ${exports} \ - | xargs -d '\n' mkdir -p - '' - } - - # exports file is ${exports} - # keep this comment so that this job is restarted whenever exports changes! - exportfs -ra - ''; - - daemonType = "fork"; - - exec = "rpc.mountd -f /etc/exports"; - }; - } - - // optionalAttrs (cfg.client.enable || cfg.server.enable) - { statd = - { description = "Kernel NFS server - Network Status Monitor"; - - path = [ pkgs.nfsUtils pkgs.sysvtools pkgs.utillinux ]; - - stopOn = "never"; # needed during shutdown - - preStart = - '' - start portmap || true - mkdir -p /var/lib/nfs - mkdir -p /var/lib/nfs/sm - mkdir -p /var/lib/nfs/sm.bak - sm-notify -d - ''; - - daemonType = "fork"; - - exec = "rpc.statd --no-notify"; - }; - }; - - }; - -} diff --git a/modules/services/network-filesystems/nfsd.nix b/modules/services/network-filesystems/nfsd.nix new file mode 100644 index 000000000000..f5366bcbc00b --- /dev/null +++ b/modules/services/network-filesystems/nfsd.nix @@ -0,0 +1,147 @@ +{ config, pkgs, ... }: + +with pkgs.lib; + +let + + cfg = config.services.nfs.server; + + exports = pkgs.writeText "exports" cfg.exports; + +in + +{ + + ###### interface + + options = { + + services.nfs = { + + server = { + enable = mkOption { + default = false; + description = '' + Whether to enable the kernel's NFS server. + ''; + }; + + exports = mkOption { + default = ""; + description = '' + Contents of the /etc/exports file. See + exports + 5 for the format. + ''; + }; + + hostName = mkOption { + default = null; + description = '' + Hostname or address on which NFS requests will be accepted. + Default is all. See the option in + nfsd + 8. + ''; + }; + + nproc = mkOption { + default = 8; + description = '' + Number of NFS server threads. Defaults to the recommended value of 8. + ''; + }; + + createMountPoints = mkOption { + default = false; + description = "Whether to create the mount points in the exports file at startup time."; + }; + }; + + }; + + }; + + + ###### implementation + + config = mkIf cfg.enable { + + services.portmap.enable = true; + + services.nfs.client.enable = true; # needed for statd + + environment.systemPackages = [ pkgs.nfsUtils ]; + + environment.etc = singleton + { source = exports; + target = "exports"; + }; + + boot.kernelModules = [ "nfsd" ]; + + jobs.nfsd = + { description = "Kernel NFS server"; + + startOn = "started networking"; + + path = [ pkgs.nfsUtils ]; + + preStart = + '' + start portmap || true + start mountd || true + + # Create a state directory required by NFSv4. + mkdir -p /var/lib/nfs/v4recovery + + rpc.nfsd \ + ${if cfg.hostName != null then "-H ${cfg.hostName}" else ""} \ + ${builtins.toString cfg.nproc} + ''; + + postStop = "rpc.nfsd 0"; + + postStart = + '' + start statd || true + ''; + }; + + jobs.mountd = + { description = "Kernel NFS server - mount daemon"; + + path = [ pkgs.nfsUtils pkgs.sysvtools pkgs.utillinux ]; + + preStart = + '' + start portmap || true + + mkdir -p /var/lib/nfs + touch /var/lib/nfs/rmtab + + mountpoint -q /proc/fs/nfsd || mount -t nfsd none /proc/fs/nfsd + + ${optionalString cfg.createMountPoints + '' + # create export directories: + # skip comments, take first col which may either be a quoted + # "foo bar" or just foo (-> man export) + sed '/^#.*/d;s/^"\([^"]*\)".*/\1/;t;s/[ ].*//' ${exports} \ + | xargs -d '\n' mkdir -p + '' + } + + # exports file is ${exports} + # keep this comment so that this job is restarted whenever exports changes! + exportfs -ra + ''; + + daemonType = "fork"; + + exec = "rpc.mountd -f /etc/exports"; + }; + + }; + +} diff --git a/modules/tasks/filesystems.nix b/modules/tasks/filesystems.nix index 39ccaeee2094..529c25e17742 100644 --- a/modules/tasks/filesystems.nix +++ b/modules/tasks/filesystems.nix @@ -183,7 +183,7 @@ in # Ensure that this job is restarted when fstab changed: # ${fstab} - ${optionalString config.services.nfsKernel.client.enable '' + ${optionalString config.services.nfs.client.enable '' start statd || true ''} @@ -196,9 +196,8 @@ in # The `mount-failed' event is emitted synchronously, but we don't # want `mountall' to wait for the emergency shell. So use this # intermediate job to make the event asynchronous. - jobs.mount_failed = - { name = "mount-failed"; - task = true; + jobs."mount-failed" = + { task = true; startOn = "mount-failed"; script = '' @@ -210,9 +209,8 @@ in # On an `ip-up' event, notify mountall so that it retries mounting # remote filesystems. - jobs.mountall_ip_up = + jobs."mountall-ip-up" = { - name = "mountall-ip-up"; task = true; startOn = "ip-up"; script = @@ -221,10 +219,8 @@ in ''; }; - jobs.emergency_shell = - { name = "emergency-shell"; - - task = true; + jobs."emergency-shell" = + { task = true; extraConfig = "console owner"; diff --git a/modules/tasks/filesystems/nfs.nix b/modules/tasks/filesystems/nfs.nix index 546b63687211..c41eb02f398a 100644 --- a/modules/tasks/filesystems/nfs.nix +++ b/modules/tasks/filesystems/nfs.nix @@ -9,8 +9,27 @@ let in { - config = { + ###### interface + + options = { + + services.nfs.client.enable = mkOption { + default = any (fs: fs.fsType == "nfs" || fs.fsType == "nfs4") config.fileSystems; + description = '' + Whether to enable support for mounting NFS filesystems. + ''; + }; + + }; + + + ###### implementation + + config = mkIf config.services.nfs.client.enable { + + services.portmap.enable = true; + system.fsPackages = [ pkgs.nfsUtils ]; boot.initrd.kernelModules = mkIf inInitrd [ "nfs" ]; @@ -21,5 +40,26 @@ in cp -v ${pkgs.klibc}/lib/klibc/bin.static/nfsmount $out/bin ''; + jobs.statd = + { description = "Kernel NFS server - Network Status Monitor"; + + path = [ pkgs.nfsUtils pkgs.sysvtools pkgs.utillinux ]; + + stopOn = "never"; # needed during shutdown + + preStart = + '' + start portmap || true + mkdir -p /var/lib/nfs + mkdir -p /var/lib/nfs/sm + mkdir -p /var/lib/nfs/sm.bak + sm-notify -d + ''; + + daemonType = "fork"; + + exec = "rpc.statd --no-notify"; + }; + }; } diff --git a/tests/check-filesystems.nix b/tests/check-filesystems.nix index ba2bf352ec86..ed4b365b901f 100644 --- a/tests/check-filesystems.nix +++ b/tests/check-filesystems.nix @@ -8,14 +8,12 @@ with import ../lib/build-vms.nix { inherit nixos nixpkgs system; }; rec { nodes = { share = {pkgs, config, ...}: { - services.portmap.enable = true; - services.nfsKernel.client.enable = true; - services.nfsKernel.server.enable = true; - services.nfsKernel.server.exports = '' + services.nfs.server.enable = true; + services.nfs.server.exports = '' /repos1 192.168.1.0/255.255.255.0(rw,no_root_squash) /repos2 192.168.1.0/255.255.255.0(rw,no_root_squash) ''; - services.nfsKernel.server.createMountPoints = true; + services.nfs.server.createMountPoints = true; jobs.checkable = { startOn = [ @@ -27,22 +25,20 @@ rec { }; fsCheck = {pkgs, config, ...}: { - # enable nfs import - services.portmap.enable = true; - services.nfsKernel.client.enable = true; - fileSystems = let repos1 = { mountPoint = "/repos1"; autocreate = true; device = "share:/repos1"; + fsType = "nfs"; }; repos2 = { mountPoint = "/repos2"; autocreate = true; device = "share:/repos2"; + fsType = "nfs"; }; in pkgs.lib.mkOverrideTemplate 50 {} [ repos1 diff --git a/tests/nfs.nix b/tests/nfs.nix index 413578ec8ff8..7c1ff5e92122 100644 --- a/tests/nfs.nix +++ b/tests/nfs.nix @@ -23,12 +23,12 @@ in server = { config, pkgs, ... }: - { services.nfsKernel.server.enable = true; - services.nfsKernel.server.exports = + { services.nfs.server.enable = true; + services.nfs.server.exports = '' /data 192.168.1.0/255.255.255.0(rw,no_root_squash) ''; - services.nfsKernel.server.createMountPoints = true; + services.nfs.server.createMountPoints = true; }; }; diff --git a/tests/trac.nix b/tests/trac.nix index e13c0f157520..254996c24407 100644 --- a/tests/trac.nix +++ b/tests/trac.nix @@ -5,12 +5,11 @@ storage = {pkgs, config, ...}: { - services.portmap.enable = true; - services.nfsKernel.server.enable = true; - services.nfsKernel.server.exports = '' + services.nfs.server.enable = true; + services.nfs.server.exports = '' /repos 192.168.1.0/255.255.255.0(rw,no_root_squash) ''; - services.nfsKernel.server.createMountPoints = true; + services.nfs.server.createMountPoints = true; }; postgresql = @@ -35,11 +34,10 @@ [ { mountPoint = "/repos"; device = "storage:/repos"; fsType = "nfs"; - options = "bootwait"; } + options = "bootwait"; + } ]; - services.portmap.enable = true; - services.nfsKernel.client.enable = true; services.httpd.enable = true; services.httpd.adminAddr = "root@localhost"; services.httpd.extraSubservices = [ { serviceType = "trac"; } ];