1{
2 config,
3 lib,
4 pkgs,
5 ...
6}:
7let
8 cfg = config.services.diod;
9
10 diodBool = b: if b then "1" else "0";
11
12 diodConfig = pkgs.writeText "diod.conf" ''
13 allsquash = ${diodBool cfg.allsquash}
14 auth_required = ${diodBool cfg.authRequired}
15 exportall = ${diodBool cfg.exportall}
16 exportopts = "${lib.concatStringsSep "," cfg.exportopts}"
17 exports = { ${lib.concatStringsSep ", " (map (s: ''"${s}"'') cfg.exports)} }
18 listen = { ${lib.concatStringsSep ", " (map (s: ''"${s}"'') cfg.listen)} }
19 logdest = "${cfg.logdest}"
20 nwthreads = ${toString cfg.nwthreads}
21 squashuser = "${cfg.squashuser}"
22 statfs_passthru = ${diodBool cfg.statfsPassthru}
23 userdb = ${diodBool cfg.userdb}
24 ${cfg.extraConfig}
25 '';
26in
27{
28 options = {
29 services.diod = {
30 enable = lib.mkOption {
31 type = lib.types.bool;
32 default = false;
33 description = "Whether to enable the diod 9P file server.";
34 };
35
36 listen = lib.mkOption {
37 type = lib.types.listOf lib.types.str;
38 default = [ "0.0.0.0:564" ];
39 description = ''
40 [ "IP:PORT" [,"IP:PORT",...] ]
41 List the interfaces and ports that diod should listen on.
42 '';
43 };
44
45 exports = lib.mkOption {
46 type = lib.types.listOf lib.types.str;
47 default = [ ];
48 description = ''
49 List the file systems that clients will be allowed to mount. All paths should
50 be fully qualified. The exports table can include two types of element:
51 a string element (as above),
52 or an alternate table element form { path="/path", opts="ro" }.
53 In the alternate form, the (optional) opts attribute is a comma-separated list
54 of export options. The two table element forms can be mixed in the exports
55 table. Note that although diod will not traverse file system boundaries for a
56 given mount due to inode uniqueness constraints, subdirectories of a file
57 system can be separately exported.
58 '';
59 };
60
61 exportall = lib.mkOption {
62 type = lib.types.bool;
63 default = true;
64 description = ''
65 Export all file systems listed in /proc/mounts. If new file systems are mounted
66 after diod has started, they will become immediately mountable. If there is a
67 duplicate entry for a file system in the exports list, any options listed in
68 the exports entry will apply.
69 '';
70 };
71
72 exportopts = lib.mkOption {
73 type = lib.types.listOf lib.types.str;
74 default = [ ];
75 description = ''
76 Establish a default set of export options. These are overridden, not appended
77 to, by opts attributes in an "exports" entry.
78 '';
79 };
80
81 nwthreads = lib.mkOption {
82 type = lib.types.int;
83 default = 16;
84 description = ''
85 Sets the (fixed) number of worker threads created to handle 9P
86 requests for a unique aname.
87 '';
88 };
89
90 authRequired = lib.mkOption {
91 type = lib.types.bool;
92 default = false;
93 description = ''
94 Allow clients to connect without authentication, i.e. without a valid MUNGE credential.
95 '';
96 };
97
98 userdb = lib.mkOption {
99 type = lib.types.bool;
100 default = false;
101 description = ''
102 This option disables password/group lookups. It allows any uid to attach and
103 assumes gid=uid, and supplementary groups contain only the primary gid.
104 '';
105 };
106
107 allsquash = lib.mkOption {
108 type = lib.types.bool;
109 default = true;
110 description = ''
111 Remap all users to "nobody". The attaching user need not be present in the
112 password file.
113 '';
114 };
115
116 squashuser = lib.mkOption {
117 type = lib.types.str;
118 default = "nobody";
119 description = ''
120 Change the squash user. The squash user must be present in the password file.
121 '';
122 };
123
124 logdest = lib.mkOption {
125 type = lib.types.str;
126 default = "syslog:daemon:err";
127 description = ''
128 Set the destination for logging.
129 The value has the form of "syslog:facility:level" or "filename".
130 '';
131 };
132
133 statfsPassthru = lib.mkOption {
134 type = lib.types.bool;
135 default = false;
136 description = ''
137 This option configures statfs to return the host file system's type
138 rather than V9FS_MAGIC.
139 '';
140 };
141
142 extraConfig = lib.mkOption {
143 type = lib.types.lines;
144 default = "";
145 description = "Extra configuration options for diod.conf.";
146 };
147 };
148 };
149
150 config = lib.mkIf config.services.diod.enable {
151 environment.systemPackages = [ pkgs.diod ];
152
153 systemd.services.diod = {
154 description = "diod 9P file server";
155 wantedBy = [ "multi-user.target" ];
156 after = [ "network.target" ];
157 serviceConfig = {
158 ExecStart = "${pkgs.diod}/sbin/diod -f -c ${diodConfig}";
159 };
160 };
161 };
162}