Skip to content
Browse files

bug 659544 - android partner repacks. r=rail

  • Loading branch information...
1 parent f772505 commit d9e20c05ec51c596d5dced189e72c61ba6a0e44b @escapewindow escapewindow committed
View
45 configs/partner_repacks/release_mozilla-release_android.py
@@ -0,0 +1,45 @@
+FTP_SERVER = "stage.mozilla.org"
+FTP_USER = "ffxbld"
+FTP_SSH_KEY = "~/.ssh/ffxbld_dsa"
+FTP_UPLOAD_BASE_DIR = "/pub/mozilla.org/mobile/candidates/%(version)s-candidates/build%(buildnum)d"
+DOWNLOAD_BASE_URL = "http://%s%s" % (FTP_SERVER, FTP_UPLOAD_BASE_DIR)
+APK_BASE_NAME = "fennec-%(version)s.%(locale)s.android-arm.apk"
+HG_SHARE_BASE_DIR = "/builds/hg-shared"
+KEYSTORE = "/home/cltsign/.android/android-release.keystore"
+KEY_ALIAS = "release"
+
+config = {
+ "log_name": "partner_repack",
+ "locales_file": "buildbot-configs/mozilla/l10n-changesets_mobile-release.json",
+ "additional_locales": ['en-US'],
+ "platforms": ["android"],
+ "repos": [{
+ "repo": "http://hg.mozilla.org/build/buildbot-configs",
+ "revision": "default",
+ }],
+ 'vcs_share_base': HG_SHARE_BASE_DIR,
+ "ftp_upload_base_dir": FTP_UPLOAD_BASE_DIR,
+ "ftp_ssh_key": FTP_SSH_KEY,
+ "ftp_user": FTP_USER,
+ "ftp_server": FTP_SERVER,
+ "installer_base_names": {
+ "android": APK_BASE_NAME,
+ },
+ "partner_config": {
+ "android-market": {},
+ },
+ "download_unsigned_base_subdir": "unsigned/%(platform)s/%(locale)s",
+ "download_base_url": DOWNLOAD_BASE_URL,
+
+ "release_config_file": "buildbot-configs/mozilla/release-fennec-mozilla-release.py",
+
+ "default_actions": ["clobber", "pull", "download", "repack", "upload-unsigned-bits"],
+
+ # signing (optional)
+ "keystore": KEYSTORE,
+ "key_alias": KEY_ALIAS,
+ "exes": {
+ "jarsigner": "/tools/jdk-1.6.0_17/bin/jarsigner",
+ "zipalign": "/tools/android-sdk-r8/tools/zipalign",
+ },
+}
View
50 configs/partner_repacks/staging_release_mozilla-release_android.py
@@ -0,0 +1,50 @@
+FTP_SERVER = "dev-stage01.build.sjc1.mozilla.com"
+FTP_USER = "ffxbld"
+FTP_SSH_KEY = "~/.ssh/ffxbld_dsa"
+FTP_UPLOAD_BASE_DIR = "/pub/mozilla.org/mobile/candidates/%(version)s-candidates/build%(buildnum)d"
+#DOWNLOAD_BASE_URL = "http://%s%s" % (FTP_SERVER, FTP_UPLOAD_BASE_DIR)
+DOWNLOAD_BASE_URL = "http://ftp.mozilla.org/pub/mozilla.org/mobile/candidates/%(version)s-candidates/build%(buildnum)d"
+#DOWNLOAD_BASE_URL = "http://dev-stage01.build.mozilla.org/pub/mozilla.org/mobile/candidates/11.0b1-candidates/build1/"
+APK_BASE_NAME = "fennec-%(version)s.%(locale)s.android-arm.apk"
+#APK_BASE_NAME = "fennec-11.0b1.%(locale)s.android-arm.apk"
+HG_SHARE_BASE_DIR = "/builds/hg-shared"
+#KEYSTORE = "/home/cltsign/.android/android-release.keystore"
+KEYSTORE = "/home/cltbld/.android/android.keystore"
+#KEY_ALIAS = "release"
+KEY_ALIAS = "nightly"
+
+config = {
+ "log_name": "partner_repack",
+ "locales_file": "buildbot-configs/mozilla/l10n-changesets_mobile-release.json",
+ "additional_locales": ['en-US'],
+ "platforms": ["android"],
+ "repos": [{
+ "repo": "http://hg.mozilla.org/build/buildbot-configs",
+ "revision": "default",
+ }],
+ 'vcs_share_base': HG_SHARE_BASE_DIR,
+ "ftp_upload_base_dir": FTP_UPLOAD_BASE_DIR,
+ "ftp_ssh_key": FTP_SSH_KEY,
+ "ftp_user": FTP_USER,
+ "ftp_server": FTP_SERVER,
+ "installer_base_names": {
+ "android": APK_BASE_NAME,
+ },
+ "partner_config": {
+ "android-market": {},
+ },
+ "download_unsigned_base_subdir": "unsigned/%(platform)s/%(locale)s",
+ "download_base_url": DOWNLOAD_BASE_URL,
+
+ "release_config_file": "buildbot-configs/mozilla/release-fennec-mozilla-release.py",
+
+ "default_actions": ["clobber", "pull", "download", "repack", "upload-unsigned-bits"],
+
+ # signing (optional)
+ "keystore": KEYSTORE,
+ "key_alias": KEY_ALIAS,
+ "exes": {
+ "jarsigner": "/tools/jdk-1.6.0_17/bin/jarsigner",
+ "zipalign": "/tools/android-sdk-r8/tools/zipalign",
+ },
+}
View
3 configs/signing/android_mozilla-release.py
@@ -50,6 +50,9 @@
"update_platform_map": {
'android': 'Android_arm-eabi-gcc3',
},
+ "enable_partner_repacks": False,
+ "partner_platforms": ['android'],
+ "partners": ['android-market'],
"update_channels": {
'release': {
'url': RELEASE_UPDATE_URL,
View
3 configs/signing/staging_android_mozilla-beta.py
@@ -48,6 +48,9 @@
"update_platform_map": {
'android': 'Android_arm-eabi-gcc3',
},
+# "enable_partner_repacks": True,
+# "partner_platforms": ['android'],
+# "partners": ['android-market'],
"update_channels": {
'release': {
'url': RELEASE_UPDATE_URL,
View
22 mozharness/base/errors.py
@@ -101,6 +101,28 @@ class VCSException(Exception):
'explanation': r'''The apk is missing!''',
}]
+ZipErrorList = BaseErrorList + [{
+ 'substr': r'''zip warning:''',
+ 'level': WARNING,
+},{
+ 'substr': r'''zip error:''',
+ 'level': ERROR,
+},{
+ 'substr': r'''Cannot open file: it does not appear to be a valid archive''',
+ 'level': ERROR,
+}]
+
+ZipalignErrorList = BaseErrorList + [{
+ 'regex': re.compile(r'''Unable to open .* as a zip archive'''),
+ 'level': ERROR,
+},{
+ 'regex': re.compile(r'''Output file .* exists'''),
+ 'level': ERROR,
+},{
+ 'substr': r'''Input and output can't be the same file''',
+ 'level': ERROR,
+}]
+
# __main__ {{{1
View
84 mozharness/base/script.py
@@ -21,10 +21,8 @@
import shutil
import subprocess
import sys
-import tarfile
import urllib2
import urlparse
-import zipfile
try:
import simplejson as json
@@ -41,15 +39,26 @@ class OSMixin(object):
Depends on LogMixin, ShellMixin, and a self.config of some sort.
"""
- def mkdir_p(self, path):
+ def mkdir_p(self, path, error_level=ERROR):
+ """
+ Returns None for success, not None for failure
+ """
if not os.path.exists(path):
self.info("mkdir: %s" % path)
if not self.config.get('noop'):
- os.makedirs(path)
+ try:
+ os.makedirs(path)
+ except OSError:
+ self.log("Can't create directory %s!" % path,
+ level=error_level)
+ return -1
else:
self.debug("mkdir_p: %s Already exists." % path)
def rmtree(self, path, log_level=INFO, error_level=ERROR, exit_code=-1):
+ """
+ Returns None for success, not None for failure
+ """
self.log("rmtree: %s" % path, level=log_level)
if os.path.exists(path):
if not self.config.get('noop'):
@@ -66,7 +75,6 @@ def rmtree(self, path, log_level=INFO, error_level=ERROR, exit_code=-1):
return -1
else:
self.debug("%s doesn't exist." % path)
- return 0
def _is_windows(self):
system = platform.system()
@@ -139,7 +147,7 @@ def download_file(self, url, file_name=None, parent_dir=None,
self.info("Downloading %s%s" % (url, message))
f = urllib2.urlopen(req)
if create_parent_dir and parent_dir:
- self.mkdir_p(parent_dir)
+ self.mkdir_p(parent_dir, error_level=error_level)
local_file = open(file_name, 'wb')
local_file.write(f.read())
local_file.close()
@@ -179,6 +187,60 @@ def copyfile(self, src, dest, log_level=INFO, error_level=ERROR):
except (IOError, shutil.Error):
self.dump_exception("Can't copy %s to %s!" % (src, dest),
level=error_level)
+ return -1
+
+ def write_to_file(self, file_path, contents, verbose=True,
+ open_mode='w', create_parent_dir=False,
+ error_level=ERROR):
+ """
+ Write contents to file_path.
+
+ This doesn't currently create the parent_dir or translate into
+ abs_path; that needs to be done beforehand, since OSMixin doesn't
+ necessarily have access to query_abs_dirs().
+
+ Returns file_path if successful, None if not.
+ """
+ self.info("Writing to file %s" % file_path)
+ if verbose:
+ self.info("Contents:")
+ for line in contents.splitlines():
+ self.info(" %s" % line)
+ if create_parent_dir:
+ parent_dir = os.path.dirname(file_path)
+ self.mkdir_p(parent_dir, error_level=error_level)
+ try:
+ fh = open(file_path, open_mode)
+ fh.write(contents)
+ fh.close()
+ return file_path
+ except IOError:
+ self.log("%s can't be opened for writing!" % file_path,
+ level=error_level)
+
+ def read_from_file(self, file_path, verbose=True, open_mode='r',
+ error_level=ERROR):
+ """
+ Reads from file_path.
+
+ Returns contents if successful, None if not.
+ """
+ self.info("Reading from file %s" % file_path)
+ if not os.path.exists(file_path):
+ self.log("%s doesn't exist!" % file_path, level=error_level)
+ return
+ try:
+ fh = open(file_path, open_mode)
+ contents = fh.read()
+ fh.close()
+ if verbose:
+ self.info("Contents:")
+ for line in contents.splitlines():
+ self.info(" %s" % line)
+ return contents
+ except IOError:
+ self.log("%s can't be opened for reading!" % file_path,
+ level=error_level)
def chdir(self, dir_name, ignore_if_noop=False):
self.log("Changing directory to %s." % dir_name)
@@ -403,8 +465,8 @@ def get_output_from_command(self, command, cwd=None,
return_level = DEBUG
output = None
if os.path.exists(tmp_stdout_filename) and os.path.getsize(tmp_stdout_filename):
- fh = open(tmp_stdout_filename)
- output = fh.read()
+ output = self.read_from_file(tmp_stdout_filename,
+ verbose=False)
if not silent:
self.info("Output received:")
output_lines = output.rstrip().splitlines()
@@ -414,18 +476,16 @@ def get_output_from_command(self, command, cwd=None,
line = line.decode("utf-8")
self.info(' %s' % line)
output = '\n'.join(output_lines)
- fh.close()
if os.path.exists(tmp_stderr_filename) and os.path.getsize(tmp_stderr_filename):
return_level = ERROR
self.error("Errors received:")
- fh = open(tmp_stderr_filename)
- errors = fh.read()
+ errors = self.read_from_file(tmp_stderr_filename,
+ verbose=False)
for line in errors.rstrip().splitlines():
if not line or line.isspace():
continue
line = line.decode("utf-8")
self.error(' %s' % line)
- fh.close()
elif p.returncode:
return_level = ERROR
# Clean up.
View
140 mozharness/base/signing.py
@@ -7,11 +7,32 @@
"""Generic signing methods.
"""
+import getpass
import hashlib
import os
+import re
+import subprocess
+
+from mozharness.base.errors import JarsignerErrorList, ZipErrorList, ZipalignErrorList
+from mozharness.base.log import OutputParser, IGNORE, DEBUG, INFO, ERROR, FATAL
+
+UnsignApkErrorList = [{
+ 'regex': re.compile(r'''zip warning: name not matched: '?META-INF/'''),
+ 'level': INFO,
+ 'explanation': r'''This apk is already unsigned.''',
+},{
+ 'substr': r'''zip error: Nothing to do!''',
+ 'level': IGNORE,
+}] + ZipErrorList
+
+TestJarsignerErrorList = [{
+ "substr": "jarsigner: unable to open jar file:",
+ "level": IGNORE,
+}] + JarsignerErrorList
+
-# BaseSigningMixin {{{1
+# BaseSigningMixin {{{1
class BaseSigningMixin(object):
"""Generic signing helper methods.
"""
@@ -25,10 +46,121 @@ def query_filesize(self, file_path):
def query_sha512sum(self, file_path):
self.info("Determining sha512sum for %s" % file_path)
m = hashlib.sha512()
- fh = open(file_path, 'rb')
- contents = fh.read()
- fh.close()
+ contents = self.read_from_file(file_path, verbose=False,
+ open_mode='rb')
m.update(contents)
sha512 = m.hexdigest()
self.info(" %s" % sha512)
return sha512
+
+
+
+# AndroidSigningMixin {{{1
+class AndroidSigningMixin(object):
+ """
+ Generic Android apk signing methods.
+
+ Dependent on BaseScript.
+ """
+ # TODO port build/tools/release/signing/verify-android-signature.sh here
+
+ key_passphrase = os.environ.get('android_keypass')
+ store_passphrase = os.environ.get('android_storepass')
+
+ def passphrase(self):
+ if not self.store_passphrase:
+ self.store_passphrase = getpass.getpass("Store passphrase: ")
+ if not self.key_passphrase:
+ self.key_passphrase = getpass.getpass("Key passphrase: ")
+
+ def _verify_passphrases(self, keystore, key_alias, error_level=FATAL):
+ self.info("Verifying passphrases...")
+ status = self.sign_apk("NOTAREALAPK", keystore,
+ self.store_passphrase, self.key_passphrase,
+ key_alias, remove_signature=False,
+ log_level=DEBUG, error_level=DEBUG,
+ error_list=TestJarsignerErrorList)
+ if status == 0:
+ self.info("Passphrases are good.")
+ elif status < 0:
+ self.log("Encountered errors while trying to sign!",
+ level=error_level)
+ else:
+ self.log("Unable to verify passphrases!",
+ level=error_level)
+ return status
+
+ def verify_passphrases(self):
+ c = self.config
+ self._verify_passphrases(c['keystore'], c['key_alias'])
+
+ def postflight_passphrase(self):
+ self.verify_passphrases()
+
+ def sign_apk(self, apk, keystore, storepass, keypass, key_alias,
+ remove_signature=True, error_list=None,
+ log_level=INFO, error_level=ERROR):
+ """
+ Signs an apk with jarsigner.
+ """
+ jarsigner = self.query_exe('jarsigner')
+ if remove_signature:
+ status = self.unsign_apk(apk)
+ if status:
+ self.error("Can't remove signature in %s!" % apk)
+ return -1
+ if error_list is None:
+ error_list = JarsignerErrorList[:]
+ # This needs to run silently, so no run_command() or
+ # get_output_from_command() (though I could add a
+ # suppress_command_echo=True or something?)
+ self.log("(signing %s)" % apk, level=log_level)
+ try:
+ p = subprocess.Popen([jarsigner, "-keystore", keystore,
+ "-storepass", storepass,
+ "-keypass", keypass,
+ apk, key_alias],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT)
+ except OSError:
+ self.dump_exception("Error while signing %s (missing %s?):" % (apk, jarsigner))
+ return -2
+ except ValueError:
+ self.dump_exception("Popen called with invalid arguments during signing?")
+ return -3
+ parser = OutputParser(config=self.config, log_obj=self.log_obj,
+ error_list=error_list)
+ loop = True
+ while loop:
+ if p.poll() is not None:
+ """Avoid losing the final lines of the log?"""
+ loop = False
+ for line in p.stdout:
+ parser.add_lines(line)
+ if parser.num_errors:
+ self.log("(failure)", level=error_level)
+ else:
+ self.log("(success)", level=log_level)
+ return parser.num_errors
+
+ def unsign_apk(self, apk, **kwargs):
+ zip_bin = self.query_exe("zip")
+ return self.run_command([zip_bin, apk, '-d', 'META-INF/*'],
+ error_list=UnsignApkErrorList,
+ success_codes=[0, 12],
+ return_type='num_errors', **kwargs)
+
+ def align_apk(self, unaligned_apk, aligned_apk, error_level=ERROR):
+ """
+ Zipalign apk.
+ Returns None on success, not None on failure.
+ """
+ dirs = self.query_abs_dirs()
+ zipalign = self.query_exe("zipalign")
+ if self.run_command([zipalign, '-f', '4',
+ unaligned_apk, aligned_apk],
+ return_type='num_errors',
+ cwd=dirs['abs_work_dir'],
+ error_list=ZipalignErrorList):
+ self.log("Unable to zipalign %s to %s!" % (unaligned_apk, aligned_apk), level=error_level)
+ return -1
View
96 mozharness/base/transfer.py
@@ -0,0 +1,96 @@
+#!/usr/bin/env python
+# ***** BEGIN LICENSE BLOCK *****
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this file,
+# You can obtain one at http://mozilla.org/MPL/2.0/.
+# ***** END LICENSE BLOCK *****
+"""Generic ways to upload + download files.
+"""
+
+import os
+
+from mozharness.base.errors import SSHErrorList
+from mozharness.base.log import ERROR
+
+# TransferMixin {{{1
+class TransferMixin(object):
+ """
+ Generic transfer methods.
+
+ Dependent on BaseScript.
+ """
+ def rsync_upload_directory(self, local_path, ssh_key, ssh_user,
+ remote_host, remote_path,
+ rsync_options=None,
+ error_level=ERROR,
+ create_remote_directory=True,
+ ):
+ """
+ Create a remote directory and upload the contents of
+ a local directory to it via rsync+ssh.
+
+ Return None on success, not None on failure.
+ """
+ dirs = self.query_abs_dirs()
+ self.info("Uploading the contents of %s to %s:%s" % (local_path, remote_host, remote_path))
+ rsync = self.query_exe("rsync")
+ ssh = self.query_exe("ssh")
+ if rsync_options is None:
+ rsync_options = ['-azv']
+ if not os.path.isdir(local_path):
+ self.log("%s isn't a directory!" % local_path,
+ level=ERROR)
+ return -1
+ if create_remote_directory:
+ mkdir_error_list = [{
+ 'substr': r'''exists but is not a directory''',
+ 'level': ERROR
+ }] + SSHErrorList
+ if self.run_command([ssh, '-oIdentityFile=%s' % ssh_key,
+ '%s@%s' % (ssh_user, remote_host),
+ 'mkdir', '-p', remote_path],
+ cwd=dirs['abs_work_dir'],
+ return_type='num_errors',
+ error_list=mkdir_error_list):
+ self.log("Unable to create remote directory %s:%s!" % (remote_host, remote_path), level=error_level)
+ return -2
+ if self.run_command([rsync, '-e',
+ '%s -oIdentityFile=%s' % (ssh, ssh_key)
+ ] + rsync_options + ['.',
+ '%s@%s:%s/' % (ssh_user, remote_host, remote_path)],
+ cwd=local_path,
+ return_type='num_errors',
+ error_list=SSHErrorList):
+ self.log("Unable to rsync %s to %s:%s!" % (local_path, remote_host, remote_path), level=error_level)
+ return -3
+
+ def rsync_download_directory(self, ssh_key, ssh_user, remote_host,
+ remote_path, local_path,
+ rsync_options=None,
+ error_level=ERROR,
+ ):
+ """
+ Create a remote directory and upload the contents of
+ a local directory to it via rsync+ssh.
+
+ Return None on success, not None on failure.
+ """
+ self.info("Downloading the contents of %s:%s to %s" % (remote_host, remote_path, local_path))
+ rsync = self.query_exe("rsync")
+ ssh = self.query_exe("ssh")
+ if rsync_options is None:
+ rsync_options = ['-azv']
+ if not os.path.isdir(local_path):
+ self.log("%s isn't a directory!" % local_path,
+ level=error_level)
+ return -1
+ if self.run_command([rsync, '-e',
+ '%s -oIdentityFile=%s' % (ssh, ssh_key)
+ ] + rsync_options + [
+ '%s@%s:%s/' % (ssh_user, remote_host, remote_path),
+ '.'],
+ cwd=local_path,
+ return_type='num_errors',
+ error_list=SSHErrorList):
+ self.log("Unable to rsync %s:%s to %s!" % (remote_host, remote_path, local_path), level=error_level)
+ return -3
View
4 mozharness/mozilla/l10n/locales.py
@@ -83,9 +83,7 @@ def parse_locales_file(self, locales_file):
locales.append(locale)
self.locale_dict[locale] = locales_json[locale]['revision']
else:
- fh = open(locales_file)
- locales = fh.read().split()
- fh.close()
+ locales = self.read_from_file(locales_file).split()
return locales
def run_compare_locales(self, locale, halt_on_failure=False):
View
10 mozharness/mozilla/signing.py
@@ -12,7 +12,7 @@
from mozharness.base.errors import BaseErrorList
from mozharness.base.log import ERROR, FATAL
-from mozharness.base.signing import BaseSigningMixin
+from mozharness.base.signing import AndroidSigningMixin, BaseSigningMixin
AndroidSignatureVerificationErrorList = BaseErrorList + [{
"regex": re.compile(r'''^Invalid$'''),
@@ -80,11 +80,7 @@ def create_complete_snippet(self, binary_path, version, buildid,
contents = SNIPPET_TEMPLATE % replace_dict
self.mkdir_p(snippet_dir)
snippet_path = os.path.join(snippet_dir, snippet_file)
- try:
- fh = open(snippet_path, 'w')
- fh.write(contents)
- fh.close()
- except:
+ if self.write_to_file(snippet_path, contents, verbose=False) is None:
self.log("Unable to write complete snippet to %s!" % snippet_path,
level=error_level)
return False
@@ -94,7 +90,7 @@ def create_complete_snippet(self, binary_path, version, buildid,
# MobileSigningMixin {{{1
-class MobileSigningMixin(SigningMixin):
+class MobileSigningMixin(AndroidSigningMixin, SigningMixin):
def verify_android_signature(self, apk, script=None, key_alias="nightly",
tools_dir="tools/", env=None):
"""Runs mjessome's android signature verification script.
View
4 scripts/configtest.py
@@ -78,9 +78,9 @@ def test_json_configs(self):
if config_file.endswith(".json"):
filecount[0] += 1
self.info("Testing %s." % config_file)
- fh = open(config_file)
+ contents = self.read_from_file(config_file, verbose=False)
try:
- json.load(fh)
+ json.loads(contents)
except ValueError:
self.add_summary("%s is invalid json." % config_file,
level="error")
View
23 scripts/mobile_l10n.py
@@ -18,8 +18,9 @@
# load modules from parent dir
sys.path.insert(1, os.path.dirname(sys.path[0]))
-from mozharness.base.errors import BaseErrorList, MakefileErrorList, SSHErrorList
+from mozharness.base.errors import BaseErrorList, MakefileErrorList
from mozharness.base.log import OutputParser
+from mozharness.base.transfer import TransferMixin
from mozharness.mozilla.release import ReleaseMixin
from mozharness.mozilla.signing import MobileSigningMixin
from mozharness.base.vcs.vcsbase import MercurialScript
@@ -29,7 +30,7 @@
# MobileSingleLocale {{{1
class MobileSingleLocale(LocalesMixin, ReleaseMixin, MobileSigningMixin,
- MercurialScript):
+ TransferMixin, MercurialScript):
config_options = [[
['--locale',],
{"action": "extend",
@@ -435,22 +436,14 @@ def create_nightly_snippets(self):
def upload_nightly_snippets(self):
c = self.config
dirs = self.query_abs_dirs()
- update_dir = os.path.join(dirs['abs_work_dir'], 'update',)
+ update_dir = os.path.join(dirs['abs_work_dir'], 'update')
if not os.path.exists(update_dir):
self.error("No such directory %s! Skipping..." % update_dir)
return
- rsync = self.query_exe("rsync")
- ssh = self.query_exe("ssh")
- aus_upload_dir = c['aus_upload_base_dir']
- cmd = [ssh, '-oIdentityFile=%s' % c['aus_ssh_key'],
- '%s@%s' % (c['aus_user'], c['aus_server']),
- 'mkdir', '-p', aus_upload_dir]
- self.run_command(cmd, cwd=dirs['abs_work_dir'],
- error_list=SSHErrorList)
- cmd = [rsync, '-e']
- cmd += ['%s -oIdentityFile=%s' % (ssh, c['aus_ssh_key']), '-azv', './']
- cmd += ["%s@%s:%s/" % (c['aus_user'], c['aus_server'], aus_upload_dir)]
- self.run_command(cmd, cwd=update_dir, error_list=SSHErrorList)
+ if self.rsync_upload_directory(update_dir, c['aus_ssh_key'],
+ c['aus_user'], c['aus_server'],
+ c['aus_upload_dir']):
+ self.return_code += 1
View
334 scripts/mobile_partner_repack.py
@@ -0,0 +1,334 @@
+#!/usr/bin/env python
+# ***** BEGIN LICENSE BLOCK *****
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this file,
+# You can obtain one at http://mozilla.org/MPL/2.0/.
+# ***** END LICENSE BLOCK *****
+"""mobile_partner_repack.py
+
+"""
+
+from copy import deepcopy
+import os
+import sys
+
+# load modules from parent dir
+sys.path.insert(1, os.path.dirname(sys.path[0]))
+
+from mozharness.base.errors import ZipErrorList
+from mozharness.base.log import FATAL
+from mozharness.base.transfer import TransferMixin
+from mozharness.base.vcs.vcsbase import MercurialScript
+from mozharness.mozilla.l10n.locales import LocalesMixin
+from mozharness.mozilla.release import ReleaseMixin
+from mozharness.mozilla.signing import MobileSigningMixin
+
+SUPPORTED_PLATFORMS = ["android"]
+
+
+
+# MobilePartnerRepack {{{1
+class MobilePartnerRepack(LocalesMixin, ReleaseMixin, MobileSigningMixin,
+ TransferMixin, MercurialScript):
+ config_options = [[
+ ['--locale',],
+ {"action": "extend",
+ "dest": "locales",
+ "type": "string",
+ "help": "Specify the locale(s) to repack"
+ }
+ ],[
+ ['--partner',],
+ {"action": "extend",
+ "dest": "partners",
+ "type": "string",
+ "help": "Specify the partner(s) to repack"
+ }
+ ],[
+ ['--locales-file',],
+ {"action": "store",
+ "dest": "locales_file",
+ "type": "string",
+ "help": "Specify a json file to determine which locales to repack"
+ }
+ ],[
+ ['--tag-override',],
+ {"action": "store",
+ "dest": "tag_override",
+ "type": "string",
+ "help": "Override the tags set for all repos"
+ }
+ ],[
+ ['--platform',],
+ {"action": "extend",
+ "dest": "platforms",
+ "type": "choice",
+ "choices": SUPPORTED_PLATFORMS,
+ "help": "Specify the platform(s) to repack"
+ }
+ ],[
+ ['--user-repo-override',],
+ {"action": "store",
+ "dest": "user_repo_override",
+ "type": "string",
+ "help": "Override the user repo path for all repos"
+ }
+ ],[
+ ['--release-config-file',],
+ {"action": "store",
+ "dest": "release_config_file",
+ "type": "string",
+ "help": "Specify the release config file to use"
+ }
+ ],[
+ ['--version',],
+ {"action": "store",
+ "dest": "version",
+ "type": "string",
+ "help": "Specify the current version"
+ }
+ ],[
+ ['--old-version',],
+ {"action": "store",
+ "dest": "old_version",
+ "type": "string",
+ "help": "Specify the version to update from"
+ }
+ ],[
+ ['--buildnum',],
+ {"action": "store",
+ "dest": "buildnum",
+ "type": "int",
+ "default": 1,
+ "metavar": "INT",
+ "help": "Specify the current release build num (e.g. build1, build2)"
+ }
+ ]]
+
+ def __init__(self, require_config_file=True):
+ self.release_config = {}
+ LocalesMixin.__init__(self)
+ MercurialScript.__init__(self,
+ config_options=self.config_options,
+ all_actions=[
+ "passphrase",
+ "clobber",
+ "pull",
+ "download",
+ "repack",
+ "upload-unsigned-bits",
+ "sign",
+ "upload-signed-bits",
+ ],
+ require_config_file=require_config_file
+ )
+
+ # Helper methods {{{2
+ def add_failure(self, platform, locale, **kwargs):
+ s = "%s:%s" % (platform, locale)
+ if 'message' in kwargs:
+ kwargs['message'] = kwargs['message'] % {'platform': platform, 'locale': locale}
+ super(MobilePartnerRepack, self).add_failure(s, **kwargs)
+
+ def query_failure(self, platform, locale):
+ s = "%s:%s" % (platform, locale)
+ return super(MobilePartnerRepack, self).query_failure(s)
+
+ # Actions {{{2
+
+ def pull(self):
+ c = self.config
+ dirs = self.query_abs_dirs()
+ repos = []
+ replace_dict = {}
+ if c.get("user_repo_override"):
+ replace_dict['user_repo_override'] = c['user_repo_override']
+ # deepcopy() needed because of self.config lock bug :(
+ for repo_dict in deepcopy(c['repos']):
+ repo_dict['repo'] = repo_dict['repo'] % replace_dict
+ repos.append(repo_dict)
+ else:
+ repos = c['repos']
+ self.vcs_checkout_repos(repos, parent_dir=dirs['abs_work_dir'],
+ tag_override=c.get('tag_override'))
+
+ def download(self):
+ c = self.config
+ rc = self.query_release_config()
+ dirs = self.query_abs_dirs()
+ locales = self.query_locales()
+ replace_dict = {
+ 'buildnum': rc['buildnum'],
+ 'version': rc['version'],
+ }
+ success_count = total_count = 0
+ for platform in c['platforms']:
+ base_installer_name = c['installer_base_names'][platform]
+ base_url = c['download_base_url'] + '/' + \
+ c['download_unsigned_base_subdir'] + '/' + \
+ base_installer_name
+ replace_dict['platform'] = platform
+ for locale in locales:
+ replace_dict['locale'] = locale
+ url = base_url % replace_dict
+ installer_name = base_installer_name % replace_dict
+ parent_dir = '%s/original/%s/%s' % (dirs['abs_work_dir'],
+ platform, locale)
+ file_path = '%s/%s' % (parent_dir, installer_name)
+ self.mkdir_p(parent_dir)
+ total_count += 1
+ if not self.download_file(url, file_path):
+ self.add_failure(platform, locale,
+ message="Unable to download %(platform)s:%(locale)s installer!")
+ else:
+ success_count += 1
+ self.summarize_success_count(success_count, total_count,
+ message="Downloaded %d of %d installers successfully.")
+
+ def _repack_apk(self, partner, orig_path, repack_path):
+ """ Repack the apk with a partner update channel.
+ Returns True for success, None for failure
+ """
+ dirs = self.query_abs_dirs()
+ zip_bin = self.query_exe("zip")
+ unzip_bin = self.query_exe("unzip")
+ file_name = os.path.basename(orig_path)
+ tmp_dir = os.path.join(dirs['abs_work_dir'], 'tmp')
+ tmp_file = os.path.join(tmp_dir, file_name)
+ tmp_prefs_dir = os.path.join(tmp_dir, 'defaults', 'pref')
+ # Error checking for each step.
+ # Ignoring the mkdir_p()s since the subsequent copyfile()s will
+ # error out if unsuccessful.
+ if self.rmtree(tmp_dir):
+ return
+ self.mkdir_p(tmp_prefs_dir)
+ if self.copyfile(orig_path, tmp_file):
+ return
+ if self.write_to_file(os.path.join(tmp_prefs_dir, 'partner.js'),
+ 'pref("app.partner.%s", "%s");' % (partner, partner)
+ ) is None:
+ return
+ if self.run_command([unzip_bin, file_name, 'omni.ja'],
+ error_list=ZipErrorList,
+ return_type='num_errors',
+ cwd=tmp_dir):
+ self.error("Can't extract omni.ja from %s!" % file_name)
+ return
+ if self.run_command([zip_bin, '-9r', 'omni.ja',
+ 'defaults/pref/partner.js'],
+ error_list=ZipErrorList,
+ return_type='num_errors',
+ cwd=tmp_dir):
+ self.error("Can't add partner.js to omni.ja!")
+ return
+ if self.run_command([zip_bin, '-9r', file_name, 'omni.ja'],
+ error_list=ZipErrorList,
+ return_type='num_errors',
+ cwd=tmp_dir):
+ self.error("Can't re-add omni.ja to %s!" % file_name)
+ return
+ if self.unsign_apk(tmp_file):
+ return
+ repack_dir = os.path.dirname(repack_path)
+ self.mkdir_p(repack_dir)
+ if self.copyfile(tmp_file, repack_path):
+ return
+ return True
+
+ def repack(self):
+ c = self.config
+ rc = self.query_release_config()
+ dirs = self.query_abs_dirs()
+ locales = self.query_locales()
+ success_count = total_count = 0
+ for platform in c['platforms']:
+ for locale in locales:
+ installer_name = c['installer_base_names'][platform] % {'version': rc['version'], 'locale': locale}
+ if self.query_failure(platform, locale):
+ self.warning("%s:%s had previous issues; skipping!" % (platform, locale))
+ continue
+ original_path = '%s/original/%s/%s/%s' % (dirs['abs_work_dir'], platform, locale, installer_name)
+ for partner in c['partner_config'].keys():
+ repack_path = '%s/unsigned/partner-repacks/%s/%s/%s/%s' % (dirs['abs_work_dir'], partner, platform, locale, installer_name)
+ total_count += 1
+ if self._repack_apk(partner, original_path, repack_path):
+ success_count += 1
+ else:
+ self.add_failure(platform, locale,
+ message="Unable to repack %(platform)s:%(locale)s installer!")
+ self.summarize_success_count(success_count, total_count,
+ message="Repacked %d of %d installers successfully.")
+
+ def _upload(self, dir_name="unsigned/partner-repacks"):
+ c = self.config
+ dirs = self.query_abs_dirs()
+ local_path = os.path.join(dirs['abs_work_dir'], dir_name)
+ rc = self.query_release_config()
+ replace_dict = {
+ 'buildnum': rc['buildnum'],
+ 'version': rc['version'],
+ }
+ remote_path = '%s/%s' % (c['ftp_upload_base_dir'] % replace_dict, dir_name)
+ if self.rsync_upload_directory(local_path, c['ftp_ssh_key'],
+ c['ftp_user'], c['ftp_server'],
+ remote_path):
+ self.return_code +=1
+
+ def upload_unsigned_bits(self):
+ self._upload()
+
+ # passphrase() in AndroidSigningMixin
+ # verify_passphrases() in AndroidSigningMixin
+
+ def preflight_sign(self):
+ if 'passphrase' not in self.actions:
+ self.passphrase()
+ self.verify_passphrases()
+
+ def sign(self):
+ c = self.config
+ rc = self.query_release_config()
+ dirs = self.query_abs_dirs()
+ locales = self.query_locales()
+ success_count = total_count = 0
+ for platform in c['platforms']:
+ for locale in locales:
+ installer_name = c['installer_base_names'][platform] % {'version': rc['version'], 'locale': locale}
+ if self.query_failure(platform, locale):
+ self.warning("%s:%s had previous issues; skipping!" % (platform, locale))
+ continue
+ for partner in c['partner_config'].keys():
+ unsigned_path = '%s/unsigned/partner-repacks/%s/%s/%s/%s' % (dirs['abs_work_dir'], partner, platform, locale, installer_name)
+ signed_dir = '%s/partner-repacks/%s/%s/%s' % (dirs['abs_work_dir'], partner, platform, locale)
+ signed_path = "%s/%s" % (signed_dir, installer_name)
+ total_count +=1
+ self.info("Signing %s %s." % (platform, locale))
+ if not os.path.exists(unsigned_path):
+ self.error("Missing apk %s!" % unsigned_path)
+ continue
+ if self.sign_apk(unsigned_path, c['keystore'],
+ self.store_passphrase, self.key_passphrase,
+ c['key_alias']) != 0:
+ self.add_summary("Unable to sign %s:%s apk!" % (platform, locale), level=FATAL)
+ else:
+ self.mkdir_p(signed_dir)
+ if self.align_apk(unsigned_path, signed_path):
+ self.add_failure(platform, locale,
+ message="Unable to align %(platform)s%(locale)s apk!")
+ self.rmtree(signed_dir)
+ else:
+ success_count += 1
+ self.summarize_success_count(success_count, total_count,
+ message="Signed %d of %d apks successfully.")
+
+ # TODO verify signatures.
+
+ def upload_signed_bits(self):
+ self._upload(dir_name="partner-repacks")
+
+
+
+# main {{{1
+if __name__ == '__main__':
+ mobile_partner_repack = MobilePartnerRepack()
+ mobile_partner_repack.run()
View
5 scripts/mozmill_updates.py
@@ -152,9 +152,9 @@ def run_mozmill(self):
error_list=MozmillErrorList,
)
if os.path.exists(report_json):
- fh = open(report_json)
+ raw_json = self.read_from_file(report_json, verbose=False)
try:
- contents = json.load(fh)
+ contents = json.loads(raw_json)
passed = contents['tests_passed']
failed = contents['tests_failed']
skipped = contents['tests_skipped']
@@ -168,7 +168,6 @@ def run_mozmill(self):
self.add_summary("%s is invalid json!", level="error")
finally:
self.copy_to_upload_dir(report_json)
- fh.close()
else:
self.add_summary("%s on %s channel didn't create report json!" % (version, channel), level="error")
self.return_code += 1
View
2 scripts/peptest.py
@@ -15,7 +15,7 @@
from mozharness.base.log import DEBUG, INFO, WARNING, ERROR, FATAL
from mozharness.base.python import virtualenv_config_options, VirtualenvMixin
from mozharness.base.vcs.vcsbase import MercurialScript
-from mozharness.mozilla.buildbot import BuildbotMixin, TBPL_SUCCESS, TBPL_WARNING, TBPL_FAILURE
+from mozharness.mozilla.buildbot import BuildbotMixin, TBPL_SUCCESS, TBPL_FAILURE
import urlparse
class PepTest(VirtualenvMixin, BuildbotMixin, MercurialScript):
View
188 scripts/sign_android.py
@@ -7,21 +7,20 @@
"""sign_android.py
"""
-# TODO partner repacks downloading/signing
# TODO split out signing and transfers to helper objects so we can do
# the downloads/signing/uploads in parallel, speeding that up
+# TODO retire this script when Android signing-on-demand lands.
from copy import deepcopy
-import getpass
import os
-import subprocess
import sys
# load modules from parent dir
sys.path.insert(1, os.path.dirname(sys.path[0]))
-from mozharness.base.errors import BaseErrorList, JarsignerErrorList, SSHErrorList
-from mozharness.base.log import OutputParser, ERROR, FATAL, IGNORE
+from mozharness.base.errors import BaseErrorList
+from mozharness.base.log import ERROR, FATAL
+from mozharness.base.transfer import TransferMixin
from mozharness.mozilla.release import ReleaseMixin
from mozharness.mozilla.signing import MobileSigningMixin
from mozharness.base.vcs.vcsbase import MercurialScript
@@ -29,15 +28,12 @@
# So far this only references the ftp platform name.
SUPPORTED_PLATFORMS = ["android", "android-xul"]
-TEST_JARSIGNER_ERROR_LIST = [{
- "substr": "jarsigner: unable to open jar file:",
- "level": IGNORE,
-}] + JarsignerErrorList
# SignAndroid {{{1
-class SignAndroid(LocalesMixin, ReleaseMixin, MobileSigningMixin, MercurialScript):
+class SignAndroid(LocalesMixin, ReleaseMixin, MobileSigningMixin,
+ TransferMixin, MercurialScript):
config_options = [[
['--locale',],
{"action": "extend",
@@ -136,11 +132,22 @@ class SignAndroid(LocalesMixin, ReleaseMixin, MobileSigningMixin, MercurialScrip
"type": "string",
"help": "Specify the location of the signing keystore"
}
+ ],[
+ # XXX this is a bit of a hack.
+ # Ideally we'd have fully configured partner repack info with their own
+ # actions so they could be handled discretely.
+ # However, the ideal long term solution will involve signing-on-demand;
+ # this, along with signing support in mobile_partner_repack.py,
+ # seems to be an acceptable interim solution.
+ ['--with-partner-repacks',],
+ {"action": "store_true",
+ "dest": "enable_partner_repacks",
+ "default": False,
+ "help": "Download, sign, and verify partner repacks as well."
+ }
]]
def __init__(self, require_config_file=True):
- self.store_passphrase = os.environ.get('android_storepass')
- self.key_passphrase = os.environ.get('android_keypass')
self.release_config = {}
LocalesMixin.__init__(self)
MobileSigningMixin.__init__(self)
@@ -181,44 +188,9 @@ def query_buildid(self, platform, base_url, buildnum=None, version=None):
return output.replace("buildID=", "")
else:
self.warning("Can't get buildID from %s (try %d)" % (url, count))
- self.critical("Can't get buildID from %s!" % url)
-
- def _sign(self, apk, remove_signature=True, error_list=None):
- c = self.config
- jarsigner = self.query_exe("jarsigner")
- zip_bin = self.query_exe("zip")
- if remove_signature:
- # Get rid of previous signature.
- # TODO error checking, but allow for no META-INF/ in the zipfile.
- self.run_command([zip_bin, apk, '-d', 'META-INF/*'])
- if error_list is None:
- error_list = JarsignerErrorList
- # This needs to run silently, so no run_command() or
- # get_output_from_command() (though I could add a
- # suppress_command_echo=True or something?)
- try:
- p = subprocess.Popen([jarsigner, "-keystore", c['keystore'],
- "-storepass", self.store_passphrase,
- "-keypass", self.key_passphrase,
- apk, c['key_alias']],
- stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT)
- except OSError:
- self.dump_exception("Error while signing %s (missing %s?):" % (apk, jarsigner))
- return -1
- except ValueError:
- self.dump_exception("Popen called with invalid arguments during signing?")
- return -2
- parser = OutputParser(config=self.config, log_obj=self.log_obj,
- error_list=error_list)
- loop = True
- while loop:
- if p.poll() is not None:
- """Avoid losing the final lines of the log?"""
- loop = False
- for line in p.stdout:
- parser.add_lines(line)
- return parser.num_errors
+ # This will break create-snippets if it isn't set.
+ # Might as well fatal().
+ self.fatal("Can't get buildID from %s!" % url)
def add_failure(self, platform, locale, **kwargs):
s = "%s:%s" % (platform, locale)
@@ -231,25 +203,10 @@ def query_failure(self, platform, locale):
return super(SignAndroid, self).query_failure(s)
# Actions {{{2
- def passphrase(self):
- if not self.store_passphrase:
- self.store_passphrase = getpass.getpass("Store passphrase: ")
- if not self.key_passphrase:
- self.key_passphrase = getpass.getpass("Key passphrase: ")
- def verify_passphrases(self):
- self.info("Verifying passphrases...")
- status = self._sign("NOTAREALAPK", remove_signature=False,
- error_list=TEST_JARSIGNER_ERROR_LIST)
- if status == 0:
- self.info("Passphrases are good.")
- elif status < 0:
- self.fatal("Encountered errors while trying to sign!")
- else:
- self.fatal("Unable to verify passphrases!")
-
- def postflight_passphrase(self):
- self.verify_passphrases()
+ # passphrase() is in AndroidSigningMixin
+ # verify_passphrases() is in AndroidSigningMixin
+ # postflight_passphrase() is in AndroidSigningMixin
def pull(self):
c = self.config
@@ -297,6 +254,18 @@ def download_unsigned_bits(self):
success_count += 1
self.summarize_success_count(success_count, total_count,
message="Downloaded %d of %d unsigned apks successfully.")
+ if c['enable_partner_repacks']:
+ self.info("Downloading partner-repacks")
+ if replace_dict.get('platform'):
+ del(replace_dict['platform'])
+ remote_dir = c['ftp_upload_base_dir'] % replace_dict + '/unsigned/partner-repacks'
+ local_dir = os.path.join(dirs['abs_work_dir'], 'unsigned', 'partner-repacks')
+ self.mkdir_p(local_dir)
+ if self.rsync_download_directory(rc['ftp_ssh_key'], rc['ftp_user'],
+ rc['ftp_server'], remote_dir,
+ local_dir):
+ self.add_summary("Unable to download partner repacks!", level=ERROR)
+ self.rmtree(local_dir)
def preflight_sign(self):
if 'passphrase' not in self.actions:
@@ -309,14 +278,13 @@ def sign(self):
dirs = self.query_abs_dirs()
locales = self.query_locales()
success_count = total_count = 0
- zipalign = self.query_exe("zipalign")
for platform in c['platforms']:
for locale in locales:
if self.query_failure(platform, locale):
self.warning("%s:%s had previous issues; skipping!" % (platform, locale))
continue
unsigned_path = '%s/unsigned/%s/%s/gecko.ap_' % (dirs['abs_work_dir'], platform, locale)
- signed_dir = '%s/%s/%s' % (dirs['abs_work_dir'], platform, locale)
+ signed_dir = '%s/signed/%s/%s' % (dirs['abs_work_dir'], platform, locale)
signed_file_name = c['apk_base_name'] % {'version': rc['version'],
'locale': locale}
signed_path = "%s/%s" % (signed_dir, signed_file_name)
@@ -325,14 +293,14 @@ def sign(self):
if not os.path.exists(unsigned_path):
self.error("Missing apk %s!" % unsigned_path)
continue
- if self._sign(unsigned_path) != 0:
- self.add_summary("Unable to sign %s:%s apk!",
+ if self.sign_apk(unsigned_path, c['keystore'],
+ self.store_passphrase, self.key_passphrase,
+ c['key_alias']) != 0:
+ self.add_summary("Unable to sign %s:%s apk!" % (platform, locale),
level=FATAL)
else:
self.mkdir_p(signed_dir)
- if self.run_command([zipalign, '-f', '4',
- unsigned_path, signed_path],
- error_list=BaseErrorList):
+ if self.align_apk(unsigned_path, signed_path):
self.add_failure(platform, locale,
message="Unable to align %(platform)s:%(locale)s apk!")
self.rmtree(signed_dir)
@@ -340,6 +308,37 @@ def sign(self):
success_count += 1
self.summarize_success_count(success_count, total_count,
message="Signed %d of %d apks successfully.")
+ if c['enable_partner_repacks']:
+ total_count = success_count = 0
+ self.info("Signing partner repacks.")
+ for partner in c.get("partners", []):
+ for platform in c.get("partner_platforms", []):
+ for locale in locales:
+ file_name = c['apk_base_name'] % {'version': rc['version'],
+ 'locale': locale}
+ unsigned_path = '%s/unsigned/partner-repacks/%s/%s/%s/%s' % (dirs['abs_work_dir'], partner, platform, locale, file_name)
+ signed_dir = '%s/signed/partner-repacks/%s/%s/%s' % (dirs['abs_work_dir'], partner, platform, locale)
+ signed_path = '%s/%s' % (signed_dir, file_name)
+ total_count += 1
+ self.info("Signing %s %s %s." % (partner, platform, locale))
+ if not os.path.exists(unsigned_path):
+ self.warning("%s doesn't exist; skipping." % unsigned_path)
+ continue
+ if self.sign_apk(unsigned_path, c['keystore'],
+ self.store_passphrase, self.key_passphrase,
+ c['key_alias']) != 0:
+ self.add_summary("Unable to sign %s %s:%s apk!" % (partner, platform, locale),
+ level=ERROR)
+ continue
+ else:
+ self.mkdir_p(signed_dir)
+ if self.align_apk(unsigned_path, signed_path):
+ self.add_summary("Unable to align %s %s:%s apk!" % (partner, platform, locale))
+ self.rmtree(signed_dir)
+ else:
+ success_count += 1
+ self.summarize_success_count(success_count, total_count,
+ message="Signed %d of %d partner apks successfully.")
def verify_signatures(self):
c = self.config
@@ -352,7 +351,7 @@ def verify_signatures(self):
if self.query_failure(platform, locale):
self.warning("%s:%s had previous issues; skipping!" % (platform, locale))
continue
- signed_path = '%s/%s/%s' % (platform, locale,
+ signed_path = 'signed/%s/%s/%s' % (platform, locale,
c['apk_base_name'] % {'version': rc['version'],
'locale': locale})
if not os.path.exists(os.path.join(dirs['abs_work_dir'],
@@ -375,28 +374,20 @@ def verify_signatures(self):
def upload_signed_bits(self):
c = self.config
+ dirs = self.query_abs_dirs()
if not c['platforms']:
self.info("No platforms to rsync! Skipping...")
return
rc = self.query_release_config()
- dirs = self.query_abs_dirs()
- rsync = self.query_exe("rsync")
- ssh = self.query_exe("ssh")
+ signed_dir = os.path.join(dirs['abs_work_dir'], 'signed')
ftp_upload_dir = c['ftp_upload_base_dir'] % {
'version': rc['version'],
'buildnum': rc['buildnum'],
}
- cmd = [ssh, '-oIdentityFile=%s' % rc['ftp_ssh_key'],
- '%s@%s' % (rc['ftp_user'], rc['ftp_server']),
- 'mkdir', '-p', ftp_upload_dir]
- self.run_command(cmd, cwd=dirs['abs_work_dir'],
- error_list=SSHErrorList)
- cmd = [rsync, '-e']
- cmd += ['%s -oIdentityFile=%s' % (ssh, rc['ftp_ssh_key']), '-azv']
- cmd += c['platforms']
- cmd += ["%s@%s:%s/" % (rc['ftp_user'], rc['ftp_server'], ftp_upload_dir)]
- self.run_command(cmd, cwd=dirs['abs_work_dir'],
- error_list=SSHErrorList)
+ if self.rsync_upload_directory(signed_dir, rc['ftp_ssh_key'],
+ rc['ftp_user'], rc['ftp_server'],
+ ftp_upload_dir,):
+ self.return_code += 1
def create_snippets(self):
c = self.config
@@ -479,25 +470,18 @@ def upload_snippets(self):
c = self.config
rc = self.query_release_config()
dirs = self.query_abs_dirs()
- update_dir = os.path.join(dirs['abs_work_dir'], 'update',)
+ update_dir = os.path.join(dirs['abs_work_dir'], 'update')
if not os.path.exists(update_dir):
self.error("No such directory %s! Skipping..." % update_dir)
return
- rsync = self.query_exe("rsync")
- ssh = self.query_exe("ssh")
aus_upload_dir = c['aus_upload_base_dir'] % {
'version': rc['version'],
'buildnum': rc['buildnum'],
}
- cmd = [ssh, '-oIdentityFile=%s' % rc['aus_ssh_key'],
- '%s@%s' % (rc['aus_user'], rc['aus_server']),
- 'mkdir', '-p', aus_upload_dir]
- self.run_command(cmd, cwd=dirs['abs_work_dir'],
- error_list=SSHErrorList)
- cmd = [rsync, '-e']
- cmd += ['%s -oIdentityFile=%s' % (ssh, rc['aus_ssh_key']), '-azv', './']
- cmd += ["%s@%s:%s/" % (rc['aus_user'], rc['aus_server'], aus_upload_dir)]
- self.run_command(cmd, cwd=update_dir, error_list=SSHErrorList)
+ if self.rsync_upload_directory(update_dir, rc['aus_ssh_key'],
+ rc['aus_user'], rc['aus_server'],
+ aus_upload_dir):
+ self.return_code += 1
View
2 unit.sh
@@ -53,7 +53,7 @@ fi
export PYTHONPATH=`env pwd`:$PYTHONPATH
echo "### Running pyflakes"
-pyflakes $MOZHARNESS_PY_FILES $SCRIPTS_PY_FILES
+pyflakes $MOZHARNESS_PY_FILES $SCRIPTS_PY_FILES | grep -v "local variable 'url' is assigned to" | grep -v "redefinition of unused 'json'"
echo "### Running pylint"
pylint -E -e F -f parseable $MOZHARNESS_PY_FILES $SCRIPTS_PY_FILES 2>&1 | egrep -v '(No config file found, using default configuration|Instance of .* has no .* member)'

0 comments on commit d9e20c0

Please sign in to comment.
Something went wrong with that request. Please try again.