diff --git a/recipe_modules/cipd/api.py b/recipe_modules/cipd/api.py index cb5406558..b5940eec2 100644 --- a/recipe_modules/cipd/api.py +++ b/recipe_modules/cipd/api.py @@ -6,12 +6,26 @@ from recipe_engine import recipe_api class CIPDApi(recipe_api.RecipeApi): - """CIPDApi provides support for CIPD.""" + """CIPDApi provides basic support for CIPD. + + This assumes that `cipd` (or `cipd.exe` on windows) has been installed + somewhere in $PATH. This will be true if you use depot_tools, or if your + recipe is running inside of chrome-infrastructure's systems (buildbot, + swarming). + """ def __init__(self, *args, **kwargs): super(CIPDApi, self).__init__(*args, **kwargs) - self._cipd_executable = None - self._cipd_version = None self._cipd_credentials = None + self._executable = None + + def initialize(self): + self._executable = 'cipd' + if self.m.platform.is_win: + self._executable += '.exe' + + @property + def executable(self): + return self._executable def set_service_account_credentials(self, path): self._cipd_credentials = path @@ -40,39 +54,12 @@ class CIPDApi(recipe_api.RecipeApi): }[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['start_dir'].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, + self.executable, 'pkg-build', '-in', input_dir, '-name', package_name, @@ -85,10 +72,8 @@ class CIPDApi(recipe_api.RecipeApi): ) def register(self, package_name, package_path, refs=None, tags=None): - assert self._cipd_executable - cmd = [ - self._cipd_executable, + self.executable, 'pkg-register', package_path, '-json-output', self.m.json.output(), ] @@ -111,9 +96,8 @@ class CIPDApi(recipe_api.RecipeApi): This builds and uploads the package in one step. """ - assert self._cipd_executable cmd = [ - self._cipd_executable, + self.executable, 'create', '-pkg-def', pkg_def, '-json-output', self.m.json.output(), @@ -138,13 +122,11 @@ class CIPDApi(recipe_api.RecipeApi): 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())] ensure_file = self.m.raw_io.input('\n'.join(package_list)) cmd = [ - self._cipd_executable, + self.executable, 'ensure', '-root', root, '-ensure-file', ensure_file, @@ -158,10 +140,8 @@ class CIPDApi(recipe_api.RecipeApi): ) def set_tag(self, package_name, version, tags): - assert self._cipd_executable - cmd = [ - self._cipd_executable, + self.executable, 'set-tag', package_name, '-version', version, '-json-output', self.m.json.output(), @@ -180,10 +160,8 @@ class CIPDApi(recipe_api.RecipeApi): ) def set_ref(self, package_name, version, refs): - assert self._cipd_executable - cmd = [ - self._cipd_executable, + self.executable, 'set-ref', package_name, '-version', version, '-json-output', self.m.json.output(), @@ -202,11 +180,10 @@ class CIPDApi(recipe_api.RecipeApi): ) 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, + self.executable, 'search', package_name, '-tag', tag, '-json-output', self.m.json.output(), @@ -222,10 +199,8 @@ class CIPDApi(recipe_api.RecipeApi): def describe(self, package_name, version, test_data_refs=None, test_data_tags=None): - assert self._cipd_executable - cmd = [ - self._cipd_executable, + self.executable, 'describe', package_name, '-version', version, '-json-output', self.m.json.output(), diff --git a/recipe_modules/cipd/example.expected/basic.json b/recipe_modules/cipd/example.expected/basic.json index 437ca664a..427a21788 100644 --- a/recipe_modules/cipd/example.expected/basic.json +++ b/recipe_modules/cipd/example.expected/basic.json @@ -1,53 +1,7 @@ [ { "cmd": [ - "python", - "-u", - "RECIPE_MODULE[depot_tools::cipd]/resources/bootstrap.py", - "--platform", - "linux-amd64", - "--dest-directory", - "[START_DIR]/cipd", - "--json-output", - "/path/to/tmp/json" - ], - "name": "install cipd", - "~followup_annotations": [ - "@@@STEP_TEXT@cipd instance_id: 40-chars-fake-of-the-package-instance_id@@@", - "@@@STEP_LOG_LINE@json.output@{@@@", - "@@@STEP_LOG_LINE@json.output@ \"executable\": \"[START_DIR]/cipd/cipd\", @@@", - "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\"@@@", - "@@@STEP_LOG_LINE@json.output@}@@@", - "@@@STEP_LOG_END@json.output@@@" - ] - }, - { - "cmd": [ - "python", - "-u", - "RECIPE_MODULE[depot_tools::cipd]/resources/bootstrap.py", - "--platform", - "linux-amd64", - "--dest-directory", - "[START_DIR]/cipd", - "--json-output", - "/path/to/tmp/json", - "--version", - "deadbeaf" - ], - "name": "install cipd (2)", - "~followup_annotations": [ - "@@@STEP_TEXT@cipd instance_id: 40-chars-fake-of-the-package-instance_id@@@", - "@@@STEP_LOG_LINE@json.output@{@@@", - "@@@STEP_LOG_LINE@json.output@ \"executable\": \"[START_DIR]/cipd/cipd\", @@@", - "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\"@@@", - "@@@STEP_LOG_LINE@json.output@}@@@", - "@@@STEP_LOG_END@json.output@@@" - ] - }, - { - "cmd": [ - "[START_DIR]/cipd/cipd", + "cipd", "ensure", "-root", "[START_DIR]/packages", @@ -73,7 +27,7 @@ }, { "cmd": [ - "[START_DIR]/cipd/cipd", + "cipd", "search", "public/package/linux-amd64", "-tag", @@ -98,7 +52,7 @@ }, { "cmd": [ - "[START_DIR]/cipd/cipd", + "cipd", "describe", "public/package/linux-amd64", "-version", @@ -149,7 +103,7 @@ }, { "cmd": [ - "[START_DIR]/cipd/cipd", + "cipd", "ensure", "-root", "[START_DIR]/packages", @@ -179,7 +133,7 @@ }, { "cmd": [ - "[START_DIR]/cipd/cipd", + "cipd", "search", "private/package/linux-amd64", "-tag", @@ -204,7 +158,7 @@ }, { "cmd": [ - "[START_DIR]/cipd/cipd", + "cipd", "describe", "private/package/linux-amd64", "-version", @@ -250,7 +204,7 @@ }, { "cmd": [ - "[START_DIR]/cipd/cipd", + "cipd", "pkg-build", "-in", "fake-input-dir", @@ -274,7 +228,7 @@ }, { "cmd": [ - "[START_DIR]/cipd/cipd", + "cipd", "pkg-build", "-in", "fake-input-dir", @@ -300,7 +254,7 @@ }, { "cmd": [ - "[START_DIR]/cipd/cipd", + "cipd", "pkg-register", "fake-package-path", "-json-output", @@ -329,7 +283,7 @@ }, { "cmd": [ - "[START_DIR]/cipd/cipd", + "cipd", "create", "-pkg-def", "[START_DIR]/fake-package.yaml", @@ -354,7 +308,7 @@ }, { "cmd": [ - "[START_DIR]/cipd/cipd", + "cipd", "set-tag", "fake-package", "-version", @@ -384,7 +338,7 @@ }, { "cmd": [ - "[START_DIR]/cipd/cipd", + "cipd", "set-ref", "fake-package", "-version", @@ -414,7 +368,7 @@ }, { "cmd": [ - "[START_DIR]/cipd/cipd", + "cipd", "search", "fake-package/linux-amd64", "-tag", diff --git a/recipe_modules/cipd/example.expected/describe-failed.json b/recipe_modules/cipd/example.expected/describe-failed.json index a39a45b0f..85cba04b9 100644 --- a/recipe_modules/cipd/example.expected/describe-failed.json +++ b/recipe_modules/cipd/example.expected/describe-failed.json @@ -1,53 +1,7 @@ [ { "cmd": [ - "python", - "-u", - "RECIPE_MODULE[depot_tools::cipd]/resources/bootstrap.py", - "--platform", - "linux-amd64", - "--dest-directory", - "[START_DIR]/cipd", - "--json-output", - "/path/to/tmp/json" - ], - "name": "install cipd", - "~followup_annotations": [ - "@@@STEP_TEXT@cipd instance_id: 40-chars-fake-of-the-package-instance_id@@@", - "@@@STEP_LOG_LINE@json.output@{@@@", - "@@@STEP_LOG_LINE@json.output@ \"executable\": \"[START_DIR]/cipd/cipd\", @@@", - "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\"@@@", - "@@@STEP_LOG_LINE@json.output@}@@@", - "@@@STEP_LOG_END@json.output@@@" - ] - }, - { - "cmd": [ - "python", - "-u", - "RECIPE_MODULE[depot_tools::cipd]/resources/bootstrap.py", - "--platform", - "linux-amd64", - "--dest-directory", - "[START_DIR]/cipd", - "--json-output", - "/path/to/tmp/json", - "--version", - "deadbeaf" - ], - "name": "install cipd (2)", - "~followup_annotations": [ - "@@@STEP_TEXT@cipd instance_id: 40-chars-fake-of-the-package-instance_id@@@", - "@@@STEP_LOG_LINE@json.output@{@@@", - "@@@STEP_LOG_LINE@json.output@ \"executable\": \"[START_DIR]/cipd/cipd\", @@@", - "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\"@@@", - "@@@STEP_LOG_LINE@json.output@}@@@", - "@@@STEP_LOG_END@json.output@@@" - ] - }, - { - "cmd": [ - "[START_DIR]/cipd/cipd", + "cipd", "ensure", "-root", "[START_DIR]/packages", @@ -73,7 +27,7 @@ }, { "cmd": [ - "[START_DIR]/cipd/cipd", + "cipd", "search", "public/package/linux-amd64", "-tag", @@ -98,7 +52,7 @@ }, { "cmd": [ - "[START_DIR]/cipd/cipd", + "cipd", "describe", "public/package/linux-amd64", "-version", diff --git a/recipe_modules/cipd/example.expected/describe-many-instances.json b/recipe_modules/cipd/example.expected/describe-many-instances.json index 00bebc037..8a4779271 100644 --- a/recipe_modules/cipd/example.expected/describe-many-instances.json +++ b/recipe_modules/cipd/example.expected/describe-many-instances.json @@ -1,53 +1,7 @@ [ { "cmd": [ - "python", - "-u", - "RECIPE_MODULE[depot_tools::cipd]/resources/bootstrap.py", - "--platform", - "linux-amd64", - "--dest-directory", - "[START_DIR]/cipd", - "--json-output", - "/path/to/tmp/json" - ], - "name": "install cipd", - "~followup_annotations": [ - "@@@STEP_TEXT@cipd instance_id: 40-chars-fake-of-the-package-instance_id@@@", - "@@@STEP_LOG_LINE@json.output@{@@@", - "@@@STEP_LOG_LINE@json.output@ \"executable\": \"[START_DIR]/cipd/cipd\", @@@", - "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\"@@@", - "@@@STEP_LOG_LINE@json.output@}@@@", - "@@@STEP_LOG_END@json.output@@@" - ] - }, - { - "cmd": [ - "python", - "-u", - "RECIPE_MODULE[depot_tools::cipd]/resources/bootstrap.py", - "--platform", - "linux-amd64", - "--dest-directory", - "[START_DIR]/cipd", - "--json-output", - "/path/to/tmp/json", - "--version", - "deadbeaf" - ], - "name": "install cipd (2)", - "~followup_annotations": [ - "@@@STEP_TEXT@cipd instance_id: 40-chars-fake-of-the-package-instance_id@@@", - "@@@STEP_LOG_LINE@json.output@{@@@", - "@@@STEP_LOG_LINE@json.output@ \"executable\": \"[START_DIR]/cipd/cipd\", @@@", - "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\"@@@", - "@@@STEP_LOG_LINE@json.output@}@@@", - "@@@STEP_LOG_END@json.output@@@" - ] - }, - { - "cmd": [ - "[START_DIR]/cipd/cipd", + "cipd", "ensure", "-root", "[START_DIR]/packages", @@ -73,7 +27,7 @@ }, { "cmd": [ - "[START_DIR]/cipd/cipd", + "cipd", "search", "public/package/linux-amd64", "-tag", @@ -98,7 +52,7 @@ }, { "cmd": [ - "[START_DIR]/cipd/cipd", + "cipd", "describe", "public/package/linux-amd64", "-version", @@ -149,7 +103,7 @@ }, { "cmd": [ - "[START_DIR]/cipd/cipd", + "cipd", "ensure", "-root", "[START_DIR]/packages", @@ -179,7 +133,7 @@ }, { "cmd": [ - "[START_DIR]/cipd/cipd", + "cipd", "search", "private/package/linux-amd64", "-tag", @@ -204,7 +158,7 @@ }, { "cmd": [ - "[START_DIR]/cipd/cipd", + "cipd", "describe", "private/package/linux-amd64", "-version", @@ -250,7 +204,7 @@ }, { "cmd": [ - "[START_DIR]/cipd/cipd", + "cipd", "pkg-build", "-in", "fake-input-dir", @@ -274,7 +228,7 @@ }, { "cmd": [ - "[START_DIR]/cipd/cipd", + "cipd", "pkg-build", "-in", "fake-input-dir", @@ -300,7 +254,7 @@ }, { "cmd": [ - "[START_DIR]/cipd/cipd", + "cipd", "pkg-register", "fake-package-path", "-json-output", @@ -329,7 +283,7 @@ }, { "cmd": [ - "[START_DIR]/cipd/cipd", + "cipd", "create", "-pkg-def", "[START_DIR]/fake-package.yaml", @@ -354,7 +308,7 @@ }, { "cmd": [ - "[START_DIR]/cipd/cipd", + "cipd", "set-tag", "fake-package", "-version", @@ -384,7 +338,7 @@ }, { "cmd": [ - "[START_DIR]/cipd/cipd", + "cipd", "set-ref", "fake-package", "-version", @@ -414,7 +368,7 @@ }, { "cmd": [ - "[START_DIR]/cipd/cipd", + "cipd", "search", "fake-package/linux-amd64", "-tag", diff --git a/recipe_modules/cipd/example.expected/install-failed.json b/recipe_modules/cipd/example.expected/install-failed.json deleted file mode 100644 index 8487fc8a5..000000000 --- a/recipe_modules/cipd/example.expected/install-failed.json +++ /dev/null @@ -1,31 +0,0 @@ -[ - { - "cmd": [ - "python", - "-u", - "RECIPE_MODULE[depot_tools::cipd]/resources/bootstrap.py", - "--platform", - "linux-amd64", - "--dest-directory", - "[START_DIR]/cipd", - "--json-output", - "/path/to/tmp/json" - ], - "name": "install cipd", - "~followup_annotations": [ - "step returned non-zero exit code: 1", - "@@@STEP_LOG_LINE@json.output@{@@@", - "@@@STEP_LOG_LINE@json.output@ \"executable\": \"[START_DIR]/cipd/cipd\", @@@", - "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\"@@@", - "@@@STEP_LOG_LINE@json.output@}@@@", - "@@@STEP_LOG_END@json.output@@@", - "@@@STEP_FAILURE@@@" - ] - }, - { - "name": "$result", - "reason": "Step('install cipd') failed with return_code 1", - "recipe_result": null, - "status_code": 1 - } -] \ No newline at end of file diff --git a/recipe_modules/cipd/example.expected/mac64.json b/recipe_modules/cipd/example.expected/mac64.json index 000e4a102..69b1a16d0 100644 --- a/recipe_modules/cipd/example.expected/mac64.json +++ b/recipe_modules/cipd/example.expected/mac64.json @@ -1,53 +1,7 @@ [ { "cmd": [ - "python", - "-u", - "RECIPE_MODULE[depot_tools::cipd]/resources/bootstrap.py", - "--platform", - "mac-amd64", - "--dest-directory", - "[START_DIR]/cipd", - "--json-output", - "/path/to/tmp/json" - ], - "name": "install cipd", - "~followup_annotations": [ - "@@@STEP_TEXT@cipd instance_id: 40-chars-fake-of-the-package-instance_id@@@", - "@@@STEP_LOG_LINE@json.output@{@@@", - "@@@STEP_LOG_LINE@json.output@ \"executable\": \"[START_DIR]/cipd/cipd\", @@@", - "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\"@@@", - "@@@STEP_LOG_LINE@json.output@}@@@", - "@@@STEP_LOG_END@json.output@@@" - ] - }, - { - "cmd": [ - "python", - "-u", - "RECIPE_MODULE[depot_tools::cipd]/resources/bootstrap.py", - "--platform", - "mac-amd64", - "--dest-directory", - "[START_DIR]/cipd", - "--json-output", - "/path/to/tmp/json", - "--version", - "deadbeaf" - ], - "name": "install cipd (2)", - "~followup_annotations": [ - "@@@STEP_TEXT@cipd instance_id: 40-chars-fake-of-the-package-instance_id@@@", - "@@@STEP_LOG_LINE@json.output@{@@@", - "@@@STEP_LOG_LINE@json.output@ \"executable\": \"[START_DIR]/cipd/cipd\", @@@", - "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\"@@@", - "@@@STEP_LOG_LINE@json.output@}@@@", - "@@@STEP_LOG_END@json.output@@@" - ] - }, - { - "cmd": [ - "[START_DIR]/cipd/cipd", + "cipd", "ensure", "-root", "[START_DIR]/packages", @@ -73,7 +27,7 @@ }, { "cmd": [ - "[START_DIR]/cipd/cipd", + "cipd", "search", "public/package/mac-amd64", "-tag", @@ -98,7 +52,7 @@ }, { "cmd": [ - "[START_DIR]/cipd/cipd", + "cipd", "describe", "public/package/mac-amd64", "-version", @@ -149,7 +103,7 @@ }, { "cmd": [ - "[START_DIR]/cipd/cipd", + "cipd", "ensure", "-root", "[START_DIR]/packages", @@ -179,7 +133,7 @@ }, { "cmd": [ - "[START_DIR]/cipd/cipd", + "cipd", "search", "private/package/mac-amd64", "-tag", @@ -204,7 +158,7 @@ }, { "cmd": [ - "[START_DIR]/cipd/cipd", + "cipd", "describe", "private/package/mac-amd64", "-version", @@ -250,7 +204,7 @@ }, { "cmd": [ - "[START_DIR]/cipd/cipd", + "cipd", "pkg-build", "-in", "fake-input-dir", @@ -274,7 +228,7 @@ }, { "cmd": [ - "[START_DIR]/cipd/cipd", + "cipd", "pkg-build", "-in", "fake-input-dir", @@ -300,7 +254,7 @@ }, { "cmd": [ - "[START_DIR]/cipd/cipd", + "cipd", "pkg-register", "fake-package-path", "-json-output", @@ -329,7 +283,7 @@ }, { "cmd": [ - "[START_DIR]/cipd/cipd", + "cipd", "create", "-pkg-def", "[START_DIR]/fake-package.yaml", @@ -354,7 +308,7 @@ }, { "cmd": [ - "[START_DIR]/cipd/cipd", + "cipd", "set-tag", "fake-package", "-version", @@ -384,7 +338,7 @@ }, { "cmd": [ - "[START_DIR]/cipd/cipd", + "cipd", "set-ref", "fake-package", "-version", @@ -414,7 +368,7 @@ }, { "cmd": [ - "[START_DIR]/cipd/cipd", + "cipd", "search", "fake-package/mac-amd64", "-tag", diff --git a/recipe_modules/cipd/example.expected/win64.json b/recipe_modules/cipd/example.expected/win64.json index e1fef45aa..0687892fd 100644 --- a/recipe_modules/cipd/example.expected/win64.json +++ b/recipe_modules/cipd/example.expected/win64.json @@ -1,53 +1,7 @@ [ { "cmd": [ - "python", - "-u", - "RECIPE_MODULE[depot_tools::cipd]\\resources\\bootstrap.py", - "--platform", - "windows-amd64", - "--dest-directory", - "[START_DIR]\\cipd", - "--json-output", - "/path/to/tmp/json" - ], - "name": "install cipd", - "~followup_annotations": [ - "@@@STEP_TEXT@cipd instance_id: 40-chars-fake-of-the-package-instance_id@@@", - "@@@STEP_LOG_LINE@json.output@{@@@", - "@@@STEP_LOG_LINE@json.output@ \"executable\": \"[START_DIR]\\\\cipd\\\\cipd\", @@@", - "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\"@@@", - "@@@STEP_LOG_LINE@json.output@}@@@", - "@@@STEP_LOG_END@json.output@@@" - ] - }, - { - "cmd": [ - "python", - "-u", - "RECIPE_MODULE[depot_tools::cipd]\\resources\\bootstrap.py", - "--platform", - "windows-amd64", - "--dest-directory", - "[START_DIR]\\cipd", - "--json-output", - "/path/to/tmp/json", - "--version", - "deadbeaf" - ], - "name": "install cipd (2)", - "~followup_annotations": [ - "@@@STEP_TEXT@cipd instance_id: 40-chars-fake-of-the-package-instance_id@@@", - "@@@STEP_LOG_LINE@json.output@{@@@", - "@@@STEP_LOG_LINE@json.output@ \"executable\": \"[START_DIR]\\\\cipd\\\\cipd\", @@@", - "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\"@@@", - "@@@STEP_LOG_LINE@json.output@}@@@", - "@@@STEP_LOG_END@json.output@@@" - ] - }, - { - "cmd": [ - "[START_DIR]\\cipd\\cipd", + "cipd.exe", "ensure", "-root", "[START_DIR]\\packages", @@ -73,7 +27,7 @@ }, { "cmd": [ - "[START_DIR]\\cipd\\cipd", + "cipd.exe", "search", "public/package/windows-amd64", "-tag", @@ -98,7 +52,7 @@ }, { "cmd": [ - "[START_DIR]\\cipd\\cipd", + "cipd.exe", "describe", "public/package/windows-amd64", "-version", @@ -149,7 +103,7 @@ }, { "cmd": [ - "[START_DIR]\\cipd\\cipd", + "cipd.exe", "ensure", "-root", "[START_DIR]\\packages", @@ -179,7 +133,7 @@ }, { "cmd": [ - "[START_DIR]\\cipd\\cipd", + "cipd.exe", "search", "private/package/windows-amd64", "-tag", @@ -204,7 +158,7 @@ }, { "cmd": [ - "[START_DIR]\\cipd\\cipd", + "cipd.exe", "describe", "private/package/windows-amd64", "-version", @@ -250,7 +204,7 @@ }, { "cmd": [ - "[START_DIR]\\cipd\\cipd", + "cipd.exe", "pkg-build", "-in", "fake-input-dir", @@ -274,7 +228,7 @@ }, { "cmd": [ - "[START_DIR]\\cipd\\cipd", + "cipd.exe", "pkg-build", "-in", "fake-input-dir", @@ -300,7 +254,7 @@ }, { "cmd": [ - "[START_DIR]\\cipd\\cipd", + "cipd.exe", "pkg-register", "fake-package-path", "-json-output", @@ -329,7 +283,7 @@ }, { "cmd": [ - "[START_DIR]\\cipd\\cipd", + "cipd.exe", "create", "-pkg-def", "[START_DIR]\\fake-package.yaml", @@ -354,7 +308,7 @@ }, { "cmd": [ - "[START_DIR]\\cipd\\cipd", + "cipd.exe", "set-tag", "fake-package", "-version", @@ -384,7 +338,7 @@ }, { "cmd": [ - "[START_DIR]\\cipd\\cipd", + "cipd.exe", "set-ref", "fake-package", "-version", @@ -414,7 +368,7 @@ }, { "cmd": [ - "[START_DIR]\\cipd\\cipd", + "cipd.exe", "search", "fake-package/windows-amd64", "-tag", diff --git a/recipe_modules/cipd/example.py b/recipe_modules/cipd/example.py index 18c9cdeba..03c164eec 100644 --- a/recipe_modules/cipd/example.py +++ b/recipe_modules/cipd/example.py @@ -11,11 +11,6 @@ DEPS = [ ] def RunSteps(api): - # First, you need a cipd client. - api.cipd.install_client('install cipd') - api.cipd.install_client('install cipd', version='deadbeaf') - assert api.cipd.get_executable() - # Need to set service account credentials. api.cipd.set_service_account_credentials( api.cipd.default_bot_service_account_credentials) @@ -86,11 +81,6 @@ def GenTests(api): api.platform('win', 64) ) - yield ( - api.test('install-failed') + - api.step_data('install cipd', retcode=1) - ) - yield ( api.test('describe-failed') + api.platform('linux', 64) + diff --git a/recipe_modules/cipd/resources/bootstrap.py b/recipe_modules/cipd/resources/bootstrap.py deleted file mode 100644 index 6344e8b14..000000000 --- a/recipe_modules/cipd/resources/bootstrap.py +++ /dev/null @@ -1,218 +0,0 @@ -# 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. - -import argparse -import errno -import hashlib -import json -import os -import sys -import tempfile -import time -import traceback -import urllib -import urllib2 - - -# Default package repository URL. -CIPD_BACKEND_URL = 'https://chrome-infra-packages.appspot.com' - -# ./cipd resolve \ -# infra/tools/cipd/ \ -# -version=git_revision:508f70d14492573c37760381060bbb5fc7904bfd -CLIENT_VERSIONS = { - 'linux-386':'3be5f38f011284779a75113d8d1cf6575920128f', - 'linux-amd64':'5c124027ab0d44efb0d545bac3d0eb5cbee590b1', - 'mac-amd64':'af11702389a57ed42d4cb51a8cbc2ac48ef4da02', - 'windows-386':'e44d78aae1c330d75c7f5ab3989f37a74227b126', - 'windows-amd64':'8c786a913fc0a0387262a899dc63c15ed9029e83', -} - - -class CipdBootstrapError(Exception): - """Raised by install_cipd_client on fatal error.""" - -def install_cipd_client(path, package, version): - """Installs CIPD client to /cipd. - - Args: - path: root directory to install CIPD client into. - package: cipd client package name, e.g. infra/tools/cipd/linux-amd64. - version: version of the package to install. - - Returns: - Absolute path to CIPD executable. - """ - print 'Ensuring CIPD client is up-to-date' - version_file = os.path.join(path, 'VERSION') - bin_file = os.path.join(path, 'cipd') - - # Resolve version to concrete instance ID, e.g "live" -> "abcdef0123....". - instance_id = call_cipd_api( - 'repo/v1/instance/resolve', - {'package_name': package, 'version': version})['instance_id'] - print 'CIPD client %s => %s' % (version, instance_id) - - # Already installed? - installed_instance_id = (read_file(version_file) or '').strip() - if installed_instance_id == instance_id and os.path.exists(bin_file): - return bin_file, instance_id - - # Resolve instance ID to an URL to fetch client binary from. - client_info = call_cipd_api( - 'repo/v1/client', - {'package_name': package, 'instance_id': instance_id}) - print 'CIPD client binary info:\n%s' % dump_json(client_info) - - # Fetch the client. It is ~10 MB, so don't bother and fetch it into memory. - status, raw_client_bin = fetch_url(client_info['client_binary']['fetch_url']) - if status != 200: - print 'Failed to fetch client binary, HTTP %d' % status - raise CipdBootstrapError('Failed to fetch client binary, HTTP %d' % status) - digest = hashlib.sha1(raw_client_bin).hexdigest() - if digest != client_info['client_binary']['sha1']: - raise CipdBootstrapError('Client SHA1 mismatch') - - # Success. - print 'Fetched CIPD client %s:%s at %s' % (package, instance_id, bin_file) - write_file(bin_file, raw_client_bin) - os.chmod(bin_file, 0755) - write_file(version_file, instance_id + '\n') - return bin_file, instance_id - - -def call_cipd_api(endpoint, query): - """Sends GET request to CIPD backend, parses JSON response.""" - url = '%s/_ah/api/%s' % (CIPD_BACKEND_URL, endpoint) - if query: - url += '?' + urllib.urlencode(query) - status, body = fetch_url(url) - if status != 200: - raise CipdBootstrapError('Server replied with HTTP %d' % status) - try: - body = json.loads(body) - except ValueError: - raise CipdBootstrapError('Server returned invalid JSON') - status = body.get('status') - if status != 'SUCCESS': - m = body.get('error_message') or '' - raise CipdBootstrapError('Server replied with error %s: %s' % (status, m)) - return body - - -def fetch_url(url, headers=None): - """Sends GET request (with retries). - - Args: - url: URL to fetch. - headers: dict with request headers. - - Returns: - (200, reply body) on success. - (HTTP code, None) on HTTP 401, 403, or 404 reply. - - Raises: - Whatever urllib2 raises. - """ - req = urllib2.Request(url) - req.add_header('User-Agent', 'cipd recipe bootstrap.py') - for k, v in (headers or {}).iteritems(): - req.add_header(str(k), str(v)) - i = 0 - while True: - i += 1 - try: - print 'GET %s' % url - return 200, urllib2.urlopen(req, timeout=60).read() - except Exception as e: - if isinstance(e, urllib2.HTTPError): - print 'Failed to fetch %s, server returned HTTP %d' % (url, e.code) - if e.code in (401, 403, 404): - return e.code, None - else: - print 'Failed to fetch %s' % url - if i == 20: - raise - print 'Retrying in %d sec.' % i - time.sleep(i) - - -def ensure_directory(path): - """Creates a directory.""" - # Handle a case where a file is being converted into a directory. - chunks = path.split(os.sep) - for i in xrange(len(chunks)): - p = os.sep.join(chunks[:i+1]) - if os.path.exists(p) and not os.path.isdir(p): - os.remove(p) - break - try: - os.makedirs(path) - except OSError as e: - if e.errno != errno.EEXIST: - raise - - -def read_file(path): - """Returns contents of a file or None if missing.""" - try: - with open(path, 'r') as f: - return f.read() - except IOError as e: - if e.errno == errno.ENOENT: - return None - raise - - -def write_file(path, data): - """Puts a file on disk, atomically.""" - ensure_directory(os.path.dirname(path)) - fd, temp_file = tempfile.mkstemp(dir=os.path.dirname(path)) - with os.fdopen(fd, 'w') as f: - f.write(data) - if not sys.platform in ('linux2', 'darwin'): - # On windows we should remove destination file if it exists. - if os.path.exists(path): - os.remove(path) - # At this point we may crash, and it's OK, as next time we'll just - # re-install CIPD from scratch. - os.rename(temp_file, path) - - -def dump_json(obj): - """Pretty-formats object to JSON.""" - return json.dumps(obj, indent=2, sort_keys=True, separators=(',',':')) - - -def main(args): - parser = argparse.ArgumentParser('bootstrap cipd') - parser.add_argument('--json-output', default=None) - parser.add_argument('--version', default=None) - parser.add_argument('--platform', required=True) - parser.add_argument('--dest-directory', required=True) - opts = parser.parse_args(args) - - package = "infra/tools/cipd/%s" % opts.platform - version = opts.version or CLIENT_VERSIONS[opts.platform] - - try: - exe_path, instance_id = install_cipd_client(opts.dest_directory, - package, version) - result = { - 'executable': exe_path, - 'instance_id': instance_id - } - if opts.json_output: - with open(opts.json_output, 'w') as f: - json.dump(result, f) - except Exception as e: - print 'Exception installing cipd: %s' % e - _exc_type, _exc_value, exc_traceback = sys.exc_info() - traceback.print_tb(exc_traceback) - return 1 - - return 0 - -if __name__ == '__main__': - sys.exit(main(sys.argv[1:])) diff --git a/recipe_modules/cipd/test_api.py b/recipe_modules/cipd/test_api.py index 3dc30108a..a310ba641 100644 --- a/recipe_modules/cipd/test_api.py +++ b/recipe_modules/cipd/test_api.py @@ -29,21 +29,12 @@ class CIPDTestApi(recipe_test_api.RecipeTestApi): dic['error'] = error return self.m.json.output(dic, retcode=retcode) - def make_test_executable(self): - return str(self.m.path['start_dir'].join('cipd', 'cipd')) - def example_error(self, error, retcode=None): return self._resultify( result=None, error=error, retcode=1 if retcode is None else retcode) - def example_install_client(self, package_name, version=None, retcode=None): - return self.m.json.output({ - 'executable': self.make_test_executable(), - 'instance_id': self.make_resolved_version(version), - }, retcode=retcode) - def example_build(self, package_name, version=None): return self._resultify(self.make_pin(package_name, version))