lol

nixos: init moosefs module

+253
+1
nixos/modules/module-list.nix
··· 684 684 ./services/network-filesystems/litestream/default.nix 685 685 ./services/network-filesystems/netatalk.nix 686 686 ./services/network-filesystems/nfsd.nix 687 + ./services/network-filesystems/moosefs.nix 687 688 ./services/network-filesystems/openafs/client.nix 688 689 ./services/network-filesystems/openafs/server.nix 689 690 ./services/network-filesystems/orangefs/server.nix
+252
nixos/modules/services/network-filesystems/moosefs.nix
··· 1 + { config, lib, pkgs, ... }: 2 + 3 + with lib; 4 + 5 + let 6 + cfg = config.services.moosefs; 7 + 8 + mfsUser = if cfg.runAsUser then "moosefs" else "root"; 9 + 10 + settingsFormat = let 11 + 12 + listSep = " "; 13 + allowedTypes = with types; [ bool int float str ]; 14 + valueToString = val: 15 + if isList val then concatStringsSep listSep (map (x: valueToString x) val) 16 + else if isBool val then (if val then "1" else "0") 17 + else toString val; 18 + 19 + in { 20 + type = with types; let 21 + valueType = oneOf ([ 22 + (listOf valueType) 23 + ] ++ allowedTypes) // { 24 + description = "Flat key-value file"; 25 + }; 26 + in attrsOf valueType; 27 + 28 + generate = name: value: 29 + pkgs.writeText name ( lib.concatStringsSep "\n" ( 30 + lib.mapAttrsToList (key: val: "${key} = ${valueToString val}") value )); 31 + }; 32 + 33 + 34 + initTool = pkgs.writeShellScriptBin "mfsmaster-init" '' 35 + if [ ! -e ${cfg.master.settings.DATA_PATH}/metadata.mfs ]; then 36 + cp ${pkgs.moosefs}/var/mfs/metadata.mfs.empty ${cfg.master.settings.DATA_PATH} 37 + chmod +w ${cfg.master.settings.DATA_PATH}/metadata.mfs.empty 38 + ${pkgs.moosefs}/bin/mfsmaster -a -c ${masterCfg} start 39 + ${pkgs.moosefs}/bin/mfsmaster -c ${masterCfg} stop 40 + rm ${cfg.master.settings.DATA_PATH}/metadata.mfs.empty 41 + fi 42 + ''; 43 + 44 + # master config file 45 + masterCfg = settingsFormat.generate 46 + "mfsmaster.cfg" cfg.master.settings; 47 + 48 + # metalogger config file 49 + metaloggerCfg = settingsFormat.generate 50 + "mfsmetalogger.cfg" cfg.metalogger.settings; 51 + 52 + # chunkserver config file 53 + chunkserverCfg = settingsFormat.generate 54 + "mfschunkserver.cfg" cfg.chunkserver.settings; 55 + 56 + # generic template for all deamons 57 + systemdService = name: extraConfig: configFile: { 58 + wantedBy = [ "multi-user.target" ]; 59 + wants = [ "network-online.target" ]; 60 + after = [ "network.target" "network-online.target" ]; 61 + 62 + serviceConfig = { 63 + Type = "forking"; 64 + ExecStart = "${pkgs.moosefs}/bin/mfs${name} -c ${configFile} start"; 65 + ExecStop = "${pkgs.moosefs}/bin/mfs${name} -c ${configFile} stop"; 66 + ExecReload = "${pkgs.moosefs}/bin/mfs${name} -c ${configFile} reload"; 67 + PIDFile = "${cfg."${name}".settings.DATA_PATH}/.mfs${name}.lock"; 68 + } // extraConfig; 69 + }; 70 + 71 + in { 72 + ###### interface 73 + 74 + options = { 75 + services.moosefs = { 76 + masterHost = mkOption { 77 + type = types.str; 78 + default = null; 79 + description = "IP or DNS name of master host."; 80 + }; 81 + 82 + runAsUser = mkOption { 83 + type = types.bool; 84 + default = true; 85 + example = true; 86 + description = "Run daemons as user moosefs instead of root."; 87 + }; 88 + 89 + client.enable = mkEnableOption "Moosefs client."; 90 + 91 + master = { 92 + enable = mkOption { 93 + type = types.bool; 94 + description = '' 95 + Enable Moosefs master daemon. 96 + 97 + You need to run <literal>mfsmaster-init</literal> on a freshly installed master server to 98 + initialize the <literal>DATA_PATH</literal> direcory. 99 + ''; 100 + default = false; 101 + }; 102 + 103 + 104 + exports = mkOption { 105 + type = with types; listOf str; 106 + default = null; 107 + description = "Paths to export (see mfsexports.cfg)."; 108 + example = [ 109 + "* / rw,alldirs,admin,maproot=0:0" 110 + "* . rw" 111 + ]; 112 + }; 113 + 114 + openFirewall = mkOption { 115 + type = types.bool; 116 + description = "Whether to automatically open the necessary ports in the firewall."; 117 + default = false; 118 + }; 119 + 120 + settings = mkOption { 121 + type = types.submodule { 122 + freeformType = settingsFormat.type; 123 + 124 + options.DATA_PATH = mkOption { 125 + type = types.str; 126 + default = "/var/lib/mfs"; 127 + description = "Data storage directory."; 128 + }; 129 + }; 130 + 131 + description = "Contents of config file (mfsmaster.cfg)."; 132 + }; 133 + }; 134 + 135 + metalogger = { 136 + enable = mkEnableOption "Moosefs metalogger daemon."; 137 + 138 + settings = mkOption { 139 + type = types.submodule { 140 + freeformType = settingsFormat.type; 141 + 142 + options.DATA_PATH = mkOption { 143 + type = types.str; 144 + default = "/var/lib/mfs"; 145 + description = "Data storage directory"; 146 + }; 147 + }; 148 + 149 + description = "Contents of metalogger config file (mfsmetalogger.cfg)."; 150 + }; 151 + }; 152 + 153 + chunkserver = { 154 + enable = mkEnableOption "Moosefs chunkserver daemon."; 155 + 156 + openFirewall = mkOption { 157 + type = types.bool; 158 + description = "Whether to automatically open the necessary ports in the firewall."; 159 + default = false; 160 + }; 161 + 162 + hdds = mkOption { 163 + type = with types; listOf str; 164 + default = null; 165 + description = "Mount points to be used by chunkserver for storage (see mfshdd.cfg)."; 166 + example = [ "/mnt/hdd1" ]; 167 + }; 168 + 169 + settings = mkOption { 170 + type = types.submodule { 171 + freeformType = settingsFormat.type; 172 + 173 + options.DATA_PATH = mkOption { 174 + type = types.str; 175 + default = "/var/lib/mfs"; 176 + description = "Directory for lock file."; 177 + }; 178 + }; 179 + 180 + description = "Contents of chunkserver config file (mfschunkserver.cfg)."; 181 + }; 182 + }; 183 + }; 184 + }; 185 + 186 + ###### implementation 187 + 188 + config = mkIf ( cfg.client.enable || cfg.master.enable || cfg.metalogger.enable || cfg.chunkserver.enable ) { 189 + 190 + warnings = [ ( mkIf (!cfg.runAsUser) "Running moosefs services as root is not recommended.") ]; 191 + 192 + # Service settings 193 + services.moosefs = { 194 + master.settings = mkIf cfg.master.enable { 195 + WORKING_USER = mfsUser; 196 + EXPORTS_FILENAME = toString ( pkgs.writeText "mfsexports.cfg" 197 + (concatStringsSep "\n" cfg.master.exports)); 198 + }; 199 + 200 + metalogger.settings = mkIf cfg.metalogger.enable { 201 + WORKING_USER = mfsUser; 202 + MASTER_HOST = cfg.masterHost; 203 + }; 204 + 205 + chunkserver.settings = mkIf cfg.chunkserver.enable { 206 + WORKING_USER = mfsUser; 207 + MASTER_HOST = cfg.masterHost; 208 + HDD_CONF_FILENAME = toString ( pkgs.writeText "mfshdd.cfg" 209 + (concatStringsSep "\n" cfg.chunkserver.hdds)); 210 + }; 211 + }; 212 + 213 + # Create system user account for daemons 214 + users = mkIf ( cfg.runAsUser && ( cfg.master.enable || cfg.metalogger.enable || cfg.chunkserver.enable ) ) { 215 + users.moosefs = { 216 + isSystemUser = true; 217 + description = "moosefs daemon user"; 218 + group = "moosefs"; 219 + }; 220 + groups.moosefs = {}; 221 + }; 222 + 223 + environment.systemPackages = 224 + (lib.optional cfg.client.enable pkgs.moosefs) ++ 225 + (lib.optional cfg.master.enable initTool); 226 + 227 + networking.firewall.allowedTCPPorts = 228 + (lib.optionals cfg.master.openFirewall [ 9419 9420 9421 ]) ++ 229 + (lib.optional cfg.chunkserver.openFirewall 9422); 230 + 231 + # Ensure storage directories exist 232 + systemd.tmpfiles.rules = 233 + optional cfg.master.enable "d ${cfg.master.settings.DATA_PATH} 0700 ${mfsUser} ${mfsUser}" 234 + ++ optional cfg.metalogger.enable "d ${cfg.metalogger.settings.DATA_PATH} 0700 ${mfsUser} ${mfsUser}" 235 + ++ optional cfg.chunkserver.enable "d ${cfg.chunkserver.settings.DATA_PATH} 0700 ${mfsUser} ${mfsUser}"; 236 + 237 + # Service definitions 238 + systemd.services.mfs-master = mkIf cfg.master.enable 239 + ( systemdService "master" { 240 + TimeoutStartSec = 1800; 241 + TimeoutStopSec = 1800; 242 + Restart = "no"; 243 + } masterCfg ); 244 + 245 + systemd.services.mfs-metalogger = mkIf cfg.metalogger.enable 246 + ( systemdService "metalogger" { Restart = "on-abnormal"; } metaloggerCfg ); 247 + 248 + systemd.services.mfs-chunkserver = mkIf cfg.chunkserver.enable 249 + ( systemdService "chunkserver" { Restart = "on-abnormal"; } chunkserverCfg ); 250 + }; 251 + } 252 +