def clean_userdir(self): """ Attempts to delete all directories under self.userdir other than the one owned by this process. If a directory is locked, it is skipped. """ self.logger.debug("Cleaning user dir: %s" % self.userdir) dirs = self.userdir.dirs() for dir in dirs: if str(dir) == str(self.dir): self.logger.debug("Skipping self: %s", dir) continue lock = old_div(dir, ".lock") if lock.exists(): # 1962, on Windows this fails if lock is missing f = open(str(lock), "r") try: portalocker.lock( f, portalocker.LOCK_EX | portalocker.LOCK_NB) # Must close for Windows, otherwise "...other process" f.close() except: print("Locked: %s" % dir) continue dir.rmtree(onerror=self.on_rmtree) print("Deleted: %s" % dir)
def clean_userdir(self): """ Attempts to delete all directories under self.userdir other than the one owned by this process. If a directory is locked, it is skipped. """ self.logger.debug("Cleaning user dir: %s" % self.userdir) dirs = self.userdir.dirs() for dir in dirs: if str(dir) == str(self.dir): self.logger.debug("Skipping self: %s", dir) continue lock = dir / ".lock" if lock.exists(): # 1962, on Windows this fails if lock is missing f = open(str(lock), "r") try: portalocker.lock( f, portalocker.LOCK_EX | portalocker.LOCK_NB) # Must close for Windows, otherwise "...other process" f.close() except: print "Locked: %s" % dir continue dir.rmtree(onerror=self.on_rmtree) print "Deleted: %s" % dir
def __init__(self, filename, env_config=None, exclusive=True, read_only=False): # Logs to the class name self.logger = logging.getLogger(self.__class__.__name__) self.XML = None # Parsed XML Element self.filename = filename # Path to the file to be read and written self.env_config = Environment(env_config) # Environment override # Whether or not an exclusive lock should be acquired self.exclusive = exclusive # Further, if saving should even be allowed. self.read_only = read_only self.save_on_close = True self.open_source() if self.exclusive: # must be "a+" try: portalocker.lock(self.lock, portalocker.LOCK_NB | portalocker.LOCK_EX) except portalocker.LockException: self.lock = None # Prevent deleting of the file self.close() raise self.source.seek(0) text = self.source.read() self.source.close() if text: self.XML = XML(text) try: self.version_check() self.toplinks_check() except: self.close() raise # Nothing defined, so create a new tree if self.XML is None: default = self.default() self.XML = Element("icegrid") properties = SubElement(self.XML, "properties", id=self.INTERNAL) SubElement(properties, "property", name=self.DEFAULT, value=default) SubElement(properties, "property", name=self.KEY, value=self.VERSION) properties = SubElement(self.XML, "properties", id=default) SubElement(properties, "property", name=self.KEY, value=self.VERSION)
def __init__(self, filename, env_config=None, exclusive=True, read_only=False): # Logs to the class name self.logger = logging.getLogger(self.__class__.__name__) self.XML = None # Parsed XML Element self.filename = filename # Path to the file to be read and written self.env_config = Environment(env_config) # Environment override # Whether or not an exclusive lock should be acquired self.exclusive = exclusive # Further, if saving should even be allowed. self.read_only = read_only self.save_on_close = True self.open_source() if self.exclusive: # must be "a+" try: portalocker.lock( self.lock, portalocker.LOCK_NB | portalocker.LOCK_EX) except portalocker.LockException: self.lock = None # Prevent deleting of the file self.close() raise self.source.seek(0) text = self.source.read() self.source.close() if text: self.XML = XML(text) try: self.version_check() self.toplinks_check() except: self.close() raise # Nothing defined, so create a new tree if self.XML is None: default = self.default() self.XML = Element("icegrid") properties = SubElement(self.XML, "properties", id=self.INTERNAL) SubElement(properties, "property", name=self.DEFAULT, value=default) SubElement(properties, "property", name=self.KEY, value=self.VERSION) properties = SubElement(self.XML, "properties", id=default) SubElement(properties, "property", name=self.KEY, value=self.VERSION)
def __init__(self, prefix="omero"): """ Initializes a TempFileManager instance with a userDir containing the given prefix value, or "omero" by default. Also registers an atexit callback to call self.cleanup() on exit. """ self.logger = logging.getLogger("omero.util.TempFileManager") self.is_win32 = (sys.platform == "win32") self.prefix = prefix self.userdir = old_div(self.tmpdir(), ("%s_%s" % (self.prefix, self.username()))) """ User-accessible directory of the form $TMPDIR/omero_$USERNAME. If the given directory is not writable, an attempt is made to use an alternative """ if not self.create(self.userdir) and not self.access(self.userdir): i = 0 while i < 10: t = path("%s_%s" % (self.userdir, i)) if self.create(t) or self.access(t): self.userdir = t break raise Exception( "Failed to create temporary directory: %s" % self.userdir) self.dir = old_div(self.userdir, self.pid()) """ Directory under which all temporary files and folders will be created. An attempt to remove a path not in this directory will lead to an exception. """ # Now create the directory. If a later step throws an # exception, we should try to rollback this change. if not self.dir.exists(): self.dir.makedirs() self.logger.debug("Using temp dir: %s" % self.dir) self.lock = None try: self.lock = open(str(old_div(self.dir, ".lock")), "a+") """ .lock file under self.dir which is used to prevent other TempFileManager instances (also in other languages) from cleaning up this directory. """ try: portalocker.lock( self.lock, portalocker.LOCK_EX | portalocker.LOCK_NB) atexit.register(self.cleanup) except: lock = self.lock self.lock = None if lock: self.lock.close() raise finally: try: if not self.lock: self.cleanup() except: self.logger.warn("Error on cleanup after error", exc_info=True)
def tmpdir(self): """ Returns a platform-specific user-writable temporary directory First, the value of "OMERO_TMPDIR" is attempted (if available), then user's home directory, then the global temp director. Typical errors for any of the possible temp locations are: * non-existence * inability to lock See: https://trac.openmicroscopy.org/ome/ticket/1653 """ locktest = None # Read temporary files directory from deprecated OMERO_TEMPDIR envvar custom_tmpdir_deprecated = os.environ.get('OMERO_TEMPDIR', None) if 'OMERO_TEMPDIR' in os.environ: import warnings warnings.warn( "OMERO_TEMPDIR is deprecated. Use OMERO_TMPDIR instead.", DeprecationWarning) # Read temporary files directory from OMERO_TMPDIR envvar default_tmpdir = None if custom_tmpdir_deprecated: default_tmpdir = path(custom_tmpdir_deprecated) / "omero" / "tmp" custom_tmpdir = os.environ.get('OMERO_TMPDIR', default_tmpdir) # List target base directories by order of precedence targets = [] if custom_tmpdir: targets.append(path(custom_tmpdir)) targets.append(old_div(get_omero_userdir(), "tmp")) targets.append(path(tempfile.gettempdir()) / "omero" / "tmp") # Handles existing files named tmp # See https://trac.openmicroscopy.org/ome/ticket/2805 for target in targets: if target.exists() and not target.isdir(): self.logger.debug("%s exists and is not a directory" % target) targets.remove(target) name = None choice = None locktest = None for target in targets: if choice is not None: break try: try: self.create(target) name = self.mkstemp( prefix=".lock_test", suffix=".tmp", dir=target) locktest = open(name, "a+") portalocker.lock( locktest, portalocker.LOCK_EX | portalocker.LOCK_NB) locktest.close() locktest = None choice = target self.logger.debug("Chose global tmpdir: %s", choice) finally: if locktest is not None: try: locktest.close() except: self.logger.warn( "Failed to close locktest: %s", name, exc_info=True) if name is not None: try: os.remove(name) except: self.logger.debug("Failed os.remove(%s)", name) except Exception as e: if "Operation not permitted" in str(e) or \ "Operation not supported" in str(e): # This is the issue described in ticket:1653 # To prevent printing the warning, we just continue # here. self.logger.debug("%s does not support locking.", target) else: self.logger.warn("Invalid tmp dir: %s" % target, exc_info=True) if choice is None: raise Exception("Could not find lockable tmp dir") return choice
def __init__(self, prefix="omero"): """ Initializes a TempFileManager instance with a userDir containing the given prefix value, or "omero" by default. Also registers an atexit callback to call self.cleanup() on exit. """ self.logger = logging.getLogger("omero.util.TempFileManager") self.is_win32 = (sys.platform == "win32") self.prefix = prefix self.userdir = self.tmpdir() / ("%s_%s" % (self.prefix, self.username())) """ User-accessible directory of the form $TMPDIR/omero_$USERNAME. If the given directory is not writable, an attempt is made to use an alternative """ if not self.create(self.userdir) and not self.access(self.userdir): i = 0 while i < 10: t = path("%s_%s" % (self.userdir, i)) if self.create(t) or self.access(t): self.userdir = t break raise Exception( "Failed to create temporary directory: %s" % self.userdir) self.dir = self.userdir / self.pid() """ Directory under which all temporary files and folders will be created. An attempt to remove a path not in this directory will lead to an exception. """ # Now create the directory. If a later step throws an # exception, we should try to rollback this change. if not self.dir.exists(): self.dir.makedirs() self.logger.debug("Using temp dir: %s" % self.dir) self.lock = None try: self.lock = open(str(self.dir / ".lock"), "a+") """ .lock file under self.dir which is used to prevent other TempFileManager instances (also in other languages) from cleaning up this directory. """ try: portalocker.lock( self.lock, portalocker.LOCK_EX | portalocker.LOCK_NB) atexit.register(self.cleanup) except: lock = self.lock self.lock = None if lock: self.lock.close() raise finally: try: if not self.lock: self.cleanup() except: self.logger.warn("Error on cleanup after error", exc_info=True)
def tmpdir(self): """ Returns a platform-specific user-writable temporary directory First, the value of "OMERO_TMPDIR" is attempted (if available), then user's home directory, then the global temp director. Typical errors for any of the possible temp locations are: * non-existence * inability to lock See: http://trac.openmicroscopy.org.uk/ome/ticket/1653 """ locktest = None # Read temporary files directory from deprecated OMERO_TEMPDIR envvar custom_tmpdir_deprecated = os.environ.get('OMERO_TEMPDIR', None) if 'OMERO_TEMPDIR' in os.environ: import warnings warnings.warn( "OMERO_TEMPDIR is deprecated. Use OMERO_TMPDIR instead.", DeprecationWarning) # Read temporary files directory from OMERO_TMPDIR envvar default_tmpdir = None if custom_tmpdir_deprecated: default_tmpdir = path(custom_tmpdir_deprecated) / "omero" / "tmp" custom_tmpdir = os.environ.get('OMERO_TMPDIR', default_tmpdir) # List target base directories by order of precedence targets = [] if custom_tmpdir: targets.append(path(custom_tmpdir)) targets.append(get_omero_userdir() / "tmp") targets.append(path(tempfile.gettempdir()) / "omero" / "tmp") # Handles existing files named tmp # See https://trac.openmicroscopy.org.uk/ome/ticket/2805 for target in targets: if target.exists() and not target.isdir(): self.logger.debug("%s exists and is not a directory" % target) targets.remove(target) name = None choice = None locktest = None for target in targets: if choice is not None: break try: try: self.create(target) name = self.mkstemp( prefix=".lock_test", suffix=".tmp", dir=target) locktest = open(name, "a+") portalocker.lock( locktest, portalocker.LOCK_EX | portalocker.LOCK_NB) locktest.close() locktest = None choice = target self.logger.debug("Chose global tmpdir: %s", choice) finally: if locktest is not None: try: locktest.close() except: self.logger.warn( "Failed to close locktest: %s", name, exc_info=True) if name is not None: try: os.remove(name) except: self.logger.debug("Failed os.remove(%s)", name) except Exception, e: if "Operation not permitted" in str(e) or \ "Operation not supported" in str(e): # This is the issue described in ticket:1653 # To prevent printing the warning, we just continue # here. self.logger.debug("%s does not support locking.", target) else: self.logger.warn("Invalid tmp dir: %s" % target, exc_info=True)