Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(157)

Unified Diff: scripts/tools/cros/cros_builder_convert.py

Issue 1402253002: CrOS: Load Chromite pins from JSON. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/build
Patch Set: Rebase (without pin JSON). Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « scripts/slave/unittests/recipe_lint_test.py ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: scripts/tools/cros/cros_builder_convert.py
diff --git a/scripts/tools/cros/cros_builder_convert.py b/scripts/tools/cros/cros_builder_convert.py
deleted file mode 100755
index d16a6f42341426791c3bcec44fe7eadff7c795e8..0000000000000000000000000000000000000000
--- a/scripts/tools/cros/cros_builder_convert.py
+++ /dev/null
@@ -1,273 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Updates BuildBot builder directories to the new 'cbuildbot'-driven naming
-scheme.
-
-Classic BuildBot CrOS waterfalls define build directories by composing the
-directory name from component parts resembling the target and a final branch
-name. Oftentimes, these component parts (and, therefore, the composition) don't
-actually match the name of the underlying 'cbuildbot' target.
-
-This presents problems because the build target are fundamentally driven by
-their underlying 'cbuildbot' target, but the composition scheme is extremely
-arbitrary.
-
-Consequently, BuildBot masters are being migrated to a new, deterministic,
-'cbuildbot'-driven naming scheme. A builder building 'cbuildbot' target
-<target> and checking Chromite/'cbuildbot' from branch <branch> will use the
-builder name: <target>-<branch>. This is universally sustainable across all
-waterfalls and ensures that 'cbuildbot' builds are tracked and numbered based
-on their underlying 'cbuildbot' target.
-
-This script is intended to be run on a stopped BuildBot master during build
-directory migration. It will iterate through each build directory in the current
-master naming scheme and rename the classic directories into their new
-'cbuildbot'-driven namespace.
-"""
-
-import argparse
-import collections
-import logging
-import os
-import re
-import shutil
-import sys
-
-from common import cros_chromite
-
-
-class UpdateInfo(collections.namedtuple(
- 'UpdateInfo',
- ('src', 'cbb_name', 'branch'))):
- """Information about a single directory update action."""
-
- _STATIC_PERMUTATIONS = {
- 'Canary master': 'master-canary',
- }
-
- _TRANSFORMATIONS = (
- (r'-canary-', r'-release-'),
- (r'-full', r'-release'),
- (r'-pre-flight', r'-pre-flight-branch'),
- (r'(x86|amd64)$', r'\1-generic'),
- (r'^chromium-tot-chromeos-(.+)-asan', r'\1-tot-asan-informational'),
- (r'^chromium-tot-chromeos-(.+)', r'\1-tot-chrome-pfq-informational'),
- (r'^chromium-(.+)-telemetry$', r'\1-telemetry'),
- (r'(.+)-bin$', r'\1'),
- )
-
- @property
- def dst(self):
- """Constructs the <cbuildbot>-<branch> form."""
- return '%s-%s' % (self.cbb_name, self.branch)
-
- @classmethod
- def permutations(cls, name):
- """Attempts to permute a legacy BuildBot name into a Chromite target.
-
- Args:
- name (str): The source name to process and map.
- Yields (str): Various permutations of 'name'.
- """
- # No cbuildbot targets use upper-case letters.
- name = name.lower()
-
- # If 'name' is already a 'cbuildbot' target, return it unmodified.
- yield name
-
- # Apply static permutations.
- p = cls._STATIC_PERMUTATIONS.get(name)
- if p:
- yield p
-
- # Replace 'canary' with 'release'.
- for find, replace in cls._TRANSFORMATIONS:
- name = re.sub(find, replace, name)
- yield name
-
- # Is 'name' valid if it was a release group?
- if not name.endswith('-group'):
- # We never build 'full' group variants.
- name_group = ('%s-group' % (name,)).replace('-full-', '-release-')
- yield name_group
-
- @classmethod
- def process(cls, config, name, branches=None, blacklist=None):
- """Construct an UpdateInfo to map a source name.
-
- This function works by attempting to transform a source name into a known
- 'cbuildbot' target name. If successful, it will use that successful
- transformation as validation of the correctness and return an UpdateInfo
- describing the transformation.
-
- Args:
- config (cros_chromite.ChromiteConfig) The Chromite config instance.
- name (str): The source name to process and map.
- branches (list): A list of valid branches, extracted from 'cros_chromite'.
- Returns (UpdateInfo/None): The constructed UpdateInfo, or None if there was
- no identified mapping.
- """
- def sliding_split_gen():
- parts = name.split('-')
- for i in xrange(len(parts), 0, -1):
- yield '-'.join(parts[:i]), '-'.join(parts[i:])
-
- logging.debug("Processing candidate name: %s", name)
- candidates = set()
- branch = None
- for orig_name, branch in sliding_split_gen():
- logging.debug("Trying construction: Name(%s), Branch(%s)",
- orig_name, branch)
- if branches and not branch in branches:
- logging.debug("Ignoring branch value '%s'.", branch)
- continue
-
- # See if we can properly permute the original name.
- for permuted_name in cls.permutations(orig_name):
- if blacklist and any(b in permuted_name for b in blacklist):
- logging.debug("Ignoring blacklisted config name: %s", permuted_name)
- continue
- if permuted_name in config:
- candidates.add(permuted_name)
- if not candidates:
- logging.debug("No 'cbuildbot' config for attempts [%s] branch [%s].",
- orig_name, branch)
- continue
-
- # We've found a permutation that matches a 'cbuildbot' target.
- break
- else:
- logging.info("No 'cbuildbot' permutations for [%s].", name)
- return None
-
- if not branch:
- # We need to do an update to add the branch. Default to 'master'.
- branch = 'master'
-
- candidates = sorted(candidates)
- for candidate in candidates:
- logging.debug("Identified 'cbuildbot' name [%s] => [%s] branch [%s].",
- name, candidate, branch)
- return [cls(name, p, branch) for p in candidates]
-
-
-def main(args):
- """Main execution function.
-
- Args:
- args (list): Command-line argument array.
- """
- parser = argparse.ArgumentParser()
- parser.add_argument('path', nargs='+', metavar='PATH',
- help='The path to the master directory to process.')
- parser.add_argument('-v', '--verbose', action='count', default=0,
- help='Increase verbosity. Can be specified multiple times.')
- parser.add_argument('-d', '--dry-run', action='store_true',
- help="Print what actions will be taken, but don't modify anything.")
- parser.add_argument('-n', '--names', action='store_true',
- help="If specified, then regard 'path' as directory names to test.")
- parser.add_argument('-B', '--blacklist', action='append', default=[],
- help="Blacklist configs that contain this text.")
- args = parser.parse_args()
-
- # Select verbosity.
- if args.verbose == 0:
- loglevel = logging.WARNING
- elif args.verbose == 1:
- loglevel = logging.INFO
- else:
- loglevel = logging.DEBUG
- logging.getLogger().setLevel(loglevel)
-
- # Load all availables Chromite configs. We're going to load ToT.
- config_names = set()
- branches = set()
- for branch in cros_chromite.PINS.iterkeys():
- branches.add(branch)
- config_names.update(cros_chromite.Get(branch=branch).iterkeys())
-
- # If we're just testing against names, do that.
- if args.names:
- errors = 0
- for n in args.path:
- update_info_list = UpdateInfo.process(config_names, n, branches=branches,
- blacklist=args.blacklist)
- if update_info_list:
- for update_info in update_info_list:
- logging.warning("[%s] => [%s]", update_info.src, update_info.dst)
- else:
- logging.warning("No transformation for name [%s].", n)
- errors += 1
- return errors
-
- # Construct the set of actions to take.
- cbb_already = set()
- unmatched = set()
- multiples = {}
- updates = []
- for path in args.path:
- if not os.path.isdir(path):
- raise ValueError("Supplied master directory is not valid: %s" % (path,))
-
- seen = set()
- for f in os.listdir(path):
- f_path = os.path.join(path, f)
- if not os.path.isdir(f_path):
- continue
-
- update_info_list = UpdateInfo.process(config_names, f, branches=branches,
- blacklist=args.blacklist)
- if not update_info_list:
- logging.info("No update information for directory [%s]", f)
- unmatched.add(f)
- continue
- elif len(update_info_list) != 1:
- multiples[f] = update_info_list
- continue
- update_info = update_info_list[0]
-
- # Make sure that we don't stomp on directory names. This shouldn't happen,
- # since the mapping to 'cbuildbot' names is inherently deconflicting, but
- # it's good to assert it just in case.
- update_info_names = set((update_info.src, update_info.dst))
- if update_info_names.intersection(seen):
- logging.error("Updated names intersect with existing names: %s",
- ", ".join(update_info_names.intersection(seen)))
- return 1
- seen.update(update_info_names)
-
- # We are already in <cbuildbot>-<branch> format, so do nothing.
- if update_info.src == update_info.dst:
- cbb_already.add(update_info.src)
- else:
- updates.append((path, update_info))
-
- # Execute the updates.
- logging.info("Executing %d updates.", len(updates))
- for master_dir, update_info in updates:
- logging.info("Updating [%s]: [%s] => [%s]", master_dir, update_info.src,
- update_info.dst)
- if not args.dry_run:
- shutil.move(os.path.join(master_dir, update_info.src),
- os.path.join(master_dir, update_info.dst))
- logging.info("Updated %d directories.", len(updates))
- if logging.getLogger().isEnabledFor(logging.DEBUG):
- logging.debug("%d directories already matching: %s",
- len(cbb_already), ', '.join(sorted(cbb_already)))
- if unmatched:
- logging.warning("%d unmatched directories: %s",
- len(unmatched), ', '.join(sorted(unmatched)))
- if multiples:
- for f in sorted(multiples.iterkeys()):
- logging.warning("Multiple permutations of [%s]: %s\n%s",
- f, ", ".join(m.dst for m in multiples[f]),
- '\n'.join('mv %s %s' % (f, m.dst) for m in multiples[f]))
- return 0
-
-
-if __name__ == '__main__':
- logging.basicConfig()
- sys.exit(main(sys.argv[1:]))
« no previous file with comments | « scripts/slave/unittests/recipe_lint_test.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698