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
8 mkPackageOption optionalString types;
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 = {
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 = "List of IP addresses this server is advertised under. See NetInfo(5)";
94 description = "Cell name, this server will serve.";
95 example = "grand.central.org";
98 cellServDB = mkOption {
100 type = with types; listOf (submodule [ { options = cellServDBConfig;} ]);
101 description = "Definition of all cell-local database server machines.";
104 package = mkPackageOption pkgs "openafs" { };
111 description = "Fileserver role, serves files and volumes from its local storage.";
114 fileserverArgs = mkOption {
115 default = "-vattachpar 128 -vhashsize 11 -L -rxpck 400 -cb 1000000";
117 description = "Arguments to the dafileserver process. See its man page.";
120 volserverArgs = mkOption {
123 description = "Arguments to the davolserver process. See its man page.";
124 example = "-sync never";
127 salvageserverArgs = mkOption {
130 description = "Arguments to the salvageserver process. See its man page.";
131 example = "-showlog";
134 salvagerArgs = mkOption {
137 description = "Arguments to the dasalvager process. See its man page.";
138 example = "-showlog -showmounts";
147 Database server role, maintains the Volume Location Database,
148 Protection Database (and Backup Database, see
149 `backup` role). There can be multiple
150 servers in the database role for replication, which then need
151 reliable network connection to each other.
153 Servers in this role appear in AFSDB DNS records or the
158 vlserverArgs = mkOption {
161 description = "Arguments to the vlserver process. See its man page.";
165 ptserverArgs = mkOption {
168 description = "Arguments to the ptserver process. See its man page.";
169 example = "-restricted -default_access S---- S-M---";
174 enable = mkEnableOption ''
175 the backup server role. When using OpenAFS built-in buserver, use in conjunction with the
176 `database` role to maintain the Backup
177 Database. Normally only used in conjunction with tape storage
178 or IBM's Tivoli Storage Manager.
180 For a modern backup server, enable this role and see
184 enableFabs = mkEnableOption ''
185 FABS, the flexible AFS backup system. It stores volumes as dump files, relying on other
186 pre-existing backup solutions for handling them
189 buserverArgs = mkOption {
192 description = "Arguments to the buserver process. See its man page.";
196 cellServDB = mkOption {
198 type = with types; listOf (submodule [ { options = cellServDBConfig;} ]);
200 Definition of all cell-local backup database server machines.
201 Use this when your cell uses less backup database servers than
202 other database server machines.
206 fabsArgs = mkOption {
210 Arguments to the fabsys process. See
211 {manpage}`fabsys_server(1)` and
212 {manpage}`fabsys_config(1)`.
216 fabsExtraConfig = mkOption {
220 Additional configuration parameters for the FABS backup server.
222 example = literalExpression ''
224 afs.localauth = true;
225 afs.keytab = config.sops.secrets.fabsKeytab.path;
232 dottedPrincipals= mkOption {
236 If enabled, allow principal names containing (.) dots. Enabling
237 this has security implications!
241 udpPacketSize = mkOption {
245 UDP packet size to use in Bytes. Higher values can speed up
246 communications. The default of 1 MB is a sufficient in most
247 cases. Make sure to increase the kernel's UDP buffer size
248 accordingly via `net.core(w|r|opt)mem_max`
257 config = mkIf cfg.enable {
260 { assertion = cfg.cellServDB != [];
261 message = "You must specify all cell-local database servers in config.services.openafsServer.cellServDB.";
263 { assertion = cfg.cellName != "";
264 message = "You must specify the local cell name in config.services.openafsServer.cellName.";
268 environment.systemPackages = [ openafsBin ];
273 target = "openafs/BosConfig";
277 text = mkCellServDB cfg.cellName cfg.cellServDB;
278 target = "openafs/server/CellServDB";
283 target = "openafs/server/ThisCell";
287 enable = useBuCellServDB;
288 text = mkCellServDB cfg.cellName cfg.roles.backup.cellServDB;
289 target = "openafs/backup/CellServDB";
295 description = "OpenAFS server";
296 after = [ "network.target" ];
297 wantedBy = [ "multi-user.target" ];
298 restartIfChanged = false;
299 unitConfig.ConditionPathExists = [
300 "|/etc/openafs/server/KeyFileExt"
303 mkdir -m 0755 -p /var/openafs
304 ${optionalString (netInfo != null) "cp ${netInfo} /var/openafs/netInfo"}
305 ${optionalString useBuCellServDB "cp ${buCellServDB}"}
308 ExecStart = "${openafsBin}/bin/bosserver -nofork";
309 ExecStop = "${openafsBin}/bin/bos shutdown localhost -wait -localauth";