Add more error checking to preflight queue.

What's new?
  - cros_mark_as_stable now exits with errors if directories are specified
    that don't exist.
  - cbuildbot.py always explicitly specifies overlay directories so
    cros_mark_as_stable can rely on them existing.
  - Package names and paths are now separated with colons instead of
    spaces, so as to allow for us using the same syntax with
    enter_chroot.sh as we use without the same script. (enter_chroot.sh
    mucks with command-lines that contain spaces or quotes.)
  - All buildbots now explicitly specify what overlays they want to rev. Public buildbots only rev public ebuilds and private buildbots now only rev private ebuilds.

BUG=chromium-os:8647
TEST=Ran unit tests. Manually marked packages as stable.

Change-Id: I1df6d428973d91329c4f5159e2886889a3ebb7c7

Review URL: http://codereview.chromium.org/4442001
This commit is contained in:
David James 2010-11-11 10:37:04 -08:00
parent 9a40915f00
commit b4258c8bd4
4 changed files with 83 additions and 70 deletions

View File

@ -181,37 +181,35 @@ def _ParseRevisionString(revision_string, repo_dictionary):
return revisions.items() return revisions.items()
def _UprevFromRevisionList(buildroot, tracking_branch, revision_list, board): def _UprevFromRevisionList(buildroot, tracking_branch, revision_list, board,
overlays):
"""Uprevs based on revision list.""" """Uprevs based on revision list."""
if not revision_list: if not revision_list:
Info('No packages found to uprev') Info('No packages found to uprev')
return return
package_str = '' packages = []
for package, revision in revision_list: for package, revision in revision_list:
package_str += package + ' ' assert ':' not in package, 'Invalid package name: %s' % package
packages.append(package)
package_str = package_str.strip()
cwd = os.path.join(buildroot, 'src', 'scripts') cwd = os.path.join(buildroot, 'src', 'scripts')
# TODO(davidjames): --foo="bar baz" only works here because we're using
# enter_chroot.
RunCommand(['./cros_mark_as_stable', RunCommand(['./cros_mark_as_stable',
'--board=%s' % board, '--board=%s' % board,
'--tracking_branch="%s"' % tracking_branch, '--tracking_branch=%s' % tracking_branch,
'--packages="%s"' % package_str, '--overlays=%s' % ':'.join(overlays),
'--packages=%s' % ':'.join(packages),
'commit'], 'commit'],
cwd=cwd, enter_chroot=True) cwd=cwd, enter_chroot=True)
def _UprevAllPackages(buildroot, tracking_branch, board): def _UprevAllPackages(buildroot, tracking_branch, board, overlays):
"""Uprevs all packages that have been updated since last uprev.""" """Uprevs all packages that have been updated since last uprev."""
cwd = os.path.join(buildroot, 'src', 'scripts') cwd = os.path.join(buildroot, 'src', 'scripts')
# TODO(davidjames): --foo="bar baz" only works here because we're using
# enter_chroot.
RunCommand(['./cros_mark_as_stable', '--all', RunCommand(['./cros_mark_as_stable', '--all',
'--board=%s' % board, '--board=%s' % board,
'--tracking_branch="%s"' % tracking_branch, 'commit'], '--overlays=%s' % ':'.join(overlays),
'--tracking_branch=%s' % tracking_branch, 'commit'],
cwd=cwd, enter_chroot=True) cwd=cwd, enter_chroot=True)
@ -228,12 +226,13 @@ def _GetVMConstants(buildroot):
return (vdisk_size.strip(), statefulfs_size.strip()) return (vdisk_size.strip(), statefulfs_size.strip())
def _GitCleanup(buildroot, board, tracking_branch): def _GitCleanup(buildroot, board, tracking_branch, overlays):
"""Clean up git branch after previous uprev attempt.""" """Clean up git branch after previous uprev attempt."""
cwd = os.path.join(buildroot, 'src', 'scripts') cwd = os.path.join(buildroot, 'src', 'scripts')
if os.path.exists(cwd): if os.path.exists(cwd):
RunCommand(['./cros_mark_as_stable', '--srcroot=..', RunCommand(['./cros_mark_as_stable', '--srcroot=..',
'--board=%s' % board, '--board=%s' % board,
'--overlays=%s' % ':'.join(overlays),
'--tracking_branch=%s' % tracking_branch, 'clean'], '--tracking_branch=%s' % tracking_branch, 'clean'],
cwd=cwd, error_ok=True) cwd=cwd, error_ok=True)
@ -257,9 +256,9 @@ def _WipeOldOutput(buildroot):
# =========================== Main Commands =================================== # =========================== Main Commands ===================================
def _PreFlightRinse(buildroot, board, tracking_branch): def _PreFlightRinse(buildroot, board, tracking_branch, overlays):
"""Cleans up any leftover state from previous runs.""" """Cleans up any leftover state from previous runs."""
_GitCleanup(buildroot, board, tracking_branch) _GitCleanup(buildroot, board, tracking_branch, overlays)
_CleanUpMountPoints(buildroot) _CleanUpMountPoints(buildroot)
RunCommand(['sudo', 'killall', 'kvm'], error_ok=True) RunCommand(['sudo', 'killall', 'kvm'], error_ok=True)
@ -347,7 +346,7 @@ def _RunSmokeSuite(buildroot, results_dir):
], cwd=cwd, error_ok=False) ], cwd=cwd, error_ok=False)
def _UprevPackages(buildroot, tracking_branch, revisionfile, board): def _UprevPackages(buildroot, tracking_branch, revisionfile, board, overlays):
"""Uprevs a package based on given revisionfile. """Uprevs a package based on given revisionfile.
If revisionfile is set to None or does not resolve to an actual file, this If revisionfile is set to None or does not resolve to an actual file, this
@ -376,26 +375,19 @@ def _UprevPackages(buildroot, tracking_branch, revisionfile, board):
# print >> sys.stderr, 'CBUILDBOT Revision list found %s' % revisions # print >> sys.stderr, 'CBUILDBOT Revision list found %s' % revisions
# revision_list = _ParseRevisionString(revisions, # revision_list = _ParseRevisionString(revisions,
# _CreateRepoDictionary(buildroot, board)) # _CreateRepoDictionary(buildroot, board))
# _UprevFromRevisionList(buildroot, tracking_branch, revision_list, board) # _UprevFromRevisionList(buildroot, tracking_branch, revision_list, board,
# overlays)
#else: #else:
Info('CBUILDBOT Revving all') Info('CBUILDBOT Revving all')
_UprevAllPackages(buildroot, tracking_branch, board) _UprevAllPackages(buildroot, tracking_branch, board, overlays)
def _UprevPush(buildroot, tracking_branch, board, overlays): def _UprevPush(buildroot, tracking_branch, board, overlays):
"""Pushes uprev changes to the main line.""" """Pushes uprev changes to the main line."""
cwd = os.path.join(buildroot, 'src', 'scripts') cwd = os.path.join(buildroot, 'src', 'scripts')
public_overlay = '%s/src/third_party/chromiumos-overlay' % buildroot
private_overlay = '%s/src/private-overlays/chromeos-overlay' % buildroot
if overlays == 'private':
overlays = [private_overlay]
elif overlays == 'public':
overlays = [public_overlay]
else:
overlays = [public_overlay, private_overlay]
RunCommand(['./cros_mark_as_stable', '--srcroot=..', RunCommand(['./cros_mark_as_stable', '--srcroot=..',
'--board=%s' % board, '--board=%s' % board,
'--overlays=%s' % " ".join(overlays), '--overlays=%s' % ':'.join(overlays),
'--tracking_branch=%s' % tracking_branch, '--tracking_branch=%s' % tracking_branch,
'--push_options=--bypass-hooks -f', 'push'], '--push_options=--bypass-hooks -f', 'push'],
cwd=cwd) cwd=cwd)
@ -467,6 +459,32 @@ def _GetConfig(config_name):
return buildconfig return buildconfig
def ResolveOverlays(overlays):
"""Return the list of overlays to use for a given buildbot.
Args:
overlays: A string describing which overlays you want.
'private': Just the private overlay.
'public': Just the public overlay.
'both': Both the public and private overlays.
"""
public_overlay = '%s/src/third_party/chromiumos-overlay' % buildroot
private_overlay = '%s/src/private-overlays/chromeos-overlay' % buildroot
if overlays == 'private':
dirs = [private_overlay]
elif overlays == 'public':
dirs = [public_overlay]
elif overlays == 'both':
dirs = [public_overlay, private_overlay]
else:
Die('Incorrect overlay configuration: %s' % overlays)
for dir in dirs:
assert ':' not in dir, 'Overlay must not contain colons: %s' % dir
if not os.path.exists(dir):
Die('Missing overlay: %s' % dir)
return dirs
def main(): def main():
# Parse options # Parse options
usage = "usage: %prog [options] cbuildbot_config" usage = "usage: %prog [options] cbuildbot_config"
@ -502,8 +520,11 @@ def main():
parser.print_usage() parser.print_usage()
sys.exit(1) sys.exit(1)
# Calculate list of overlay directories.
overlays = ResolveOverlays(buildconfig['overlays'])
try: try:
_PreFlightRinse(buildroot, buildconfig['board'], tracking_branch) _PreFlightRinse(buildroot, buildconfig['board'], tracking_branch, overlays)
if options.clobber or not os.path.isdir(buildroot): if options.clobber or not os.path.isdir(buildroot):
_FullCheckout(buildroot, tracking_branch, url=options.url) _FullCheckout(buildroot, tracking_branch, url=options.url)
else: else:
@ -519,7 +540,7 @@ def main():
if buildconfig['uprev']: if buildconfig['uprev']:
_UprevPackages(buildroot, tracking_branch, revisionfile, _UprevPackages(buildroot, tracking_branch, revisionfile,
board=buildconfig['board']) buildconfig['board'], overlays)
_EnableLocalAccount(buildroot) _EnableLocalAccount(buildroot)
_Build(buildroot) _Build(buildroot)
@ -545,7 +566,7 @@ def main():
# Master bot needs to check if the other slaves completed. # Master bot needs to check if the other slaves completed.
if cbuildbot_comm.HaveSlavesCompleted(config): if cbuildbot_comm.HaveSlavesCompleted(config):
_UprevPush(buildroot, tracking_branch, buildconfig['board'], _UprevPush(buildroot, tracking_branch, buildconfig['board'],
buildconfig['overlays']) overlays)
else: else:
Die('CBUILDBOT - One of the slaves has failed!!!') Die('CBUILDBOT - One of the slaves has failed!!!')

View File

@ -19,9 +19,9 @@ hostname -- Needed for 'important' slaves. The hostname of the bot. Should
match hostname in slaves.cfg in buildbot checkout. match hostname in slaves.cfg in buildbot checkout.
unittests -- Runs unittests for packages. unittests -- Runs unittests for packages.
smoke_bvt -- Runs the test smoke suite in a qemu-based VM using KVM. smoke_bvt -- Runs the test smoke suite in a qemu-based VM using KVM.
overlays -- If this bot is a master bot, select what overlays to push changes overlays -- Select what overlays to look at. This can be 'public', 'private'
to. This can be 'public', 'private', or 'both'. There should only or 'both'. There should only be one master bot pushing changes to
be one bot pushing changes to each overlay. each overlay per branch.
""" """
@ -33,6 +33,7 @@ config['default'] = {
'important' : False, 'important' : False,
'unittests' : False, 'unittests' : False,
'smoke_bvt' : False, 'smoke_bvt' : False,
'overlays': 'public',
} }
config['x86-generic-pre-flight-queue'] = { config['x86-generic-pre-flight-queue'] = {
'board' : 'x86-generic', 'board' : 'x86-generic',
@ -69,6 +70,7 @@ config['x86_agz_bin'] = {
'important' : False, 'important' : False,
'unittests' : True, 'unittests' : True,
'smoke_bvt' : True, 'smoke_bvt' : True,
'overlays': 'private',
} }
config['x86_dogfood_bin'] = { config['x86_dogfood_bin'] = {
'board' : 'x86-dogfood', 'board' : 'x86-dogfood',
@ -77,52 +79,29 @@ config['x86_dogfood_bin'] = {
'important' : False, 'important' : False,
'unittests' : True, 'unittests' : True,
'smoke_bvt' : True, 'smoke_bvt' : True,
'overlays': 'private',
} }
config['x86_pineview_bin'] = { config['x86_pineview_bin'] = {
'board' : 'x86-pineview', 'board' : 'x86-pineview',
'uprev' : True, 'uprev' : True,
'master' : False, 'master' : False,
'important' : False, 'important' : False,
'hostname' : 'codf200.jail',
'unittests': True, 'unittests': True,
'overlays': 'public',
} }
config['arm_tegra2_bin'] = { config['arm_tegra2_bin'] = {
'board' : 'tegra2', 'board' : 'tegra2',
'uprev' : True, 'uprev' : True,
'master' : False, 'master' : False,
'important' : False, 'important' : False,
'hostname' : 'codg172.jail',
'unittests' : False,
}
config['arm_voguev210_bin'] = {
'board' : 'voguev210',
'uprev' : True,
'master' : False,
'important' : False,
'hostname' : 'codf196.jail',
'unittests' : False,
}
config['arm_beagleboard_bin'] = {
'board' : 'beagleboard',
'master' : False,
'uprev' : True,
'important' : False,
'hostname' : 'codf202.jail',
'unittests' : False,
}
config['arm_st1q_bin'] = {
'board' : 'st1q',
'uprev' : True,
'master' : False,
'important' : False,
'hostname' : 'codg158.jail',
'unittests' : False, 'unittests' : False,
'overlays': 'public',
} }
config['arm_generic_bin'] = { config['arm_generic_bin'] = {
'board' : 'arm-generic', 'board' : 'arm-generic',
'uprev' : True, 'uprev' : True,
'master' : False, 'master' : False,
'important' : False, 'important' : False,
'hostname' : 'codg175.jail',
'unittests' : False, 'unittests' : False,
'overlays': 'public',
} }

View File

@ -166,15 +166,17 @@ class CBuildBotTest(mox.MoxTestBase):
m_file.read().AndReturn(self._test_string) m_file.read().AndReturn(self._test_string)
m_file.close() m_file.close()
overlays = [ '%s/src/third_party/chromiumos-overlay' % self._buildroot ]
cbuildbot.RunCommand(['./cros_mark_as_stable', '--all', cbuildbot.RunCommand(['./cros_mark_as_stable', '--all',
'--board=%s' % self._test_board, '--board=%s' % self._test_board,
'--tracking_branch="cros/master"', 'commit'], '--overlays=%s' % ':'.join(overlays),
'--tracking_branch=cros/master', 'commit'],
cwd='%s/src/scripts' % self._buildroot, cwd='%s/src/scripts' % self._buildroot,
enter_chroot=True) enter_chroot=True)
self.mox.ReplayAll() self.mox.ReplayAll()
cbuildbot._UprevPackages(self._buildroot, self.tracking_branch, cbuildbot._UprevPackages(self._buildroot, self.tracking_branch,
self._revision_file, self._test_board) self._revision_file, self._test_board, overlays)
self.mox.VerifyAll() self.mox.VerifyAll()
def testUprevAllPackages(self): def testUprevAllPackages(self):
@ -187,15 +189,18 @@ class CBuildBotTest(mox.MoxTestBase):
m_file.read().AndReturn('None') m_file.read().AndReturn('None')
m_file.close() m_file.close()
overlays = [ '%s/src/third_party/chromiumos-overlay' % self._buildroot ]
cbuildbot.RunCommand(['./cros_mark_as_stable', '--all', cbuildbot.RunCommand(['./cros_mark_as_stable', '--all',
'--board=%s' % self._test_board, '--board=%s' % self._test_board,
'--tracking_branch="cros/master"', 'commit'], '--overlays=%s' % ':'.join(overlays),
'--tracking_branch=cros/master', 'commit'],
cwd='%s/src/scripts' % self._buildroot, cwd='%s/src/scripts' % self._buildroot,
enter_chroot=True) enter_chroot=True)
self.mox.ReplayAll() self.mox.ReplayAll()
overlays = [ '%s/src/third_party/chromiumos-overlay' % self._buildroot ]
cbuildbot._UprevPackages(self._buildroot, self.tracking_branch, cbuildbot._UprevPackages(self._buildroot, self.tracking_branch,
self._revision_file, self._test_board) self._revision_file, self._test_board, overlays)
self.mox.VerifyAll() self.mox.VerifyAll()

View File

@ -22,10 +22,10 @@ from cros_build_lib import Info, RunCommand, Warning, Die
gflags.DEFINE_string('board', '', gflags.DEFINE_string('board', '',
'Board for which the package belongs.', short_name='b') 'Board for which the package belongs.', short_name='b')
gflags.DEFINE_string('overlays', '', gflags.DEFINE_string('overlays', '',
'Space separated list of overlays to modify.', 'Colon-separated list of overlays to modify.',
short_name='o') short_name='o')
gflags.DEFINE_string('packages', '', gflags.DEFINE_string('packages', '',
'Space separated list of packages to mark as stable.', 'Colon-separated list of packages to mark as stable.',
short_name='p') short_name='p')
gflags.DEFINE_string('push_options', '', gflags.DEFINE_string('push_options', '',
'Options to use with git-cl push using push command.') 'Options to use with git-cl push using push command.')
@ -245,7 +245,10 @@ def _SimpleRunCommand(command):
"""Runs a shell command and returns stdout back to caller.""" """Runs a shell command and returns stdout back to caller."""
_Print(' + %s' % command) _Print(' + %s' % command)
proc_handle = subprocess.Popen(command, stdout=subprocess.PIPE, shell=True) proc_handle = subprocess.Popen(command, stdout=subprocess.PIPE, shell=True)
return proc_handle.communicate()[0] stdout = proc_handle.communicate()[0]
retcode = proc_handle.wait()
assert retcode == 0, "Return code %s for command: %s" % (retcode, command)
return stdout
# ======================= End Global Helper Functions ======================== # ======================= End Global Helper Functions ========================
@ -487,11 +490,16 @@ def main(argv):
except gflags.FlagsError, e : except gflags.FlagsError, e :
_PrintUsageAndDie(str(e)) _PrintUsageAndDie(str(e))
package_list = gflags.FLAGS.packages.split() package_list = gflags.FLAGS.packages.split(':')
_CheckSaneArguments(package_list, command) _CheckSaneArguments(package_list, command)
if gflags.FLAGS.overlays: if gflags.FLAGS.overlays:
overlays = dict((path, []) for path in gflags.FLAGS.overlays.split()) overlays = {}
for path in gflags.FLAGS.overlays.split(':'):
if not os.path.exists(path):
Die('Cannot find overlay: %s' % path)
overlays[path] = []
else: else:
Warning('Missing --overlays argument')
overlays = { overlays = {
'%s/private-overlays/chromeos-overlay' % gflags.FLAGS.srcroot: [], '%s/private-overlays/chromeos-overlay' % gflags.FLAGS.srcroot: [],
'%s/third_party/chromiumos-overlay' % gflags.FLAGS.srcroot: [] '%s/third_party/chromiumos-overlay' % gflags.FLAGS.srcroot: []