| #!/usr/bin/python2.6 |
| # Copyright (c) 2011 The Chromium OS Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| """Refresh online Portage package status spreadsheet.""" |
| |
| import optparse |
| import os |
| import shutil |
| import sys |
| |
| sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..')) |
| import chromite.lib.cros_build_lib as cros_lib |
| import chromite.lib.operation as operation |
| |
| oper = operation.Operation('refresh_package_status') |
| oper.verbose = True # Without verbose Info messages don't show up. |
| |
| TMP_ROOT = '/tmp' |
| SCRIPT_DIR = os.path.dirname(__file__) |
| GDATA_CRED_FILE = '.gdata_cred.txt' |
| GENTOO_DIR = 'gentoo-portage' |
| PRTG_GIT_URL = 'ssh://gerrit.chromium.org:29418/chromiumos/overlays/portage.git' |
| FUNTOO_GIT_URL = 'git://github.com/funtoo/portage.git' |
| |
| def RunGit(cwd, cmd, args=[]): |
| """Run the git |cmd| with |args| in the |cwd| directory.""" |
| cmdline = ['git', cmd] + args |
| cros_lib.RunCommand(cmdline, cwd=cwd) |
| |
| |
| def UpdateOriginGentoo(): |
| """Update origin/gentoo on server and return path to local copy.""" |
| gentoo_root = '%s/%s' % (TMP_ROOT, GENTOO_DIR) |
| oper.Info('Performing update of origin/gentoo upstream mirror as requested.') |
| |
| if os.path.exists(gentoo_root): |
| shutil.rmtree(gentoo_root) |
| |
| RunGit(cwd=TMP_ROOT, cmd='clone', args=[PRTG_GIT_URL, GENTOO_DIR]) |
| RunGit(cwd=gentoo_root, cmd='remote', args=['add', 'funtoo', FUNTOO_GIT_URL]) |
| RunGit(cwd=gentoo_root, cmd='checkout', |
| args=['-b', 'gentoo', '--track', 'origin/gentoo']) |
| RunGit(cwd=gentoo_root, cmd='fetch', args=['funtoo']) |
| RunGit(cwd=gentoo_root, cmd='merge', args=['remotes/funtoo/gentoo.org']) |
| RunGit(cwd=gentoo_root, cmd='push') |
| |
| return gentoo_root |
| |
| |
| def CleanupOriginGentoo(gentoo_root): |
| """Remove the local copy of origin/gentoo source.""" |
| if os.path.exists(gentoo_root): |
| oper.Info('Removing local copy of origin/gentoo upstream mirror now.') |
| shutil.rmtree(gentoo_root) |
| |
| |
| def PrepareBoards(boards): |
| """Run setup_board for any boards that need it.""" |
| scripts_dir = os.path.join(SCRIPT_DIR, '..', '..', 'src', 'scripts') |
| for board in boards.split(':'): |
| if not os.path.isdir('/build/%s' % board): |
| oper.Info('Running setup_board for board=%s' % board) |
| cros_lib.RunCommand(['./setup_board', '--board=%s' % board], |
| cwd=scripts_dir) |
| |
| |
| def PrepareCSVRoot(): |
| """Prepare CSV output directory for use.""" |
| csv_root = '%s/%s' % (TMP_ROOT, 'csv') |
| if os.path.exists(csv_root): |
| shutil.rmtree(csv_root) |
| |
| os.mkdir(csv_root) |
| |
| return csv_root |
| |
| |
| def RefreshPackageStatus(board, upstream, csv_root, test, cred_file): |
| """Run through steps to refresh package status spreadsheet. |
| |
| |board| is a comma-separated list of chromeos boards to use. |
| |upstream| is a path to origin/gentoo upstream. Can be None. |
| Put all csv files under the |csv_root| directory. |
| If |test| is True, upload to test spreadsheet instead of real one. |
| Use |cred_file| as credentials file for spreadsheet upload. |
| """ |
| |
| # Run all chromeos targets for all boards. |
| oper.Info('Getting package status for all chromeos targets on all boards.') |
| cpu_cmd_baseline = ['cros_portage_upgrade', '--board=%s' % board] |
| if upstream: |
| cpu_cmd_baseline.append('--upstream=%s' % upstream) |
| |
| cros_csv = '%s/chromeos-boards.csv' % csv_root |
| cros_lib.RunCommand(cpu_cmd_baseline + |
| ['--to-csv=%s' % cros_csv, |
| 'chromeos']) |
| |
| crosdev_csv = '%s/chromeos-dev-boards.csv' % csv_root |
| cros_lib.RunCommand(cpu_cmd_baseline + |
| ['--to-csv=%s' % crosdev_csv, |
| 'chromeos', 'chromeos-dev']) |
| |
| crostest_csv = '%s/chromeos-test-boards.csv' % csv_root |
| cros_lib.RunCommand(cpu_cmd_baseline + |
| ['--to-csv=%s' % crostest_csv, |
| 'chromeos', 'chromeos-dev', 'chromeos-test']) |
| |
| # Run all host targets (world, hard-host-depends) for the host. |
| oper.Info('Getting package status for all host targets.') |
| cpu_host_baseline = ['cros_portage_upgrade', '--host'] |
| if upstream: |
| cpu_host_baseline.append('--upstream=%s' % upstream) |
| |
| hostworld_csv = '%s/world-host.csv' % csv_root |
| cros_lib.RunCommand(cpu_host_baseline + |
| ['--to-csv=%s' % hostworld_csv, |
| 'world']) |
| |
| hosthhd_csv = '%s/hhd-host.csv' % csv_root |
| cros_lib.RunCommand(cpu_host_baseline + |
| ['--to-csv=%s' % hosthhd_csv, |
| 'hard-host-depends']) |
| |
| # Merge all csv tables into one. |
| oper.Info('Merging all package status files into one.') |
| allboards_csv = '%s/all-boards.csv' % csv_root |
| cros_lib.RunCommand(['merge_package_status', |
| '--out=%s' % allboards_csv, |
| cros_csv, crosdev_csv, crostest_csv]) |
| |
| allhost_csv = '%s/all-host.csv' % csv_root |
| cros_lib.RunCommand(['merge_package_status', |
| '--out=%s' % allhost_csv, |
| hostworld_csv, hosthhd_csv]) |
| |
| allfinal_csv = '%s/all-final.csv' % csv_root |
| cros_lib.RunCommand(['merge_package_status', |
| '--out=%s' % allfinal_csv, |
| allboards_csv, allhost_csv]) |
| |
| # Upload the final csv file to the online spreadsheet. |
| oper.Info('Uploading package status to online spreadsheet.') |
| upload_cmdline = ['upload_package_status', '--verbose', |
| '--cred-file=%s' % cred_file] |
| if test: |
| upload_cmdline.append('--test-spreadsheet') |
| |
| upload_cmdline.append(allfinal_csv) |
| cros_lib.RunCommand(upload_cmdline) |
| |
| |
| def main(): |
| """Main function.""" |
| usage = 'Usage: %prog --board=<board>:... [options]' |
| epilog = ('\n' |
| 'This must be run inside the chroot.\n' |
| 'This script encapsulates the steps involved in updating the ' |
| 'online Portage package status spreadsheet.\n' |
| 'It was created for use by a buildbot, but can be run manually.\n' |
| '\n' |
| ) |
| |
| class MyOptParser(optparse.OptionParser): |
| """Override default epilog formatter, which strips newlines.""" |
| def format_epilog(self, formatter): |
| return self.epilog |
| |
| parser = MyOptParser(usage=usage, epilog=epilog) |
| parser.add_option('--board', dest='board', type='string', action='store', |
| default=None, help='Target board(s), colon-separated') |
| parser.add_option('--cred-file', dest='cred_file', type='string', |
| action='store', |
| default='%s/%s' % (os.environ['HOME'], GDATA_CRED_FILE), |
| help='Path to gdata credentials file [default: "%default"]') |
| parser.add_option('--test-spreadsheet', dest='test', |
| action='store_true', default=False, |
| help='Upload changes to test spreadsheet instead') |
| parser.add_option('--update-gentoo-first', dest='update_gentoo', |
| action='store_true', default=False, |
| help='Perform update to origin/gentoo before refresh') |
| |
| (options, args) = parser.parse_args() |
| |
| if not options.board: |
| parser.print_help() |
| oper.Die('Board is required.') |
| |
| upstream = None |
| if options.update_gentoo: |
| upstream = UpdateOriginGentoo() |
| |
| csv_root = PrepareCSVRoot() |
| PrepareBoards(options.board) |
| |
| RefreshPackageStatus(board=options.board, upstream=upstream, |
| csv_root=csv_root, test=options.test, |
| cred_file=options.cred_file) |
| |
| if options.update_gentoo: |
| CleanupOriginGentoo(upstream) |
| |
| |
| if __name__ == '__main__': |
| main() |