# 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. from recipe_engine import recipe_api class CIPDApi(recipe_api.RecipeApi): """CIPDApi provides support for CIPD.""" def __init__(self, *args, **kwargs): super(CIPDApi, self).__init__(*args, **kwargs) self._cipd_executable = None self._cipd_version = None self._cipd_credentials = None def set_service_account_credentials(self, path): self._cipd_credentials = path @property def default_bot_service_account_credentials(self): # Path to a service account credentials to use to talk to CIPD backend. # Deployed by Puppet. if self.m.platform.is_win: return 'C:\\creds\\service_accounts\\service-account-cipd-builder.json' else: return '/creds/service_accounts/service-account-cipd-builder.json' def platform_suffix(self): """Use to get full package name that is platform indepdent. Example: >>> 'my/package/%s' % api.cipd.platform_suffix() 'my/package/linux-amd64' """ return '%s-%s' % ( self.m.platform.name.replace('win', 'windows'), { 32: '386', 64: 'amd64', }[self.m.platform.bits], ) def install_client(self, step_name='install cipd', version=None): """Ensures the client is installed. If you specify version as a hash, make sure its correct platform. """ # TODO(seanmccullough): clean up older CIPD installations. step = self.m.python( name=step_name, script=self.resource('bootstrap.py'), args=[ '--platform', self.platform_suffix(), '--dest-directory', self.m.path['slave_build'].join('cipd'), '--json-output', self.m.json.output(), ] + (['--version', version] if version else []), step_test_data=lambda: self.test_api.example_install_client(version) ) self._cipd_executable = step.json.output['executable'] step.presentation.step_text = ( 'cipd instance_id: %s' % step.json.output['instance_id']) return step def get_executable(self): return self._cipd_executable def build(self, input_dir, output_package, package_name, install_mode=None): assert self._cipd_executable assert not install_mode or install_mode in ['copy', 'symlink'] return self.m.step( 'build %s' % self.m.path.basename(package_name), [ self._cipd_executable, 'pkg-build', '--in', input_dir, '--name', package_name, '--out', output_package, '--json-output', self.m.json.output(), ] + ( ['--install-mode', install_mode] if install_mode else [] ), step_test_data=lambda: self.test_api.example_build(package_name) ) def register(self, package_name, package_path, refs=None, tags=None): assert self._cipd_executable cmd = [ self._cipd_executable, 'pkg-register', package_path, '--json-output', self.m.json.output(), ] if self._cipd_credentials: cmd.extend(['--service-account-json', self._cipd_credentials]) if refs: for ref in refs: cmd.extend(['--ref', ref]) if tags: for tag, value in sorted(tags.items()): cmd.extend(['--tag', '%s:%s' % (tag, value)]) return self.m.step( 'register %s' % package_name, cmd, step_test_data=lambda: self.test_api.example_register(package_name) ) def create(self, pkg_def, refs=None, tags=None): """Creates a package based on YAML package definition file. This builds and uploads the package in one step. """ assert self._cipd_executable cmd = [ self._cipd_executable, 'create', '--pkg-def', pkg_def, '--json-output', self.m.json.output(), ] if self._cipd_credentials: cmd.extend(['--service-account-json', self._cipd_credentials]) if refs: for ref in refs: cmd.extend(['--ref', ref]) if tags: for tag, value in sorted(tags.items()): cmd.extend(['--tag', '%s:%s' % (tag, value)]) return self.m.step('create %s' % self.m.path.basename(pkg_def), cmd) def ensure(self, root, packages): """Ensures that packages are installed in a given root dir. packages must be a mapping from package name to its version, where * name must be for right platform (see also ``platform_suffix``), * version could be either instance_id, or ref, or unique tag. If installing a package requires credentials, call ``set_service_account_credentials`` before calling this function. """ assert self._cipd_executable package_list = ['%s %s' % (name, version) for name, version in sorted(packages.items())] list_data = self.m.raw_io.input('\n'.join(package_list)) cmd = [ self._cipd_executable, 'ensure', '--root', root, '--list', list_data, '--json-output', self.m.json.output(), ] if self._cipd_credentials: cmd.extend(['--service-account-json', self._cipd_credentials]) return self.m.step( 'ensure_installed', cmd, step_test_data=lambda: self.test_api.example_ensure(packages) ) def set_tag(self, package_name, version, tags): assert self._cipd_executable cmd = [ self._cipd_executable, 'set-tag', package_name, '--version', version, '--json-output', self.m.json.output(), ] if self._cipd_credentials: cmd.extend(['--service-account-json', self._cipd_credentials]) for tag, value in sorted(tags.items()): cmd.extend(['--tag', '%s:%s' % (tag, value)]) return self.m.step( 'cipd set-tag %s' % package_name, cmd, step_test_data=lambda: self.test_api.example_set_tag( package_name, version ) ) def set_ref(self, package_name, version, refs): assert self._cipd_executable cmd = [ self._cipd_executable, 'set-ref', package_name, '--version', version, '--json-output', self.m.json.output(), ] if self._cipd_credentials: cmd.extend(['--service-account-json', self._cipd_credentials]) for r in refs: cmd.extend(['--ref', r]) return self.m.step( 'cipd set-ref %s' % package_name, cmd, step_test_data=lambda: self.test_api.example_set_ref( package_name, version ) ) def search(self, package_name, tag): assert self._cipd_executable assert ':' in tag, 'tag must be in a form "k:v"' cmd = [ self._cipd_executable, 'search', package_name, '--tag', tag, '--json-output', self.m.json.output(), ] if self._cipd_credentials: cmd.extend(['--service-account-json', self._cipd_credentials]) return self.m.step( 'cipd search %s %s' % (package_name, tag), cmd, step_test_data=lambda: self.test_api.example_search(package_name) ) def describe(self, package_name, version, test_data_refs=None, test_data_tags=None): assert self._cipd_executable cmd = [ self._cipd_executable, 'describe', package_name, '--version', version, '--json-output', self.m.json.output(), ] if self._cipd_credentials: cmd.extend(['--service-account-json', self._cipd_credentials]) return self.m.step( 'cipd describe %s' % package_name, cmd, step_test_data=lambda: self.test_api.example_describe( package_name, version, test_data_refs=test_data_refs, test_data_tags=test_data_tags ) )