{ config, lib, pkgs, ... }: with lib; let cfg = config.services.slurm; # configuration file can be generated by http://slurm.schedmd.com/configurator.html defaultUser = "slurm"; configFile = pkgs.writeTextDir "slurm.conf" '' ClusterName=${cfg.clusterName} StateSaveLocation=${cfg.stateSaveLocation} SlurmUser=${cfg.user} ${optionalString (cfg.controlMachine != null) ''controlMachine=${cfg.controlMachine}''} ${optionalString (cfg.controlAddr != null) ''controlAddr=${cfg.controlAddr}''} ${toString (map (x: "NodeName=${x}\n") cfg.nodeName)} ${toString (map (x: "PartitionName=${x}\n") cfg.partitionName)} PlugStackConfig=${plugStackConfig} ProctrackType=${cfg.procTrackType} ${cfg.extraConfig} ''; plugStackConfig = pkgs.writeTextDir "plugstack.conf" '' ${optionalString cfg.enableSrunX11 ''optional ${pkgs.slurm-spank-x11}/lib/x11.so''} ${cfg.extraPlugstackConfig} ''; cgroupConfig = pkgs.writeTextDir "cgroup.conf" '' ${cfg.extraCgroupConfig} ''; slurmdbdConf = pkgs.writeTextDir "slurmdbd.conf" '' DbdHost=${cfg.dbdserver.dbdHost} SlurmUser=${cfg.user} StorageType=accounting_storage/mysql ${cfg.dbdserver.extraConfig} ''; # slurm expects some additional config files to be # in the same directory as slurm.conf etcSlurm = pkgs.symlinkJoin { name = "etc-slurm"; paths = [ configFile cgroupConfig plugStackConfig ]; }; in { ###### interface meta.maintainers = [ maintainers.markuskowa ]; options = { services.slurm = { server = { enable = mkOption { type = types.bool; default = false; description = '' Wether to enable the slurm control daemon. Note that the standard authentication method is "munge". The "munge" service needs to be provided with a password file in order for slurm to work properly (see services.munge.password). ''; }; }; dbdserver = { enable = mkEnableOption "SlurmDBD service"; dbdHost = mkOption { type = types.str; default = config.networking.hostName; description = '' Hostname of the machine where slurmdbd is running (i.e. name returned by hostname -s). ''; }; extraConfig = mkOption { type = types.lines; default = ""; description = '' Extra configuration for slurmdbd.conf ''; }; }; client = { enable = mkEnableOption "slurm client daemon"; }; enableStools = mkOption { type = types.bool; default = false; description = '' Wether to provide a slurm.conf file. Enable this option if you do not run a slurm daemon on this host (i.e. server.enable and client.enable are false) but you still want to run slurm commands from this host. ''; }; package = mkOption { type = types.package; default = pkgs.slurm; defaultText = "pkgs.slurm"; example = literalExample "pkgs.slurm-full"; description = '' The package to use for slurm binaries. ''; }; controlMachine = mkOption { type = types.nullOr types.str; default = null; example = null; description = '' The short hostname of the machine where SLURM control functions are executed (i.e. the name returned by the command "hostname -s", use "tux001" rather than "tux001.my.com"). ''; }; controlAddr = mkOption { type = types.nullOr types.str; default = cfg.controlMachine; example = null; description = '' Name that ControlMachine should be referred to in establishing a communications path. ''; }; clusterName = mkOption { type = types.str; default = "default"; example = "myCluster"; description = '' Necessary to distinguish accounting records in a multi-cluster environment. ''; }; nodeName = mkOption { type = types.listOf types.str; default = []; example = literalExample ''[ "linux[1-32] CPUs=1 State=UNKNOWN" ];''; description = '' Name that SLURM uses to refer to a node (or base partition for BlueGene systems). Typically this would be the string that "/bin/hostname -s" returns. Note that now you have to write node's parameters after the name. ''; }; partitionName = mkOption { type = types.listOf types.str; default = []; example = literalExample ''[ "debug Nodes=linux[1-32] Default=YES MaxTime=INFINITE State=UP" ];''; description = '' Name by which the partition may be referenced. Note that now you have to write the partition's parameters after the name. ''; }; enableSrunX11 = mkOption { default = false; type = types.bool; description = '' If enabled srun will accept the option "--x11" to allow for X11 forwarding from within an interactive session or a batch job. This activates the slurm-spank-x11 module. Note that this option also enables 'services.openssh.forwardX11' on the client. This option requires slurm to be compiled without native X11 support. ''; }; procTrackType = mkOption { type = types.str; default = "proctrack/linuxproc"; description = '' Plugin to be used for process tracking on a job step basis. The slurmd daemon uses this mechanism to identify all processes which are children of processes it spawns for a user job step. ''; }; stateSaveLocation = mkOption { type = types.str; default = "/var/spool/slurmctld"; description = '' Directory into which the Slurm controller, slurmctld, saves its state. ''; }; user = mkOption { type = types.str; default = defaultUser; description = '' Set this option when you want to run the slurmctld daemon as something else than the default slurm user "slurm". Note that the UID of this user needs to be the same on all nodes. ''; }; extraConfig = mkOption { default = ""; type = types.lines; description = '' Extra configuration options that will be added verbatim at the end of the slurm configuration file. ''; }; extraPlugstackConfig = mkOption { default = ""; type = types.lines; description = '' Extra configuration that will be added to the end of plugstack.conf. ''; }; extraCgroupConfig = mkOption { default = ""; type = types.lines; description = '' Extra configuration for cgroup.conf. This file is used when procTrackType=proctrack/cgroup. ''; }; }; }; ###### implementation config = let wrappedSlurm = pkgs.stdenv.mkDerivation { name = "wrappedSlurm"; builder = pkgs.writeText "builder.sh" '' source $stdenv/setup mkdir -p $out/bin find ${getBin cfg.package}/bin -type f -executable | while read EXE do exename="$(basename $EXE)" wrappername="$out/bin/$exename" cat > "$wrappername" <