Bug 1476372 - Add fetch tasks for raptor chromium builds. r=rwood,glandium,tomprince
authorGregory Mierzwinski <gmierz2@outlook.com>
Wed, 06 Mar 2019 19:45:34 +0000
changeset 463062 225dab563b6d23fb8393547466169b3ca51ede22
parent 463061 3dc5de51e6313dca5675b3c6b501c3f9f9da91b8
child 463063 ea4a69b40a661069ff0d4e212cba859b0717f814
push id112354
push usershindli@mozilla.com
push dateFri, 08 Mar 2019 09:43:34 +0000
treeherdermozilla-inbound@15d3e8135d57 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersrwood, glandium, tomprince
bugs1476372
milestone67.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1476372 - Add fetch tasks for raptor chromium builds. r=rwood,glandium,tomprince Differential Revision: https://phabricator.services.mozilla.com/D21372
.cron.yml
taskcluster/ci/fetch/chromium-fetch.yml
taskcluster/ci/fetch/kind.yml
taskcluster/ci/test/kind.yml
taskcluster/ci/test/raptor-chrome.yml
taskcluster/docker/fetch/Dockerfile
taskcluster/scripts/misc/fetch-chromium.py
taskcluster/taskgraph/target_tasks.py
taskcluster/taskgraph/transforms/fetch.py
taskcluster/taskgraph/transforms/tests.py
testing/mozharness/mozharness/mozilla/testing/raptor.py
--- a/.cron.yml
+++ b/.cron.yml
@@ -106,16 +106,27 @@ jobs:
           target-tasks-method: customv8_update
           optimize-target-tasks: false
       run-on-projects:
           - mozilla-central
       when:
           by-project:
               mozilla-central: [{hour: 10, minute: 30}]
 
+    - name: chromium-update
+      job:
+          type: decision-task
+          treeherder-symbol: Chromium
+          target-tasks-method: chromium_update
+      run-on-projects:
+          - mozilla-central
+      when:
+          by-project:
+              mozilla-central: [{hour: 10, minute: 30}]
+
     - name: bouncer-check
       job:
           type: decision-task
           treeherder-symbol: Rel
           target-tasks-method: cron_bouncer_check
       run-on-projects:
           - mozilla-beta
           - mozilla-release
new file mode 100644
--- /dev/null
+++ b/taskcluster/ci/fetch/chromium-fetch.yml
@@ -0,0 +1,28 @@
+job-defaults:
+    fetch:
+        type: chromium-fetch
+        script: /builds/worker/bin/fetch-chromium.py
+
+linux64-chromium:
+    description: 'Linux64 Chromium Fetch'
+    fetch:
+        platform: linux
+        artifact-name: chrome-linux.tar.bz2
+
+win32-chromium:
+    description: 'Windows32 Chromium Fetch'
+    fetch:
+        platform: win32
+        artifact-name: chrome-win32.tar.bz2
+
+win64-chromium:
+    description: 'Windows64 Chromium Fetch'
+    fetch:
+        platform: win64
+        artifact-name: chrome-win64.tar.bz2
+
+mac-chromium:
+    description: 'MacOSX Chromium Fetch'
+    fetch:
+        platform: mac
+        artifact-name: chrome-mac.tar.bz2
--- a/taskcluster/ci/fetch/kind.yml
+++ b/taskcluster/ci/fetch/kind.yml
@@ -8,8 +8,9 @@ transforms:
     - taskgraph.transforms.fetch:transforms
     - taskgraph.transforms.try_job:transforms
     - taskgraph.transforms.job:transforms
     - taskgraph.transforms.task:transforms
 
 jobs-from:
     - benchmarks.yml
     - toolchains.yml
+    - chromium-fetch.yml
--- a/taskcluster/ci/test/kind.yml
+++ b/taskcluster/ci/test/kind.yml
@@ -24,16 +24,17 @@ transforms:
 jobs-from:
     - awsy.yml
     - compiled.yml
     - firefox-ui.yml
     - marionette.yml
     - misc.yml
     - mochitest.yml
     - raptor.yml
+    - raptor-chrome.yml
     - reftest.yml
     - talos.yml
     - web-platform.yml
     - xpcshell.yml
 
 
 job-defaults:
     require-signed-extensions:
--- a/taskcluster/ci/test/raptor-chrome.yml
+++ b/taskcluster/ci/test/raptor-chrome.yml
@@ -34,16 +34,30 @@ job-defaults:
                 windows10-64-ccov/debug:
                     - raptor/windows_vm_config.py
                 linux64-ccov/opt:
                     - raptor/linux64_config_taskcluster.py
                 android-hw.*:
                     - raptor/android_hw_config.py
                 default:
                     - raptor/linux_config.py
+    fetches:
+        by-test-platform:
+            win.*64.*:
+                fetch:
+                    - win64-chromium
+            win.*32.*:
+                fetch:
+                    - win32-chromium
+            macosx.*:
+                fetch:
+                    - mac-chromium
+            default:
+                fetch:
+                    - linux64-chromium
 
 raptor-tp6-1-chrome:
     description: "Raptor tp6-1 on Chrome"
     try-name: raptor-tp6-1-chrome
     treeherder-symbol: Rap-C(tp6-1)
     run-on-projects: ['try', 'mozilla-central']
     tier: 2
     max-run-time: 1200
@@ -224,47 +238,92 @@ raptor-unity-webgl-chrome:
     treeherder-symbol: Rap-C(ugl)
     run-on-projects: ['try', 'mozilla-central']
     tier: 2
     mozharness:
         extra-options:
             - --test=raptor-unity-webgl
             - --app=chrome
     fetches:
-        fetch:
-            - unity-webgl
+        by-test-platform:
+            win.*64.*:
+                fetch:
+                    - win64-chromium
+                    - unity-webgl
+            win.*32.*:
+                fetch:
+                    - win32-chromium
+                    - unity-webgl
+            macosx.*:
+                fetch:
+                    - mac-chromium
+                    - unity-webgl
+            default:
+                fetch:
+                    - linux64-chromium
+                    - unity-webgl
 
 raptor-wasm-misc-chrome:
     description: "Raptor WASM Misc on Chrome"
     try-name: raptor-wasm-misc-chrome
     treeherder-symbol: Rap-C(wm)
     run-on-projects: ['try', 'mozilla-central']
     tier: 2
     mozharness:
         extra-options:
             - --test=raptor-wasm-misc
             - --app=chrome
     fetches:
-        fetch:
-            - wasm-misc
+        by-test-platform:
+            win.*64.*:
+                fetch:
+                    - win64-chromium
+                    - wasm-misc
+            win.*32.*:
+                fetch:
+                    - win32-chromium
+                    - wasm-misc
+            macosx.*:
+                fetch:
+                    - mac-chromium
+                    - wasm-misc
+            default:
+                fetch:
+                    - linux64-chromium
+                    - wasm-misc
 
 raptor-assorted-dom-chrome:
     description: "Raptor Assorted-Dom on Chrome"
     try-name: raptor-assorted-dom-chrome
     treeherder-symbol: Rap-C(dom)
     run-on-projects: ['try', 'mozilla-central']
     tier: 2
     max-run-time: 1500
     mozharness:
         extra-options:
             - --test=raptor-assorted-dom
             - --app=chrome
     fetches:
-        fetch:
-            - assorted-dom
+        by-test-platform:
+            win.*64.*:
+                fetch:
+                    - win64-chromium
+                    - assorted-dom
+            win.*32.*:
+                fetch:
+                    - win32-chromium
+                    - assorted-dom
+            macosx.*:
+                fetch:
+                    - mac-chromium
+                    - assorted-dom
+            default:
+                fetch:
+                    - linux64-chromium
+                    - assorted-dom
 
 raptor-wasm-godot-chrome:
     description: "Raptor Wasm Godot on Chrome"
     try-name: raptor-wasm-godot-chrome
     treeherder-symbol: Rap-C(godot)
     run-on-projects: ['try', 'mozilla-central']
     tier: 2
     max-run-time: 1500
--- a/taskcluster/docker/fetch/Dockerfile
+++ b/taskcluster/docker/fetch/Dockerfile
@@ -1,9 +1,15 @@
 # %ARG DOCKER_IMAGE_PARENT
 FROM $DOCKER_IMAGE_PARENT
 
 RUN apt-get update && \
     apt-get install \
-      gnupg
+      gnupg \
+      bzip2 \
+      python3-requests \
+      unzip
 
 # %include taskcluster/scripts/misc/fetch-content
 ADD topsrcdir/taskcluster/scripts/misc/fetch-content /builds/worker/bin/fetch-content
+
+# %include taskcluster/scripts/misc/fetch-chromium.py
+ADD topsrcdir/taskcluster/scripts/misc/fetch-chromium.py /builds/worker/bin/fetch-chromium.py
new file mode 100644
--- /dev/null
+++ b/taskcluster/scripts/misc/fetch-chromium.py
@@ -0,0 +1,206 @@
+#!/usr/bin/python3 -u
+# -*- coding: utf-8 -*-
+
+# 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/.
+
+'''
+This script downloads the latest chromium build (or a manually
+defined version) for a given platform. It then uploads the build,
+with the revision of the build stored in a REVISION file.
+'''
+
+from __future__ import absolute_import, print_function
+
+import argparse
+import errno
+import json
+import os
+import shutil
+import subprocess
+import requests
+import tempfile
+
+NEWEST_BASE_URL = 'https://download-chromium.appspot.com/'
+NEWREV_DOWNLOAD_URL = NEWEST_BASE_URL + 'dl/%s?type=snapshots'
+NEWREV_REVISION_URL = NEWEST_BASE_URL + 'rev/%s?type=snapshots'
+
+OLDREV_BASE_URL = 'http://commondatastorage.googleapis.com/chromium-browser-snapshots/'
+OLDREV_DOWNLOAD_URL = OLDREV_BASE_URL + '%s/%s/%s'  # (platform/revision/archive)
+
+CHROMIUM_INFO = {
+    'linux': {
+        'platform': 'Linux_x64',
+        'archive': 'chrome-linux.zip',
+        'result': 'chrome-linux.tar.bz2'
+    },
+    'win32': {
+        'platform': 'Win_x64',
+        'archive': 'chrome-win.zip',
+        'result': 'chrome-win32.tar.bz2'
+    },
+    'win64': {
+        'platform': 'Win_x64',
+        'archive': 'chrome-win.zip',
+        'result': 'chrome-win64.tar.bz2'
+    },
+    'mac': {
+        'platform': 'Mac',
+        'archive': 'chrome-mac.zip',
+        'result': 'chrome-mac.tar.bz2'
+    }
+}
+
+
+def log(msg):
+    print('build-chromium: %s' % msg)
+
+
+def fetch_file(url, filepath):
+    '''Download a file from the given url to a given file.'''
+    size = 4096
+    r = requests.get(url, stream=True)
+    r.raise_for_status()
+
+    with open(filepath, 'wb') as fd:
+        for chunk in r.iter_content(size):
+            fd.write(chunk)
+
+
+def fetch_chromium_revision(platform):
+    '''Get the revision of the latest chromium build. '''
+    chromium_platform = CHROMIUM_INFO[platform]['platform']
+    revision_url = NEWREV_REVISION_URL % chromium_platform
+
+    log(
+        'Getting revision number for latest %s chromium build...' %
+        chromium_platform
+    )
+
+    # Expects a JSON of the form:
+    # {
+    #   'content': '<REVNUM>',
+    #   'last-modified': '<DATE>'
+    # }
+    r = requests.get(revision_url, timeout=30)
+    r.raise_for_status()
+
+    chromium_revision = json.loads(
+        r.content.decode('utf-8')
+    )['content']
+
+    return chromium_revision
+
+
+def fetch_chromium_build(platform, revision, zippath):
+    '''Download a chromium build for a given revision, or the latest. '''
+    use_oldrev = True
+    if not revision:
+        use_oldrev = False
+        revision = fetch_chromium_revision(platform)
+
+    download_platform = CHROMIUM_INFO[platform]['platform']
+    if use_oldrev:
+        chromium_archive = CHROMIUM_INFO[platform]['archive']
+        download_url = OLDREV_DOWNLOAD_URL % (
+            download_platform, revision, chromium_archive
+        )
+    else:
+        download_url = NEWREV_DOWNLOAD_URL % download_platform
+
+    log(
+        'Downloading %s chromium build revision %s...' %
+        (download_platform, revision)
+    )
+
+    fetch_file(download_url, zippath)
+    return revision
+
+
+def build_chromium_archive(platform, revision=None):
+    '''
+    Download and store a chromium build for a given platform.
+
+    Retrieves either the latest version, or uses a pre-defined version if
+    the `--revision` option is given a revision.
+    '''
+    upload_dir = os.environ.get('UPLOAD_DIR')
+    if upload_dir:
+        # Create the upload directory if it doesn't exist.
+        try:
+            log('Creating upload directory in %s...' % os.path.abspath(upload_dir))
+            os.makedirs(upload_dir)
+        except OSError as e:
+            if e.errno != errno.EEXIST:
+                raise
+
+    # Make a temporary location for the file
+    tmppath = tempfile.mkdtemp()
+    tmpzip = os.path.join(tmppath, 'tmp-chrome.zip')
+
+    revision = fetch_chromium_build(platform, revision, tmpzip)
+
+    # Unpack archive in `tmpzip` to store the revision number
+    log('Unpacking archive at: %s to: %s' % (tmpzip, tmppath))
+    unzip_command = ['unzip', '-q', '-o', tmpzip, '-d', tmppath]
+    subprocess.check_call(unzip_command)
+
+    dirs = [
+        d for d in os.listdir(tmppath)
+        if os.path.isdir(os.path.join(tmppath, d)) and d.startswith('chrome-')
+    ]
+
+    if len(dirs) > 1:
+        raise Exception(
+            "Too many directories starting with 'chrome-' after extracting."
+        )
+    elif len(dirs) == 0:
+        raise Exception(
+            "Could not find any directories after extraction of chromium zip."
+        )
+
+    chrome_dir = os.path.join(tmppath, dirs[0])
+    revision_file = os.path.join(chrome_dir, '.REVISION')
+    with open(revision_file, 'w+') as f:
+        f.write(str(revision))
+
+    tar_file = CHROMIUM_INFO[platform]['result']
+    tar_command = ['tar', 'cjf', tar_file, '-C', tmppath, dirs[0]]
+    log(
+        "Added revision to %s file." % revision_file
+    )
+
+    log('Tarring with the command: %s' % str(tar_command))
+    subprocess.check_call(tar_command)
+
+    upload_dir = os.environ.get('UPLOAD_DIR')
+    if upload_dir:
+        # Move the tarball to the output directory for upload.
+        log('Moving %s to the upload directory...' % tar_file)
+        shutil.copy(tar_file, os.path.join(upload_dir, tar_file))
+
+    shutil.rmtree(tmppath)
+
+
+def parse_args():
+    '''Read command line arguments and return options.'''
+    parser = argparse.ArgumentParser()
+    parser.add_argument(
+        '--platform',
+        help='Platform version of chromium to build.',
+        required=True
+    )
+    parser.add_argument(
+        '--revision',
+        help='Revision of chromium to build to get. '
+             '(Defaults to the newest chromium build).',
+        default=None
+    )
+
+    return parser.parse_args()
+
+
+if __name__ == '__main__':
+    args = vars(parse_args())
+    build_chromium_archive(**args)
--- a/taskcluster/taskgraph/target_tasks.py
+++ b/taskcluster/taskgraph/target_tasks.py
@@ -565,16 +565,25 @@ def target_tasks_searchfox(full_task_gra
 
 
 @_target_task('customv8_update')
 def target_tasks_customv8_update(full_task_graph, parameters, graph_config):
     """Select tasks required for building latest d8/v8 version."""
     return ['toolchain-linux64-custom-v8']
 
 
+@_target_task('chromium_update')
+def target_tasks_chromium_update(full_task_graph, parameters, graph_config):
+    """Select tasks required for building latest chromium versions."""
+    return ['fetch-linux64-chromium',
+            'fetch-win32-chromium',
+            'fetch-win64-chromium',
+            'fetch-mac-chromium']
+
+
 @_target_task('pipfile_update')
 def target_tasks_pipfile_update(full_task_graph, parameters, graph_config):
     """Select the set of tasks required to perform nightly in-tree pipfile updates
     """
     def filter(task):
         # For now any task in the repo-update kind is ok
         return task.kind in ['pipfile-update']
     return [l for l, t in full_task_graph.tasks.iteritems() if filter(t)]
--- a/taskcluster/taskgraph/transforms/fetch.py
+++ b/taskcluster/taskgraph/transforms/fetch.py
@@ -2,19 +2,22 @@
 # 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/.
 
 # Support for running tasks that download remote content and re-export
 # it as task artifacts.
 
 from __future__ import absolute_import, unicode_literals
 
+from mozbuild.shellutil import quote as shell_quote
+
 import os
 
 from voluptuous import (
+    Any,
     Optional,
     Required,
 )
 
 import taskgraph
 
 from .base import (
     TransformSequence,
@@ -38,45 +41,61 @@ FETCH_SCHEMA = Schema({
 
     # Relative path (from config.path) to the file the task was defined
     # in.
     Optional('job-from'): basestring,
 
     # Description of the task.
     Required('description'): basestring,
 
-    Required('fetch'): {
-        'type': 'static-url',
-
-        # The URL to download.
-        Required('url'): basestring,
+    Required('fetch'): Any(
+        {
+            'type': 'static-url',
 
-        # The SHA-256 of the downloaded content.
-        Required('sha256'): basestring,
+            # The URL to download.
+            Required('url'): basestring,
 
-        # Size of the downloaded entity, in bytes.
-        Required('size'): int,
+            # The SHA-256 of the downloaded content.
+            Required('sha256'): basestring,
+
+            # Size of the downloaded entity, in bytes.
+            Required('size'): int,
 
-        # GPG signature verification.
-        Optional('gpg-signature'): {
-            # URL where GPG signature document can be obtained. Can contain the
-            # value ``{url}``, which will be substituted with the value from
-            # ``url``.
-            Required('sig-url'): basestring,
-            # Path to file containing GPG public key(s) used to validate
-            # download.
-            Required('key-path'): basestring,
+            # GPG signature verification.
+            Optional('gpg-signature'): {
+                # URL where GPG signature document can be obtained. Can contain the
+                # value ``{url}``, which will be substituted with the value from
+                # ``url``.
+                Required('sig-url'): basestring,
+                # Path to file containing GPG public key(s) used to validate
+                # download.
+                Required('key-path'): basestring,
+            },
+
+            # The name to give to the generated artifact.
+            Optional('artifact-name'): basestring,
+
+            # IMPORTANT: when adding anything that changes the behavior of the task,
+            # it is important to update the digest data used to compute cache hits.
         },
+        {
+            'type': 'chromium-fetch',
 
-        # The name to give to the generated artifact.
-        Optional('artifact-name'): basestring,
+            Required('script'): basestring,
+
+            # Platform type for chromium build
+            Required('platform'): basestring,
 
-        # IMPORTANT: when adding anything that changes the behavior of the task,
-        # it is important to update the digest data used to compute cache hits.
-    },
+            # Chromium revision to obtain
+            Optional('revision'): basestring,
+
+            # The name to give to the generated artifact.
+            Required('artifact-name'): basestring
+        }
+    ),
 })
 
 transforms = TransformSequence()
 transforms.add_validate(FETCH_SCHEMA)
 
 
 @transforms.add
 def process_fetch_job(config, jobs):
@@ -84,16 +103,18 @@ def process_fetch_job(config, jobs):
     for job in jobs:
         if 'fetch' not in job:
             continue
 
         typ = job['fetch']['type']
 
         if typ == 'static-url':
             yield create_fetch_url_task(config, job)
+        elif typ == 'chromium-fetch':
+            yield create_chromium_fetch_task(config, job)
         else:
             # validate() should have caught this.
             assert False
 
 
 def make_base_task(config, name, description, command):
     # Fetch tasks are idempotent and immutable. Have them live for
     # essentially forever.
@@ -184,8 +205,60 @@ def create_fetch_url_task(config, job):
             cache_name=cache_name,
             # We don't include the GPG signature in the digest because it isn't
             # materially important for caching: GPG signatures are supplemental
             # trust checking beyond what the shasum already provides.
             digest_data=[fetch['sha256'], '%d' % fetch['size'], artifact_name],
         )
 
     return task
+
+
+def create_chromium_fetch_task(config, job):
+    name = job['name']
+    fetch = job['fetch']
+    artifact_name = fetch.get('artifact-name')
+
+    workdir = '/builds/worker'
+
+    platform = fetch.get('platform')
+    revision = fetch.get('revision')
+
+    args = '--platform ' + shell_quote(platform)
+    if revision:
+        args += ' --revision ' + shell_quote(revision)
+
+    cmd = [
+        'bash',
+        '-c',
+        'cd {} && '
+        '/usr/bin/python3 {} {}'.format(
+            workdir, fetch['script'], args
+        )
+    ]
+
+    env = {
+        'UPLOAD_DIR': '/builds/worker/artifacts'
+    }
+
+    task = make_base_task(config, name, job['description'], cmd)
+    task['treeherder']['symbol'] = join_symbol('Fetch-URL', name)
+    task['worker']['artifacts'] = [{
+        'type': 'directory',
+        'name': 'public',
+        'path': '/builds/worker/artifacts',
+    }]
+    task['worker']['env'] = env
+    task['attributes']['fetch-artifact'] = 'public/%s' % artifact_name
+
+    if not taskgraph.fast:
+        cache_name = task['label'].replace('{}-'.format(config.kind), '', 1)
+
+        # This adds the level to the index path automatically.
+        add_optimization(
+            config,
+            task,
+            cache_type=CACHE_TYPE,
+            cache_name=cache_name,
+            digest_data=["revision={}".format(revision), "platform={}".format(platform)],
+        )
+
+    return task
--- a/taskcluster/taskgraph/transforms/tests.py
+++ b/taskcluster/taskgraph/transforms/tests.py
@@ -425,19 +425,22 @@ test_description_schema = Schema({
     # target.dmg (Mac), target.apk (Android), target.tar.bz2 (Linux),
     # or target.zip (Windows).
     Optional('target'): optionally_keyed_by(
         'test-platform',
         Any(basestring, None),
     ),
 
     # A list of artifacts to install from 'fetch' tasks.
-    Optional('fetches'): {
-        basestring: [basestring],
-    },
+    Optional('fetches'): optionally_keyed_by(
+        'test-platform',
+        {
+            basestring: [basestring]
+        }
+    ),
 }, required=True)
 
 
 @transforms.add
 def handle_keyed_by_mozharness(config, tests):
     """Resolve a mozharness field if it is keyed by something"""
     for test in tests:
         resolve_keyed_by(test, 'mozharness', item_name=test['test-name'])
@@ -742,16 +745,17 @@ def handle_keyed_by(config, tests):
         'mozharness.chunked',
         'mozharness.config',
         'mozharness.extra-options',
         'mozharness.requires-signed-builds',
         'mozharness.script',
         'workdir',
         'worker-type',
         'virtualization',
+        'fetches',
     ]
     for test in tests:
         for field in fields:
             resolve_keyed_by(test, field, item_name=test['test-name'],
                              project=config.params['project'])
         yield test
 
 
--- a/testing/mozharness/mozharness/mozilla/testing/raptor.py
+++ b/testing/mozharness/mozharness/mozilla/testing/raptor.py
@@ -6,17 +6,16 @@ from __future__ import absolute_import, 
 
 import argparse
 import copy
 import json
 import os
 import re
 import sys
 import subprocess
-import time
 
 from shutil import copyfile
 
 import mozharness
 
 from mozharness.base.errors import PythonErrorList
 from mozharness.base.log import OutputParser, DEBUG, ERROR, CRITICAL, INFO
 from mozharness.mozilla.testing.testbase import TestingMixin, testing_config_options
@@ -246,93 +245,41 @@ class Raptor(TestingMixin, MercurialScri
         abs_dirs['abs_blob_upload_dir'] = os.path.join(abs_dirs['abs_work_dir'],
                                                        'blobber_upload_dir')
         abs_dirs['abs_test_install_dir'] = os.path.join(abs_dirs['abs_work_dir'], 'tests')
 
         self.abs_dirs = abs_dirs
         return self.abs_dirs
 
     def install_chrome(self):
-        # temporary hack to install google chrome in production; until chrome is in our CI
+        '''install google chrome in production; installation
+        requirements depend on the platform'''
         if self.app != "chrome":
             self.info("Google Chrome is not required")
             return
 
         if self.config.get("run_local"):
             self.info("expecting Google Chrome to be pre-installed locally")
             return
 
-        # in production we can put the chrome build in mozharness/mozilla/testing/chrome
-        self.chrome_dest = os.path.join(here, 'chrome')
-
-        # mozharness/base/script.py.self.platform_name will return one of:
-        # 'linux64', 'linux', 'macosx', 'win64', 'win32'
-
-        base_url = "http://commondatastorage.googleapis.com/chromium-browser-snapshots"
-
-        # note: temporarily use a specified chromium revision number to download; however
-        # in the future we will be using a fetch task to get a new chromium (Bug 1476372)
+        self.info("Getting fetched chromium build")
+        self.chrome_dest = os.path.normpath(os.path.abspath(os.environ['MOZ_FETCHES_DIR']))
 
         if 'mac' in self.platform_name():
-            # for now hardcoding a revision; but change this to update to newer version; from:
-            # http://commondatastorage.googleapis.com/chromium-browser-snapshots/Mac/LAST_CHANGE
-
-            # Note: Using an older version of Chromium on OSX b/c of an issue with a pop-up
-            # dialog appearing with newer Chromium on OSX; please see:
-            # Bug 1520523 - Update Chromium version running with Raptor in production
-            chromium_rev = "634618"
-            chrome_archive_file = "chrome-mac.zip"
-            chrome_url = "%s/Mac/%s/%s" % (base_url, chromium_rev, chrome_archive_file)
             self.chrome_path = os.path.join(self.chrome_dest, 'chrome-mac', 'Chromium.app',
                                             'Contents', 'MacOS', 'Chromium')
 
         elif 'linux' in self.platform_name():
-            # for now hardcoding a revision; but change this to update to newer version; from:
-            # http://commondatastorage.googleapis.com/chromium-browser-snapshots/Linux_x64/LAST_CHANGE
-            chromium_rev = "634637"
-            chrome_archive_file = "chrome-linux.zip"
-            chrome_url = "%s/Linux_x64/%s/%s" % (base_url, chromium_rev, chrome_archive_file)
             self.chrome_path = os.path.join(self.chrome_dest, 'chrome-linux', 'chrome')
 
         else:
-            # windows 7/10
-            # for now hardcoding a revision; but change this to update to newer version; from:
-            # http://commondatastorage.googleapis.com/chromium-browser-snapshots/Win_x64/LAST_CHANGE
-            chromium_rev = "634634"
-            chrome_archive_file = "chrome-win.zip"  # same zip name for win32/64
-
-            # one url for Win x64/32
-            chrome_url = "%s/Win_x64/%s/%s" % (base_url, chromium_rev, chrome_archive_file)
-
             self.chrome_path = os.path.join(self.chrome_dest, 'chrome-win', 'Chrome.exe')
 
-        chrome_archive = os.path.join(self.chrome_dest, chrome_archive_file)
-
-        self.info("installing google chrome - temporary install hack")
-        self.info("chrome archive is: %s" % chrome_archive)
         self.info("chrome dest is: %s" % self.chrome_dest)
-
-        if os.path.exists(self.chrome_path):
-            self.info("google chrome binary already exists at: %s" % self.chrome_path)
-            return
-
-        if not os.path.exists(chrome_archive):
-            # download the chrome installer
-            self.download_file(chrome_url, parent_dir=self.chrome_dest)
-
-        commands = []
-        commands.append(['unzip', '-q', '-o', chrome_archive_file, '-d', self.chrome_dest])
-
-        # now run the commands to unpack / install google chrome
-        for next_command in commands:
-            return_code = self.run_command(next_command, cwd=self.chrome_dest)
-            time.sleep(30)
-            if return_code not in [0]:
-                self.info("abort: failed to install %s to %s with command: %s"
-                          % (chrome_archive_file, self.chrome_dest, next_command))
+        self.info("chrome path is: %s" % self.chrome_path)
 
         # now ensure chrome binary exists
         if os.path.exists(self.chrome_path):
             self.info("successfully installed Google Chrome to: %s" % self.chrome_path)
         else:
             self.info("abort: failed to install Google Chrome")
 
     def raptor_options(self, args=None, **kw):