nixos/preload: init
[NixPkgs.git] / nixos / modules / services / network-filesystems / orangefs / server.nix
blob085b64e4c040cab24d16915912a4c92b03d906ee
1 { config, lib, pkgs, ...} :
3 with lib;
5 let
6   cfg = config.services.orangefs.server;
8   aliases = mapAttrsToList (alias: url: alias) cfg.servers;
10   # Maximum handle number is 2^63
11   maxHandle = 9223372036854775806;
13   # One range of handles for each meta/data instance
14   handleStep = maxHandle / (length aliases) / 2;
16   fileSystems = mapAttrsToList (name: fs: ''
17     <FileSystem>
18       Name ${name}
19       ID ${toString fs.id}
20       RootHandle ${toString fs.rootHandle}
22       ${fs.extraConfig}
24       <MetaHandleRanges>
25       ${concatStringsSep "\n" (
26           imap0 (i: alias:
27             let
28               begin = i * handleStep + 3;
29               end = begin + handleStep - 1;
30             in "Range ${alias} ${toString begin}-${toString end}") aliases
31        )}
32       </MetaHandleRanges>
34       <DataHandleRanges>
35       ${concatStringsSep "\n" (
36           imap0 (i: alias:
37             let
38               begin = i * handleStep + 3 + (length aliases) * handleStep;
39               end = begin + handleStep - 1;
40             in "Range ${alias} ${toString begin}-${toString end}") aliases
41        )}
42       </DataHandleRanges>
44       <StorageHints>
45       TroveSyncMeta ${if fs.troveSyncMeta then "yes" else "no"}
46       TroveSyncData ${if fs.troveSyncData then "yes" else "no"}
47       ${fs.extraStorageHints}
48       </StorageHints>
50     </FileSystem>
51   '') cfg.fileSystems;
53   configFile = ''
54     <Defaults>
55     LogType ${cfg.logType}
56     DataStorageSpace ${cfg.dataStorageSpace}
57     MetaDataStorageSpace ${cfg.metadataStorageSpace}
59     BMIModules ${concatStringsSep "," cfg.BMIModules}
60     ${cfg.extraDefaults}
61     </Defaults>
63     ${cfg.extraConfig}
65     <Aliases>
66     ${concatStringsSep "\n" (mapAttrsToList (alias: url: "Alias ${alias} ${url}") cfg.servers)}
67     </Aliases>
69     ${concatStringsSep "\n" fileSystems}
70   '';
72 in {
73   ###### interface
75   options = {
76     services.orangefs.server = {
77       enable = mkEnableOption (lib.mdDoc "OrangeFS server");
79       logType = mkOption {
80         type = with types; enum [ "file" "syslog" ];
81         default = "syslog";
82         description = lib.mdDoc "Destination for log messages.";
83       };
85       dataStorageSpace = mkOption {
86         type = types.nullOr types.str;
87         default = null;
88         example = "/data/storage";
89         description = lib.mdDoc "Directory for data storage.";
90       };
92       metadataStorageSpace = mkOption {
93         type = types.nullOr types.str;
94         default = null;
95         example = "/data/meta";
96         description = lib.mdDoc "Directory for meta data storage.";
97       };
99       BMIModules = mkOption {
100         type = with types; listOf str;
101         default = [ "bmi_tcp" ];
102         example = [ "bmi_tcp" "bmi_ib"];
103         description = lib.mdDoc "List of BMI modules to load.";
104       };
106       extraDefaults = mkOption {
107         type = types.lines;
108         default = "";
109         description = lib.mdDoc "Extra config for `<Defaults>` section.";
110       };
112       extraConfig = mkOption {
113         type = types.lines;
114         default = "";
115         description = lib.mdDoc "Extra config for the global section.";
116       };
118       servers = mkOption {
119         type = with types; attrsOf types.str;
120         default = {};
121         example = {
122           node1 = "tcp://node1:3334";
123           node2 = "tcp://node2:3334";
124         };
125         description = lib.mdDoc "URLs for storage server including port. The attribute names define the server alias.";
126       };
128       fileSystems = mkOption {
129         description = lib.mdDoc ''
130           These options will create the `<FileSystem>` sections of config file.
131         '';
132         default = { orangefs = {}; };
133         example = literalExpression ''
134           {
135             fs1 = {
136               id = 101;
137             };
139             fs2 = {
140               id = 102;
141             };
142           }
143         '';
144         type = with types; attrsOf (submodule ({ ... } : {
145           options = {
146             id = mkOption {
147               type = types.int;
148               default = 1;
149               description = lib.mdDoc "File system ID (must be unique within configuration).";
150             };
152             rootHandle = mkOption {
153               type = types.int;
154               default = 3;
155               description = lib.mdDoc "File system root ID.";
156             };
158             extraConfig = mkOption {
159               type = types.lines;
160               default = "";
161               description = lib.mdDoc "Extra config for `<FileSystem>` section.";
162             };
164             troveSyncMeta = mkOption {
165               type = types.bool;
166               default = true;
167               description = lib.mdDoc "Sync meta data.";
168             };
170             troveSyncData = mkOption {
171               type = types.bool;
172               default = false;
173               description = lib.mdDoc "Sync data.";
174             };
176             extraStorageHints = mkOption {
177               type = types.lines;
178               default = "";
179               description = lib.mdDoc "Extra config for `<StorageHints>` section.";
180             };
181           };
182         }));
183       };
184     };
185   };
187   ###### implementation
189   config = mkIf cfg.enable {
190     environment.systemPackages = [ pkgs.orangefs ];
192     # orangefs daemon will run as user
193     users.users.orangefs = {
194       isSystemUser = true;
195       group = "orangefs";
196     };
197     users.groups.orangefs = {};
199     # To format the file system the config file is needed.
200     environment.etc."orangefs/server.conf" = {
201       text = configFile;
202       user = "orangefs";
203       group = "orangefs";
204     };
206     systemd.services.orangefs-server = {
207       wantedBy = [ "multi-user.target" ];
208       requires = [ "network-online.target" ];
209       after = [ "network-online.target" ];
211       serviceConfig = {
212         # Run as "simple" in foreground mode.
213         # This is more reliable
214         ExecStart = ''
215           ${pkgs.orangefs}/bin/pvfs2-server -d \
216             /etc/orangefs/server.conf
217         '';
218         TimeoutStopSec = "120";
219         User = "orangefs";
220         Group = "orangefs";
221       };
222     };
223   };