Index: dart/tools/bots/bot_utils.py |
diff --git a/dart/tools/bots/bot_utils.py b/dart/tools/bots/bot_utils.py |
new file mode 100644 |
index 0000000000000000000000000000000000000000..a5e97b417708435126372e558e9f7976f37d0bc9 |
--- /dev/null |
+++ b/dart/tools/bots/bot_utils.py |
@@ -0,0 +1,177 @@ |
+#!/usr/bin/env python |
+# |
+# Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
+# for details. All rights reserved. Use of this source code is governed by a |
+# BSD-style license that can be found in the LICENSE file. |
+ |
+import hashlib |
+import imp |
+import os |
+import subprocess |
+import sys |
+ |
+DART_DIR = os.path.abspath( |
+ os.path.normpath(os.path.join(__file__, '..', '..', '..'))) |
+ |
+def GetUtils(): |
+ '''Dynamically load the tools/utils.py python module.''' |
+ return imp.load_source('utils', os.path.join(DART_DIR, 'tools', 'utils.py')) |
+ |
+utils = GetUtils() |
+ |
+SYSTEM_RENAMES = { |
+ 'win32': 'windows', |
+ 'windows': 'windows', |
+ 'win': 'windows', |
+ |
+ 'linux': 'linux', |
+ 'linux2': 'linux', |
+ 'lucid32': 'linux', |
+ 'lucid64': 'linux', |
+ |
+ 'darwin': 'macos', |
+ 'mac': 'macos', |
+ 'macos': 'macos', |
+} |
+ |
+ARCH_RENAMES = { |
+ '32': 'ia32', |
+ 'ia32': 'ia32', |
+ |
+ '64': 'x64', |
+ 'x64': 'x64', |
+} |
+ |
+class Channel(object): |
+ BLEEDING_EDGE = 'be' |
+ DEV = 'dev' |
+ STABLE = 'stable' |
+ ALL_CHANNELS = [BLEEDING_EDGE, DEV, STABLE] |
+ |
+class ReleaseType(object): |
ricow1
2013/09/16 11:51:30
To be consistent, should we make a Mode class as w
kustermann
2013/09/16 14:15:54
Done.
|
+ RAW = 'raw' |
+ SIGNED = 'signed' |
+ RELEASE = 'release' |
+ ALL_TYPES = [RAW, SIGNED, RELEASE] |
+ |
+class GCSNamer(object): |
+ def __init__(self, channel=Channel.BLEEDING_EDGE, |
+ release_type=ReleaseType.RAW): |
+ assert channel in Channel.ALL_CHANNELS |
+ assert release_type in ReleaseType.ALL_TYPES |
+ |
+ self.channel = channel |
+ self.release_type = release_type |
+ self.bucket = 'gs://dart-archive' |
+ |
+ def dartium_directory(self, revision): |
+ return self._variant_directory('dartium', revision) |
+ |
+ def sdk_directory(self, revision): |
+ return self._variant_directory('sdk', revision) |
+ |
+ def editor_directory(self, revision): |
+ return self._variant_directory('editor', revision) |
+ |
+ def editor_eclipse_update_directory(self, revision): |
+ return self._variant_directory('editor-eclipse-update', revision) |
+ |
+ def apidocs_directory(self, revision): |
+ return self._variant_directory('api-docs', revision) |
+ |
+ def misc_directory(self, revision): |
+ return self._variant_directory('misc', revision) |
+ |
+ def version_file(self, revision): |
+ return '%s/channels/%s/%s/%s/VERSION' % (self.bucket, self.channel, self.release_type, |
+ revision) |
+ |
+ def _variant_directory(self, name, revision): |
+ return '%s/channels/%s/%s/%s/%s' % (self.bucket, self.channel, self.release_type, |
+ revision, name) |
+ |
+ def apidocs_zipfile(self): |
ricow1
2013/09/16 11:51:30
we use zipfilename in other functions
kustermann
2013/09/16 14:15:54
Done.
|
+ return 'dart-api-docs.zip' |
+ |
+ def editor_zipfilename(self, system, arch): |
+ return 'darteditor-%s-%s.zip' % ( |
+ SYSTEM_RENAMES[system], ARCH_RENAMES[arch]) |
+ |
+ def sdk_zipfilename(self, system, arch, mode): |
+ assert mode in ['release', 'debug'] |
ricow1
2013/09/16 11:51:30
if you create a Mode class, then use it here for t
kustermann
2013/09/16 14:15:54
Done.
|
+ return 'dartsdk-%s-%s-%s.zip' % ( |
+ SYSTEM_RENAMES[system], ARCH_RENAMES[arch], mode) |
+ |
+ def dartium_zipfilename(self, system, arch, mode): |
+ return self._dartium_variant_zipfilename('dartium', system, arch, mode) |
+ |
+ def content_shell_zipfilename(self, system, arch, mode): |
+ return self._dartium_variant_zipfilename( |
+ 'content_shell', system, arch, mode) |
+ |
+ def cromedriver_zipfilename(self, system, arch, mode): |
+ return self.dartium_variant_zipfilename( |
+ 'chromedriver', system, arch, mode) |
+ |
+ def dartium_variant_zipfilename(self, name, system, arch, mode): |
ricow1
2013/09/16 11:51:30
do we need the above functions if we have this?
kustermann
2013/09/16 14:15:54
Probably not. I started with this function to be p
|
+ assert name in ['chromedriver', 'dartium', 'content_shell'] |
+ assert mode in ['release', 'debug'] |
+ return '%s-%s-%s-%s.zip' % ( |
+ name, SYSTEM_RENAMES[system], ARCH_RENAMES[arch], mode) |
+ |
+def run(command, env=None): |
+ print "Running command: ", command |
+ p = subprocess.Popen(command, stdout=subprocess.PIPE, |
+ stderr=subprocess.PIPE, env=env) |
+ (stdout, stderr) = p.communicate() |
+ if p.returncode: |
ricow1
2013/09/16 11:51:30
I would actually be specific here
if p.returncode
kustermann
2013/09/16 14:15:54
I changed it -- but that's not the "pythonic way"!
|
+ print >> sys.stderr, "Failed to execute '%s'. Exit code: %s." % ( |
+ command, p.returncode) |
+ print >> sys.stderr, "stdout: ", stdout |
+ print >> sys.stderr, "stderr: ", stderr |
+ raise Exception("Failed to execute %s." % command) |
+ |
+class GSUtil(object): |
+ GSUTIL_PATH = os.path.join(DART_DIR, 'third_party', 'gsutil', 'gsutil') |
ricow1
2013/09/16 11:51:30
this will probably not work on dartium, since we d
kustermann
2013/09/16 14:15:54
Good point. I've added more logic now to search fo
|
+ assert os.path.exists(GSUTIL_PATH) |
+ |
+ def execute(self, gsutil_args): |
+ env = dict(os.environ) |
+ # If we're on the buildbot, we use a specific boto file. |
+ if utils.GetUserName() == 'chrome-bot': |
+ boto_config = { |
+ 'linux': '/mnt/data/b/build/site_config/.boto', |
+ 'macos': '/Volumes/data/b/build/site_config/.boto', |
+ 'win32': r'e:\b\build\site_config\.boto', |
+ }[utils.GuessOS()] |
+ env['AWS_CREDENTIAL_FILE'] = boto_config |
ricow1
2013/09/16 11:51:30
do we need to specify this at this point?
This wil
kustermann
2013/09/16 14:15:54
We probably don't need it. But BB contains it in i
|
+ env['BOTO_CONFIG'] = boto_config |
+ run([sys.executable, GSUtil.GSUTIL_PATH] + gsutil_args, |
+ env=env) |
+ |
+def CalculateChecksum(filename): |
+ """Calculate the MD5 checksum for filename.""" |
+ |
+ md5 = hashlib.md5() |
+ |
+ with open(filename, 'rb') as f: |
+ data = f.read(65536) |
+ while len(data) > 0: |
+ md5.update(data) |
+ data = f.read(65536) |
+ |
+ return md5.hexdigest() |
+ |
+def CreateChecksumFile(filename, mangled_filename=None): |
+ """Create and upload an MD5 checksum file for filename.""" |
+ if not mangled_filename: |
+ mangled_filename = os.path.basename(filename) |
+ |
+ checksum = CalculateChecksum(filename) |
+ checksum_filename = '%s.md5sum' % filename |
+ |
+ with open(checksum_filename, 'w') as f: |
+ f.write('%s *%s' % (checksum, mangled_filename)) |
+ |
+ return checksum_filename |
+ |