nixos/preload: init
[NixPkgs.git] / nixos / modules / services / network-filesystems / openafs / server.nix
blobfbaa7cfc19293fb573f5ff5f339184aa55c59be7
1 { config, lib, pkgs, ... }:
3 # openafsBin, openafsSrv, mkCellServDB
4 with import ./lib.nix { inherit config lib pkgs; };
6 let
7   inherit (lib) concatStringsSep literalExpression mkIf mkOption mkEnableOption
8   optionalString types;
10   bosConfig = pkgs.writeText "BosConfig" (''
11     restrictmode 1
12     restarttime 16 0 0 0 0
13     checkbintime 3 0 5 0 0
14   '' + (optionalString cfg.roles.database.enable ''
15     bnode simple vlserver 1
16     parm ${openafsSrv}/libexec/openafs/vlserver ${optionalString cfg.dottedPrincipals "-allow-dotted-principals"} ${cfg.roles.database.vlserverArgs}
17     end
18     bnode simple ptserver 1
19     parm ${openafsSrv}/libexec/openafs/ptserver ${optionalString cfg.dottedPrincipals "-allow-dotted-principals"} ${cfg.roles.database.ptserverArgs}
20     end
21   '') + (optionalString cfg.roles.fileserver.enable ''
22     bnode dafs dafs 1
23     parm ${openafsSrv}/libexec/openafs/dafileserver ${optionalString cfg.dottedPrincipals "-allow-dotted-principals"} -udpsize ${udpSizeStr} ${cfg.roles.fileserver.fileserverArgs}
24     parm ${openafsSrv}/libexec/openafs/davolserver ${optionalString cfg.dottedPrincipals "-allow-dotted-principals"} -udpsize ${udpSizeStr} ${cfg.roles.fileserver.volserverArgs}
25     parm ${openafsSrv}/libexec/openafs/salvageserver ${cfg.roles.fileserver.salvageserverArgs}
26     parm ${openafsSrv}/libexec/openafs/dasalvager ${cfg.roles.fileserver.salvagerArgs}
27     end
28   '') + (optionalString (cfg.roles.database.enable && cfg.roles.backup.enable && (!cfg.roles.backup.enableFabs)) ''
29     bnode simple buserver 1
30     parm ${openafsSrv}/libexec/openafs/buserver ${cfg.roles.backup.buserverArgs} ${optionalString useBuCellServDB "-cellservdb /etc/openafs/backup/"}
31     end
32   '') + (optionalString (cfg.roles.database.enable &&
33                          cfg.roles.backup.enable &&
34                          cfg.roles.backup.enableFabs) ''
35     bnode simple buserver 1
36     parm ${lib.getBin pkgs.fabs}/bin/fabsys server --config ${fabsConfFile} ${cfg.roles.backup.fabsArgs}
37     end
38   ''));
40   netInfo = if (cfg.advertisedAddresses != []) then
41     pkgs.writeText "NetInfo" ((concatStringsSep "\nf " cfg.advertisedAddresses) + "\n")
42   else null;
44   buCellServDB = pkgs.writeText "backup-cellServDB-${cfg.cellName}"
45     (mkCellServDB cfg.cellName cfg.roles.backup.cellServDB);
47   useBuCellServDB = (cfg.roles.backup.cellServDB != []) && (!cfg.roles.backup.enableFabs);
49   cfg = config.services.openafsServer;
51   udpSizeStr = toString cfg.udpPacketSize;
53   fabsConfFile = pkgs.writeText "fabs.yaml" (builtins.toJSON ({
54     afs = {
55       aklog = cfg.package + "/bin/aklog";
56       cell = cfg.cellName;
57       dumpscan = cfg.package + "/bin/afsdump_scan";
58       fs = cfg.package + "/bin/fs";
59       pts = cfg.package + "/bin/pts";
60       vos = cfg.package + "/bin/vos";
61     };
62     k5start.command = (lib.getBin pkgs.kstart) + "/bin/k5start";
63   } // cfg.roles.backup.fabsExtraConfig));
65 in {
67   options = {
69     services.openafsServer = {
71       enable = mkOption {
72         default = false;
73         type = types.bool;
74         description = lib.mdDoc ''
75           Whether to enable the OpenAFS server. An OpenAFS server needs a
76           complex setup. So, be aware that enabling this service and setting
77           some options does not give you a turn-key-ready solution. You need
78           at least a running Kerberos 5 setup, as OpenAFS relies on it for
79           authentication. See the Guide "QuickStartUnix" coming with
80           `pkgs.openafs.doc` for complete setup
81           instructions.
82         '';
83       };
85       advertisedAddresses = mkOption {
86         type = types.listOf types.str;
87         default = [];
88         description = lib.mdDoc "List of IP addresses this server is advertised under. See NetInfo(5)";
89       };
91       cellName = mkOption {
92         default = "";
93         type = types.str;
94         description = lib.mdDoc "Cell name, this server will serve.";
95         example = "grand.central.org";
96       };
98       cellServDB = mkOption {
99         default = [];
100         type = with types; listOf (submodule [ { options = cellServDBConfig;} ]);
101         description = lib.mdDoc "Definition of all cell-local database server machines.";
102       };
104       package = mkOption {
105         default = pkgs.openafs;
106         defaultText = literalExpression "pkgs.openafs";
107         type = types.package;
108         description = lib.mdDoc "OpenAFS package for the server binaries";
109       };
111       roles = {
112         fileserver = {
113           enable = mkOption {
114             default = true;
115             type = types.bool;
116             description = lib.mdDoc "Fileserver role, serves files and volumes from its local storage.";
117           };
119           fileserverArgs = mkOption {
120             default = "-vattachpar 128 -vhashsize 11 -L -rxpck 400 -cb 1000000";
121             type = types.str;
122             description = lib.mdDoc "Arguments to the dafileserver process. See its man page.";
123           };
125           volserverArgs = mkOption {
126             default = "";
127             type = types.str;
128             description = lib.mdDoc "Arguments to the davolserver process. See its man page.";
129             example = "-sync never";
130           };
132           salvageserverArgs = mkOption {
133             default = "";
134             type = types.str;
135             description = lib.mdDoc "Arguments to the salvageserver process. See its man page.";
136             example = "-showlog";
137           };
139           salvagerArgs = mkOption {
140             default = "";
141             type = types.str;
142             description = lib.mdDoc "Arguments to the dasalvager process. See its man page.";
143             example = "-showlog -showmounts";
144           };
145         };
147         database = {
148           enable = mkOption {
149             default = true;
150             type = types.bool;
151             description = lib.mdDoc ''
152               Database server role, maintains the Volume Location Database,
153               Protection Database (and Backup Database, see
154               `backup` role). There can be multiple
155               servers in the database role for replication, which then need
156               reliable network connection to each other.
158               Servers in this role appear in AFSDB DNS records or the
159               CellServDB.
160             '';
161           };
163           vlserverArgs = mkOption {
164             default = "";
165             type = types.str;
166             description = lib.mdDoc "Arguments to the vlserver process. See its man page.";
167             example = "-rxbind";
168           };
170           ptserverArgs = mkOption {
171             default = "";
172             type = types.str;
173             description = lib.mdDoc "Arguments to the ptserver process. See its man page.";
174             example = "-restricted -default_access S---- S-M---";
175           };
176         };
178         backup = {
179           enable = mkEnableOption (lib.mdDoc ''
180             the backup server role. When using OpenAFS built-in buserver, use in conjunction with the
181             `database` role to maintain the Backup
182             Database. Normally only used in conjunction with tape storage
183             or IBM's Tivoli Storage Manager.
185             For a modern backup server, enable this role and see
186             {option}`enableFabs`
187           '');
189           enableFabs = mkEnableOption (lib.mdDoc ''
190             FABS, the flexible AFS backup system. It stores volumes as dump files, relying on other
191             pre-existing backup solutions for handling them.
192           '');
194           buserverArgs = mkOption {
195             default = "";
196             type = types.str;
197             description = lib.mdDoc "Arguments to the buserver process. See its man page.";
198             example = "-p 8";
199           };
201           cellServDB = mkOption {
202             default = [];
203             type = with types; listOf (submodule [ { options = cellServDBConfig;} ]);
204             description = lib.mdDoc ''
205               Definition of all cell-local backup database server machines.
206               Use this when your cell uses less backup database servers than
207               other database server machines.
208             '';
209           };
211           fabsArgs = mkOption {
212             default = "";
213             type = types.str;
214             description = lib.mdDoc ''
215               Arguments to the fabsys process. See
216               {manpage}`fabsys_server(1)` and
217               {manpage}`fabsys_config(1)`.
218             '';
219           };
221           fabsExtraConfig = mkOption {
222             default = {};
223             type = types.attrs;
224             description = lib.mdDoc ''
225               Additional configuration parameters for the FABS backup server.
226             '';
227             example = literalExpression ''
228             {
229               afs.localauth = true;
230               afs.keytab = config.sops.secrets.fabsKeytab.path;
231             }
232             '';
233           };
234         };
235       };
237       dottedPrincipals= mkOption {
238         default = false;
239         type = types.bool;
240         description = lib.mdDoc ''
241           If enabled, allow principal names containing (.) dots. Enabling
242           this has security implications!
243         '';
244       };
246       udpPacketSize = mkOption {
247         default = 1310720;
248         type = types.int;
249         description = lib.mdDoc ''
250           UDP packet size to use in Bytes. Higher values can speed up
251           communications. The default of 1 MB is a sufficient in most
252           cases. Make sure to increase the kernel's UDP buffer size
253           accordingly via `net.core(w|r|opt)mem_max`
254           sysctl.
255         '';
256       };
258     };
260   };
262   config = mkIf cfg.enable {
264     assertions = [
265       { assertion = cfg.cellServDB != [];
266         message = "You must specify all cell-local database servers in config.services.openafsServer.cellServDB.";
267       }
268       { assertion = cfg.cellName != "";
269         message = "You must specify the local cell name in config.services.openafsServer.cellName.";
270       }
271     ];
273     environment.systemPackages = [ openafsBin ];
275     environment.etc = {
276       bosConfig = {
277         source = bosConfig;
278         target = "openafs/BosConfig";
279         mode = "0644";
280       };
281       cellServDB = {
282         text = mkCellServDB cfg.cellName cfg.cellServDB;
283         target = "openafs/server/CellServDB";
284         mode = "0644";
285       };
286       thisCell = {
287         text = cfg.cellName;
288         target = "openafs/server/ThisCell";
289         mode = "0644";
290       };
291       buCellServDB = {
292         enable = useBuCellServDB;
293         text = mkCellServDB cfg.cellName cfg.roles.backup.cellServDB;
294         target = "openafs/backup/CellServDB";
295       };
296     };
298     systemd.services = {
299       openafs-server = {
300         description = "OpenAFS server";
301         after = [ "network.target" ];
302         wantedBy = [ "multi-user.target" ];
303         restartIfChanged = false;
304         unitConfig.ConditionPathExists = [
305           "|/etc/openafs/server/KeyFileExt"
306         ];
307         preStart = ''
308           mkdir -m 0755 -p /var/openafs
309           ${optionalString (netInfo != null) "cp ${netInfo} /var/openafs/netInfo"}
310           ${optionalString useBuCellServDB "cp ${buCellServDB}"}
311         '';
312         serviceConfig = {
313           ExecStart = "${openafsBin}/bin/bosserver -nofork";
314           ExecStop = "${openafsBin}/bin/bos shutdown localhost -wait -localauth";
315         };
316       };
317     };
318   };