@@ -23,6 +23,7 @@ import argparse
2323import importlib
2424import logging
2525import multiprocessing as mp
26+ import os
2627import re
2728import socket
2829import sys
@@ -106,6 +107,8 @@ def parse_args():
106107 help = 'Do not check when was the last execution, run from timestamp 0.' )
107108 parser .add_argument ('--print-versions-details' , dest = 'print_versions_details' , action = 'store_true' , default = False ,
108109 help = 'Print extra details about the versions if enabled..' )
110+ parser .add_argument ('--instance-name' , dest = 'instance_name' , action = 'store' , default = None ,
111+ help = 'Instance name used to differentiate execution state files (timestamp and PID). If omitted, inferred from configuration.' )
109112 args = parser .parse_args ()
110113 dryable .set (args .dry_run )
111114 logging .info (args )
@@ -215,42 +218,79 @@ def find_matching_rules(rules, object_path):
215218 return result
216219
217220
218- filepath = tempfile .gettempdir () + "/repoCleaner.txt"
221+ def get_instance_name (args = None ):
222+ """
223+ Determine the instance identifier based on args or config.
224+ """
225+ if args is None :
226+ return "default"
227+ if getattr (args , 'instance_name' , None ):
228+ return args .instance_name
229+ if getattr (args , 'config_consul' , None ):
230+ items = args .config_consul .split (':' )
231+ if len (items ) >= 3 :
232+ return Path (items [2 ]).stem
233+ if getattr (args , 'config_git' , None ):
234+ return "git"
235+ if getattr (args , 'config' , None ):
236+ config_stem = Path (args .config ).stem
237+ if getattr (args , 'only_path' , None ) and args .only_path != "" :
238+ sanitized_path = re .sub (r'[^a-zA-Z0-9_-]' , '_' , args .only_path .strip ('/' ))
239+ return f"{ config_stem } _{ sanitized_path } "
240+ return config_stem
241+ return "default"
242+
243+
244+ def get_timestamp_filepath (instance_name : str = None ) -> str :
245+ """
246+ Returns the path to the file where the timestamp of the last execution is stored for a given instance.
247+ """
248+ if instance_name :
249+ sanitized = re .sub (r'[^a-zA-Z0-9_-]' , '_' , instance_name )
250+ return os .path .join (tempfile .gettempdir (), f"repoCleaner_{ sanitized } .txt" )
251+ else :
252+ return os .path .join (tempfile .gettempdir (), "repoCleaner.txt" )
253+
254+
255+ filepath = get_timestamp_filepath ()
219256currentTimeStamp = int (time .time () * 1000 )
220257
221258
222- def get_ts_last_execution (ignore_last_execution : bool ):
259+ def get_ts_last_execution (ignore_last_execution : bool , filepath_override : str = None ):
223260 """
224261 Returns the timestamp of the last execution.
225- It is stored in a file in $TMP/repoCleaner .txt.
262+ It is stored in a file in $TMP/repoCleaner_<instance> .txt.
226263 :return: the timestamp of the last execution or 0 if it cannot find it.
227264 """
228265 if ignore_last_execution :
229266 logging .info (f"Option ignore_last_execution set, we return 0 as timestamp." )
230267 return 0
231268
269+ target_filepath = filepath_override if filepath_override is not None else filepath
232270 try :
233- f = open (filepath , "r" )
271+ f = open (target_filepath , "r" )
234272 except IOError :
235- logging .info (f"File { filepath } not readable, we return 0 as timestamp." )
273+ logging .info (f"File { target_filepath } not readable, we return 0 as timestamp." )
236274 return 0
237275 timestamp = f .read ()
238- logging .info (f"Timestamp retrieved from { filepath } : { timestamp } " )
276+ logging .info (f"Timestamp retrieved from { target_filepath } : { timestamp } " )
239277 f .close ()
240278 return timestamp
241279
242280
243- def store_saved_timestamp ():
281+ def store_saved_timestamp (filepath_override : str = None , timestamp : int = None ):
244282 """
245283 Store the timestamp we saved at the beginning of the execution of this script.
246284 """
285+ target_filepath = filepath_override if filepath_override is not None else filepath
286+ ts = timestamp if timestamp is not None else currentTimeStamp
247287 try :
248- f = open (filepath , "w+" )
288+ f = open (target_filepath , "w+" )
249289 except IOError :
250- logging .error (f"Could not write the saved timestamp to { filepath } " )
290+ logging .error (f"Could not write the saved timestamp to { target_filepath } " )
251291 return
252- f .write (str (currentTimeStamp ))
253- logging .info (f"Stored timestamp { currentTimeStamp } in { filepath } " )
292+ f .write (str (ts ))
293+ logging .info (f"Stored timestamp { ts } in { target_filepath } " )
254294 f .close ()
255295
256296
@@ -376,13 +416,15 @@ def process_object(object_path, rules, ccdb, args):
376416
377417
378418def run (args , ccdb_url , rules ):
419+ instance_name = get_instance_name (args )
420+ ts_filepath = get_timestamp_filepath (instance_name )
379421
380422 # Get list of objects from CCDB
381423 ccdb = Ccdb (ccdb_url , args .print_versions_details )
382424 ccdb .logger = logging .getLogger
383425 ccdb .set_adjustable_eov = args .set_adjustableEOV
384426 logging .info (f"ccdb.set_adjustable_eov: { ccdb .set_adjustable_eov } " )
385- paths = ccdb .get_objects_list (get_ts_last_execution (args .ignore_last_execution ), args .only_path , args .only_path_no_subdir )
427+ paths = ccdb .get_objects_list (get_ts_last_execution (args .ignore_last_execution , ts_filepath ), args .only_path , args .only_path_no_subdir )
386428 if args .only_path != '' :
387429 paths = [item for item in paths if item is not None and item .startswith (args .only_path )]
388430 logging .debug (paths )
@@ -399,7 +441,7 @@ def run(args, ccdb_url, rules):
399441 message = datetime .today ().strftime ('%Y-%m-%d-%H:%M:%S' )
400442 store_crucial_log (message + f" - End of the cleaner (total deleted: { ccdb .counter_deleted } , total updated: { ccdb .counter_validity_updated } )" )
401443 if not args .dry_run and not args .ignore_last_execution :
402- store_saved_timestamp ()
444+ store_saved_timestamp (ts_filepath )
403445
404446# ****************
405447# We start here !
@@ -413,8 +455,11 @@ def main():
413455 args = parse_args ()
414456 logging .getLogger ().setLevel (int (args .log_level ))
415457
458+ instance_name = get_instance_name (args )
459+ pid_filename = f'o2-qc-repo-cleaner_{ instance_name } .pid' if instance_name else 'o2-qc-repo-cleaner.pid'
460+
416461 try :
417- with PIDFile (filename = 'o2-qc-repo-cleaner.pid' ):
462+ with PIDFile (filename = pid_filename ):
418463 ccdb_url , rules = read_config (args )
419464 run (args , ccdb_url , rules )
420465 except AlreadyRunningError :
0 commit comments