1 { config, lib, pkgs, ... }:
3 # openafsBin, openafsSrv, mkCellServDB
4 with import ./lib.nix { inherit config lib pkgs; };
7 inherit (lib) concatStringsSep literalExpression mkIf mkOption mkEnableOption
10 bosConfig = pkgs.writeText "BosConfig" (''
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}
18 bnode simple ptserver 1
19 parm ${openafsSrv}/libexec/openafs/ptserver ${optionalString cfg.dottedPrincipals "-allow-dotted-principals"} ${cfg.roles.database.ptserverArgs}
21 '') + (optionalString cfg.roles.fileserver.enable ''
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}
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/"}
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}
40 netInfo = if (cfg.advertisedAddresses != []) then
41 pkgs.writeText "NetInfo" ((concatStringsSep "\nf " cfg.advertisedAddresses) + "\n")
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 ({
55 aklog = cfg.package + "/bin/aklog";
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";
62 k5start.command = (lib.getBin pkgs.kstart) + "/bin/k5start";
63 } // cfg.roles.backup.fabsExtraConfig));
69 services.openafsServer = {
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
85 advertisedAddresses = mkOption {
86 type = types.listOf types.str;
88 description = lib.mdDoc "List of IP addresses this server is advertised under. See NetInfo(5)";
94 description = lib.mdDoc "Cell name, this server will serve.";
95 example = "grand.central.org";
98 cellServDB = mkOption {
100 type = with types; listOf (submodule [ { options = cellServDBConfig;} ]);
101 description = lib.mdDoc "Definition of all cell-local database server machines.";
105 default = pkgs.openafs;
106 defaultText = literalExpression "pkgs.openafs";
107 type = types.package;
108 description = lib.mdDoc "OpenAFS package for the server binaries";
116 description = lib.mdDoc "Fileserver role, serves files and volumes from its local storage.";
119 fileserverArgs = mkOption {
120 default = "-vattachpar 128 -vhashsize 11 -L -rxpck 400 -cb 1000000";
122 description = lib.mdDoc "Arguments to the dafileserver process. See its man page.";
125 volserverArgs = mkOption {
128 description = lib.mdDoc "Arguments to the davolserver process. See its man page.";
129 example = "-sync never";
132 salvageserverArgs = mkOption {
135 description = lib.mdDoc "Arguments to the salvageserver process. See its man page.";
136 example = "-showlog";
139 salvagerArgs = mkOption {
142 description = lib.mdDoc "Arguments to the dasalvager process. See its man page.";
143 example = "-showlog -showmounts";
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
163 vlserverArgs = mkOption {
166 description = lib.mdDoc "Arguments to the vlserver process. See its man page.";
170 ptserverArgs = mkOption {
173 description = lib.mdDoc "Arguments to the ptserver process. See its man page.";
174 example = "-restricted -default_access S---- S-M---";
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
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.
194 buserverArgs = mkOption {
197 description = lib.mdDoc "Arguments to the buserver process. See its man page.";
201 cellServDB = mkOption {
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.
211 fabsArgs = mkOption {
214 description = lib.mdDoc ''
215 Arguments to the fabsys process. See
216 {manpage}`fabsys_server(1)` and
217 {manpage}`fabsys_config(1)`.
221 fabsExtraConfig = mkOption {
224 description = lib.mdDoc ''
225 Additional configuration parameters for the FABS backup server.
227 example = literalExpression ''
229 afs.localauth = true;
230 afs.keytab = config.sops.secrets.fabsKeytab.path;
237 dottedPrincipals= mkOption {
240 description = lib.mdDoc ''
241 If enabled, allow principal names containing (.) dots. Enabling
242 this has security implications!
246 udpPacketSize = mkOption {
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`
262 config = mkIf cfg.enable {
265 { assertion = cfg.cellServDB != [];
266 message = "You must specify all cell-local database servers in config.services.openafsServer.cellServDB.";
268 { assertion = cfg.cellName != "";
269 message = "You must specify the local cell name in config.services.openafsServer.cellName.";
273 environment.systemPackages = [ openafsBin ];
278 target = "openafs/BosConfig";
282 text = mkCellServDB cfg.cellName cfg.cellServDB;
283 target = "openafs/server/CellServDB";
288 target = "openafs/server/ThisCell";
292 enable = useBuCellServDB;
293 text = mkCellServDB cfg.cellName cfg.roles.backup.cellServDB;
294 target = "openafs/backup/CellServDB";
300 description = "OpenAFS server";
301 after = [ "network.target" ];
302 wantedBy = [ "multi-user.target" ];
303 restartIfChanged = false;
304 unitConfig.ConditionPathExists = [
305 "|/etc/openafs/server/KeyFileExt"
308 mkdir -m 0755 -p /var/openafs
309 ${optionalString (netInfo != null) "cp ${netInfo} /var/openafs/netInfo"}
310 ${optionalString useBuCellServDB "cp ${buCellServDB}"}
313 ExecStart = "${openafsBin}/bin/bosserver -nofork";
314 ExecStop = "${openafsBin}/bin/bos shutdown localhost -wait -localauth";