2626 lib . mapAttrsToList ( key : val : "${ key } = ${ valueToString val } " ) value ) ) ;
2727 } ;
2828
29-
29+ # Manual initialization tool
3030 initTool = pkgs . writeShellScriptBin "mfsmaster-init" ''
3131 if [ ! -e ${ cfg . master . settings . DATA_PATH } /metadata.mfs ]; then
3232 cp ${ pkgs . moosefs } /var/mfs/metadata.mfs.empty ${ cfg . master . settings . DATA_PATH }
3737 fi
3838 '' ;
3939
40- # master config file
41- masterCfg = settingsFormat . generate
42- "mfsmaster.cfg" cfg . master . settings ;
43-
44- # metalogger config file
45- metaloggerCfg = settingsFormat . generate
46- "mfsmetalogger.cfg" cfg . metalogger . settings ;
47-
48- # chunkserver config file
49- chunkserverCfg = settingsFormat . generate
50- "mfschunkserver.cfg" cfg . chunkserver . settings ;
40+ masterCfg = settingsFormat . generate "mfsmaster.cfg" cfg . master . settings ;
41+ metaloggerCfg = settingsFormat . generate "mfsmetalogger.cfg" cfg . metalogger . settings ;
42+ chunkserverCfg = settingsFormat . generate "mfschunkserver.cfg" cfg . chunkserver . settings ;
5143
52- # generic template for all daemons
5344 systemdService = name : extraConfig : configFile : {
5445 wantedBy = [ "multi-user.target" ] ;
5546 wants = [ "network-online.target" ] ;
6657
6758in {
6859 ###### interface
69-
7060 options = {
7161 services . moosefs = {
7262 masterHost = lib . mkOption {
7363 type = lib . types . str ;
7464 default = null ;
75- description = "IP or DNS name of master host ." ;
65+ description = "IP or DNS name of the MooseFS master server ." ;
7666 } ;
7767
7868 runAsUser = lib . mkOption {
7969 type = lib . types . bool ;
8070 default = true ;
8171 example = true ;
82- description = "Run daemons as user moosefs instead of root." ;
72+ description = "Run daemons as moosefs user instead of root for better security ." ;
8373 } ;
8474
85- client . enable = lib . mkEnableOption "Moosefs client" ;
75+ client . enable = lib . mkEnableOption "MooseFS client" ;
8676
8777 master = {
8878 enable = lib . mkOption {
8979 type = lib . types . bool ;
9080 description = ''
91- Enable Moosefs master daemon.
92-
93- You need to run `mfsmaster-init` on a freshly installed master server to
94- initialize the `DATA_PATH` directory.
81+ Enable MooseFS master daemon.
82+ The master server coordinates all MooseFS operations and stores metadata.
9583 '' ;
9684 default = false ;
9785 } ;
9886
87+ autoInit = lib . mkOption {
88+ type = lib . types . bool ;
89+ default = false ;
90+ description = "Whether to automatically initialize the master's metadata directory on first run. Use with caution." ;
91+ } ;
92+
9993 exports = lib . mkOption {
10094 type = with lib . types ; listOf str ;
10195 default = null ;
102- description = "Paths to export (see mfsexports.cfg)." ;
96+ description = "Export definitions for MooseFS (see mfsexports.cfg)." ;
10397 example = [
10498 "* / rw,alldirs,admin,maproot=0:0"
10599 "* . rw"
108102
109103 openFirewall = lib . mkOption {
110104 type = lib . types . bool ;
111- description = "Whether to automatically open the necessary ports in the firewall ." ;
105+ description = "Whether to automatically open required firewall ports for master service ." ;
112106 default = false ;
113107 } ;
114108
@@ -119,16 +113,15 @@ in {
119113 options . DATA_PATH = lib . mkOption {
120114 type = lib . types . str ;
121115 default = "/var/lib/mfs" ;
122- description = "Data storage directory ." ;
116+ description = "Directory for storing master metadata ." ;
123117 } ;
124118 } ;
125-
126- description = "Contents of config file (mfsmaster.cfg)." ;
119+ description = "Master configuration options (mfsmaster.cfg)." ;
127120 } ;
128121 } ;
129122
130123 metalogger = {
131- enable = lib . mkEnableOption "Moosefs metalogger daemon" ;
124+ enable = lib . mkEnableOption "MooseFS metalogger daemon that maintains a backup copy of the master's metadata " ;
132125
133126 settings = lib . mkOption {
134127 type = lib . types . submodule {
@@ -137,28 +130,27 @@ in {
137130 options . DATA_PATH = lib . mkOption {
138131 type = lib . types . str ;
139132 default = "/var/lib/mfs" ;
140- description = "Data storage directory " ;
133+ description = "Directory for storing metalogger data. " ;
141134 } ;
142135 } ;
143-
144- description = "Contents of metalogger config file (mfsmetalogger.cfg)." ;
136+ description = "Metalogger configuration options (mfsmetalogger.cfg)." ;
145137 } ;
146138 } ;
147139
148140 chunkserver = {
149- enable = lib . mkEnableOption "Moosefs chunkserver daemon" ;
141+ enable = lib . mkEnableOption "MooseFS chunkserver daemon that stores file data " ;
150142
151143 openFirewall = lib . mkOption {
152144 type = lib . types . bool ;
153- description = "Whether to automatically open the necessary ports in the firewall ." ;
145+ description = "Whether to automatically open required firewall ports for chunkserver service ." ;
154146 default = false ;
155147 } ;
156148
157149 hdds = lib . mkOption {
158150 type = with lib . types ; listOf str ;
159- default = null ;
160- description = "Mount points to be used by chunkserver for storage (see mfshdd.cfg)." ;
161- example = [ "/mnt/hdd1" ] ;
151+ default = null ;
152+ description = "Mount points used by chunkserver for data storage (see mfshdd.cfg)." ;
153+ example = [ "/mnt/hdd1" "/mnt/hdd2" ] ;
162154 } ;
163155
164156 settings = lib . mkOption {
@@ -168,29 +160,65 @@ in {
168160 options . DATA_PATH = lib . mkOption {
169161 type = lib . types . str ;
170162 default = "/var/lib/mfs" ;
171- description = "Directory for lock file ." ;
163+ description = "Directory for lock files and other runtime data ." ;
172164 } ;
173165 } ;
166+ description = "Chunkserver configuration options (mfschunkserver.cfg)." ;
167+ } ;
168+ } ;
169+
170+ cgiserver = {
171+ enable = lib . mkEnableOption ''
172+ MooseFS CGI server for web interface.
173+ Warning: The CGI server interface should be properly secured from unauthorized access,
174+ as it provides full control over your MooseFS installation.
175+ '' ;
174176
175- description = "Contents of chunkserver config file (mfschunkserver.cfg)." ;
177+ openFirewall = lib . mkOption {
178+ type = lib . types . bool ;
179+ description = "Whether to automatically open the web interface port." ;
180+ default = false ;
181+ } ;
182+
183+ settings = lib . mkOption {
184+ type = lib . types . submodule {
185+ freeformType = settingsFormat . type ;
186+ options = {
187+ BIND_HOST = lib . mkOption {
188+ type = lib . types . str ;
189+ default = "0.0.0.0" ;
190+ description = "IP address to bind CGI server to." ;
191+ } ;
192+
193+ PORT = lib . mkOption {
194+ type = lib . types . port ;
195+ default = 9425 ;
196+ description = "Port for CGI server to listen on." ;
197+ } ;
198+ } ;
199+ } ;
200+ default = { } ;
201+ description = "CGI server configuration options." ;
176202 } ;
177203 } ;
178204 } ;
179205 } ;
180206
181207 ###### implementation
208+ config = lib . mkIf ( cfg . client . enable || cfg . master . enable || cfg . metalogger . enable || cfg . chunkserver . enable || cfg . cgiserver . enable ) {
209+ warnings = [ ( lib . mkIf ( ! cfg . runAsUser ) "Running MooseFS services as root is not recommended." ) ] ;
182210
183- config = lib . mkIf ( cfg . client . enable || cfg . master . enable || cfg . metalogger . enable || cfg . chunkserver . enable ) {
184-
185- warnings = [ ( lib . mkIf ( ! cfg . runAsUser ) "Running moosefs services as root is not recommended." ) ] ;
186-
187- # Service settings
188211 services . moosefs = {
189- master . settings = lib . mkIf cfg . master . enable {
190- WORKING_USER = mfsUser ;
191- EXPORTS_FILENAME = toString ( pkgs . writeText "mfsexports.cfg"
192- ( lib . concatStringsSep "\n " cfg . master . exports ) ) ;
193- } ;
212+ master . settings = lib . mkIf cfg . master . enable ( lib . mkMerge [
213+ {
214+ WORKING_USER = mfsUser ;
215+ EXPORTS_FILENAME = toString ( pkgs . writeText "mfsexports.cfg"
216+ ( lib . concatStringsSep "\n " cfg . master . exports ) ) ;
217+ }
218+ ( lib . mkIf cfg . cgiserver . enable {
219+ MFSCGISERV = toString cfg . cgiserver . settings . PORT ;
220+ } )
221+ ] ) ;
194222
195223 metalogger . settings = lib . mkIf cfg . metalogger . enable {
196224 WORKING_USER = mfsUser ;
@@ -205,11 +233,10 @@ in {
205233 } ;
206234 } ;
207235
208- # Create system user account for daemons
209- users = lib . mkIf ( cfg . runAsUser && ( cfg . master . enable || cfg . metalogger . enable || cfg . chunkserver . enable ) ) {
236+ users = lib . mkIf ( cfg . runAsUser && ( cfg . master . enable || cfg . metalogger . enable || cfg . chunkserver . enable || cfg . cgiserver . enable ) ) {
210237 users . moosefs = {
211238 isSystemUser = true ;
212- description = "moosefs daemon user" ;
239+ description = "MooseFS daemon user" ;
213240 group = "moosefs" ;
214241 } ;
215242 groups . moosefs = { } ;
@@ -219,28 +246,74 @@ in {
219246 ( lib . optional cfg . client . enable pkgs . moosefs ) ++
220247 ( lib . optional cfg . master . enable initTool ) ;
221248
222- networking . firewall . allowedTCPPorts =
223- ( lib . optionals cfg . master . openFirewall [ 9419 9420 9421 ] ) ++
224- ( lib . optional cfg . chunkserver . openFirewall 9422 ) ;
225-
226- # Ensure storage directories exist
227- systemd . tmpfiles . rules =
228- lib . optional cfg . master . enable "d ${ cfg . master . settings . DATA_PATH } 0700 ${ mfsUser } ${ mfsUser } "
229- ++ lib . optional cfg . metalogger . enable "d ${ cfg . metalogger . settings . DATA_PATH } 0700 ${ mfsUser } ${ mfsUser } "
230- ++ lib . optional cfg . chunkserver . enable "d ${ cfg . chunkserver . settings . DATA_PATH } 0700 ${ mfsUser } ${ mfsUser } " ;
231-
232- # Service definitions
233- systemd . services . mfs-master = lib . mkIf cfg . master . enable
234- ( systemdService "master" {
235- TimeoutStartSec = 1800 ;
236- TimeoutStopSec = 1800 ;
237- Restart = "no" ;
238- } masterCfg ) ;
239-
240- systemd . services . mfs-metalogger = lib . mkIf cfg . metalogger . enable
241- ( systemdService "metalogger" { Restart = "on-abnormal" ; } metaloggerCfg ) ;
242-
243- systemd . services . mfs-chunkserver = lib . mkIf cfg . chunkserver . enable
244- ( systemdService "chunkserver" { Restart = "on-abnormal" ; } chunkserverCfg ) ;
245- } ;
249+ networking . firewall . allowedTCPPorts = lib . mkMerge [
250+ ( lib . optionals cfg . master . openFirewall [ 9419 9420 9421 ] )
251+ ( lib . optional cfg . chunkserver . openFirewall 9422 )
252+ ( lib . optional ( cfg . cgiserver . enable && cfg . cgiserver . openFirewall ) cfg . cgiserver . settings . PORT )
253+ ] ;
254+
255+ systemd . tmpfiles . rules = [
256+ # Master directories
257+ ( lib . optionalString cfg . master . enable
258+ "d ${ cfg . master . settings . DATA_PATH } 0700 ${ mfsUser } ${ mfsUser } -" )
259+
260+ # Metalogger directories
261+ ( lib . optionalString cfg . metalogger . enable
262+ "d ${ cfg . metalogger . settings . DATA_PATH } 0700 ${ mfsUser } ${ mfsUser } -" )
263+
264+ # Chunkserver directories
265+ ( lib . optionalString cfg . chunkserver . enable
266+ "d ${ cfg . chunkserver . settings . DATA_PATH } 0700 ${ mfsUser } ${ mfsUser } -" )
267+ ] ++ lib . optionals ( cfg . chunkserver . enable && cfg . chunkserver . hdds != null )
268+ ( map ( dir : "d ${ dir } 0755 ${ mfsUser } ${ mfsUser } -" ) cfg . chunkserver . hdds ) ;
269+
270+ systemd . services = lib . mkMerge [
271+ ( lib . mkIf cfg . master . enable {
272+ mfs-master = ( lib . mkMerge [
273+ ( systemdService "master" {
274+ TimeoutStartSec = 1800 ;
275+ TimeoutStopSec = 1800 ;
276+ Restart = "on-failure" ;
277+ User = mfsUser ;
278+ } masterCfg )
279+ {
280+ preStart = lib . mkIf cfg . master . autoInit "${ initTool } /bin/mfsmaster-init" ;
281+ }
282+ ] ) ;
283+ } )
284+
285+ ( lib . mkIf cfg . metalogger . enable {
286+ mfs-metalogger = systemdService "metalogger" {
287+ Restart = "on-abnormal" ;
288+ User = mfsUser ;
289+ } metaloggerCfg ;
290+ } )
291+
292+ ( lib . mkIf cfg . chunkserver . enable {
293+ mfs-chunkserver = systemdService "chunkserver" {
294+ Restart = "on-abnormal" ;
295+ User = mfsUser ;
296+ } chunkserverCfg ;
297+ } )
298+
299+ ( lib . mkIf cfg . cgiserver . enable {
300+ mfs-cgiserv = {
301+ description = "MooseFS CGI Server" ;
302+ wantedBy = [ "multi-user.target" ] ;
303+ after = [ "mfs-master.service" ] ;
304+
305+ serviceConfig = {
306+ Type = "simple" ;
307+ ExecStart = "${ pkgs . moosefs } /bin/mfscgiserv -D /var/lib/mfs -f start" ;
308+ ExecStop = "${ pkgs . moosefs } /bin/mfscgiserv -D /var/lib/mfs stop" ;
309+ Restart = "on-failure" ;
310+ RestartSec = "30s" ;
311+ User = mfsUser ;
312+ Group = mfsUser ;
313+ WorkingDirectory = "/var/lib/mfs" ;
314+ } ;
315+ } ;
316+ } )
317+ ] ;
318+ } ;
246319}
0 commit comments