From 36b43fb1eaa46bd18e884b1f0d769533dd677902 Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Wed, 1 May 2013 11:05:48 +1200 Subject: [PATCH] Bug 867029, Port windows clobberer fixes to purge_builds.py (unable to free enough space), r=jhopkins --- buildfarm/maintenance/purge_builds.py | 35 +++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/buildfarm/maintenance/purge_builds.py b/buildfarm/maintenance/purge_builds.py index 5f354642d..978fac473 100644 --- a/buildfarm/maintenance/purge_builds.py +++ b/buildfarm/maintenance/purge_builds.py @@ -30,10 +30,13 @@ if sys.platform == 'win32': # os.statvfs doesn't work on Windows - import win32file + from win32file import RemoveDirectory, DeleteFile, \ + GetFileAttributesW, SetFileAttributesW, GetDiskFreeSpace, \ + FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_DIRECTORY + from win32api import FindFiles def freespace(p): - secsPerClus, bytesPerSec, nFreeClus, totClus = win32file.GetDiskFreeSpace(p) + secsPerClus, bytesPerSec, nFreeClus, totClus = GetDiskFreeSpace(p) return secsPerClus * bytesPerSec * nFreeClus else: def freespace(p): @@ -47,10 +50,38 @@ def mtime_sort(p1, p2): return cmp(os.path.getmtime(p1), os.path.getmtime(p2)) +def rmdirRecursiveWindows(dir): + """Windows-specific version of rmdirRecursive that handles + path lengths longer than MAX_PATH. + """ + + dir = os.path.realpath(dir) + # Make sure directory is writable + SetFileAttributesW('\\\\?\\' + dir, FILE_ATTRIBUTE_NORMAL) + + for ffrec in FindFiles('\\\\?\\' + dir + '\*.*'): + file_attr = ffrec[0] + name = ffrec[8] + if name == '.' or name == '..': + continue + full_name = os.path.join(dir, name) + + if file_attr & FILE_ATTRIBUTE_DIRECTORY: + rmdirRecursiveWindows(full_name) + else: + SetFileAttributesW('\\\\?\\' + full_name, FILE_ATTRIBUTE_NORMAL) + DeleteFile('\\\\?\\' + full_name) + RemoveDirectory('\\\\?\\' + dir) + + def rmdirRecursive(dir): """This is a replacement for shutil.rmtree that works better under windows. Thanks to Bear at the OSAF for the code. (Borrowed from buildbot.slave.commands)""" + if os.name == 'nt': + rmdirRecursiveWindows(dir) + return + if not os.path.exists(dir): # This handles broken links if os.path.islink(dir):