From c2a4d8fcd616b87eeed72002aeb5b03554358544 Mon Sep 17 00:00:00 2001 From: Eli Kogan-Wang Date: Tue, 15 Oct 2024 05:18:56 +0200 Subject: [PATCH] locking error for multiple simultaneous batou deployments is displayed more beautiful --- src/batou/deploy.py | 2 +- src/batou/utils.py | 14 +++++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/batou/deploy.py b/src/batou/deploy.py index c8e62d1c..933cd85d 100644 --- a/src/batou/deploy.py +++ b/src/batou/deploy.py @@ -361,7 +361,7 @@ def main( else: ACTION = "DEPLOYMENT" SUCCESS_FORMAT = {"green": True} - with locked(".batou-lock"): + with locked(".batou-lock", exit_on_failure=True): deployment = Deployment( environment, platform, diff --git a/src/batou/utils.py b/src/batou/utils.py index 7ce3b2b5..93cb107b 100644 --- a/src/batou/utils.py +++ b/src/batou/utils.py @@ -64,13 +64,25 @@ def flush(self): @contextlib.contextmanager -def locked(filename): +def locked(filename, exit_on_failure=False): # XXX can we make this not leave files around? with open(filename, "a+") as lockfile: try: fcntl.lockf(lockfile, fcntl.LOCK_EX | fcntl.LOCK_NB) except IOError: print("Could not acquire lock {}".format(filename), file=sys.stderr) + if exit_on_failure: + print( + "Another instance of batou may be running, or a stale lock file may exist.", + file=sys.stderr, + ) + print( + "If you are sure no other instance is running, you can remove the lock file manually.", + file=sys.stderr, + ) + print("Lock file: {}".format(filename), file=sys.stderr) + print("Exiting.", file=sys.stderr) + sys.exit(1) raise RuntimeError( 'cannot create lock "%s": more than one instance running ' "concurrently?" % lockfile,