Whamcloud - gitweb
LU-16228 utils: improve lljobstats parsing
authorAndreas Dilger <adilger@whamcloud.com>
Wed, 16 Aug 2023 18:14:21 +0000 (12:14 -0600)
committerAndreas Dilger <adilger@whamcloud.com>
Mon, 21 Aug 2023 08:44:46 +0000 (08:44 +0000)
Change the hard-coded python3 interpreter path to use "env".

Allow lljobstats to parse JobIDs from Insight that have a leading
"@" if the jobname is not specified.  Otherwise it is not valid
YAML and causes the parser to choke.

Test-Parameters: trivial
Signed-off-by: Bjoern Olausson <bolausson@ddn.com>
Change-Id: Ibd7eba46fe80d39993810c06a3ada0f06ee694c6
Reviewed-on: https://review.whamcloud.com/c/ex/lustre-release/+/51964
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Feng Lei <flei@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
lustre.spec.in
lustre/utils/lljobstat

index 1347d59..8ae317c 100644 (file)
@@ -227,6 +227,7 @@ BuildRequires: redhat-rpm-config
 BuildRequires: pkgconfig
 %if 0%{?rhel} > 7 || 0%{?fedora} > 33 || 0%{?rhel} < 1
 Suggests: bash-completion
+Suggests: libyaml-devel
 %endif
 %else
 BuildRequires: pkg-config
index b235dc4..fdb9736 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/python3
+#!/usr/bin/env python3
 
 '''
 lljobstat command. Read job_stats files, parse and aggregate data of every
@@ -11,7 +11,14 @@ import subprocess
 import sys
 import time
 import yaml
+import signal
 
+try:
+    from yaml import CLoader as Loader
+except ImportError:
+    from yaml import Loader
+
+signal.signal(signal.SIGINT, signal.default_int_handler)
 
 class ArgParser: # pylint: disable=too-few-public-methods
     '''
@@ -103,9 +110,10 @@ class JobStatsParser:
         read single job_stats file, parse it and return an object
         '''
         cmd = ['lctl', 'get_param', '-n', param]
-        output = subprocess.check_output(cmd).decode()
+        out = subprocess.check_output(cmd).decode()
+        output = out.replace('job_id:          @', 'job_id:          .')
         try:
-            yaml_obj = yaml.safe_load(output)  # need several seconds...
+            yaml_obj = yaml.load(output, Loader=Loader)  # need several seconds...
         except yaml.scanner.ScannerError:
             # only print the file name here
             print("failed to parse the content of %s" % param, file=sys.stdout)
@@ -228,12 +236,16 @@ class JobStatsParser:
         self.args = argparser.args
 
         i = 0
-        while True:
-            self.run_once_retry()
-            i += 1
-            if self.args.repeats != -1 and i >= self.args.repeats:
-                break
-            time.sleep(self.args.interval)
+        try:
+            while True:
+                self.run_once_retry()
+                i += 1
+                if self.args.repeats != -1 and i >= self.args.repeats:
+                    break
+                time.sleep(self.args.interval)
+        except (KeyboardInterrupt):
+            print("\nReceived KeyboardInterrupt - stopping", file=sys.stderr)
+            sys.exit()
 
 
 if __name__ == "__main__":