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

Side by Side Diff: scripts/slave/recipe_modules/gae_sdk/api.py

Issue 2355483004: Add CIPD GAE SDK recipe module and packager. (Closed)
Patch Set: Go SDKs need architecture. 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 from recipe_engine import recipe_api
9
10
11 class GaeSdkApi(recipe_api.RecipeApi):
12
13 PLAT_PYTHON = 'python'
14 PLAT_GO = 'go'
15
16 # The Google Storage GAE SDK bucket base. All SDK packages are stored in here
17 # under a basename + version ZIP file.
18 GS_BUCKET_BASE = 'gs://appengine-sdks/featured'
19 # The GS path to the "LATEST" YAML file.
20 GS_VERSION_YAML = '%s/VERSION' % (GS_BUCKET_BASE,)
21
22 # Hacky regex for the "release" YAML variable.
23 RE_RELEASE = re.compile(r'^release:\s+"([^"]+)"$')
24
25 # Map of {Platform => {Arch => (base, dirname)}}. Platform names are
26 # "recipe_engine/platform" values.
27 _PKG_MAP = {
28 PLAT_PYTHON: {
29 'all': ('google_appengine_', 'google_appengine'),
30 },
31 PLAT_GO: {
32 'linux-amd64': ('go_appengine_sdk_linux_amd64-', 'go_appengine'),
33 'linux-386': ('go_appengine_sdk_linux_386-', 'go_appengine'),
34 'mac-amd64': ('go_appengine_sdk_darwin_amd64-', 'go_appengine'),
35 },
36 }
37
38 # Map of architecture bitness to CIPD bitness suffix.
39 _BITS_MAP = {
40 64: 'amd64',
41 32: '386',
iannucci 2016/09/30 21:05:21 hm... I didn't realize it was 386 instead of x86.
dnj 2016/09/30 22:54:54 I've generally seen i386 / i686 vs. amd64 / x86_64
42 }
43
44
45 class VersionParseError(Exception):
46 pass
47
48
49 class PackageNotFound(Exception):
50 def __init__(self, plat, arch):
51 super(GaeSdkApi.PackageNotFound, self).__init__(
52 'Package not found for %s on %s' % (plat, arch))
53 self.plat = plat
54 self.arch = arch
55
56
57 def __init__(self, *args, **kwargs):
58 super(GaeSdkApi, self).__init__(*args, **kwargs)
59 self._latest = None
60
61 def _step_name(self, desc):
62 return 'GAE SDK: %s' % (desc,)
63
64 @property
65 def latest_ref(self):
66 return 'latest'
67
68 def version_tag(self, version):
69 return ('gae_sdk_version', version)
70
71 def _package_spec(self, plat, arch):
72 plat_dict = self._PKG_MAP.get(plat, {})
73 for a in (arch, 'all'):
74 spec = plat_dict.get(a)
75 if spec:
76 download_base, dirname = spec
77 pkg_name = 'infra/gae_sdk/%s/%s' % (plat, a)
78 return pkg_name, download_base, dirname
79 raise self.PackageNotFound(plat, arch)
80
81 def package(self, plat, arch=None):
82 arch = arch or '%s-%s' % (
83 self.m.platform.name, self._BITS_MAP[self.m.platform.bits])
84 pkg_name, _, _ = self._package_spec(plat, arch)
85 return pkg_name
86
87 @property
88 def platforms(self):
89 return sorted(self._PKG_MAP.keys())
90
91 @property
92 def all_packages(self):
93 for plat, arch_dict in sorted(self._PKG_MAP.items()):
94 for arch in sorted(arch_dict.keys()):
95 yield plat, arch
96
97 def latest_upstream_version(self):
98 if self._latest is None:
99 step_result = self.m.gsutil.cat(
100 self.GS_VERSION_YAML,
101 name=self._step_name('Get Latest'),
102 stdout=self.m.raw_io.output())
103 self._latest = self._parse_latest_yaml(step_result.stdout)
104 step_result.presentation.step_text += ' %s' % (self._latest,)
105 return self._latest
106
107 @classmethod
108 def _parse_latest_yaml(cls, text):
109 # Rather than import a YAML parser, we will specifically search for the
110 # string:
111 #
112 # release: "<version>"
113 for line in text.splitlines():
114 m = cls.RE_RELEASE.match(line)
115 if m:
116 return m.group(1)
117 raise cls.VersionParseError('Could not parse release version from YAML.')
118
119 def download_and_unpack(self, plat, arch, version):
iannucci 2016/09/30 21:05:21 can we move this to the packaging recipe? Otherwis
dnj 2016/09/30 22:54:54 Done.
120 # Get the package base for this OS.
121 _, base, dirname = self._package_spec(plat, arch)
122 name = '%s%s.zip' % (base, version)
123 artifact_url = '%s/%s' % (self.GS_BUCKET_BASE, name)
124
125 tdir = self.m.path.mkdtemp('gae_sdk')
126 dst = tdir.join(name) # Store the ZIP file here.
127 unzip_dir = tdir.join('unpack') # Unzip contents here.
128 self.m.gsutil.download_url(
129 artifact_url,
130 dst,
131 name=self._step_name('Download %s %s' % (plat, arch,)))
132 self.m.zip.unzip(
133 self._step_name('Unzip %s %s' % (plat, arch)),
134 dst,
135 unzip_dir,
136 quiet=True)
137
138 pkg_dir = unzip_dir.join(dirname)
139 self.m.path.mock_add_paths(pkg_dir)
140 assert self.m.path.exists(pkg_dir), (
141 'Package directory [%s] does not exist' % (pkg_dir,))
142 return pkg_dir
143
144 def fetch(self, plat, dst):
iannucci 2016/09/30 21:05:21 it should somehow be made clear that this is reall
dnj 2016/09/30 22:54:54 Done.
145 pkg = self.package(plat)
146 self.m.cipd.ensure(dst, {pkg: self.latest_ref})
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698