diff --git a/lib/ood_core.rb b/lib/ood_core.rb index aa25ad73c..019af8120 100644 --- a/lib/ood_core.rb +++ b/lib/ood_core.rb @@ -12,6 +12,7 @@ module Job require "ood_core/job/script" require "ood_core/job/info" require "ood_core/job/cluster_info" + require "ood_core/job/queue_info" require "ood_core/job/status" require "ood_core/job/adapter" require "ood_core/job/factory" diff --git a/lib/ood_core/job/adapter.rb b/lib/ood_core/job/adapter.rb index 6fc36f51b..c0a371de2 100644 --- a/lib/ood_core/job/adapter.rb +++ b/lib/ood_core/job/adapter.rb @@ -197,6 +197,13 @@ def sanitize_job_name(job_name) def job_name_illegal_chars ENV["OOD_JOB_NAME_ILLEGAL_CHARS"].to_s end + + # Return the list of queues for this scheduler. + # + # @return [Array] + def queues + [] + end end end end diff --git a/lib/ood_core/job/adapters/slurm.rb b/lib/ood_core/job/adapters/slurm.rb index 60f067c34..23f23c92f 100644 --- a/lib/ood_core/job/adapters/slurm.rb +++ b/lib/ood_core/job/adapters/slurm.rb @@ -300,7 +300,37 @@ def all_squeue_fields } end + def queues + info_raw = call('scontrol', 'show', 'part', '-o') + + [].tap do |ret_arr| + info_raw.each_line do |line| + ret_arr << str_to_acct_info(line) + end + end + end + private + def str_to_acct_info(line) + hsh = line.split(' ').map do |token| + m = token.match(/^(?\w+)=(?.+)$/) + [m[:key], m[:value]] + end.to_h.symbolize_keys + + hsh[:name] = hsh[:PartitionName] + hsh[:qos] = hsh[:QoS].to_s == 'N/A' ? [] : hsh[:QoS].to_s.split(',') + hsh[:allow_accounts] = if hsh[:AllowAccounts].nil? || hsh[:AllowAccounts].to_s == 'ALL' + nil + else + hsh[:AllowAccounts].to_s.split(',') + end + + + hsh[:deny_accounts] = hsh[:DenyAccounts].nil? ? [] : hsh[:DenyAccounts].to_s.split(',') + + OodCore::Job::QueueInfo.new(**hsh) + end + # Modify the StringIO instance by advancing past the squeue header # # The first two "records" should always be discarded. Consider the @@ -605,6 +635,10 @@ def directive_prefix '#SBATCH' end + def queues + @slurm.queues + end + private # Convert duration to seconds def duration_in_seconds(time) diff --git a/lib/ood_core/job/queue_info.rb b/lib/ood_core/job/queue_info.rb new file mode 100644 index 000000000..085e68721 --- /dev/null +++ b/lib/ood_core/job/queue_info.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +# QueueInfo is information about a given queue on a scheduler. +class OodCore::Job::QueueInfo + # The name of the queue. + attr_reader :name + alias to_s name + + # The QoSes associated with this queue + attr_reader :qos + + # The accounts that are allowed to use this queue. + # + # nil means ALL accounts are allowed. + attr_reader :allow_accounts + + # The accounts that are not allowed to use this queue. + attr_reader :deny_accounts + + def initialize(**opts) + @name = opts.fetch(:name, 'unknown') + @qos = opts.fetch(:qos, []) + @allow_accounts = opts.fetch(:allow_accounts, nil) + @deny_accounts = opts.fetch(:deny_accounts, []) + end + + def to_h + instance_variables.map do |var| + name = var.to_s.gsub('@', '').to_sym + [name, send(name)] + end.to_h + end +end diff --git a/spec/fixtures/output/slurm/owens_partitions.txt b/spec/fixtures/output/slurm/owens_partitions.txt new file mode 100644 index 000000000..bf947cb0e --- /dev/null +++ b/spec/fixtures/output/slurm/owens_partitions.txt @@ -0,0 +1,14 @@ +PartitionName=batch AllowGroups=ALL DenyAccounts=pcon0003,pcon0014,pcon0015,pcon0016,pcon0401,pcon0008,pas1429,pcon0009,pcon0020,pcon0022,pcon0023,pcon0024,pcon0025,pcon0040,pcon0026,pcon0041,pcon0080,pcon0100,pcon0101,pcon0120,pcon0140,pcon0160,pcon0180,pcon0200,pas1901,pcon0220,pcon0240,pcon0260,pcon0280,pcon0300,pcon0320,pcon0340,pcon0341,pcon0360,pcon0380,pcon0381,pcon0441,pcon0481,pcon0501,pcon0421 AllowQos=ALL AllocNodes=ALL Default=YES QoS=N/A DefaultTime=01:00:00 DisableRootJobs=NO ExclusiveUser=NO GraceTime=0 Hidden=NO MaxNodes=UNLIMITED MaxTime=7-00:00:00 MinNodes=0 LLN=NO MaxCPUsPerNode=UNLIMITED NodeSets=cpu,gpu,hugemem Nodes=o[0002-0006,0008-0011,0013-0183,0185-0261,0263-0399,0401-0499,0501-0647,0649-0659,0661-0701,0703-0722,0724-0805,0809-0824] PriorityJobFactor=1000 PriorityTier=1 RootOnly=NO ReqResv=NO OverSubscribe=NO OverTimeLimit=NONE PreemptMode=OFF State=INACTIVE TotalCPUs=23000 TotalNodes=810 SelectTypeParameters=NONE JobDefaults=(null) DefMemPerNode=UNLIMITED MaxMemPerNode=UNLIMITED TRES=cpu=23000,mem=120391880M,node=810,billing=23000,gres/gpfs:ess=810,gres/gpfs:scratch=810,gres/gpu=154,gres/gpu:p100=154,gres/pfsdir=810,gres/pfsdir:scratch=810,gres/vis=154,license/abaqus@osc=350,license/abaquscae@osc=10,license/ansys@osc=50,license/ansyspar@osc=900,license/comsolscript@osc=3,license/epik@osc=10,license/gauss-billing@osc=50000,license/glide@osc=20,license/ligprep@osc=10,license/lsdyna@osc=1000,license/macromodel@osc=10,license/qikprop@osc=10,license/starccm@osc=80,license/starccmpar@osc=4000,license/stata@osc=5,license/usearch@osc=1 +PartitionName=debug AllowGroups=ALL DenyAccounts=pcon0003,pcon0014,pcon0015,pcon0016,pcon0401,pcon0008,pas1429,pcon0009,pcon0020,pcon0022,pcon0023,pcon0024,pcon0025,pcon0040,pcon0026,pcon0041,pcon0080,pcon0100,pcon0101,pcon0120,pcon0140,pcon0160,pcon0180,pcon0200,pas1901,pcon0220,pcon0240,pcon0260,pcon0280,pcon0300,pcon0320,pcon0340,pcon0341,pcon0360,pcon0380,pcon0381,pcon0441,pcon0481,pcon0501,pcon0421 AllowQos=ALL AllocNodes=ALL Default=NO QoS=debug DefaultTime=00:30:00 DisableRootJobs=NO ExclusiveUser=NO GraceTime=0 Hidden=NO MaxNodes=2 MaxTime=01:00:00 MinNodes=0 LLN=NO MaxCPUsPerNode=28 NodeSets=cpu Nodes=o[0002-0006,0008-0011,0013-0183,0185-0261,0263-0399,0401-0499,0501-0647] PriorityJobFactor=5000 PriorityTier=1 RootOnly=NO ReqResv=NO OverSubscribe=NO OverTimeLimit=NONE PreemptMode=OFF State=UP TotalCPUs=17920 TotalNodes=640 SelectTypeParameters=NONE JobDefaults=(null) DefMemPerCPU=4315 MaxMemPerCPU=4315 TRES=cpu=17920,mem=75512.50G,node=640,billing=17920,gres/gpfs:ess=640,gres/gpfs:scratch=640,gres/pfsdir=640,gres/pfsdir:scratch=640,license/abaqus@osc=350,license/abaquscae@osc=10,license/ansys@osc=50,license/ansyspar@osc=900,license/comsolscript@osc=3,license/epik@osc=10,license/gauss-billing@osc=50000,license/glide@osc=20,license/ligprep@osc=10,license/lsdyna@osc=1000,license/macromodel@osc=10,license/qikprop@osc=10,license/starccm@osc=80,license/starccmpar@osc=4000,license/stata@osc=5,license/usearch@osc=1 +PartitionName=gpubackfill-parallel AllowGroups=ALL DenyAccounts=pcon0003,pcon0014,pcon0015,pcon0016,pcon0401,pcon0008,pas1429,pcon0009,pcon0020,pcon0022,pcon0023,pcon0024,pcon0025,pcon0040,pcon0026,pcon0041,pcon0080,pcon0100,pcon0101,pcon0120,pcon0140,pcon0160,pcon0180,pcon0200,pas1901,pcon0220,pcon0240,pcon0260,pcon0280,pcon0300,pcon0320,pcon0340,pcon0341,pcon0360,pcon0380,pcon0381,pcon0441,pcon0481,pcon0501,pcon0421 AllowQos=ALL AllocNodes=ALL Default=NO QoS=N/A DefaultTime=01:00:00 DisableRootJobs=NO ExclusiveUser=NO GraceTime=0 Hidden=NO MaxNodes=81 MaxTime=04:00:00 MinNodes=2 LLN=NO MaxCPUsPerNode=28 NodeSets=gpu Nodes=o[0649-0659,0661-0701,0703-0722,0724-0805] PriorityJobFactor=1000 PriorityTier=1 RootOnly=NO ReqResv=NO OverSubscribe=EXCLUSIVE OverTimeLimit=NONE PreemptMode=OFF State=UP TotalCPUs=4312 TotalNodes=154 SelectTypeParameters=NONE JobDefaults=(null) DefMemPerCPU=4315 MaxMemPerCPU=4315 TRES=cpu=4312,mem=18606280M,node=154,billing=4312,gres/gpfs:ess=154,gres/gpfs:scratch=154,gres/gpu=154,gres/gpu:p100=154,gres/pfsdir=154,gres/pfsdir:scratch=154,gres/vis=154,license/abaqus@osc=350,license/abaquscae@osc=10,license/ansys@osc=50,license/ansyspar@osc=900,license/comsolscript@osc=3,license/epik@osc=10,license/gauss-billing@osc=50000,license/glide@osc=20,license/ligprep@osc=10,license/lsdyna@osc=1000,license/macromodel@osc=10,license/qikprop@osc=10,license/starccm@osc=80,license/starccmpar@osc=4000,license/stata@osc=5,license/usearch@osc=1 +PartitionName=gpubackfill-serial AllowGroups=ALL DenyAccounts=pcon0003,pcon0014,pcon0015,pcon0016,pcon0401,pcon0008,pas1429,pcon0009,pcon0020,pcon0022,pcon0023,pcon0024,pcon0025,pcon0040,pcon0026,pcon0041,pcon0080,pcon0100,pcon0101,pcon0120,pcon0140,pcon0160,pcon0180,pcon0200,pas1901,pcon0220,pcon0240,pcon0260,pcon0280,pcon0300,pcon0320,pcon0340,pcon0341,pcon0360,pcon0380,pcon0381,pcon0441,pcon0481,pcon0501,pcon0421 AllowQos=ALL AllocNodes=ALL Default=NO QoS=N/A DefaultTime=01:00:00 DisableRootJobs=NO ExclusiveUser=NO GraceTime=0 Hidden=NO MaxNodes=1 MaxTime=04:00:00 MinNodes=0 LLN=NO MaxCPUsPerNode=28 NodeSets=gpu Nodes=o[0649-0659,0661-0701,0703-0722,0724-0805] PriorityJobFactor=1000 PriorityTier=1 RootOnly=NO ReqResv=NO OverSubscribe=NO OverTimeLimit=NONE PreemptMode=OFF State=UP TotalCPUs=4312 TotalNodes=154 SelectTypeParameters=NONE JobDefaults=(null) DefMemPerCPU=4315 MaxMemPerCPU=4315 TRES=cpu=4312,mem=18606280M,node=154,billing=4312,gres/gpfs:ess=154,gres/gpfs:scratch=154,gres/gpu=154,gres/gpu:p100=154,gres/pfsdir=154,gres/pfsdir:scratch=154,gres/vis=154,license/abaqus@osc=350,license/abaquscae@osc=10,license/ansys@osc=50,license/ansyspar@osc=900,license/comsolscript@osc=3,license/epik@osc=10,license/gauss-billing@osc=50000,license/glide@osc=20,license/ligprep@osc=10,license/lsdyna@osc=1000,license/macromodel@osc=10,license/qikprop@osc=10,license/starccm@osc=80,license/starccmpar@osc=4000,license/stata@osc=5,license/usearch@osc=1 +PartitionName=gpudebug AllowGroups=ALL DenyAccounts=pcon0003,pcon0014,pcon0015,pcon0016,pcon0401,pcon0008,pas1429,pcon0009,pcon0020,pcon0022,pcon0023,pcon0024,pcon0025,pcon0040,pcon0026,pcon0041,pcon0080,pcon0100,pcon0101,pcon0120,pcon0140,pcon0160,pcon0180,pcon0200,pas1901,pcon0220,pcon0240,pcon0260,pcon0280,pcon0300,pcon0320,pcon0340,pcon0341,pcon0360,pcon0380,pcon0381,pcon0441,pcon0481,pcon0501,pcon0421 AllowQos=ALL AllocNodes=ALL Default=NO QoS=gpudebug DefaultTime=00:30:00 DisableRootJobs=NO ExclusiveUser=NO GraceTime=0 Hidden=NO MaxNodes=2 MaxTime=01:00:00 MinNodes=0 LLN=NO MaxCPUsPerNode=28 NodeSets=gpu Nodes=o[0649-0659,0661-0701,0703-0722,0724-0805] PriorityJobFactor=5000 PriorityTier=1 RootOnly=NO ReqResv=NO OverSubscribe=NO OverTimeLimit=NONE PreemptMode=OFF State=UP TotalCPUs=4312 TotalNodes=154 SelectTypeParameters=NONE JobDefaults=(null) DefMemPerCPU=4315 MaxMemPerCPU=4315 TRES=cpu=4312,mem=18606280M,node=154,billing=4312,gres/gpfs:ess=154,gres/gpfs:scratch=154,gres/gpu=154,gres/gpu:p100=154,gres/pfsdir=154,gres/pfsdir:scratch=154,gres/vis=154,license/abaqus@osc=350,license/abaquscae@osc=10,license/ansys@osc=50,license/ansyspar@osc=900,license/comsolscript@osc=3,license/epik@osc=10,license/gauss-billing@osc=50000,license/glide@osc=20,license/ligprep@osc=10,license/lsdyna@osc=1000,license/macromodel@osc=10,license/qikprop@osc=10,license/starccm@osc=80,license/starccmpar@osc=4000,license/stata@osc=5,license/usearch@osc=1 +PartitionName=gpuparallel AllowGroups=ALL DenyAccounts=pcon0003,pcon0014,pcon0015,pcon0016,pcon0401,pcon0008,pas1429,pcon0009,pcon0020,pcon0022,pcon0023,pcon0024,pcon0025,pcon0040,pcon0026,pcon0041,pcon0080,pcon0100,pcon0101,pcon0120,pcon0140,pcon0160,pcon0180,pcon0200,pas1901,pcon0220,pcon0240,pcon0260,pcon0280,pcon0300,pcon0320,pcon0340,pcon0341,pcon0360,pcon0380,pcon0381,pcon0441,pcon0481,pcon0501,pcon0421 AllowQos=ALL AllocNodes=ALL Default=NO QoS=owens-gpu-partition DefaultTime=01:00:00 DisableRootJobs=NO ExclusiveUser=NO GraceTime=0 Hidden=NO MaxNodes=8 MaxTime=4-00:00:00 MinNodes=2 LLN=NO MaxCPUsPerNode=28 NodeSets=gpu Nodes=o[0649-0659,0661-0701,0703-0722,0724-0805] PriorityJobFactor=2000 PriorityTier=1 RootOnly=NO ReqResv=NO OverSubscribe=EXCLUSIVE OverTimeLimit=NONE PreemptMode=OFF State=UP TotalCPUs=4312 TotalNodes=154 SelectTypeParameters=NONE JobDefaults=(null) DefMemPerCPU=4315 MaxMemPerCPU=4315 TRES=cpu=4312,mem=18606280M,node=154,billing=4312,gres/gpfs:ess=154,gres/gpfs:scratch=154,gres/gpu=154,gres/gpu:p100=154,gres/pfsdir=154,gres/pfsdir:scratch=154,gres/vis=154,license/abaqus@osc=350,license/abaquscae@osc=10,license/ansys@osc=50,license/ansyspar@osc=900,license/comsolscript@osc=3,license/epik@osc=10,license/gauss-billing@osc=50000,license/glide@osc=20,license/ligprep@osc=10,license/lsdyna@osc=1000,license/macromodel@osc=10,license/qikprop@osc=10,license/starccm@osc=80,license/starccmpar@osc=4000,license/stata@osc=5,license/usearch@osc=1 +PartitionName=gpuserial AllowGroups=ALL DenyAccounts=pcon0003,pcon0014,pcon0015,pcon0016,pcon0401,pcon0008,pas1429,pcon0009,pcon0020,pcon0022,pcon0023,pcon0024,pcon0025,pcon0040,pcon0026,pcon0041,pcon0080,pcon0100,pcon0101,pcon0120,pcon0140,pcon0160,pcon0180,pcon0200,pas1901,pcon0220,pcon0240,pcon0260,pcon0280,pcon0300,pcon0320,pcon0340,pcon0341,pcon0360,pcon0380,pcon0381,pcon0441,pcon0481,pcon0501,pcon0421 AllowQos=ALL AllocNodes=ALL Default=NO QoS=owens-gpu-partition DefaultTime=01:00:00 DisableRootJobs=NO ExclusiveUser=NO GraceTime=0 Hidden=NO MaxNodes=1 MaxTime=7-00:00:00 MinNodes=0 LLN=NO MaxCPUsPerNode=28 NodeSets=gpu Nodes=o[0649-0659,0661-0701,0703-0722,0724-0805] PriorityJobFactor=2000 PriorityTier=1 RootOnly=NO ReqResv=NO OverSubscribe=NO OverTimeLimit=NONE PreemptMode=OFF State=UP TotalCPUs=4312 TotalNodes=154 SelectTypeParameters=NONE JobDefaults=(null) DefMemPerCPU=4315 MaxMemPerCPU=4315 TRES=cpu=4312,mem=18606280M,node=154,billing=4312,gres/gpfs:ess=154,gres/gpfs:scratch=154,gres/gpu=154,gres/gpu:p100=154,gres/pfsdir=154,gres/pfsdir:scratch=154,gres/vis=154,license/abaqus@osc=350,license/abaquscae@osc=10,license/ansys@osc=50,license/ansyspar@osc=900,license/comsolscript@osc=3,license/epik@osc=10,license/gauss-billing@osc=50000,license/glide@osc=20,license/ligprep@osc=10,license/lsdyna@osc=1000,license/macromodel@osc=10,license/qikprop@osc=10,license/starccm@osc=80,license/starccmpar@osc=4000,license/stata@osc=5,license/usearch@osc=1 +PartitionName=hugemem AllowGroups=ALL DenyAccounts=pcon0003,pcon0014,pcon0015,pcon0016,pcon0401,pcon0008,pas1429,pcon0009,pcon0020,pcon0022,pcon0023,pcon0024,pcon0025,pcon0040,pcon0026,pcon0041,pcon0080,pcon0100,pcon0101,pcon0120,pcon0140,pcon0160,pcon0180,pcon0200,pas1901,pcon0220,pcon0240,pcon0260,pcon0280,pcon0300,pcon0320,pcon0340,pcon0341,pcon0360,pcon0380,pcon0381,pcon0441,pcon0481,pcon0501,pcon0421 AllowQos=ALL AllocNodes=ALL Default=NO QoS=owens-hugemem-partition DefaultTime=01:00:00 DisableRootJobs=NO ExclusiveUser=NO GraceTime=0 Hidden=NO MaxNodes=1 MaxTime=7-00:00:00 MinNodes=0 LLN=NO MaxCPUsPerNode=48 NodeSets=hugemem Nodes=o[0809-0824] PriorityJobFactor=1000 PriorityTier=1 RootOnly=NO ReqResv=NO OverSubscribe=NO OverTimeLimit=NONE PreemptMode=OFF State=UP TotalCPUs=768 TotalNodes=16 SelectTypeParameters=NONE JobDefaults=(null) DefMemPerCPU=31850 MaxMemPerCPU=31850 TRES=cpu=768,mem=23887.50G,node=16,billing=768,gres/gpfs:ess=16,gres/gpfs:scratch=16,gres/pfsdir=16,gres/pfsdir:scratch=16,license/abaqus@osc=350,license/abaquscae@osc=10,license/ansys@osc=50,license/ansyspar@osc=900,license/comsolscript@osc=3,license/epik@osc=10,license/gauss-billing@osc=50000,license/glide@osc=20,license/ligprep@osc=10,license/lsdyna@osc=1000,license/macromodel@osc=10,license/qikprop@osc=10,license/starccm@osc=80,license/starccmpar@osc=4000,license/stata@osc=5,license/usearch@osc=1 +PartitionName=hugemem-parallel AllowGroups=ALL AllowAccounts=pzs0708,pzs0710,pzs0712,pas1061,pys0343,pes0843 AllowQos=ALL AllocNodes=ALL Default=NO QoS=N/A DefaultTime=01:00:00 DisableRootJobs=NO ExclusiveUser=NO GraceTime=0 Hidden=NO MaxNodes=16 MaxTime=4-00:00:00 MinNodes=2 LLN=NO MaxCPUsPerNode=48 NodeSets=hugemem Nodes=o[0809-0824] PriorityJobFactor=1000 PriorityTier=1 RootOnly=NO ReqResv=NO OverSubscribe=NO OverTimeLimit=NONE PreemptMode=OFF State=UP TotalCPUs=768 TotalNodes=16 SelectTypeParameters=NONE JobDefaults=(null) DefMemPerCPU=31850 MaxMemPerCPU=31850 TRES=cpu=768,mem=23887.50G,node=16,billing=768,gres/gpfs:ess=16,gres/gpfs:scratch=16,gres/pfsdir=16,gres/pfsdir:scratch=16,license/abaqus@osc=350,license/abaquscae@osc=10,license/ansys@osc=50,license/ansyspar@osc=900,license/comsolscript@osc=3,license/epik@osc=10,license/gauss-billing@osc=50000,license/glide@osc=20,license/ligprep@osc=10,license/lsdyna@osc=1000,license/macromodel@osc=10,license/qikprop@osc=10,license/starccm@osc=80,license/starccmpar@osc=4000,license/stata@osc=5,license/usearch@osc=1 +PartitionName=longserial AllowGroups=ALL AllowAccounts=pjs0246,pas0300,paa0008,pas1178,paa0026,pas1245,pas1350,pas0578,pds0281,pas0107,pas0471,pan0092,pes0597,pas0426,pzs0708,pzs0710,pcon0005,paa0010,pas1554,pys1044,pjs0320,pas1674,pas1289,pas1963,pan0092,pas1963,pas1583 AllowQos=ALL AllocNodes=ALL Default=NO QoS=N/A DefaultTime=01:00:00 DisableRootJobs=NO ExclusiveUser=NO GraceTime=0 Hidden=NO MaxNodes=1 MaxTime=14-00:00:00 MinNodes=0 LLN=NO MaxCPUsPerNode=28 NodeSets=cpu Nodes=o[0002-0006,0008-0011,0013-0183,0185-0261,0263-0399,0401-0499,0501-0647] PriorityJobFactor=1000 PriorityTier=1 RootOnly=NO ReqResv=NO OverSubscribe=NO OverTimeLimit=NONE PreemptMode=OFF State=UP TotalCPUs=17920 TotalNodes=640 SelectTypeParameters=NONE JobDefaults=(null) DefMemPerCPU=4315 MaxMemPerCPU=4315 TRES=cpu=17920,mem=75512.50G,node=640,billing=17920,gres/gpfs:ess=640,gres/gpfs:scratch=640,gres/pfsdir=640,gres/pfsdir:scratch=640,license/abaqus@osc=350,license/abaquscae@osc=10,license/ansys@osc=50,license/ansyspar@osc=900,license/comsolscript@osc=3,license/epik@osc=10,license/gauss-billing@osc=50000,license/glide@osc=20,license/ligprep@osc=10,license/lsdyna@osc=1000,license/macromodel@osc=10,license/qikprop@osc=10,license/starccm@osc=80,license/starccmpar@osc=4000,license/stata@osc=5,license/usearch@osc=1 +PartitionName=parallel AllowGroups=ALL DenyAccounts=pcon0003,pcon0014,pcon0015,pcon0016,pcon0401,pcon0008,pas1429,pcon0009,pcon0020,pcon0022,pcon0023,pcon0024,pcon0025,pcon0040,pcon0026,pcon0041,pcon0080,pcon0100,pcon0101,pcon0120,pcon0140,pcon0160,pcon0180,pcon0200,pas1901,pcon0220,pcon0240,pcon0260,pcon0280,pcon0300,pcon0320,pcon0340,pcon0341,pcon0360,pcon0380,pcon0381,pcon0441,pcon0481,pcon0501,pcon0421 AllowQos=ALL AllocNodes=ALL Default=NO QoS=N/A DefaultTime=01:00:00 DisableRootJobs=NO ExclusiveUser=NO GraceTime=0 Hidden=NO MaxNodes=81 MaxTime=4-00:00:00 MinNodes=2 LLN=NO MaxCPUsPerNode=28 NodeSets=cpu Nodes=o[0002-0006,0008-0011,0013-0183,0185-0261,0263-0399,0401-0499,0501-0647] PriorityJobFactor=2000 PriorityTier=1 RootOnly=NO ReqResv=NO OverSubscribe=EXCLUSIVE OverTimeLimit=NONE PreemptMode=OFF State=UP TotalCPUs=17920 TotalNodes=640 SelectTypeParameters=NONE JobDefaults=(null) DefMemPerCPU=4315 MaxMemPerCPU=4315 TRES=cpu=17920,mem=75512.50G,node=640,billing=17920,gres/gpfs:ess=640,gres/gpfs:scratch=640,gres/pfsdir=640,gres/pfsdir:scratch=640,license/abaqus@osc=350,license/abaquscae@osc=10,license/ansys@osc=50,license/ansyspar@osc=900,license/comsolscript@osc=3,license/epik@osc=10,license/gauss-billing@osc=50000,license/glide@osc=20,license/ligprep@osc=10,license/lsdyna@osc=1000,license/macromodel@osc=10,license/qikprop@osc=10,license/starccm@osc=80,license/starccmpar@osc=4000,license/stata@osc=5,license/usearch@osc=1 +PartitionName=quick AllowGroups=ALL DenyAccounts=pcon0003,pcon0014,pcon0015,pcon0016,pcon0401,pcon0008,pas1429,pcon0009,pcon0020,pcon0022,pcon0023,pcon0024,pcon0025,pcon0040,pcon0026,pcon0041,pcon0080,pcon0100,pcon0101,pcon0120,pcon0140,pcon0160,pcon0180,pcon0200,pas1901,pcon0220,pcon0240,pcon0260,pcon0280,pcon0300,pcon0320,pcon0340,pcon0341,pcon0360,pcon0380,pcon0381,pcon0441,pcon0481,pcon0501,pcon0421 AllowQos=ALL AllocNodes=web[02-09],webtest[02-09],webdev[02-09],owens-rw[01-02] Default=NO QoS=quick DefaultTime=01:00:00 DisableRootJobs=NO ExclusiveUser=NO GraceTime=0 Hidden=YES MaxNodes=2 MaxTime=1-00:00:00 MinNodes=0 LLN=NO MaxCPUsPerNode=28 NodeSets=quick Nodes=o[0807-0808] PriorityJobFactor=10000 PriorityTier=1 RootOnly=NO ReqResv=NO OverSubscribe=NO OverTimeLimit=NONE PreemptMode=OFF State=UP TotalCPUs=56 TotalNodes=2 SelectTypeParameters=NONE JobDefaults=(null) DefMemPerCPU=4315 MaxMemPerCPU=4315 TRES=cpu=56,mem=241640M,node=2,billing=56,gres/gpfs:ess=2,gres/gpfs:scratch=2,gres/pfsdir=2,gres/pfsdir:scratch=2,license/abaqus@osc=350,license/abaquscae@osc=10,license/ansys@osc=50,license/ansyspar@osc=900,license/comsolscript@osc=3,license/epik@osc=10,license/gauss-billing@osc=50000,license/glide@osc=20,license/ligprep@osc=10,license/lsdyna@osc=1000,license/macromodel@osc=10,license/qikprop@osc=10,license/starccm@osc=80,license/starccmpar@osc=4000,license/stata@osc=5,license/usearch@osc=1 +PartitionName=serial AllowGroups=ALL DenyAccounts=pcon0003,pcon0014,pcon0015,pcon0016,pcon0401,pcon0008,pas1429,pcon0009,pcon0020,pcon0022,pcon0023,pcon0024,pcon0025,pcon0040,pcon0026,pcon0041,pcon0080,pcon0100,pcon0101,pcon0120,pcon0140,pcon0160,pcon0180,pcon0200,pas1901,pcon0220,pcon0240,pcon0260,pcon0280,pcon0300,pcon0320,pcon0340,pcon0341,pcon0360,pcon0380,pcon0381,pcon0441,pcon0481,pcon0501,pcon0421 AllowQos=ALL AllocNodes=ALL Default=NO QoS=N/A DefaultTime=01:00:00 DisableRootJobs=NO ExclusiveUser=NO GraceTime=0 Hidden=NO MaxNodes=1 MaxTime=7-00:00:00 MinNodes=0 LLN=NO MaxCPUsPerNode=28 NodeSets=cpu Nodes=o[0002-0006,0008-0011,0013-0183,0185-0261,0263-0399,0401-0499,0501-0647] PriorityJobFactor=2000 PriorityTier=1 RootOnly=NO ReqResv=NO OverSubscribe=NO OverTimeLimit=NONE PreemptMode=OFF State=UP TotalCPUs=17920 TotalNodes=640 SelectTypeParameters=NONE JobDefaults=(null) DefMemPerCPU=4315 MaxMemPerCPU=4315 TRES=cpu=17920,mem=75512.50G,node=640,billing=17920,gres/gpfs:ess=640,gres/gpfs:scratch=640,gres/pfsdir=640,gres/pfsdir:scratch=640,license/abaqus@osc=350,license/abaquscae@osc=10,license/ansys@osc=50,license/ansyspar@osc=900,license/comsolscript@osc=3,license/epik@osc=10,license/gauss-billing@osc=50000,license/glide@osc=20,license/ligprep@osc=10,license/lsdyna@osc=1000,license/macromodel@osc=10,license/qikprop@osc=10,license/starccm@osc=80,license/starccmpar@osc=4000,license/stata@osc=5,license/usearch@osc=1 +PartitionName=systems AllowGroups=ALL AllowAccounts=root,pzs0708,pzs0710,pzs0722 AllowQos=ALL AllocNodes=ALL Default=NO QoS=N/A DefaultTime=NONE DisableRootJobs=NO ExclusiveUser=NO GraceTime=0 Hidden=NO MaxNodes=UNLIMITED MaxTime=UNLIMITED MinNodes=0 LLN=NO MaxCPUsPerNode=UNLIMITED NodeSets=allnodes Nodes=o[0002-0006,0008-0011,0013-0183,0185-0261,0263-0399,0401-0499,0501-0647,0649-0659,0661-0701,0703-0722,0724-0805,0807-0824] PriorityJobFactor=10000 PriorityTier=1 RootOnly=NO ReqResv=NO OverSubscribe=NO OverTimeLimit=NONE PreemptMode=OFF State=UP TotalCPUs=23056 TotalNodes=812 SelectTypeParameters=NONE JobDefaults=(null) DefMemPerNode=UNLIMITED MaxMemPerNode=UNLIMITED TRES=cpu=23056,mem=120633520M,node=812,billing=23056,gres/gpfs:ess=812,gres/gpfs:scratch=812,gres/gpu=154,gres/gpu:p100=154,gres/pfsdir=812,gres/pfsdir:scratch=812,gres/vis=154,license/abaqus@osc=350,license/abaquscae@osc=10,license/ansys@osc=50,license/ansyspar@osc=900,license/comsolscript@osc=3,license/epik@osc=10,license/gauss-billing@osc=50000,license/glide@osc=20,license/ligprep@osc=10,license/lsdyna@osc=1000,license/macromodel@osc=10,license/qikprop@osc=10,license/starccm@osc=80,license/starccmpar@osc=4000,license/stata@osc=5,license/usearch@osc=1 diff --git a/spec/job/adapter_spec.rb b/spec/job/adapter_spec.rb index 270a6a6ba..f08883e7c 100644 --- a/spec/job/adapter_spec.rb +++ b/spec/job/adapter_spec.rb @@ -208,4 +208,10 @@ end end end + + describe '#queues' do + it 'returns an empty array' do + expect(adapter.queues).to eq([]) + end + end end diff --git a/spec/job/adapters/slurm_spec.rb b/spec/job/adapters/slurm_spec.rb index 8a86d0123..29937f267 100644 --- a/spec/job/adapters/slurm_spec.rb +++ b/spec/job/adapters/slurm_spec.rb @@ -1226,4 +1226,54 @@ def job_info(opts = {}) end end end + + describe '#queues' do + context 'when scontrol returns successfully' do + let(:slurm) { OodCore::Job::Adapters::Slurm::Batch.new } + let(:expected_queue_names) {[ + 'batch', 'debug', 'gpubackfill-parallel', 'gpubackfill-serial', 'gpudebug', + 'gpuparallel', 'gpuserial', 'hugemem', 'hugemem-parallel', 'longserial', + 'parallel', 'quick', 'serial', 'systems' + ]} + let(:quick_deny_accounts) {[ + 'pcon0003','pcon0014','pcon0015','pcon0016','pcon0401','pcon0008','pas1429','pcon0009', + 'pcon0020','pcon0022','pcon0023','pcon0024','pcon0025','pcon0040','pcon0026','pcon0041', + 'pcon0080','pcon0100','pcon0101','pcon0120','pcon0140','pcon0160','pcon0180','pcon0200', + 'pas1901','pcon0220','pcon0240','pcon0260','pcon0280','pcon0300','pcon0320','pcon0340', + 'pcon0341','pcon0360','pcon0380','pcon0381','pcon0441','pcon0481','pcon0501','pcon0421' + ]} + + it 'returns the correct queue info objects' do + # allow(Etc).to receive(:getlogin).and_return('me') + allow(Open3).to receive(:capture3) + .with({}, 'scontrol', 'show', 'part', '-o', {stdin_data: ''}) + .and_return([File.read('spec/fixtures/output/slurm/owens_partitions.txt'), '', double("success?" => true)]) + + queues = subject.queues + expect(queues.map(&:to_s)).to eq(expected_queue_names) + + systems_queue = queues.select { |q| q.name == 'systems' }.first + expect(systems_queue.allow_accounts).to eq(['root', 'pzs0708', 'pzs0710', 'pzs0722']) + expect(systems_queue.deny_accounts).to eq([]) + expect(systems_queue.qos).to eq([]) + + quick_queue = queues.select { |q| q.name == 'quick' }.first + expect(quick_queue.allow_accounts).to eq(nil) + expect(quick_queue.deny_accounts).to eq(quick_deny_accounts) + expect(quick_queue.qos).to eq(['quick']) + end + end + + context 'when scontrol fails' do + let(:slurm) { OodCore::Job::Adapters::Slurm::Batch.new } + + it 'raises the error' do + + allow(Open3).to receive(:capture3) + .with({}, 'scontrol', 'show', 'part', '-o', {stdin_data: ''}) + .and_return(['', 'the error message', double("success?" => false)]) + expect { subject.queues }.to raise_error(OodCore::Job::Adapters::Slurm::Batch::Error, 'the error message') + end + end + end end