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

Unified 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, 3 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 side-by-side diff with in-line comments
Download patch
Index: scripts/slave/recipe_modules/gae_sdk/api.py
diff --git a/scripts/slave/recipe_modules/gae_sdk/api.py b/scripts/slave/recipe_modules/gae_sdk/api.py
new file mode 100644
index 0000000000000000000000000000000000000000..493f087d986e94690b34f0f03cdbfae3eb2f6861
--- /dev/null
+++ b/scripts/slave/recipe_modules/gae_sdk/api.py
@@ -0,0 +1,146 @@
+# Copyright 2016 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 collections
+import re
+
+from recipe_engine import recipe_api
+
+
+class GaeSdkApi(recipe_api.RecipeApi):
+
+ PLAT_PYTHON = 'python'
+ PLAT_GO = 'go'
+
+ # The Google Storage GAE SDK bucket base. All SDK packages are stored in here
+ # under a basename + version ZIP file.
+ GS_BUCKET_BASE = 'gs://appengine-sdks/featured'
+ # The GS path to the "LATEST" YAML file.
+ GS_VERSION_YAML = '%s/VERSION' % (GS_BUCKET_BASE,)
+
+ # Hacky regex for the "release" YAML variable.
+ RE_RELEASE = re.compile(r'^release:\s+"([^"]+)"$')
+
+ # Map of {Platform => {Arch => (base, dirname)}}. Platform names are
+ # "recipe_engine/platform" values.
+ _PKG_MAP = {
+ PLAT_PYTHON: {
+ 'all': ('google_appengine_', 'google_appengine'),
+ },
+ PLAT_GO: {
+ 'linux-amd64': ('go_appengine_sdk_linux_amd64-', 'go_appengine'),
+ 'linux-386': ('go_appengine_sdk_linux_386-', 'go_appengine'),
+ 'mac-amd64': ('go_appengine_sdk_darwin_amd64-', 'go_appengine'),
+ },
+ }
+
+ # Map of architecture bitness to CIPD bitness suffix.
+ _BITS_MAP = {
+ 64: 'amd64',
+ 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
+ }
+
+
+ class VersionParseError(Exception):
+ pass
+
+
+ class PackageNotFound(Exception):
+ def __init__(self, plat, arch):
+ super(GaeSdkApi.PackageNotFound, self).__init__(
+ 'Package not found for %s on %s' % (plat, arch))
+ self.plat = plat
+ self.arch = arch
+
+
+ def __init__(self, *args, **kwargs):
+ super(GaeSdkApi, self).__init__(*args, **kwargs)
+ self._latest = None
+
+ def _step_name(self, desc):
+ return 'GAE SDK: %s' % (desc,)
+
+ @property
+ def latest_ref(self):
+ return 'latest'
+
+ def version_tag(self, version):
+ return ('gae_sdk_version', version)
+
+ def _package_spec(self, plat, arch):
+ plat_dict = self._PKG_MAP.get(plat, {})
+ for a in (arch, 'all'):
+ spec = plat_dict.get(a)
+ if spec:
+ download_base, dirname = spec
+ pkg_name = 'infra/gae_sdk/%s/%s' % (plat, a)
+ return pkg_name, download_base, dirname
+ raise self.PackageNotFound(plat, arch)
+
+ def package(self, plat, arch=None):
+ arch = arch or '%s-%s' % (
+ self.m.platform.name, self._BITS_MAP[self.m.platform.bits])
+ pkg_name, _, _ = self._package_spec(plat, arch)
+ return pkg_name
+
+ @property
+ def platforms(self):
+ return sorted(self._PKG_MAP.keys())
+
+ @property
+ def all_packages(self):
+ for plat, arch_dict in sorted(self._PKG_MAP.items()):
+ for arch in sorted(arch_dict.keys()):
+ yield plat, arch
+
+ def latest_upstream_version(self):
+ if self._latest is None:
+ step_result = self.m.gsutil.cat(
+ self.GS_VERSION_YAML,
+ name=self._step_name('Get Latest'),
+ stdout=self.m.raw_io.output())
+ self._latest = self._parse_latest_yaml(step_result.stdout)
+ step_result.presentation.step_text += ' %s' % (self._latest,)
+ return self._latest
+
+ @classmethod
+ def _parse_latest_yaml(cls, text):
+ # Rather than import a YAML parser, we will specifically search for the
+ # string:
+ #
+ # release: "<version>"
+ for line in text.splitlines():
+ m = cls.RE_RELEASE.match(line)
+ if m:
+ return m.group(1)
+ raise cls.VersionParseError('Could not parse release version from YAML.')
+
+ 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.
+ # Get the package base for this OS.
+ _, base, dirname = self._package_spec(plat, arch)
+ name = '%s%s.zip' % (base, version)
+ artifact_url = '%s/%s' % (self.GS_BUCKET_BASE, name)
+
+ tdir = self.m.path.mkdtemp('gae_sdk')
+ dst = tdir.join(name) # Store the ZIP file here.
+ unzip_dir = tdir.join('unpack') # Unzip contents here.
+ self.m.gsutil.download_url(
+ artifact_url,
+ dst,
+ name=self._step_name('Download %s %s' % (plat, arch,)))
+ self.m.zip.unzip(
+ self._step_name('Unzip %s %s' % (plat, arch)),
+ dst,
+ unzip_dir,
+ quiet=True)
+
+ pkg_dir = unzip_dir.join(dirname)
+ self.m.path.mock_add_paths(pkg_dir)
+ assert self.m.path.exists(pkg_dir), (
+ 'Package directory [%s] does not exist' % (pkg_dir,))
+ return pkg_dir
+
+ 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.
+ pkg = self.package(plat)
+ self.m.cipd.ensure(dst, {pkg: self.latest_ref})

Powered by Google App Engine
This is Rietveld 408576698