Skip to content

Commit d5ba0e7

Browse files
committed
flux-queue: report enabled/started status in flux queue list
Problem: `flux queue list` only lists configuration information for queues, while `flux queue status` is required to determine if queues are enabled and started. Users should not need to run two commands to get necessary queue information. Fetch the queue status from `job-manager.queue-status` for each configured queue, or the anonymous queue if no queues are configured. Add queue "submission" and "scheduling" fields which report enabled/disabled and started/stopped respectively. Additionally, add shorter "enabled" and "started" fields which report a single character "✔/y" if true or "✗/n" if false. Support color output for the enabled and started fields. Adjust the default output format to include the enabled/started status for each queue in color. This gives users a quick way to determine the status of queues from `flux queue list`. Fixes #6145
1 parent 4ccf427 commit d5ba0e7

File tree

1 file changed

+55
-4
lines changed

1 file changed

+55
-4
lines changed

src/cmd/flux-queue.py

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
import sys
1717

1818
import flux
19-
from flux.util import UtilConfig, parse_fsd
19+
from flux.util import AltField, UtilConfig, parse_fsd
2020

2121

2222
def print_enable_status(name, status):
@@ -111,6 +111,8 @@ class FluxQueueConfig(UtilConfig):
111111
"description": "Default flux-queue list format string",
112112
"format": (
113113
"?:{queuem:<8.8} "
114+
"{color_enabled}{enabled:>2}{color_off} "
115+
"{color_started}{started:>2}{color_off} "
114116
"{defaults.timelimit!F:>8} "
115117
"{limits.timelimit!F:>8} "
116118
"{limits.range.nnodes:>10} "
@@ -238,11 +240,15 @@ def timelimit(self):
238240

239241

240242
class QueueInfo:
241-
def __init__(self, name, config):
243+
def __init__(self, name, config, enabled, started):
242244
self.name = name
243245
self.config = config
244246
self.limits = QueueLimitsInfo(name, config)
245247
self.defaults = QueueDefaultsInfo(name, config)
248+
self.scheduling = "started" if started else "stopped"
249+
self.submission = "enabled" if enabled else "disabled"
250+
self._enabled = enabled
251+
self._started = started
246252

247253
def __getattr__(self, attr):
248254
try:
@@ -263,11 +269,51 @@ def queuem(self):
263269
q = self.queue + ("*" if defaultq and self.queue == defaultq else "")
264270
return q
265271

272+
@property
273+
def color_enabled(self):
274+
return "\033[01;32m" if self._enabled else "\033[01;31m"
275+
276+
@property
277+
def color_off(self):
278+
return "\033[0;0m"
279+
280+
@property
281+
def enabled(self):
282+
return AltField("✔", "y") if self._enabled else AltField("✗", "n")
283+
284+
@property
285+
def color_started(self):
286+
return "\033[01;32m" if self._started else "\033[01;31m"
287+
288+
@property
289+
def started(self):
290+
return AltField("✔", "y") if self._started else AltField("✗", "n")
291+
292+
293+
def fetch_all_queue_status(handle, queues=None):
294+
if handle is None:
295+
# Return fake payload if handle is not open (e.g. during testing)
296+
return {"enable": True, "start": True}
297+
topic = "job-manager.queue-status"
298+
if queues is None:
299+
return handle.rpc(topic, {}).get()
300+
rpcs = {x: handle.rpc(topic, {"name": x}) for x in queues}
301+
return {x: rpcs[x].get() for x in rpcs}
302+
266303

267304
def list(args):
268305
headings = {
269306
"queue": "QUEUE",
270307
"queuem": "QUEUE",
308+
"submission": "SUBMIT",
309+
"scheduling": "SCHED",
310+
"enabled": "EN",
311+
"started": "ST",
312+
"enabled.ascii": "EN",
313+
"started.ascii": "ST",
314+
"color_enabled": "",
315+
"color_started": "",
316+
"color_off": "",
271317
"defaults.timelimit": "TDEFAULT",
272318
"limits.timelimit": "TLIMIT",
273319
"limits.range.nnodes": "NNODES",
@@ -281,6 +327,7 @@ def list(args):
281327
"limits.max.ngpus": "MAXGPUS",
282328
}
283329
config = None
330+
handle = None
284331

285332
if args.from_stdin:
286333
config = json.loads(sys.stdin.read())
@@ -297,11 +344,15 @@ def list(args):
297344

298345
queues = []
299346
if config and "queues" in config:
347+
status = fetch_all_queue_status(handle, config["queues"].keys())
300348
for key, value in config["queues"].items():
301-
queues.append(QueueInfo(key, config))
349+
queues.append(
350+
QueueInfo(key, config, status[key]["enable"], status[key]["start"])
351+
)
302352
else:
303353
# single anonymous queue
304-
queues.append(QueueInfo(None, config))
354+
status = fetch_all_queue_status(handle)
355+
queues.append(QueueInfo(None, config, status["enable"], status["start"]))
305356

306357
formatter.print_items(queues, no_header=args.no_header)
307358

0 commit comments

Comments
 (0)