1{
2 config,
3 lib,
4 pkgs,
5 ...
6}:
7let
8
9 cfg = config.services.nfs.server;
10
11 exports = pkgs.writeText "exports" cfg.exports;
12
13in
14
15{
16 imports = [
17 (lib.mkRenamedOptionModule
18 [ "services" "nfs" "lockdPort" ]
19 [ "services" "nfs" "server" "lockdPort" ]
20 )
21 (lib.mkRenamedOptionModule
22 [ "services" "nfs" "statdPort" ]
23 [ "services" "nfs" "server" "statdPort" ]
24 )
25 ];
26
27 ###### interface
28
29 options = {
30
31 services.nfs = {
32
33 server = {
34 enable = lib.mkOption {
35 type = lib.types.bool;
36 default = false;
37 description = ''
38 Whether to enable the kernel's NFS server.
39 '';
40 };
41
42 extraNfsdConfig = lib.mkOption {
43 type = lib.types.str;
44 default = "";
45 description = ''
46 Extra configuration options for the [nfsd] section of /etc/nfs.conf.
47 '';
48 };
49
50 exports = lib.mkOption {
51 type = lib.types.lines;
52 default = "";
53 description = ''
54 Contents of the /etc/exports file. See
55 {manpage}`exports(5)` for the format.
56 '';
57 };
58
59 hostName = lib.mkOption {
60 type = lib.types.nullOr lib.types.str;
61 default = null;
62 description = ''
63 Hostname or address on which NFS requests will be accepted.
64 Default is all. See the {option}`-H` option in
65 {manpage}`nfsd(8)`.
66 '';
67 };
68
69 nproc = lib.mkOption {
70 type = lib.types.int;
71 default = 8;
72 description = ''
73 Number of NFS server threads. Defaults to the recommended value of 8.
74 '';
75 };
76
77 createMountPoints = lib.mkOption {
78 type = lib.types.bool;
79 default = false;
80 description = "Whether to create the mount points in the exports file at startup time.";
81 };
82
83 mountdPort = lib.mkOption {
84 type = lib.types.nullOr lib.types.int;
85 default = null;
86 example = 4002;
87 description = ''
88 Use fixed port for rpc.mountd, useful if server is behind firewall.
89 '';
90 };
91
92 lockdPort = lib.mkOption {
93 type = lib.types.nullOr lib.types.int;
94 default = null;
95 example = 4001;
96 description = ''
97 Use a fixed port for the NFS lock manager kernel module
98 (`lockd/nlockmgr`). This is useful if the
99 NFS server is behind a firewall.
100 '';
101 };
102
103 statdPort = lib.mkOption {
104 type = lib.types.nullOr lib.types.int;
105 default = null;
106 example = 4000;
107 description = ''
108 Use a fixed port for {command}`rpc.statd`. This is
109 useful if the NFS server is behind a firewall.
110 '';
111 };
112
113 };
114
115 };
116
117 };
118
119 ###### implementation
120
121 config = lib.mkIf cfg.enable {
122
123 services.rpcbind.enable = true;
124
125 boot.supportedFilesystems = [ "nfs" ]; # needed for statd and idmapd
126
127 environment.etc.exports.source = exports;
128
129 systemd.services.nfs-server = {
130 enable = true;
131 wantedBy = [ "multi-user.target" ];
132
133 preStart = ''
134 mkdir -p /var/lib/nfs/v4recovery
135 '';
136 };
137
138 systemd.services.nfs-mountd = {
139 enable = true;
140 restartTriggers = [ exports ];
141
142 preStart = ''
143 mkdir -p /var/lib/nfs
144
145 ${lib.optionalString cfg.createMountPoints ''
146 # create export directories:
147 # skip comments, take first col which may either be a quoted
148 # "foo bar" or just foo (-> man export)
149 sed '/^#.*/d;s/^"\([^"]*\)".*/\1/;t;s/[ ].*//' ${exports} \
150 | xargs -d '\n' mkdir -p
151 ''}
152 '';
153 };
154
155 };
156
157}