tangled
alpha
login
or
join now
pyrox.dev
/
nixpkgs
0
fork
atom
lol
0
fork
atom
overview
issues
pulls
pipelines
nixosModules.MooseFS: Improve
liberodark
1 year ago
b3429b3e
c76e6f01
+144
-72
2 changed files
expand all
collapse all
unified
split
nixos
modules
services
network-filesystems
moosefs.nix
tests
moosefs.nix
+143
-70
nixos/modules/services/network-filesystems/moosefs.nix
reviewed
···
26
26
lib.mapAttrsToList (key: val: "${key} = ${valueToString val}") value ));
27
27
};
28
28
29
29
-
29
29
+
# Manual initialization tool
30
30
initTool = pkgs.writeShellScriptBin "mfsmaster-init" ''
31
31
if [ ! -e ${cfg.master.settings.DATA_PATH}/metadata.mfs ]; then
32
32
cp ${pkgs.moosefs}/var/mfs/metadata.mfs.empty ${cfg.master.settings.DATA_PATH}
···
37
37
fi
38
38
'';
39
39
40
40
-
# master config file
41
41
-
masterCfg = settingsFormat.generate
42
42
-
"mfsmaster.cfg" cfg.master.settings;
43
43
-
44
44
-
# metalogger config file
45
45
-
metaloggerCfg = settingsFormat.generate
46
46
-
"mfsmetalogger.cfg" cfg.metalogger.settings;
40
40
+
masterCfg = settingsFormat.generate "mfsmaster.cfg" cfg.master.settings;
41
41
+
metaloggerCfg = settingsFormat.generate "mfsmetalogger.cfg" cfg.metalogger.settings;
42
42
+
chunkserverCfg = settingsFormat.generate "mfschunkserver.cfg" cfg.chunkserver.settings;
47
43
48
48
-
# chunkserver config file
49
49
-
chunkserverCfg = settingsFormat.generate
50
50
-
"mfschunkserver.cfg" cfg.chunkserver.settings;
51
51
-
52
52
-
# generic template for all daemons
53
44
systemdService = name: extraConfig: configFile: {
54
45
wantedBy = [ "multi-user.target" ];
55
46
wants = [ "network-online.target" ];
···
66
57
67
58
in {
68
59
###### interface
69
69
-
70
60
options = {
71
61
services.moosefs = {
72
62
masterHost = lib.mkOption {
73
63
type = lib.types.str;
74
64
default = null;
75
75
-
description = "IP or DNS name of master host.";
65
65
+
description = "IP or DNS name of the MooseFS master server.";
76
66
};
77
67
78
68
runAsUser = lib.mkOption {
79
69
type = lib.types.bool;
80
70
default = true;
81
71
example = true;
82
82
-
description = "Run daemons as user moosefs instead of root.";
72
72
+
description = "Run daemons as moosefs user instead of root for better security.";
83
73
};
84
74
85
85
-
client.enable = lib.mkEnableOption "Moosefs client";
75
75
+
client.enable = lib.mkEnableOption "MooseFS client";
86
76
87
77
master = {
88
78
enable = lib.mkOption {
89
79
type = lib.types.bool;
90
80
description = ''
91
91
-
Enable Moosefs master daemon.
92
92
-
93
93
-
You need to run `mfsmaster-init` on a freshly installed master server to
94
94
-
initialize the `DATA_PATH` directory.
81
81
+
Enable MooseFS master daemon.
82
82
+
The master server coordinates all MooseFS operations and stores metadata.
95
83
'';
96
84
default = false;
97
85
};
98
86
87
87
+
autoInit = lib.mkOption {
88
88
+
type = lib.types.bool;
89
89
+
default = false;
90
90
+
description = "Whether to automatically initialize the master's metadata directory on first run. Use with caution.";
91
91
+
};
92
92
+
99
93
exports = lib.mkOption {
100
94
type = with lib.types; listOf str;
101
95
default = null;
102
102
-
description = "Paths to export (see mfsexports.cfg).";
96
96
+
description = "Export definitions for MooseFS (see mfsexports.cfg).";
103
97
example = [
104
98
"* / rw,alldirs,admin,maproot=0:0"
105
99
"* . rw"
···
108
102
109
103
openFirewall = lib.mkOption {
110
104
type = lib.types.bool;
111
111
-
description = "Whether to automatically open the necessary ports in the firewall.";
105
105
+
description = "Whether to automatically open required firewall ports for master service.";
112
106
default = false;
113
107
};
114
108
···
119
113
options.DATA_PATH = lib.mkOption {
120
114
type = lib.types.str;
121
115
default = "/var/lib/mfs";
122
122
-
description = "Data storage directory.";
116
116
+
description = "Directory for storing master metadata.";
123
117
};
124
118
};
125
125
-
126
126
-
description = "Contents of config file (mfsmaster.cfg).";
119
119
+
description = "Master configuration options (mfsmaster.cfg).";
127
120
};
128
121
};
129
122
130
123
metalogger = {
131
131
-
enable = lib.mkEnableOption "Moosefs metalogger daemon";
124
124
+
enable = lib.mkEnableOption "MooseFS metalogger daemon that maintains a backup copy of the master's metadata";
132
125
133
126
settings = lib.mkOption {
134
127
type = lib.types.submodule {
···
137
130
options.DATA_PATH = lib.mkOption {
138
131
type = lib.types.str;
139
132
default = "/var/lib/mfs";
140
140
-
description = "Data storage directory";
133
133
+
description = "Directory for storing metalogger data.";
141
134
};
142
135
};
143
143
-
144
144
-
description = "Contents of metalogger config file (mfsmetalogger.cfg).";
136
136
+
description = "Metalogger configuration options (mfsmetalogger.cfg).";
145
137
};
146
138
};
147
139
148
140
chunkserver = {
149
149
-
enable = lib.mkEnableOption "Moosefs chunkserver daemon";
141
141
+
enable = lib.mkEnableOption "MooseFS chunkserver daemon that stores file data";
150
142
151
143
openFirewall = lib.mkOption {
152
144
type = lib.types.bool;
153
153
-
description = "Whether to automatically open the necessary ports in the firewall.";
145
145
+
description = "Whether to automatically open required firewall ports for chunkserver service.";
154
146
default = false;
155
147
};
156
148
157
149
hdds = lib.mkOption {
158
150
type = with lib.types; listOf str;
159
159
-
default = null;
160
160
-
description = "Mount points to be used by chunkserver for storage (see mfshdd.cfg).";
161
161
-
example = [ "/mnt/hdd1" ];
151
151
+
default = null;
152
152
+
description = "Mount points used by chunkserver for data storage (see mfshdd.cfg).";
153
153
+
example = [ "/mnt/hdd1" "/mnt/hdd2" ];
162
154
};
163
155
164
156
settings = lib.mkOption {
···
168
160
options.DATA_PATH = lib.mkOption {
169
161
type = lib.types.str;
170
162
default = "/var/lib/mfs";
171
171
-
description = "Directory for lock file.";
163
163
+
description = "Directory for lock files and other runtime data.";
172
164
};
173
165
};
166
166
+
description = "Chunkserver configuration options (mfschunkserver.cfg).";
167
167
+
};
168
168
+
};
174
169
175
175
-
description = "Contents of chunkserver config file (mfschunkserver.cfg).";
170
170
+
cgiserver = {
171
171
+
enable = lib.mkEnableOption ''
172
172
+
MooseFS CGI server for web interface.
173
173
+
Warning: The CGI server interface should be properly secured from unauthorized access,
174
174
+
as it provides full control over your MooseFS installation.
175
175
+
'';
176
176
+
177
177
+
openFirewall = lib.mkOption {
178
178
+
type = lib.types.bool;
179
179
+
description = "Whether to automatically open the web interface port.";
180
180
+
default = false;
181
181
+
};
182
182
+
183
183
+
settings = lib.mkOption {
184
184
+
type = lib.types.submodule {
185
185
+
freeformType = settingsFormat.type;
186
186
+
options = {
187
187
+
BIND_HOST = lib.mkOption {
188
188
+
type = lib.types.str;
189
189
+
default = "0.0.0.0";
190
190
+
description = "IP address to bind CGI server to.";
191
191
+
};
192
192
+
193
193
+
PORT = lib.mkOption {
194
194
+
type = lib.types.port;
195
195
+
default = 9425;
196
196
+
description = "Port for CGI server to listen on.";
197
197
+
};
198
198
+
};
199
199
+
};
200
200
+
default = {};
201
201
+
description = "CGI server configuration options.";
176
202
};
177
203
};
178
204
};
179
205
};
180
206
181
207
###### implementation
182
182
-
183
183
-
config = lib.mkIf ( cfg.client.enable || cfg.master.enable || cfg.metalogger.enable || cfg.chunkserver.enable ) {
184
184
-
185
185
-
warnings = [ ( lib.mkIf (!cfg.runAsUser) "Running moosefs services as root is not recommended.") ];
208
208
+
config = lib.mkIf (cfg.client.enable || cfg.master.enable || cfg.metalogger.enable || cfg.chunkserver.enable || cfg.cgiserver.enable) {
209
209
+
warnings = [ ( lib.mkIf (!cfg.runAsUser) "Running MooseFS services as root is not recommended.") ];
186
210
187
187
-
# Service settings
188
211
services.moosefs = {
189
189
-
master.settings = lib.mkIf cfg.master.enable {
190
190
-
WORKING_USER = mfsUser;
191
191
-
EXPORTS_FILENAME = toString ( pkgs.writeText "mfsexports.cfg"
192
192
-
(lib.concatStringsSep "\n" cfg.master.exports));
193
193
-
};
212
212
+
master.settings = lib.mkIf cfg.master.enable (lib.mkMerge [
213
213
+
{
214
214
+
WORKING_USER = mfsUser;
215
215
+
EXPORTS_FILENAME = toString ( pkgs.writeText "mfsexports.cfg"
216
216
+
(lib.concatStringsSep "\n" cfg.master.exports));
217
217
+
}
218
218
+
(lib.mkIf cfg.cgiserver.enable {
219
219
+
MFSCGISERV = toString cfg.cgiserver.settings.PORT;
220
220
+
})
221
221
+
]);
194
222
195
223
metalogger.settings = lib.mkIf cfg.metalogger.enable {
196
224
WORKING_USER = mfsUser;
···
205
233
};
206
234
};
207
235
208
208
-
# Create system user account for daemons
209
209
-
users = lib.mkIf ( cfg.runAsUser && ( cfg.master.enable || cfg.metalogger.enable || cfg.chunkserver.enable ) ) {
236
236
+
users = lib.mkIf ( cfg.runAsUser && ( cfg.master.enable || cfg.metalogger.enable || cfg.chunkserver.enable || cfg.cgiserver.enable ) ) {
210
237
users.moosefs = {
211
238
isSystemUser = true;
212
212
-
description = "moosefs daemon user";
239
239
+
description = "MooseFS daemon user";
213
240
group = "moosefs";
214
241
};
215
242
groups.moosefs = {};
···
219
246
(lib.optional cfg.client.enable pkgs.moosefs) ++
220
247
(lib.optional cfg.master.enable initTool);
221
248
222
222
-
networking.firewall.allowedTCPPorts =
223
223
-
(lib.optionals cfg.master.openFirewall [ 9419 9420 9421 ]) ++
224
224
-
(lib.optional cfg.chunkserver.openFirewall 9422);
249
249
+
networking.firewall.allowedTCPPorts = lib.mkMerge [
250
250
+
(lib.optionals cfg.master.openFirewall [ 9419 9420 9421 ])
251
251
+
(lib.optional cfg.chunkserver.openFirewall 9422)
252
252
+
(lib.optional (cfg.cgiserver.enable && cfg.cgiserver.openFirewall) cfg.cgiserver.settings.PORT)
253
253
+
];
225
254
226
226
-
# Ensure storage directories exist
227
227
-
systemd.tmpfiles.rules =
228
228
-
lib.optional cfg.master.enable "d ${cfg.master.settings.DATA_PATH} 0700 ${mfsUser} ${mfsUser}"
229
229
-
++ lib.optional cfg.metalogger.enable "d ${cfg.metalogger.settings.DATA_PATH} 0700 ${mfsUser} ${mfsUser}"
230
230
-
++ lib.optional cfg.chunkserver.enable "d ${cfg.chunkserver.settings.DATA_PATH} 0700 ${mfsUser} ${mfsUser}";
255
255
+
systemd.tmpfiles.rules = [
256
256
+
# Master directories
257
257
+
(lib.optionalString cfg.master.enable
258
258
+
"d ${cfg.master.settings.DATA_PATH} 0700 ${mfsUser} ${mfsUser} -")
231
259
232
232
-
# Service definitions
233
233
-
systemd.services.mfs-master = lib.mkIf cfg.master.enable
234
234
-
( systemdService "master" {
235
235
-
TimeoutStartSec = 1800;
236
236
-
TimeoutStopSec = 1800;
237
237
-
Restart = "no";
238
238
-
} masterCfg );
260
260
+
# Metalogger directories
261
261
+
(lib.optionalString cfg.metalogger.enable
262
262
+
"d ${cfg.metalogger.settings.DATA_PATH} 0700 ${mfsUser} ${mfsUser} -")
239
263
240
240
-
systemd.services.mfs-metalogger = lib.mkIf cfg.metalogger.enable
241
241
-
( systemdService "metalogger" { Restart = "on-abnormal"; } metaloggerCfg );
264
264
+
# Chunkserver directories
265
265
+
(lib.optionalString cfg.chunkserver.enable
266
266
+
"d ${cfg.chunkserver.settings.DATA_PATH} 0700 ${mfsUser} ${mfsUser} -")
267
267
+
] ++ lib.optionals (cfg.chunkserver.enable && cfg.chunkserver.hdds != null)
268
268
+
(map (dir: "d ${dir} 0755 ${mfsUser} ${mfsUser} -") cfg.chunkserver.hdds);
242
269
243
243
-
systemd.services.mfs-chunkserver = lib.mkIf cfg.chunkserver.enable
244
244
-
( systemdService "chunkserver" { Restart = "on-abnormal"; } chunkserverCfg );
245
245
-
};
270
270
+
systemd.services = lib.mkMerge [
271
271
+
(lib.mkIf cfg.master.enable {
272
272
+
mfs-master = (lib.mkMerge [
273
273
+
(systemdService "master" {
274
274
+
TimeoutStartSec = 1800;
275
275
+
TimeoutStopSec = 1800;
276
276
+
Restart = "on-failure";
277
277
+
User = mfsUser;
278
278
+
} masterCfg)
279
279
+
{
280
280
+
preStart = lib.mkIf cfg.master.autoInit "${initTool}/bin/mfsmaster-init";
281
281
+
}
282
282
+
]);
283
283
+
})
284
284
+
285
285
+
(lib.mkIf cfg.metalogger.enable {
286
286
+
mfs-metalogger = systemdService "metalogger" {
287
287
+
Restart = "on-abnormal";
288
288
+
User = mfsUser;
289
289
+
} metaloggerCfg;
290
290
+
})
291
291
+
292
292
+
(lib.mkIf cfg.chunkserver.enable {
293
293
+
mfs-chunkserver = systemdService "chunkserver" {
294
294
+
Restart = "on-abnormal";
295
295
+
User = mfsUser;
296
296
+
} chunkserverCfg;
297
297
+
})
298
298
+
299
299
+
(lib.mkIf cfg.cgiserver.enable {
300
300
+
mfs-cgiserv = {
301
301
+
description = "MooseFS CGI Server";
302
302
+
wantedBy = [ "multi-user.target" ];
303
303
+
after = [ "mfs-master.service" ];
304
304
+
305
305
+
serviceConfig = {
306
306
+
Type = "simple";
307
307
+
ExecStart = "${pkgs.moosefs}/bin/mfscgiserv -D /var/lib/mfs -f start";
308
308
+
ExecStop = "${pkgs.moosefs}/bin/mfscgiserv -D /var/lib/mfs stop";
309
309
+
Restart = "on-failure";
310
310
+
RestartSec = "30s";
311
311
+
User = mfsUser;
312
312
+
Group = mfsUser;
313
313
+
WorkingDirectory = "/var/lib/mfs";
314
314
+
};
315
315
+
};
316
316
+
})
317
317
+
];
318
318
+
};
246
319
}
+1
-2
nixos/tests/moosefs.nix
reviewed
···
12
12
services.moosefs.master = {
13
13
enable = true;
14
14
openFirewall = true;
15
15
+
autoInit = true;
15
16
exports = [
16
17
"* / rw,alldirs,admin,maproot=0:0"
17
18
"* . rw"
···
76
77
# prepare master server
77
78
master.start()
78
79
master.wait_for_unit("multi-user.target")
79
79
-
master.succeed("mfsmaster-init")
80
80
-
master.succeed("systemctl restart mfs-master")
81
80
master.wait_for_unit("mfs-master.service")
82
81
83
82
metalogger.wait_for_unit("mfs-metalogger.service")