3 import logging, os, shutil, sys
25 """!Raised by various safety checks if someone tries to delete
26 something they should not, such as "/"."""
29 """!Recursive directory deleter with safeguards to prevent
30 accidental deletion of certain critical directories."""
32 """!Constructor for Deleter
33 @param logger a logging.Logger for log messages"""
43 """!Returns the logging.Logger used for log messages"""
47 """!Checks to see if the given path is one that should not be
50 Raises WillNotDelete if the given directory is one of these:
53 * Any of $HOMEhwrf, $USHhwrf, $EXhwrf, $PARMhwrf, $FIXhwrf, or $FIXgsi
55 @param norm the path to check"""
56 if not os.path.exists(norm):
58 if os.path.ismount(norm):
60 if os.path.samefile(
'/',norm):
62 for var
in (
'HOMEhwrf',
'USHhwrf',
'EXhwrf',
'PARMhwrf',
63 'FIXhwrf',
'FIXgsi' ):
65 vardir=os.environ[var]
66 if vardir==
'':
continue
67 if os.path.samefile(os.environ[var],norm):
70 def add(self,dirname):
71 """!Adds a directory to the list to be deleted. The directory
72 is passed through various safeguards first.
73 @param dirname the directory to delete"""
75 self.logger.info(
'%s: normalizes to %s'%(dirname,norm))
77 self.logger.info(
'%s: will recursively delete this'%(norm,))
79 parent=os.path.dirname(dirname)
80 self.logger.info(
'%s: will rmdir this if it is empty'%(parent,))
82 self.__rmdirs.add(parent)
83 self.__rmtrees.add(dirname)
86 """!Internal function used to log errors.
88 This is an internal implementation function called by
89 shutil.rmtree when an underlying function call failed. See
90 the Python documentation of shutil.rmtree for details.
91 @param function the funciton that failed
92 @param path the path to the function that caused problems
93 @param exc_info the exception information
94 @post self.badflag=True
96 self.logger.warning(
'%s: %s failed: %s'%(
97 str(path),str(function),str(exc_info)))
101 """!Deletes the tree, if possible.
103 @param tree the directory tree to delete"""
109 except EnvironmentError
as e:
112 self.logger.info(
'%s: rmtree'%(tree,))
113 shutil.rmtree(tree,ignore_errors=
False,onerror=self.
_rmtree_onerr)
116 """!Are there any directories to delete (ones passed to add())
117 @returns the number of directories to delete"""
121 """!Returns the list of directories to delete and clears the
127 def go(self,max_rmdir_loop=30):
128 """!Deletes all directories sent to add()
130 @param max_rmdir_loop The maximum number of directories to
131 delete before returning. This is a safeguard against
134 logger.info(
'Delete files: first pass.')
140 logger.warning(
'Some deletions failed. Will try again.')
141 logger.info(
'Delete files: second pass.')
144 if os.path.exists(tree):
147 logger.info(
'%s: already gone.'%(tree,))
150 logger.error(
'Could not delete files after two tries.')
152 logger.info(
'Remove parent and ancestor directories.')
154 while iloop<max_rmdir_loop
and self.
have_dirs():
159 logger.info(
'%s: rmdir'%(dir,))
161 except EnvironmentError
as e:
162 logger.info(
'%s: cannot remove: %s'%(dir,repr(e)))
165 parent=os.path.dirname(dir)
166 self.__rmdirs.add(parent)
167 except EnvironmentError
as e:
168 logger.warning(
'%s: cannot determine parent'%(dir,))
170 if iloop>=max_rmdir_loop:
172 'Hit maximum loop count of %d. Some ancestor directories '
173 'may still exist.'%(max_rmdir_loop,))
176 """!Main program: parses arguments, sends them to Deleter.add() and calls Deleter.go()"""
177 logger=logging.getLogger(
'hwrf_scrub')
179 for arg
in sys.argv[1:]:
183 if __name__==
'__main__':
187 except Exception
as e:
188 jlogger.critical(
'HWRF scrubber is aborting: '+str(e),exc_info=
True)
This module provides a set of utility functions to do filesystem operations.
Contains setup(), which initializes the produtil package.
badflag
If True, then at least one directory had trouble being deleted.
def validate_path(self, norm)
Checks to see if the given path is one that should not be deleted.
def rmtree(self, tree)
Deletes the tree, if possible.
Recursive directory deleter with safeguards to prevent accidental deletion of certain critical direct...
def setup(ignore_hup=False, dbnalert_logger=None, jobname=None, cluster=None, send_dbn=None, thread_logger=False, thread_stack=2 **24, kwargs)
Initializes the produtil package.
def add(self, dirname)
Adds a directory to the list to be deleted.
def norm_expand_path
Normalizes path and expand home directories.
def logger(self)
Returns the logging.Logger used for log messages.
def swap_dirs(self)
Returns the list of directories to delete and clears the internal list.
def have_dirs(self)
Are there any directories to delete (ones passed to add())
def _rmtree_onerr(self, function, path, exc_info)
Internal function used to log errors.
Raised by various safety checks if someone tries to delete something they should not, such as "/".
def go
Deletes all directories sent to add()
def __init__(self, logger)
Constructor for Deleter.