Skip to content
This repository has been archived by the owner on Sep 15, 2021. It is now read-only.

Commit

Permalink
Bug 508403 - do clobbers on release builds. r=nthomas
Browse files Browse the repository at this point in the history
  • Loading branch information
Chris AtLee committed Dec 18, 2009
1 parent 1763ed8 commit 82b7cea
Show file tree
Hide file tree
Showing 3 changed files with 782 additions and 109 deletions.
179 changes: 111 additions & 68 deletions clobberer/clobberer.py
Original file line number Original file line Diff line number Diff line change
@@ -1,19 +1,18 @@
import sys, shutil, urllib2, urllib, os #!/usr/bin/python
from datetime import datetime, timedelta # vim:sts=2 sw=2
import sys, shutil, urllib2, urllib, os, traceback, time


clobber_suffix='.deleteme' clobber_suffix='.deleteme'


def str_to_datetime(s): def ts_to_str(ts):
return datetime.strptime(s, "%Y-%m-%d %H:%M:%S") if ts is None:

return None
def datetime_to_str(dt): return time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(ts))
return dt.strftime("%Y-%m-%d %H:%M:%S")


def write_file(dt, fn): def write_file(ts, fn):
assert isinstance(dt, datetime) assert isinstance(ts, int)
dt = datetime_to_str(dt)
f = open(fn, "w") f = open(fn, "w")
f.write(dt) f.write(str(ts))
f.close() f.close()


def read_file(fn): def read_file(fn):
Expand All @@ -22,7 +21,7 @@ def read_file(fn):


data = open(fn).read().strip() data = open(fn).read().strip()
try: try:
return str_to_datetime(data) return int(data)
except ValueError: except ValueError:
return None return None


Expand Down Expand Up @@ -89,88 +88,132 @@ def do_clobber(dir, dryrun=False, skip=None):
# Prevent repeated moving. # Prevent repeated moving.
if f.endswith(clobber_suffix): if f.endswith(clobber_suffix):
rmdirRecursive(f) rmdirRecursive(f)
else: else:
shutil.move(f, clobber_path) shutil.move(f, clobber_path)
rmdirRecursive(clobber_path) rmdirRecursive(clobber_path)
except: except:
print "Couldn't clobber properly, bailing out." print "Couldn't clobber properly, bailing out."
sys.exit(1) sys.exit(1)


def getClobberDate(baseURL, branch, builder, slave): def getClobberDates(clobberURL, branch, buildername, builddir, slave, master):
url = "%s?%s" % (baseURL, params = dict(branch=branch, buildername=buildername, builddir=builddir, slave=slave, master=master)
urllib.urlencode(dict(branch=branch, builder=builder, slave=slave))) url = "%s?%s" % (clobberURL, urllib.urlencode(params))
print "Checking clobber URL: %s" % url print "Checking clobber URL: %s" % url
data = urllib2.urlopen(url).read().strip() data = urllib2.urlopen(url).read().strip()

retval = {}
try: try:
return str_to_datetime(data) for line in data.split("\n"):
line = line.strip()
if not line:
continue
builddir, builder_time, who = line.split(":")
builder_time = int(builder_time)
retval[builddir] = (builder_time, who)
return retval
except ValueError: except ValueError:
return None print "Error parsing response from server"
print data
raise


if __name__ == "__main__": if __name__ == "__main__":
from optparse import OptionParser from optparse import OptionParser
parser = OptionParser() parser = OptionParser("%prog [options] clobberURL branch buildername builddir slave master")
parser.add_option("-n", "--dry-run", dest="dryrun", action="store_true", parser.add_option("-n", "--dry-run", dest="dryrun", action="store_true",
default=False, help="don't actually delete anything") default=False, help="don't actually delete anything")
parser.add_option("-t", "--periodic", dest="period", type="float", parser.add_option("-t", "--periodic", dest="period", type="float",
default=24*7, help="hours between periodic clobbers") default=None, help="hours between periodic clobbers")
parser.add_option('-s', '--skip', help='do not delete this directory', parser.add_option('-s', '--skip', help='do not delete this file/directory',
action='append', dest='skip', default=['last-clobber']) action='append', dest='skip', default=['last-clobber'])
parser.add_option('-d', '--dir', help='clobber this directory', parser.add_option('-d', '--dir', help='clobber this directory',
dest='dir', default='.', type='string') dest='dir', default='.', type='string')
parser.add_option('-v', '--verbose', help='be more verbose',
dest='verbose', action='store_true', default=False)


options, args = parser.parse_args() options, args = parser.parse_args()
periodicClobberTime = timedelta(hours = options.period) if len(args) != 6:
parser.error("Incorrect number of arguments")


baseURL, branch, builder, slave = args if options.period:
periodicClobberTime = options.period * 3600
else:
periodicClobberTime = None

clobberURL, branch, builder, my_builddir, slave, master = args


try: try:
server_clobber_date = getClobberDate(baseURL, branch, builder, slave) server_clobber_dates = getClobberDates(clobberURL, branch, builder, my_builddir, slave, master)
except: except:
if options.verbose:
traceback.print_exc()
print "Error contacting server" print "Error contacting server"
sys.exit(1) sys.exit(1)


our_clobber_date = read_file("last-clobber") if options.verbose:

print "Server gave us", server_clobber_dates
clobber = False

now = int(time.time())
print "Our last clobber date: ", our_clobber_date
print "Server clobber date: ", server_clobber_date # Add ourself to the server_clobber_dates if it's not set

# This happens when this slave has never been clobbered
# If we don't have a last clobber date, then this is probably a fresh build. if my_builddir not in server_clobber_dates:
# We should only do a forced server clobber if we know when our last clobber server_clobber_dates[my_builddir] = None, ""
# was, and if the server date is more recent than that.
if server_clobber_date is not None and our_clobber_date is not None: root_dir = os.path.abspath(options.dir)
# If the server is giving us a clobber date, compare the server's idea of
# the clobber date to our last clobber date for builddir, (server_clobber_date, who) in server_clobber_dates.items():
if server_clobber_date > our_clobber_date: builder_dir = os.path.join(root_dir, builddir)
# If the server's clobber date is greater than our last clobber date, if not os.path.isdir(builder_dir):
# then we should clobber. print "%s doesn't exist, skipping" % builder_dir
clobber = True continue
# We should also update our clobber date to match the server's os.chdir(builder_dir)
our_clobber_date = server_clobber_date
print "Server is forcing a clobber" our_clobber_date = read_file("last-clobber")


if not clobber: clobber = False
# Next, check if more than the periodicClobberTime period has passed since
# our last clobber print "%s:Our last clobber date: " % builddir, ts_to_str(our_clobber_date)
if our_clobber_date is None: print "%s:Server clobber date: " % builddir, ts_to_str(server_clobber_date)
# We've never been clobbered
# Set our last clobber time to now, so that we'll clobber # If we don't have a last clobber date, then this is probably a fresh build.
# properly after periodicClobberTime # We should only do a forced server clobber if we know when our last clobber
our_clobber_date = datetime.utcnow() # was, and if the server date is more recent than that.
if server_clobber_date is not None and our_clobber_date is not None:
# If the server is giving us a clobber date, compare the server's idea of
# the clobber date to our last clobber date
if server_clobber_date > our_clobber_date:
# If the server's clobber date is greater than our last clobber date,
# then we should clobber.
clobber = True
# We should also update our clobber date to match the server's
our_clobber_date = server_clobber_date
if who:
print "%s:Server is forcing a clobber, initiated by %s" % (builddir, who)
else:
print "%s:Server is forcing a clobber" % builddir

if not clobber:
# Disable periodic clobbers for builders that aren't my_builddir
if builddir != my_builddir:
continue

# Next, check if more than the periodicClobberTime period has passed since
# our last clobber
if our_clobber_date is None:
# We've never been clobbered
# Set our last clobber time to now, so that we'll clobber
# properly after periodicClobberTime
our_clobber_date = now
write_file(our_clobber_date, "last-clobber")
elif periodicClobberTime and now > our_clobber_date + periodicClobberTime:
# periodicClobberTime has passed since our last clobber
clobber = True
# Update our clobber date to now
our_clobber_date = now
print "%s:More than %s seconds have passed since our last clobber" % (builddir, periodicClobberTime)

if clobber:
# Finally, perform a clobber if we're supposed to
print "%s:Clobbering..." % builddir
do_clobber(builder_dir, options.dryrun, options.skip)
write_file(our_clobber_date, "last-clobber") write_file(our_clobber_date, "last-clobber")
elif datetime.utcnow() > our_clobber_date + periodicClobberTime:
# periodicClobberTime has passed since our last clobber
clobber = True
# Update our clobber date to now
our_clobber_date = datetime.utcnow()
print "More than %s have passed since our last clobber" % periodicClobberTime

if clobber:
# Finally, perform a clobber if we're supposed to
if os.path.exists(options.dir):
print "Clobbering..."
do_clobber(options.dir, options.dryrun, options.skip)
else:
print "Clobber failed because '%s' doesn't exist" % options.dir
write_file(our_clobber_date, "last-clobber")
Loading

0 comments on commit 82b7cea

Please sign in to comment.