From 771fdd25f3755a835dc28113b203b8c201809913 Mon Sep 17 00:00:00 2001 From: Tomas Kopecek Date: Feb 04 2020 12:52:23 +0000 Subject: [PATCH 1/3] add file-locking to koji-gc Fixes: https://pagure.io/koji/issue/1332 --- diff --git a/util/koji-gc b/util/koji-gc index 19d7e26..d8a5f88 100755 --- a/util/koji-gc +++ b/util/koji-gc @@ -7,7 +7,7 @@ # Mike McLean from __future__ import absolute_import - +import fcntl import datetime import fnmatch import optparse @@ -111,6 +111,9 @@ def get_options(): parser.add_option("--weburl", default="http://localhost/koji", metavar="URL", help=_("url of koji web server (for use in notifications)")) parser.add_option("-s", "--server", help=_("url of koji XMLRPC server")) + parser.add_option("--lock-file", help=_("koji-gc will wait while specified file exists")) + parser.add_option("--exit-on-lock", action="store_true", + help=_("quit if --lock-file exists, don't wait")) #parse once to get the config file (options, args) = parser.parse_args() @@ -148,6 +151,8 @@ def get_options(): ['trashcan_tag', None, 'string'], ['no_ssl_verify', None, 'boolean'], ['timeout', None, 'integer'], + ['lock_file', None, 'string'], + ['exit_on_lock', None, 'boolean'], ] for name, alias, type in cfgmap: if alias is None: @@ -954,12 +959,40 @@ if __name__ == "__main__": session_opts = koji.grab_session_options(options) session = koji.ClientSession(options.server, session_opts) + rv = 0 try: + lock_fd = None + if options.lock_file: + # acquire lock file + while not lock_fd: + # fail, if it is completely inaccessible + lock_fd = os.open(options.lock_file, os.O_CREAT | os.O_RDWR) + try: + fcntl.flock(lock_fd, fcntl.LOCK_EX | fcntl.LOCK_NB) + break + except (IOError, OSError): + if options.exit_on_lock: + try: + session.logout() + except: + pass + sys.exit(1) + os.close(lock_fd) + lock_fd = None + if options.debug: + print("Waiting on lock: %s" % options.lock_file) + time.sleep(10) + if not options.skip_main: rv = main(args) if not rv: rv = 0 + + if lock_fd: + # release lock file + fcntl.flock(lock_fd, fcntl.LOCK_UN) + os.close(lock_fd) except KeyboardInterrupt: pass except SystemExit: From 3367c6e1535b0211ac9e1066f70c288a557856bf Mon Sep 17 00:00:00 2001 From: Tomas Kopecek Date: Feb 04 2020 12:53:30 +0000 Subject: [PATCH 2/3] default value for --lock-file option --- diff --git a/util/koji-gc b/util/koji-gc index d8a5f88..8a3d5a9 100755 --- a/util/koji-gc +++ b/util/koji-gc @@ -111,7 +111,8 @@ def get_options(): parser.add_option("--weburl", default="http://localhost/koji", metavar="URL", help=_("url of koji web server (for use in notifications)")) parser.add_option("-s", "--server", help=_("url of koji XMLRPC server")) - parser.add_option("--lock-file", help=_("koji-gc will wait while specified file exists")) + parser.add_option("--lock-file", help=_("koji-gc will wait while specified file exists. " + "Default path is /run/user//koji-gc.lock")) parser.add_option("--exit-on-lock", action="store_true", help=_("quit if --lock-file exists, don't wait")) #parse once to get the config file @@ -963,26 +964,27 @@ if __name__ == "__main__": rv = 0 try: lock_fd = None - if options.lock_file: - # acquire lock file - while not lock_fd: - # fail, if it is completely inaccessible - lock_fd = os.open(options.lock_file, os.O_CREAT | os.O_RDWR) - try: - fcntl.flock(lock_fd, fcntl.LOCK_EX | fcntl.LOCK_NB) - break - except (IOError, OSError): - if options.exit_on_lock: - try: - session.logout() - except: - pass - sys.exit(1) - os.close(lock_fd) - lock_fd = None - if options.debug: - print("Waiting on lock: %s" % options.lock_file) - time.sleep(10) + if not options.lock_file: + options.lock_file = '/run/user/%d/koji-gc.lock' % os.getuid() + # acquire lock file + while not lock_fd: + # fail, if it is completely inaccessible + lock_fd = os.open(options.lock_file, os.O_CREAT | os.O_RDWR) + try: + fcntl.flock(lock_fd, fcntl.LOCK_EX | fcntl.LOCK_NB) + break + except (IOError, OSError): + if options.exit_on_lock: + try: + session.logout() + except: + pass + sys.exit(1) + os.close(lock_fd) + lock_fd = None + if options.debug: + print("Waiting on lock: %s" % options.lock_file) + time.sleep(10) if not options.skip_main: rv = main(args) From e9ed8bdd954b58a162ff8b066e5417df3c72db3e Mon Sep 17 00:00:00 2001 From: Tomas Kopecek Date: Feb 10 2020 14:22:30 +0000 Subject: [PATCH 3/3] more detailed help message --- diff --git a/util/koji-gc b/util/koji-gc index 8a3d5a9..1f04f4a 100755 --- a/util/koji-gc +++ b/util/koji-gc @@ -112,7 +112,9 @@ def get_options(): help=_("url of koji web server (for use in notifications)")) parser.add_option("-s", "--server", help=_("url of koji XMLRPC server")) parser.add_option("--lock-file", help=_("koji-gc will wait while specified file exists. " - "Default path is /run/user//koji-gc.lock")) + "Default path is /run/user//koji-gc.lock. " + "For service usage /var/lock/koji-gc.lock is " + "recommended.")) parser.add_option("--exit-on-lock", action="store_true", help=_("quit if --lock-file exists, don't wait")) #parse once to get the config file