1{ config, lib, pkgs, ... }: 2 3# openafsBin, openafsSrv, mkCellServDB 4with import ./lib.nix { inherit config lib pkgs; }; 5 6let 7 inherit (lib) concatStringsSep mkIf mkOption optionalString types; 8 9 bosConfig = pkgs.writeText "BosConfig" ('' 10 restrictmode 1 11 restarttime 16 0 0 0 0 12 checkbintime 3 0 5 0 0 13 '' + (optionalString cfg.roles.database.enable '' 14 bnode simple vlserver 1 15 parm ${openafsSrv}/libexec/openafs/vlserver ${optionalString cfg.dottedPrincipals "-allow-dotted-principals"} ${cfg.roles.database.vlserverArgs} 16 end 17 bnode simple ptserver 1 18 parm ${openafsSrv}/libexec/openafs/ptserver ${optionalString cfg.dottedPrincipals "-allow-dotted-principals"} ${cfg.roles.database.ptserverArgs} 19 end 20 '') + (optionalString cfg.roles.fileserver.enable '' 21 bnode dafs dafs 1 22 parm ${openafsSrv}/libexec/openafs/dafileserver ${optionalString cfg.dottedPrincipals "-allow-dotted-principals"} -udpsize ${udpSizeStr} ${cfg.roles.fileserver.fileserverArgs} 23 parm ${openafsSrv}/libexec/openafs/davolserver ${optionalString cfg.dottedPrincipals "-allow-dotted-principals"} -udpsize ${udpSizeStr} ${cfg.roles.fileserver.volserverArgs} 24 parm ${openafsSrv}/libexec/openafs/salvageserver ${cfg.roles.fileserver.salvageserverArgs} 25 parm ${openafsSrv}/libexec/openafs/dasalvager ${cfg.roles.fileserver.salvagerArgs} 26 end 27 '') + (optionalString (cfg.roles.database.enable && cfg.roles.backup.enable) '' 28 bnode simple buserver 1 29 parm ${openafsSrv}/libexec/openafs/buserver ${cfg.roles.backup.buserverArgs} ${optionalString (cfg.roles.backup.cellServDB != []) "-cellservdb /etc/openafs/backup/"} 30 end 31 '')); 32 33 netInfo = if (cfg.advertisedAddresses != []) then 34 pkgs.writeText "NetInfo" ((concatStringsSep "\nf " cfg.advertisedAddresses) + "\n") 35 else null; 36 37 buCellServDB = pkgs.writeText "backup-cellServDB-${cfg.cellName}" (mkCellServDB cfg.cellName cfg.roles.backup.cellServDB); 38 39 cfg = config.services.openafsServer; 40 41 udpSizeStr = toString cfg.udpPacketSize; 42 43in { 44 45 options = { 46 47 services.openafsServer = { 48 49 enable = mkOption { 50 default = false; 51 type = types.bool; 52 description = '' 53 Whether to enable the OpenAFS server. An OpenAFS server needs a 54 complex setup. So, be aware that enabling this service and setting 55 some options does not give you a turn-key-ready solution. You need 56 at least a running Kerberos 5 setup, as OpenAFS relies on it for 57 authentication. See the Guide "QuickStartUnix" coming with 58 <literal>pkgs.openafs.doc</literal> for complete setup 59 instructions. 60 ''; 61 }; 62 63 advertisedAddresses = mkOption { 64 default = []; 65 description = "List of IP addresses this server is advertised under. See NetInfo(5)"; 66 }; 67 68 cellName = mkOption { 69 default = ""; 70 type = types.str; 71 description = "Cell name, this server will serve."; 72 example = "grand.central.org"; 73 }; 74 75 cellServDB = mkOption { 76 default = []; 77 type = with types; listOf (submodule [ { options = cellServDBConfig;} ]); 78 description = "Definition of all cell-local database server machines."; 79 }; 80 81 package = mkOption { 82 default = pkgs.openafs.server or pkgs.openafs; 83 type = types.package; 84 description = "OpenAFS package for the server binaries"; 85 }; 86 87 roles = { 88 fileserver = { 89 enable = mkOption { 90 default = true; 91 type = types.bool; 92 description = "Fileserver role, serves files and volumes from its local storage."; 93 }; 94 95 fileserverArgs = mkOption { 96 default = "-vattachpar 128 -vhashsize 11 -L -rxpck 400 -cb 1000000"; 97 type = types.str; 98 description = "Arguments to the dafileserver process. See its man page."; 99 }; 100 101 volserverArgs = mkOption { 102 default = ""; 103 type = types.str; 104 description = "Arguments to the davolserver process. See its man page."; 105 example = "-sync never"; 106 }; 107 108 salvageserverArgs = mkOption { 109 default = ""; 110 type = types.str; 111 description = "Arguments to the salvageserver process. See its man page."; 112 example = "-showlog"; 113 }; 114 115 salvagerArgs = mkOption { 116 default = ""; 117 type = types.str; 118 description = "Arguments to the dasalvager process. See its man page."; 119 example = "-showlog -showmounts"; 120 }; 121 }; 122 123 database = { 124 enable = mkOption { 125 default = true; 126 type = types.bool; 127 description = '' 128 Database server role, maintains the Volume Location Database, 129 Protection Database (and Backup Database, see 130 <literal>backup</literal> role). There can be multiple 131 servers in the database role for replication, which then need 132 reliable network connection to each other. 133 134 Servers in this role appear in AFSDB DNS records or the 135 CellServDB. 136 ''; 137 }; 138 139 vlserverArgs = mkOption { 140 default = ""; 141 type = types.str; 142 description = "Arguments to the vlserver process. See its man page."; 143 example = "-rxbind"; 144 }; 145 146 ptserverArgs = mkOption { 147 default = ""; 148 type = types.str; 149 description = "Arguments to the ptserver process. See its man page."; 150 example = "-restricted -default_access S---- S-M---"; 151 }; 152 }; 153 154 backup = { 155 enable = mkOption { 156 default = false; 157 type = types.bool; 158 description = '' 159 Backup server role. Use in conjunction with the 160 <literal>database</literal> role to maintain the Backup 161 Database. Normally only used in conjunction with tape storage 162 or IBM's Tivoli Storage Manager. 163 ''; 164 }; 165 166 buserverArgs = mkOption { 167 default = ""; 168 type = types.str; 169 description = "Arguments to the buserver process. See its man page."; 170 example = "-p 8"; 171 }; 172 173 cellServDB = mkOption { 174 default = []; 175 type = with types; listOf (submodule [ { options = cellServDBConfig;} ]); 176 description = '' 177 Definition of all cell-local backup database server machines. 178 Use this when your cell uses less backup database servers than 179 other database server machines. 180 ''; 181 }; 182 }; 183 }; 184 185 dottedPrincipals= mkOption { 186 default = false; 187 type = types.bool; 188 description = '' 189 If enabled, allow principal names containing (.) dots. Enabling 190 this has security implications! 191 ''; 192 }; 193 194 udpPacketSize = mkOption { 195 default = 1310720; 196 type = types.int; 197 description = '' 198 UDP packet size to use in Bytes. Higher values can speed up 199 communications. The default of 1 MB is a sufficient in most 200 cases. Make sure to increase the kernel's UDP buffer size 201 accordingly via <literal>net.core(w|r|opt)mem_max</literal> 202 sysctl. 203 ''; 204 }; 205 206 }; 207 208 }; 209 210 config = mkIf cfg.enable { 211 212 assertions = [ 213 { assertion = cfg.cellServDB != []; 214 message = "You must specify all cell-local database servers in config.services.openafsServer.cellServDB."; 215 } 216 { assertion = cfg.cellName != ""; 217 message = "You must specify the local cell name in config.services.openafsServer.cellName."; 218 } 219 ]; 220 221 environment.systemPackages = [ openafsBin ]; 222 223 environment.etc = { 224 bosConfig = { 225 source = bosConfig; 226 target = "openafs/BosConfig"; 227 mode = "0644"; 228 }; 229 cellServDB = { 230 text = mkCellServDB cfg.cellName cfg.cellServDB; 231 target = "openafs/server/CellServDB"; 232 mode = "0644"; 233 }; 234 thisCell = { 235 text = cfg.cellName; 236 target = "openafs/server/ThisCell"; 237 mode = "0644"; 238 }; 239 buCellServDB = { 240 enable = (cfg.roles.backup.cellServDB != []); 241 text = mkCellServDB cfg.cellName cfg.roles.backup.cellServDB; 242 target = "openafs/backup/CellServDB"; 243 }; 244 }; 245 246 systemd.services = { 247 openafs-server = { 248 description = "OpenAFS server"; 249 after = [ "syslog.target" "network.target" ]; 250 wantedBy = [ "multi-user.target" ]; 251 restartIfChanged = false; 252 unitConfig.ConditionPathExists = [ 253 "|/etc/openafs/server/rxkad.keytab" 254 "|/etc/openafs/server/KeyFileExt" 255 ]; 256 preStart = '' 257 mkdir -m 0755 -p /var/openafs 258 ${optionalString (netInfo != null) "cp ${netInfo} /var/openafs/netInfo"} 259 ${optionalString (cfg.roles.backup.cellServDB != []) "cp ${buCellServDB}"} 260 ''; 261 serviceConfig = { 262 ExecStart = "${openafsBin}/bin/bosserver -nofork"; 263 ExecStop = "${openafsBin}/bin/bos shutdown localhost -wait -localauth"; 264 }; 265 }; 266 }; 267 }; 268}