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

Side by Side Diff: scripts/slave/recipes/infra/gae_sdk_cipd_packager.py

Issue 2355483004: Add CIPD GAE SDK recipe module and packager. (Closed)
Patch Set: pylint Created 4 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 unified diff | Download patch
OLDNEW
(Empty)
1 # Copyright 2016 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
4
5 import collections
6 import re
7
8
9 DEPS = [
10 'depot_tools/cipd',
11 'gae_sdk',
12 'gsutil',
13 'recipe_engine/path',
14 'recipe_engine/python',
15 'recipe_engine/raw_io',
16 'recipe_engine/step',
17 'zip',
18 ]
19
20 # CIPD builder service account, deployed by Puppet.
21 _CIPD_CREDENTIAL_PATH = ('/creds/service_accounts/'
22 'service-account-cipd-builder.json')
23
24
25 def RunSteps(api):
26 pb = _PackageBuilder(api)
27
28 # Determine the current GAE SDK version.
29 try:
30 version = pb.latest_upstream_version()
31 except pb.VersionParseError as e:
32 api.python.failing_step('Version Fetch',
33 'Failed to fetch latest version: %s' % (e,))
34
35 # Make sure the CIPD client is installed.
36 api.cipd.install_client()
37 api.cipd.set_service_account_credentials(_CIPD_CREDENTIAL_PATH)
38
39 # Iterate over all of the GAE SDK packages and build any that don't exist.
40 version_tag = pb.version_tag(version)
41 pkg_outdir = api.path.mkdtemp('gae_sdk_package')
42 for plat, arch in api.gae_sdk.all_packages:
43 pkg_name = api.gae_sdk.package(plat, arch=arch)
44 with api.step.nest('Sync %s' % (pkg_name,)):
45 step = api.cipd.search(pkg_name, '%s:%s' % (version_tag))
46 if len(step.json.output['result']) > 0:
47 api.python.succeeding_step('Synced', 'Package is up to date.')
48 continue
49
50 # Create a temporary directory to build the package in.
51 pkg_base = pb.download_and_unpack(plat, arch, version)
52
53 # Build and register our CIPD package.
54 pkg_path = pkg_outdir.join('gae_sdk_%s_%s.pkg' % (plat, arch))
55 api.cipd.build(
56 pkg_base,
57 pkg_path,
58 pkg_name,
59 install_mode='copy',
60 )
61 api.cipd.register(
62 pkg_name,
63 pkg_path,
64 refs=[api.gae_sdk.latest_ref],
65 tags={version_tag[0]: version_tag[1]},
66 )
67
68
69 class _PackageBuilder(object):
70 # The Google Storage GAE SDK bucket base. All SDK packages are stored in here
71 # under a basename + version ZIP file.
72 _GS_BUCKET_BASE = 'gs://appengine-sdks/featured'
73 # The GS path to the "LATEST" YAML file.
74 _GS_VERSION_YAML = '%s/VERSION' % (_GS_BUCKET_BASE,)
75
76 # Hacky regex for the "release" YAML variable.
77 _RE_RELEASE = re.compile(r'^release:\s+"([^"]+)"$')
78
79 class VersionParseError(Exception):
80 pass
81
82 def __init__(self, api):
83 self._api = api
84
85 def version_tag(self, version):
86 return ('gae_sdk_version', version)
87
88 @property
89 def api(self):
90 return self._api
91
92 def latest_upstream_version(self):
93 step_result = self.api.gsutil.cat(
94 self._GS_VERSION_YAML,
95 name='Get Latest',
96 stdout=self.api.raw_io.output())
97 latest = self._parse_latest_yaml(step_result.stdout)
98 step_result.presentation.step_text += ' %s' % (latest,)
99 return latest
100
101 @classmethod
102 def _parse_latest_yaml(cls, text):
103 # Rather than import a YAML parser, we will specifically search for the
104 # string:
105 #
106 # release: "<version>"
107 for line in text.splitlines():
108 m = cls._RE_RELEASE.match(line)
109 if m:
110 return m.group(1)
111 raise cls.VersionParseError('Could not parse release version from YAML.')
112
113 def download_and_unpack(self, plat, arch, version):
114 # Get the package base for this OS.
115 _, base, dirname = self.api.gae_sdk.package_spec(plat, arch)
116 name = '%s%s.zip' % (base, version)
117 artifact_url = '%s/%s' % (self._GS_BUCKET_BASE, name)
118
119 tdir = self.api.path.mkdtemp('gae_sdk')
120 dst = tdir.join(name) # Store the ZIP file here.
121 unzip_dir = tdir.join('unpack') # Unzip contents here.
122 self.api.gsutil.download_url(
123 artifact_url,
124 dst,
125 name='Download %s %s' % (plat, arch,))
126 self.api.zip.unzip(
127 'Unzip %s %s' % (plat, arch),
128 dst,
129 unzip_dir,
130 quiet=True)
131
132 pkg_dir = unzip_dir.join(dirname)
133 self.api.path.mock_add_paths(pkg_dir)
134 assert self.api.path.exists(pkg_dir), (
135 'Package directory [%s] does not exist' % (pkg_dir,))
136 return pkg_dir
137
138
139 def GenTests(api):
140 LATEST_YAML = '\n'.join((
141 'release: "1.2.3"',
142 'foo: bar',
143 'baz:',
144 ' - qux',
145 ))
146
147 def cipd_pkg(plat, pkg_base, exists):
148 pkg_name = 'infra/gae_sdk/%s/%s' % (plat, pkg_base)
149 cipd_step = 'cipd search %s gae_sdk_version:1.2.3' % (pkg_name,)
150 instances = (2) if exists else (0)
151 return api.step_data('Sync %s.%s' % (pkg_name, cipd_step),
152 api.cipd.example_search(pkg_name, instances=instances))
153
154 yield (api.test('packages') +
155 api.step_data('gsutil Get Latest',
156 api.raw_io.stream_output(LATEST_YAML, stream='stdout')) +
157 cipd_pkg('go', 'linux-amd64', False) +
158 cipd_pkg('go', 'linux-386', True) +
159 cipd_pkg('go', 'mac-amd64', True) +
160 cipd_pkg('python', 'all', False))
161
162 yield (api.test('bad_version_yaml') +
163 api.step_data('gsutil Get Latest',
164 api.raw_io.stream_output('', stream='stdout')))
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698