2017-12-29 02:51:42 +01:00
|
|
|
{ config, lib, pkgs, ...} :
|
|
|
|
|
|
|
|
with lib;
|
|
|
|
|
|
|
|
let
|
|
|
|
cfg = config.services.beegfs;
|
|
|
|
|
|
|
|
# functions for the generations of config files
|
|
|
|
|
|
|
|
configMgmtd = name: cfg: pkgs.writeText "mgmt-${name}.conf" ''
|
|
|
|
storeMgmtdDirectory = ${cfg.mgmtd.storeDir}
|
|
|
|
storeAllowFirstRunInit = false
|
|
|
|
connAuthFile = ${cfg.connAuthFile}
|
|
|
|
connPortShift = ${toString cfg.connPortShift}
|
|
|
|
|
|
|
|
${cfg.mgmtd.extraConfig}
|
|
|
|
'';
|
|
|
|
|
|
|
|
configAdmon = name: cfg: pkgs.writeText "admon-${name}.conf" ''
|
|
|
|
sysMgmtdHost = ${cfg.mgmtdHost}
|
|
|
|
connAuthFile = ${cfg.connAuthFile}
|
|
|
|
connPortShift = ${toString cfg.connPortShift}
|
|
|
|
|
|
|
|
${cfg.admon.extraConfig}
|
|
|
|
'';
|
|
|
|
|
|
|
|
configMeta = name: cfg: pkgs.writeText "meta-${name}.conf" ''
|
|
|
|
storeMetaDirectory = ${cfg.meta.storeDir}
|
|
|
|
sysMgmtdHost = ${cfg.mgmtdHost}
|
|
|
|
connAuthFile = ${cfg.connAuthFile}
|
|
|
|
connPortShift = ${toString cfg.connPortShift}
|
|
|
|
storeAllowFirstRunInit = false
|
|
|
|
|
|
|
|
${cfg.mgmtd.extraConfig}
|
|
|
|
'';
|
|
|
|
|
|
|
|
configStorage = name: cfg: pkgs.writeText "storage-${name}.conf" ''
|
|
|
|
storeStorageDirectory = ${cfg.storage.storeDir}
|
|
|
|
sysMgmtdHost = ${cfg.mgmtdHost}
|
|
|
|
connAuthFile = ${cfg.connAuthFile}
|
|
|
|
connPortShift = ${toString cfg.connPortShift}
|
|
|
|
storeAllowFirstRunInit = false
|
|
|
|
|
|
|
|
${cfg.storage.extraConfig}
|
|
|
|
'';
|
|
|
|
|
|
|
|
configHelperd = name: cfg: pkgs.writeText "helperd-${name}.conf" ''
|
|
|
|
connAuthFile = ${cfg.connAuthFile}
|
|
|
|
${cfg.helperd.extraConfig}
|
|
|
|
'';
|
|
|
|
|
|
|
|
configClientFilename = name : "/etc/beegfs/client-${name}.conf";
|
|
|
|
|
|
|
|
configClient = name: cfg: ''
|
|
|
|
sysMgmtdHost = ${cfg.mgmtdHost}
|
|
|
|
connAuthFile = ${cfg.connAuthFile}
|
|
|
|
connPortShift = ${toString cfg.connPortShift}
|
|
|
|
|
|
|
|
${cfg.client.extraConfig}
|
|
|
|
'';
|
|
|
|
|
|
|
|
serviceList = [
|
|
|
|
{ service = "admon"; cfgFile = configAdmon; }
|
|
|
|
{ service = "meta"; cfgFile = configMeta; }
|
|
|
|
{ service = "mgmtd"; cfgFile = configMgmtd; }
|
|
|
|
{ service = "storage"; cfgFile = configStorage; }
|
|
|
|
];
|
|
|
|
|
|
|
|
# functions to generate systemd.service entries
|
|
|
|
|
|
|
|
systemdEntry = service: cfgFile: (mapAttrs' ( name: cfg:
|
|
|
|
(nameValuePair "beegfs-${service}-${name}" (mkIf cfg."${service}".enable {
|
|
|
|
wantedBy = [ "multi-user.target" ];
|
|
|
|
requires = [ "network-online.target" ];
|
|
|
|
after = [ "network-online.target" ];
|
|
|
|
serviceConfig = rec {
|
|
|
|
ExecStart = ''
|
|
|
|
${pkgs.beegfs}/bin/beegfs-${service} \
|
|
|
|
cfgFile=${cfgFile name cfg} \
|
|
|
|
pidFile=${PIDFile}
|
|
|
|
'';
|
|
|
|
PIDFile = "/run/beegfs-${service}-${name}.pid";
|
|
|
|
TimeoutStopSec = "300";
|
|
|
|
};
|
|
|
|
}))) cfg);
|
|
|
|
|
|
|
|
systemdHelperd = mapAttrs' ( name: cfg:
|
|
|
|
(nameValuePair "beegfs-helperd-${name}" (mkIf cfg.client.enable {
|
|
|
|
wantedBy = [ "multi-user.target" ];
|
|
|
|
requires = [ "network-online.target" ];
|
|
|
|
after = [ "network-online.target" ];
|
|
|
|
serviceConfig = rec {
|
|
|
|
ExecStart = ''
|
|
|
|
${pkgs.beegfs}/bin/beegfs-helperd \
|
|
|
|
cfgFile=${configHelperd name cfg} \
|
|
|
|
pidFile=${PIDFile}
|
|
|
|
'';
|
|
|
|
PIDFile = "/run/beegfs-helperd-${name}.pid";
|
|
|
|
TimeoutStopSec = "300";
|
|
|
|
};
|
|
|
|
}))) cfg;
|
|
|
|
|
|
|
|
# wrappers to beegfs tools. Avoid typing path of config files
|
|
|
|
utilWrappers = mapAttrsToList ( name: cfg:
|
|
|
|
( pkgs.runCommand "beegfs-utils-${name}" { nativeBuildInputs = [ pkgs.makeWrapper ]; } ''
|
|
|
|
mkdir -p $out/bin
|
|
|
|
|
|
|
|
makeWrapper ${pkgs.beegfs}/bin/beegfs-check-servers \
|
|
|
|
$out/bin/beegfs-check-servers-${name} \
|
|
|
|
--add-flags "-c ${configClientFilename name}" \
|
|
|
|
--prefix PATH : ${lib.makeBinPath [ pkgs.beegfs ]}
|
|
|
|
|
|
|
|
makeWrapper ${pkgs.beegfs}/bin/beegfs-ctl \
|
|
|
|
$out/bin/beegfs-ctl-${name} \
|
|
|
|
--add-flags "--cfgFile=${configClientFilename name}"
|
|
|
|
|
|
|
|
makeWrapper ${pkgs.beegfs}/bin/beegfs-ctl \
|
|
|
|
$out/bin/beegfs-df-${name} \
|
|
|
|
--add-flags "--cfgFile=${configClientFilename name}" \
|
|
|
|
--add-flags --listtargets \
|
|
|
|
--add-flags --hidenodeid \
|
|
|
|
--add-flags --pools \
|
|
|
|
--add-flags --spaceinfo
|
|
|
|
|
|
|
|
makeWrapper ${pkgs.beegfs}/bin/beegfs-fsck \
|
|
|
|
$out/bin/beegfs-fsck-${name} \
|
|
|
|
--add-flags "--cfgFile=${configClientFilename name}"
|
|
|
|
''
|
|
|
|
)) cfg;
|
|
|
|
in
|
|
|
|
{
|
|
|
|
###### interface
|
|
|
|
|
|
|
|
options = {
|
|
|
|
services.beegfsEnable = mkEnableOption "BeeGFS";
|
|
|
|
|
|
|
|
services.beegfs = mkOption {
|
|
|
|
default = {};
|
|
|
|
description = ''
|
|
|
|
BeeGFS configurations. Every mount point requires a separate configuration.
|
|
|
|
'';
|
|
|
|
type = with types; attrsOf (submodule ({ config, ... } : {
|
|
|
|
options = {
|
|
|
|
mgmtdHost = mkOption {
|
|
|
|
type = types.str;
|
|
|
|
default = null;
|
|
|
|
example = "master";
|
|
|
|
description = ''Hostname of managament host.'';
|
|
|
|
};
|
|
|
|
|
|
|
|
connAuthFile = mkOption {
|
|
|
|
type = types.str;
|
|
|
|
default = "";
|
|
|
|
example = "/etc/my.key";
|
|
|
|
description = "File containing shared secret authentication.";
|
|
|
|
};
|
|
|
|
|
|
|
|
connPortShift = mkOption {
|
|
|
|
type = types.int;
|
|
|
|
default = 0;
|
|
|
|
example = 5;
|
|
|
|
description = ''
|
|
|
|
For each additional beegfs configuration shift all
|
|
|
|
service TCP/UDP ports by at least 5.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
client = {
|
|
|
|
enable = mkEnableOption "BeeGFS client";
|
|
|
|
|
|
|
|
mount = mkOption {
|
|
|
|
type = types.bool;
|
|
|
|
default = true;
|
|
|
|
description = "Create fstab entry automatically";
|
|
|
|
};
|
|
|
|
|
|
|
|
mountPoint = mkOption {
|
|
|
|
type = types.str;
|
|
|
|
default = "/run/beegfs";
|
|
|
|
description = ''
|
|
|
|
Mount point under which the beegfs filesytem should be mounted.
|
|
|
|
If mounted manually the mount option specifing the config file is needed:
|
2017-12-31 08:51:21 +01:00
|
|
|
cfgFile=/etc/beegfs/beegfs-client-<name>.conf
|
2017-12-29 02:51:42 +01:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
extraConfig = mkOption {
|
|
|
|
type = types.lines;
|
|
|
|
default = "";
|
|
|
|
description = ''
|
|
|
|
Additional lines for beegfs-client.conf.
|
|
|
|
See documentation for further details.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
helperd = {
|
|
|
|
extraConfig = mkOption {
|
|
|
|
type = types.lines;
|
|
|
|
default = "";
|
|
|
|
description = ''
|
|
|
|
Additional lines for beegfs-helperd.conf. See documentation
|
|
|
|
for further details.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
mgmtd = {
|
|
|
|
enable = mkEnableOption "BeeGFS mgmtd daemon";
|
|
|
|
|
|
|
|
storeDir = mkOption {
|
|
|
|
type = types.path;
|
|
|
|
default = null;
|
|
|
|
example = "/data/beegfs-mgmtd";
|
|
|
|
description = ''
|
|
|
|
Data directory for mgmtd.
|
|
|
|
Must not be shared with other beegfs daemons.
|
|
|
|
This directory must exist and it must be initialized
|
2017-12-31 08:51:21 +01:00
|
|
|
with beegfs-setup-mgmtd, e.g. "beegfs-setup-mgmtd -C -p <storeDir>"
|
2017-12-29 02:51:42 +01:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
extraConfig = mkOption {
|
|
|
|
type = types.lines;
|
|
|
|
default = "";
|
|
|
|
description = ''
|
|
|
|
Additional lines for beegfs-mgmtd.conf. See documentation
|
|
|
|
for further details.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
admon = {
|
|
|
|
enable = mkEnableOption "BeeGFS admon daemon";
|
|
|
|
|
|
|
|
extraConfig = mkOption {
|
|
|
|
type = types.lines;
|
|
|
|
default = "";
|
|
|
|
description = ''
|
|
|
|
Additional lines for beegfs-admon.conf. See documentation
|
|
|
|
for further details.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
meta = {
|
|
|
|
enable = mkEnableOption "BeeGFS meta data daemon";
|
|
|
|
|
|
|
|
storeDir = mkOption {
|
|
|
|
type = types.path;
|
|
|
|
default = null;
|
|
|
|
example = "/data/beegfs-meta";
|
|
|
|
description = ''
|
|
|
|
Data directory for meta data service.
|
|
|
|
Must not be shared with other beegfs daemons.
|
|
|
|
The underlying filesystem must be mounted with xattr turned on.
|
|
|
|
This directory must exist and it must be initialized
|
|
|
|
with beegfs-setup-meta, e.g.
|
2017-12-31 08:51:21 +01:00
|
|
|
"beegfs-setup-meta -C -s <serviceID> -p <storeDir>"
|
2017-12-29 02:51:42 +01:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
extraConfig = mkOption {
|
|
|
|
type = types.str;
|
|
|
|
default = "";
|
|
|
|
description = ''
|
|
|
|
Additional lines for beegfs-meta.conf. See documentation
|
|
|
|
for further details.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
storage = {
|
|
|
|
enable = mkEnableOption "BeeGFS storage daemon";
|
|
|
|
|
|
|
|
storeDir = mkOption {
|
|
|
|
type = types.path;
|
|
|
|
default = null;
|
|
|
|
example = "/data/beegfs-storage";
|
|
|
|
description = ''
|
|
|
|
Data directories for storage service.
|
|
|
|
Must not be shared with other beegfs daemons.
|
|
|
|
The underlying filesystem must be mounted with xattr turned on.
|
|
|
|
This directory must exist and it must be initialized
|
|
|
|
with beegfs-setup-storage, e.g.
|
2017-12-31 08:51:21 +01:00
|
|
|
"beegfs-setup-storage -C -s <serviceID> -i <storageTargetID> -p <storeDir>"
|
2017-12-29 02:51:42 +01:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
extraConfig = mkOption {
|
|
|
|
type = types.str;
|
|
|
|
default = "";
|
|
|
|
description = ''
|
|
|
|
Addional lines for beegfs-storage.conf. See documentation
|
|
|
|
for further details.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
}));
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
###### implementation
|
|
|
|
|
|
|
|
config =
|
|
|
|
mkIf config.services.beegfsEnable {
|
|
|
|
|
|
|
|
environment.systemPackages = utilWrappers;
|
|
|
|
|
|
|
|
# Put the client.conf files in /etc since they are needed
|
|
|
|
# by the commandline tools
|
|
|
|
environment.etc = mapAttrs' ( name: cfg:
|
|
|
|
(nameValuePair "beegfs/client-${name}.conf" (mkIf (cfg.client.enable)
|
|
|
|
{
|
|
|
|
enable = true;
|
|
|
|
text = configClient name cfg;
|
|
|
|
}))) cfg;
|
|
|
|
|
|
|
|
# Kernel module, we need it only once per host.
|
|
|
|
boot = mkIf (
|
|
|
|
foldr (a: b: a || b) false
|
|
|
|
(map (x: x.client.enable) (collect (x: x ? client) cfg)))
|
|
|
|
{
|
|
|
|
kernelModules = [ "beegfs" ];
|
|
|
|
extraModulePackages = [ pkgs.linuxPackages.beegfs-module ];
|
|
|
|
};
|
|
|
|
|
|
|
|
# generate fstab entries
|
|
|
|
fileSystems = mapAttrs' (name: cfg:
|
|
|
|
(nameValuePair cfg.client.mountPoint (optionalAttrs cfg.client.mount (mkIf cfg.client.enable {
|
|
|
|
device = "beegfs_nodev";
|
|
|
|
fsType = "beegfs";
|
|
|
|
mountPoint = cfg.client.mountPoint;
|
|
|
|
options = [ "cfgFile=${configClientFilename name}" "_netdev" ];
|
|
|
|
})))) cfg;
|
|
|
|
|
|
|
|
# generate systemd services
|
|
|
|
systemd.services = systemdHelperd //
|
|
|
|
foldr (a: b: a // b) {}
|
|
|
|
(map (x: systemdEntry x.service x.cfgFile) serviceList);
|
|
|
|
};
|
|
|
|
}
|