163 lines
5.3 KiB
Python
163 lines
5.3 KiB
Python
# Copyright 2018 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.
|
|
|
|
"""Constants and util methods to interact with skylab inventory repo."""
|
|
|
|
import logging
|
|
import re
|
|
|
|
import common
|
|
|
|
from autotest_lib.client.common_lib import revision_control
|
|
from chromite.lib import gob_util
|
|
|
|
try:
|
|
from skylab_inventory import text_manager
|
|
except ImportError:
|
|
pass
|
|
|
|
|
|
INTERNAL_GERRIT_HOST = 'chrome-internal-review.googlesource.com'
|
|
INTERNAL_GERRIT_HOST_URL = 'https://%s' % INTERNAL_GERRIT_HOST
|
|
# The git url of the internal skylab_inventory
|
|
INTERNAL_INVENTORY_REPO_URL = ('https://chrome-internal.googlesource.com/'
|
|
'chromeos/infra_internal/skylab_inventory.git')
|
|
INTERNAL_INVENTORY_CHANGE_PATTERN = (
|
|
r'https://chrome-internal-review.googlesource.com/c/chromeos/'
|
|
'infra_internal/skylab_inventory/\\+/([0-9]*)')
|
|
MSG_INVALID_IN_SKYLAB = 'This is currently not supported with --skylab.'
|
|
MSG_ONLY_VALID_IN_SKYLAB = 'This only applies to actions on skylab inventory.'
|
|
|
|
|
|
class SkylabInventoryNotImported(Exception):
|
|
"""skylab_inventory is not imported."""
|
|
|
|
|
|
class InventoryRepoChangeNotFound(Exception):
|
|
"""Error raised when no inventory repo change number is found."""
|
|
|
|
|
|
class InventoryRepoDirNotClean(Exception):
|
|
"""Error raised when the given inventory_repo_dir contains local changes."""
|
|
|
|
|
|
def get_cl_url(change_number):
|
|
return INTERNAL_GERRIT_HOST_URL + '/' + str(change_number)
|
|
|
|
|
|
def get_cl_message(change_number):
|
|
return ('Please submit the CL at %s to make the change effective.' %
|
|
get_cl_url(change_number))
|
|
|
|
|
|
def construct_commit_message(subject, bug=None, test=None):
|
|
"""Construct commit message for skylab inventory repo commit.
|
|
|
|
@param subject: Commit message subject.
|
|
@param bug: Bug number of the commit.
|
|
@param test: Tests of the commit.
|
|
|
|
@return: A commit message string.
|
|
"""
|
|
return '\n'.join([subject, '', 'BUG=%s' % bug, 'TEST=%s' % test])
|
|
|
|
|
|
def extract_inventory_change(output):
|
|
"""Extract the change number from the output.
|
|
|
|
@param output: The git command output containing the change gerrit url.
|
|
|
|
@return: The change number (int) of the inventory change.
|
|
"""
|
|
m = re.search(INTERNAL_INVENTORY_CHANGE_PATTERN, output)
|
|
|
|
if not m:
|
|
raise InventoryRepoChangeNotFound(
|
|
'Could not extract CL number from "%r"' % output)
|
|
|
|
return int(m.group(1))
|
|
|
|
|
|
def submit_inventory_change(change_number):
|
|
"""Set review labels and submit the inventory change.
|
|
|
|
@param change_number: The change number (int) of the inventory change.
|
|
"""
|
|
logging.info('Setting review labels for %s.',
|
|
get_cl_url(change_number))
|
|
gob_util.SetReview(
|
|
INTERNAL_GERRIT_HOST,
|
|
change=change_number,
|
|
labels={'Code-Review': 2, 'Verified': 1},
|
|
msg='Set TBR by "atest --skylab"',
|
|
notify='OWNER')
|
|
|
|
logging.info('Submitting the change.')
|
|
gob_util.SubmitChange(
|
|
INTERNAL_GERRIT_HOST,
|
|
change=change_number)
|
|
|
|
|
|
class InventoryRepo(object):
|
|
"""Class to present a inventory repository."""
|
|
|
|
|
|
def __init__(self, inventory_repo_dir):
|
|
self.inventory_repo_dir = inventory_repo_dir
|
|
self.git_repo = None
|
|
|
|
|
|
def initialize(self):
|
|
"""Initialize inventory repo at the given dir."""
|
|
self.git_repo = revision_control.GitRepo(
|
|
self.inventory_repo_dir,
|
|
giturl=INTERNAL_INVENTORY_REPO_URL,
|
|
abs_work_tree=self.inventory_repo_dir)
|
|
|
|
if self.git_repo.is_repo_initialized():
|
|
if self.git_repo.status():
|
|
raise InventoryRepoDirNotClean(
|
|
'The inventory_repo_dir "%s" contains uncommitted '
|
|
'changes. Please clean up the local repo directory or '
|
|
'use another clean directory.' % self.inventory_repo_dir)
|
|
|
|
logging.info('Inventory repo was already initialized, start '
|
|
'pulling.')
|
|
self.git_repo.checkout('master')
|
|
self.git_repo.pull()
|
|
else:
|
|
logging.info('No inventory repo was found, start cloning.')
|
|
self.git_repo.clone(shallow=True)
|
|
|
|
|
|
def get_data_dir(self, data_subdir='skylab'):
|
|
"""Get path to the data dir."""
|
|
return text_manager.get_data_dir(self.inventory_repo_dir, data_subdir)
|
|
|
|
|
|
def upload_change(self, commit_message, draft=False, dryrun=False,
|
|
submit=False):
|
|
"""Commit and upload the change to gerrit.
|
|
|
|
@param commit_message: Commit message of the CL to upload.
|
|
@param draft: Boolean indicating whether to upload the CL as a draft.
|
|
@param dryrun: Boolean indicating whether to run upload as a dryrun.
|
|
@param submit: Boolean indicating whether to submit the CL directly.
|
|
|
|
@return: Change number (int) of the CL if it's uploaded to Gerrit.
|
|
"""
|
|
self.git_repo.commit(commit_message)
|
|
|
|
remote = self.git_repo.remote()
|
|
output = self.git_repo.upload_cl(
|
|
remote, 'master', draft=draft, dryrun=dryrun)
|
|
|
|
if not dryrun:
|
|
change_number = extract_inventory_change(output)
|
|
|
|
if submit:
|
|
submit_inventory_change(change_number)
|
|
|
|
return change_number
|