parent
2906718bcc
commit
8b4ce06e63
@ -0,0 +1,97 @@ |
||||
{ config, lib, pkgs, ...} : |
||||
|
||||
with lib; |
||||
|
||||
let |
||||
cfg = config.services.orangefs.client; |
||||
|
||||
in { |
||||
###### interface |
||||
|
||||
options = { |
||||
services.orangefs.client = { |
||||
enable = mkEnableOption "OrangeFS client daemon"; |
||||
|
||||
extraOptions = mkOption { |
||||
type = with types; listOf str; |
||||
default = []; |
||||
description = "Extra command line options for pvfs2-client."; |
||||
}; |
||||
|
||||
fileSystems = mkOption { |
||||
description = '' |
||||
The orangefs file systems to be mounted. |
||||
This option is prefered over using <option>fileSystems</option> directly since |
||||
the pvfs client service needs to be running for it to be mounted. |
||||
''; |
||||
|
||||
example = [{ |
||||
mountPoint = "/orangefs"; |
||||
target = "tcp://server:3334/orangefs"; |
||||
}]; |
||||
|
||||
type = with types; listOf (submodule ({ ... } : { |
||||
options = { |
||||
|
||||
mountPoint = mkOption { |
||||
type = types.str; |
||||
default = "/orangefs"; |
||||
description = "Mount point."; |
||||
}; |
||||
|
||||
options = mkOption { |
||||
type = with types; listOf str; |
||||
default = []; |
||||
description = "Mount options"; |
||||
}; |
||||
|
||||
target = mkOption { |
||||
type = types.str; |
||||
default = null; |
||||
example = "tcp://server:3334/orangefs"; |
||||
description = "Target URL"; |
||||
}; |
||||
}; |
||||
})); |
||||
}; |
||||
}; |
||||
}; |
||||
|
||||
|
||||
###### implementation |
||||
|
||||
config = mkIf cfg.enable { |
||||
environment.systemPackages = [ pkgs.orangefs ]; |
||||
|
||||
boot.supportedFilesystems = [ "pvfs2" ]; |
||||
boot.kernelModules = [ "orangefs" ]; |
||||
|
||||
systemd.services.orangefs-client = { |
||||
requires = [ "network-online.target" ]; |
||||
after = [ "network-online.target" ]; |
||||
|
||||
serviceConfig = { |
||||
Type = "simple"; |
||||
|
||||
ExecStart = '' |
||||
${pkgs.orangefs}/bin/pvfs2-client-core \ |
||||
--logtype=syslog ${concatStringsSep " " cfg.extraOptions} |
||||
''; |
||||
|
||||
TimeoutStopSec = "120"; |
||||
}; |
||||
}; |
||||
|
||||
systemd.mounts = map (fs: { |
||||
requires = [ "orangefs-client.service" ]; |
||||
after = [ "orangefs-client.service" ]; |
||||
bindsTo = [ "orangefs-client.service" ]; |
||||
wantedBy = [ "remote-fs.target" ]; |
||||
type = "pvfs2"; |
||||
options = concatStringsSep "," fs.options; |
||||
what = fs.target; |
||||
where = fs.mountPoint; |
||||
}) cfg.fileSystems; |
||||
}; |
||||
} |
||||
|
@ -0,0 +1,225 @@ |
||||
{ config, lib, pkgs, ...} : |
||||
|
||||
with lib; |
||||
|
||||
let |
||||
cfg = config.services.orangefs.server; |
||||
|
||||
aliases = mapAttrsToList (alias: url: alias) cfg.servers; |
||||
|
||||
# Maximum handle number is 2^63 |
||||
maxHandle = 9223372036854775806; |
||||
|
||||
# One range of handles for each meta/data instance |
||||
handleStep = maxHandle / (length aliases) / 2; |
||||
|
||||
fileSystems = mapAttrsToList (name: fs: '' |
||||
<FileSystem> |
||||
Name ${name} |
||||
ID ${toString fs.id} |
||||
RootHandle ${toString fs.rootHandle} |
||||
|
||||
${fs.extraConfig} |
||||
|
||||
<MetaHandleRanges> |
||||
${concatStringsSep "\n" ( |
||||
imap0 (i: alias: |
||||
let |
||||
begin = i * handleStep + 3; |
||||
end = begin + handleStep - 1; |
||||
in "Range ${alias} ${toString begin}-${toString end}") aliases |
||||
)} |
||||
</MetaHandleRanges> |
||||
|
||||
<DataHandleRanges> |
||||
${concatStringsSep "\n" ( |
||||
imap0 (i: alias: |
||||
let |
||||
begin = i * handleStep + 3 + (length aliases) * handleStep; |
||||
end = begin + handleStep - 1; |
||||
in "Range ${alias} ${toString begin}-${toString end}") aliases |
||||
)} |
||||
</DataHandleRanges> |
||||
|
||||
<StorageHints> |
||||
TroveSyncMeta ${if fs.troveSyncMeta then "yes" else "no"} |
||||
TroveSyncData ${if fs.troveSyncData then "yes" else "no"} |
||||
${fs.extraStorageHints} |
||||
</StorageHints> |
||||
|
||||
</FileSystem> |
||||
'') cfg.fileSystems; |
||||
|
||||
configFile = '' |
||||
<Defaults> |
||||
LogType ${cfg.logType} |
||||
DataStorageSpace ${cfg.dataStorageSpace} |
||||
MetaDataStorageSpace ${cfg.metadataStorageSpace} |
||||
|
||||
BMIModules ${concatStringsSep "," cfg.BMIModules} |
||||
${cfg.extraDefaults} |
||||
</Defaults> |
||||
|
||||
${cfg.extraConfig} |
||||
|
||||
<Aliases> |
||||
${concatStringsSep "\n" (mapAttrsToList (alias: url: "Alias ${alias} ${url}") cfg.servers)} |
||||
</Aliases> |
||||
|
||||
${concatStringsSep "\n" fileSystems} |
||||
''; |
||||
|
||||
in { |
||||
###### interface |
||||
|
||||
options = { |
||||
services.orangefs.server = { |
||||
enable = mkEnableOption "OrangeFS server"; |
||||
|
||||
logType = mkOption { |
||||
type = with types; enum [ "file" "syslog" ]; |
||||
default = "syslog"; |
||||
description = "Destination for log messages."; |
||||
}; |
||||
|
||||
dataStorageSpace = mkOption { |
||||
type = types.str; |
||||
default = null; |
||||
example = "/data/storage"; |
||||
description = "Directory for data storage."; |
||||
}; |
||||
|
||||
metadataStorageSpace = mkOption { |
||||
type = types.str; |
||||
default = null; |
||||
example = "/data/meta"; |
||||
description = "Directory for meta data storage."; |
||||
}; |
||||
|
||||
BMIModules = mkOption { |
||||
type = with types; listOf str; |
||||
default = [ "bmi_tcp" ]; |
||||
example = [ "bmi_tcp" "bmi_ib"]; |
||||
description = "List of BMI modules to load."; |
||||
}; |
||||
|
||||
extraDefaults = mkOption { |
||||
type = types.lines; |
||||
default = ""; |
||||
description = "Extra config for <literal><Defaults></literal> section."; |
||||
}; |
||||
|
||||
extraConfig = mkOption { |
||||
type = types.lines; |
||||
default = ""; |
||||
description = "Extra config for the global section."; |
||||
}; |
||||
|
||||
servers = mkOption { |
||||
type = with types; attrsOf types.str; |
||||
default = {}; |
||||
example = '' |
||||
{ |
||||
node1="tcp://node1:3334"; |
||||
node2="tcp://node2:3334"; |
||||
} |
||||
''; |
||||
description = "URLs for storage server including port. The attribute names define the server alias."; |
||||
}; |
||||
|
||||
fileSystems = mkOption { |
||||
description = '' |
||||
These options will create the <literal><FileSystem></literal> sections of config file. |
||||
''; |
||||
default = { orangefs = {}; }; |
||||
defaultText = literalExample "{ orangefs = {}; }"; |
||||
example = literalExample '' |
||||
{ |
||||
fs1 = { |
||||
id = 101; |
||||
}; |
||||
|
||||
fs2 = { |
||||
id = 102; |
||||
}; |
||||
} |
||||
''; |
||||
type = with types; attrsOf (submodule ({ ... } : { |
||||
options = { |
||||
id = mkOption { |
||||
type = types.int; |
||||
default = 1; |
||||
description = "File system ID (must be unique within configuration)."; |
||||
}; |
||||
|
||||
rootHandle = mkOption { |
||||
type = types.int; |
||||
default = 3; |
||||
description = "File system root ID."; |
||||
}; |
||||
|
||||
extraConfig = mkOption { |
||||
type = types.lines; |
||||
default = ""; |
||||
description = "Extra config for <literal><FileSystem></literal> section."; |
||||
}; |
||||
|
||||
troveSyncMeta = mkOption { |
||||
type = types.bool; |
||||
default = true; |
||||
description = "Sync meta data."; |
||||
}; |
||||
|
||||
troveSyncData = mkOption { |
||||
type = types.bool; |
||||
default = false; |
||||
description = "Sync data."; |
||||
}; |
||||
|
||||
extraStorageHints = mkOption { |
||||
type = types.lines; |
||||
default = ""; |
||||
description = "Extra config for <literal><StorageHints></literal> section."; |
||||
}; |
||||
}; |
||||
})); |
||||
}; |
||||
}; |
||||
}; |
||||
|
||||
###### implementation |
||||
|
||||
config = mkIf cfg.enable { |
||||
environment.systemPackages = [ pkgs.orangefs ]; |
||||
|
||||
# orangefs daemon will run as user |
||||
users.users.orangefs.isSystemUser = true; |
||||
users.groups.orangefs = {}; |
||||
|
||||
# To format the file system the config file is needed. |
||||
environment.etc."orangefs/server.conf" = { |
||||
text = configFile; |
||||
user = "orangefs"; |
||||
group = "orangefs"; |
||||
}; |
||||
|
||||
systemd.services.orangefs-server = { |
||||
wantedBy = [ "multi-user.target" ]; |
||||
requires = [ "network-online.target" ]; |
||||
after = [ "network-online.target" ]; |
||||
|
||||
serviceConfig = { |
||||
# Run as "simple" in forground mode. |
||||
# This is more reliable |
||||
ExecStart = '' |
||||
${pkgs.orangefs}/bin/pvfs2-server -d \ |
||||
/etc/orangefs/server.conf |
||||
''; |
||||
TimeoutStopSec = "120"; |
||||
User = "orangefs"; |
||||
Group = "orangefs"; |
||||
}; |
||||
}; |
||||
}; |
||||
|
||||
} |
Loading…
Reference in new issue