From 9305967d10f4532cc97f156f529f774e6caac15d Mon Sep 17 00:00:00 2001 From: Guillaume Raffy Date: Wed, 3 Jun 2026 09:37:19 +0200 Subject: [PATCH] cocluto v1.0.32 - added quman option --disable-sync - the db synchronization mechanism needs some requirements that are not always available (sge commands such as qmod and qstat, write access on quman's database), as for example on simpaweb; in such environments, --disable-sync allows quman to work for query-only actions such as show-disable-requests work related to [https://bugzilla.ipr.univ-rennes.fr/show_bug.cgi?id=3093] --- cocluto/quman.py | 27 +++++++++++++++++++-------- cocluto/version.py | 2 +- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/cocluto/quman.py b/cocluto/quman.py index 57dfec6..8b47e7f 100755 --- a/cocluto/quman.py +++ b/cocluto/quman.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 from abc import ABC, abstractmethod import sys -from typing import List, Dict, Any, Union +from typing import List, Dict, Any, Union, Optional import logging import subprocess import argparse @@ -92,15 +92,11 @@ class MockGridEngine(IGridEngine): class Sge(IGridEngine): dry_run: bool + qmod_is_available: Optional[bool] def __init__(self, dry_run: bool = False): self.dry_run = dry_run - if not self.dry_run: - # check that qmod command is available - try: - subprocess.run(["qmod", "-help"], check=True, capture_output=True) - except FileNotFoundError as exc: - raise RuntimeError("qmod command not found. Please make sure that the grid engine client is installed and qmod command is available in the PATH.") from exc + self.qmod_is_available = None def run_qmod(self, args): """runs qmod with the given arguments.""" @@ -108,11 +104,22 @@ class Sge(IGridEngine): if self.dry_run: print(f"Dry run: {' '.join(cmd)}") else: + self.check_qmod_availability() try: subprocess.run(cmd, check=True) except subprocess.CalledProcessError as e: raise RuntimeError(f"qmod command failed: {e}") from e + def check_qmod_availability(self): + if self.qmod_is_available is None: + self.qmod_is_available = False + # check that qmod command is available + try: + subprocess.run(["qmod", "-help"], check=True, capture_output=True) + except FileNotFoundError as exc: + raise RuntimeError("qmod command not found. Please make sure that the grid engine client is installed and qmod command is available in the PATH.") from exc + self.qmod_is_available = True + def disable_queue_machine(self, queue_machine: QueueMachineId): self.run_qmod(["-d", queue_machine]) @@ -417,6 +424,8 @@ def main(): "ssh_user": "qumandbw"}} parser.add_argument("--json", action="store_true", help="Output results in JSON format.") parser.add_argument("--db-def", type=str, default=json.dumps(default_db_def), help="the definition in json format of the database storing the disable requests.") + # the db synchronization mechanism needs some requirements that are not always available (sge commands such as qmod and qstat, write access on quman's database), as for example on simpaweb; in such environments, --disable-sync allows quman to work for query-only actions such as show-disable-requests + parser.add_argument("--disable-sync", action="store_true", default=False, help="if set, disable the update of the db to fix potential inconsistencies with the current state of the queues, prior to execute the asked action") # add-disable action add_parser = subparsers.add_parser("add-disable-request", help="adds a disable request to a queue") @@ -473,7 +482,9 @@ def main(): logging.debug("Connected to database successfully with connection %s", conn) quman = QueueManager(conn, grid_engine) - quman.synchronize_with_grid_engine() + if not args.disable_sync: + # fix potential inconsistencies in quman db regarding the current state of the queues + quman.synchronize_with_grid_engine() if args.action == "add-disable-request": queue_machines = quman.get_queue_machines(args.queue) diff --git a/cocluto/version.py b/cocluto/version.py index f1889b2..132b022 100644 --- a/cocluto/version.py +++ b/cocluto/version.py @@ -1,4 +1,4 @@ -__version__ = '1.0.31' +__version__ = '1.0.32' class Version(object):