From 3767568aaacc205450c686174d0dc2a2d2b1e005 Mon Sep 17 00:00:00 2001 From: Lubomír Sedlář Date: Aug 17 2018 12:47:07 +0000 Subject: symlink: Update latest symlink atomically Instead of deleting the conflicting file first and linked after, create a temporary link and move it over the target file. Signed-off-by: Lubomír Sedlář --- diff --git a/compose_utils/symlink.py b/compose_utils/symlink.py index cd22141..c64989d 100644 --- a/compose_utils/symlink.py +++ b/compose_utils/symlink.py @@ -1,6 +1,5 @@ # -*- coding: utf-8 -*- -import errno import os import productmd @@ -13,16 +12,13 @@ class ComposeSymlink(object): def _link(self, name): """Create a symbolic link with given name at the same location as the - compose. Existing file at the given path will be deleted. + compose. Existing file at the given path will be deleted atomically. """ - symlink = os.path.join(self.path, '..', name) - try: - os.unlink(symlink) - except OSError as exc: - if exc.errno != errno.ENOENT: - raise - - os.symlink(os.path.basename(self.path), symlink) + temp = os.path.join(self.path, "..", ".%s.tmp" % name) + symlink = os.path.join(self.path, "..", name) + + os.symlink(os.path.basename(self.path), temp) + os.rename(temp, symlink) def get_latest_link_name(self, minor_version=False): """Get name of latest- symlink for current compose."""