Bug 1359976: base worker payload generation on worker-type; r=wcosta r=aki draft
authorDustin J. Mitchell <dustin@mozilla.com>
Mon, 08 May 2017 22:53:50 +0000
changeset 586630 4cdfe6b8d9874b0c156671515b213d820b48482f
parent 586629 56f69a946970e5c8c37b4aea1374e4ac31b48600
child 631052 667726167fba27097a2fd1bf3f5e9409753c2893
push id61474
push userdmitchell@mozilla.com
push dateTue, 30 May 2017 20:40:03 +0000
reviewerswcosta, aki
bugs1359976
milestone55.0a1
Bug 1359976: base worker payload generation on worker-type; r=wcosta r=aki To date we have variously specified both worker-type and worker-implementation, often manually coordinated. We also embedded a few awkward assumptions such as that the native engine only runs on OS X. But a worker type has one and only one implementation, and that implementation is stable over time (as changing it would require simultaneous landings on all trees). Instead, this change makes worker-type the primary configuration, and derives both a worker implementation (defining the payload format) and worker OS (determining what to include in the payload) from that value. The derivation occurs when deciding how to implement a particular job, where the run_using functions are distinguished by worker implementation. The two-part logic to determine how and where to run a test task based on its platform is combined into a single transform, `set_worker_type`. This contains some other related changes: - MOZ_AUTOMATION is set in specific jobs, rather than everywhere docker-worker is used - the URL to test packages is factored out into a shared function - docker-worker test defaults are applied in `mozharness_test.py` - the WORKER_TYPE array in `task.py`, formerly mixing two types of keys, is split - the 'invalid' workerType is assigned an 'invalid' implementation - all tasks that do not use job descriptions but use docker-worker, etc. have `worker.os` added Tested to not produce a substantially different taskgraph for a regular push, a try push, or a nightly cron. MozReview-Commit-ID: LDHrmrpBo7I
taskcluster/ci/android-stuff/kind.yml
taskcluster/ci/artifact-build/kind.yml
taskcluster/ci/build/android.yml
taskcluster/ci/build/linux.yml
taskcluster/ci/build/macosx.yml
taskcluster/ci/build/windows.yml
taskcluster/ci/hazard/kind.yml
taskcluster/ci/source-test/doc.yml
taskcluster/ci/source-test/mozlint.yml
taskcluster/ci/source-test/python-tests.yml
taskcluster/ci/source-test/webidl.yml
taskcluster/ci/spidermonkey/kind.yml
taskcluster/ci/static-analysis/kind.yml
taskcluster/ci/toolchain/linux.yml
taskcluster/ci/toolchain/macosx.yml
taskcluster/ci/toolchain/windows.yml
taskcluster/ci/upload-symbols/kind.yml
taskcluster/ci/valgrind/kind.yml
taskcluster/taskgraph/transforms/build.py
taskcluster/taskgraph/transforms/docker_image.py
taskcluster/taskgraph/transforms/job/__init__.py
taskcluster/taskgraph/transforms/job/mozharness.py
taskcluster/taskgraph/transforms/job/mozharness_test.py
taskcluster/taskgraph/transforms/job/toolchain.py
taskcluster/taskgraph/transforms/l10n.py
taskcluster/taskgraph/transforms/repackage.py
taskcluster/taskgraph/transforms/task.py
taskcluster/taskgraph/transforms/tests.py
taskcluster/taskgraph/util/workertypes.py
--- a/taskcluster/ci/android-stuff/kind.yml
+++ b/taskcluster/ci/android-stuff/kind.yml
@@ -22,16 +22,17 @@ jobs:
         treeherder:
             platform: android-4-0-armv7-api15/opt
             kind: other
             tier: 2
             symbol: tc(Deps)
         worker-type: aws-provisioner-v1/gecko-{level}-b-android
         worker:
             implementation: docker-worker
+            os: linux
             docker-image: {in-tree: android-gradle-build}
             env:
                 GRADLE_USER_HOME: "/home/worker/workspace/build/src/dotgradle-online"
                 MH_BUILD_POOL: "taskcluster"
                 MH_CUSTOM_BUILD_VARIANT_CFG: "api-15-gradle-dependencies"
                 MOZHARNESS_ACTIONS: "get-secrets build multi-l10n update"
                 MOZHARNESS_CONFIG: >
                     builds/releng_base_android_64_builds.py
@@ -67,16 +68,17 @@ jobs:
         treeherder:
             platform: android-4-0-armv7-api15/opt
             kind: test
             tier: 2
             symbol: tc(test)
         worker-type: aws-provisioner-v1/gecko-{level}-b-android
         worker:
             implementation: docker-worker
+            os: linux
             docker-image: {in-tree: desktop-build}
             env:
                 GRADLE_USER_HOME: "/home/worker/workspace/build/src/dotgradle"
                 MH_BUILD_POOL: "taskcluster"
                 MH_CUSTOM_BUILD_VARIANT_CFG: "android-test"
                 MOZHARNESS_ACTIONS: "get-secrets build multi-l10n update"
                 MOZHARNESS_CONFIG: >
                     builds/releng_base_android_64_builds.py
@@ -113,16 +115,17 @@ jobs:
         treeherder:
             platform: android-4-0-armv7-api15/opt
             kind: test
             tier: 2
             symbol: tc(lint)
         worker-type: aws-provisioner-v1/gecko-{level}-b-android
         worker:
             implementation: docker-worker
+            os: linux
             docker-image: {in-tree: desktop-build}
             env:
                 GRADLE_USER_HOME: "/home/worker/workspace/build/src/dotgradle"
                 MH_BUILD_POOL: "taskcluster"
                 MH_CUSTOM_BUILD_VARIANT_CFG: "android-lint"
                 MOZHARNESS_ACTIONS: "get-secrets build multi-l10n update"
                 MOZHARNESS_CONFIG: >
                     builds/releng_base_android_64_builds.py
@@ -181,16 +184,17 @@ jobs:
         treeherder:
             platform: android-4-0-armv7-api15/opt
             kind: test
             tier: 2
             symbol: tc(checkstyle)
         worker-type: aws-provisioner-v1/gecko-{level}-b-android
         worker:
             implementation: docker-worker
+            os: linux
             docker-image: {in-tree: desktop-build}
             env:
                 GRADLE_USER_HOME: "/home/worker/workspace/build/src/dotgradle"
                 MH_BUILD_POOL: "taskcluster"
                 MH_CUSTOM_BUILD_VARIANT_CFG: "android-checkstyle"
                 MOZHARNESS_ACTIONS: "get-secrets build multi-l10n update"
                 MOZHARNESS_CONFIG: >
                     builds/releng_base_android_64_builds.py
@@ -230,16 +234,17 @@ jobs:
         treeherder:
             platform: android-4-0-armv7-api15/opt
             kind: test
             tier: 2
             symbol: tc(findbugs)
         worker-type: aws-provisioner-v1/gecko-{level}-b-android
         worker:
             implementation: docker-worker
+            os: linux
             docker-image: {in-tree: desktop-build}
             env:
                 GRADLE_USER_HOME: "/home/worker/workspace/build/src/dotgradle"
                 MH_BUILD_POOL: "taskcluster"
                 MH_CUSTOM_BUILD_VARIANT_CFG: "android-findbugs"
                 MOZHARNESS_ACTIONS: "get-secrets build multi-l10n update"
                 MOZHARNESS_CONFIG: >
                     builds/releng_base_android_64_builds.py
--- a/taskcluster/ci/artifact-build/kind.yml
+++ b/taskcluster/ci/artifact-build/kind.yml
@@ -17,17 +17,16 @@ jobs:
             job-name: linux64-artifact-opt
         treeherder:
             platform: linux64/opt
             kind: build
             symbol: AB
             tier: 2
         worker-type: aws-provisioner-v1/gecko-{level}-b-linux
         worker:
-            implementation: docker-worker
             docker-image: {in-tree: desktop-build}
             max-run-time: 36000
         run:
             using: mozharness
             actions: [get-secrets build generate-build-stats]
             config:
                 - builds/releng_sub_linux_configs/64_artifact.py
                 - balrog/production.py
--- a/taskcluster/ci/build/android.yml
+++ b/taskcluster/ci/build/android.yml
@@ -3,17 +3,16 @@ android-api-15/debug:
     index:
         product: mobile
         job-name: android-api-15-debug
     treeherder:
         platform: android-4-0-armv7-api15/debug
         symbol: tc(B)
     worker-type: aws-provisioner-v1/gecko-{level}-b-android
     worker:
-        implementation: docker-worker
         max-run-time: 7200
     run:
         using: mozharness
         actions: [get-secrets build generate-build-stats multi-l10n update]
         config:
             - builds/releng_base_android_64_builds.py
             - disable_signing.py
             - platform_supports_post_upload_to_latest.py
@@ -27,17 +26,16 @@ android-x86/opt:
     index:
         product: mobile
         job-name: android-x86-opt
     treeherder:
         platform: android-4-2-x86/opt
         symbol: tc(B)
     worker-type: aws-provisioner-v1/gecko-{level}-b-android
     worker:
-        implementation: docker-worker
         max-run-time: 7200
     run:
         using: mozharness
         actions: [get-secrets build generate-build-stats multi-l10n update]
         config:
             - builds/releng_base_android_64_builds.py
             - disable_signing.py
             - platform_supports_post_upload_to_latest.py
@@ -54,17 +52,16 @@ android-x86-nightly/opt:
         product: mobile
         job-name: android-x86-opt
         type: nightly
     treeherder:
         platform: android-4-2-x86/opt
         symbol: tc(N)
     worker-type: aws-provisioner-v1/gecko-{level}-b-android
     worker:
-        implementation: docker-worker
         max-run-time: 7200
     run:
         using: mozharness
         actions: [get-secrets build generate-build-stats multi-l10n update]
         config:
             - builds/releng_base_android_64_builds.py
             - disable_signing.py
             - platform_supports_post_upload_to_latest.py
@@ -79,17 +76,16 @@ android-api-15/opt:
     index:
         product: mobile
         job-name: android-api-15-opt
     treeherder:
         platform: android-4-0-armv7-api15/opt
         symbol: tc(B)
     worker-type: aws-provisioner-v1/gecko-{level}-b-android
     worker:
-        implementation: docker-worker
         max-run-time: 7200
     run:
         using: mozharness
         actions: [get-secrets build generate-build-stats multi-l10n update]
         config:
             - builds/releng_base_android_64_builds.py
             - disable_signing.py
             - platform_supports_post_upload_to_latest.py
@@ -106,17 +102,16 @@ android-api-15-nightly/opt:
         product: mobile
         job-name: android-api-15-opt
         type: nightly-with-multi-l10n
     treeherder:
         platform: android-4-0-armv7-api15/opt
         symbol: tc(N)
     worker-type: aws-provisioner-v1/gecko-{level}-b-android
     worker:
-        implementation: docker-worker
         max-run-time: 7200
     run:
         using: mozharness
         actions: [get-secrets build generate-build-stats multi-l10n update]
         config:
             - builds/releng_base_android_64_builds.py
             - disable_signing.py
             - platform_supports_post_upload_to_latest.py
@@ -131,17 +126,16 @@ android-x86-old-id/opt:
     index:
         product: mobile
         job-name: android-x86-old-id-opt
     treeherder:
         platform: android-4-2-x86-old-id/opt
         symbol: tc(B)
     worker-type: aws-provisioner-v1/gecko-{level}-b-android
     worker:
-        implementation: docker-worker
         max-run-time: 7200
     run:
         using: mozharness
         actions: [get-secrets build multi-l10n update]
         config:
             - builds/releng_base_android_64_builds.py
             - disable_signing.py
             - platform_supports_post_upload_to_latest.py
@@ -159,17 +153,16 @@ android-x86-old-id-nightly/opt:
         product: mobile
         job-name: android-x86-old-id-opt
         type: nightly
     treeherder:
         platform: android-4-2-x86-old-id/opt
         symbol: tc(N)
     worker-type: aws-provisioner-v1/gecko-{level}-b-android
     worker:
-        implementation: docker-worker
         max-run-time: 7200
     run:
         using: mozharness
         actions: [get-secrets build multi-l10n update]
         config:
             - builds/releng_base_android_64_builds.py
             - disable_signing.py
             - platform_supports_post_upload_to_latest.py
@@ -185,17 +178,16 @@ android-api-15-old-id/opt:
     index:
         product: mobile
         job-name: android-api-15-old-id-opt
     treeherder:
         platform: android-4-0-armv7-api15-old-id/opt
         symbol: tc(B)
     worker-type: aws-provisioner-v1/gecko-{level}-b-android
     worker:
-        implementation: docker-worker
         max-run-time: 7200
     run:
         using: mozharness
         actions: [get-secrets build multi-l10n update]
         config:
             - builds/releng_base_android_64_builds.py
             - disable_signing.py
             - platform_supports_post_upload_to_latest.py
@@ -213,17 +205,16 @@ android-api-15-old-id-nightly/opt:
         product: mobile
         job-name: android-api-15-old-id-opt
         type: nightly-with-multi-l10n
     treeherder:
         platform: android-4-0-armv7-api15-old-id/opt
         symbol: tc(N)
     worker-type: aws-provisioner-v1/gecko-{level}-b-android
     worker:
-        implementation: docker-worker
         max-run-time: 7200
     run:
         using: mozharness
         actions: [get-secrets build multi-l10n update]
         config:
             - builds/releng_base_android_64_builds.py
             - disable_signing.py
             - platform_supports_post_upload_to_latest.py
@@ -240,17 +231,16 @@ android-api-15-gradle/opt:
         product: mobile
         job-name: android-api-15-gradle-opt
     treeherder:
         platform: android-api-15-gradle/opt
         symbol: tc(Bg)
         tier: 2
     worker-type: aws-provisioner-v1/gecko-{level}-b-android
     worker:
-        implementation: docker-worker
         max-run-time: 7200
         env:
             # Bug 1292762 - Set GRADLE_USER_HOME to avoid sdk-manager-plugin intermittent
             GRADLE_USER_HOME: /home/worker/workspace/build/src/dotgradle
         artifacts:
           - name: public/android/maven
             path: /home/worker/workspace/build/src/obj-firefox/gradle/build/mobile/android/geckoview/maven/
             type: directory
--- a/taskcluster/ci/build/linux.yml
+++ b/taskcluster/ci/build/linux.yml
@@ -3,17 +3,16 @@ linux64/opt:
     index:
         product: firefox
         job-name: linux64-opt
     treeherder:
         platform: linux64/opt
         symbol: tc(B)
     worker-type: aws-provisioner-v1/gecko-{level}-b-linux
     worker:
-        implementation: docker-worker
         max-run-time: 36000
     run:
         using: mozharness
         actions: [get-secrets build generate-build-stats check-test update]
         config:
             - builds/releng_base_linux_64_builds.py
             - balrog/production.py
         script: "mozharness/scripts/fx_desktop_build.py"
@@ -26,17 +25,16 @@ linux64/pgo:
     index:
         product: firefox
         job-name: linux64-pgo
     treeherder:
         platform: linux64/pgo
         symbol: tc(B)
     worker-type: aws-provisioner-v1/gecko-{level}-b-linux
     worker:
-        implementation: docker-worker
         max-run-time: 36000
     coalesce-name: linux64-pgo
     run:
         using: mozharness
         actions: [get-secrets build generate-build-stats check-test update]
         options: [enable-pgo]
         config:
             - builds/releng_base_linux_64_builds.py
@@ -51,17 +49,16 @@ linux64/debug:
     index:
         product: firefox
         job-name: linux64-debug
     treeherder:
         platform: linux64/debug
         symbol: tc(B)
     worker-type: aws-provisioner-v1/gecko-{level}-b-linux
     worker:
-        implementation: docker-worker
         max-run-time: 36000
     run:
         using: mozharness
         actions: [get-secrets build generate-build-stats check-test update]
         config:
             - builds/releng_base_linux_64_builds.py
             - balrog/production.py
         script: "mozharness/scripts/fx_desktop_build.py"
@@ -78,17 +75,16 @@ linux64-devedition-nightly/opt:
         product: devedition
         job-name: linux64-opt
         type: nightly
     treeherder:
         platform: linux64-devedition/opt
         symbol: tc(N)
     worker-type: aws-provisioner-v1/gecko-{level}-b-linux
     worker:
-        implementation: docker-worker
         max-run-time: 36000
     run:
         using: mozharness
         actions: [get-secrets build generate-build-stats check-test update]
         config:
             - builds/releng_base_linux_64_builds.py
             - disable_signing.py
             - balrog/production.py
@@ -104,17 +100,16 @@ linux/opt:
     index:
         product: firefox
         job-name: linux-opt
     treeherder:
         platform: linux32/opt
         symbol: tc(B)
     worker-type: aws-provisioner-v1/gecko-{level}-b-linux
     worker:
-        implementation: docker-worker
         max-run-time: 36000
     coalesce-name: opt_linux32
     run:
         using: mozharness
         actions: [get-secrets build generate-build-stats check-test update]
         config:
             - builds/releng_base_linux_32_builds.py
             - balrog/production.py
@@ -128,17 +123,16 @@ linux/debug:
     index:
         product: firefox
         job-name: linux-debug
     treeherder:
         platform: linux32/debug
         symbol: tc(B)
     worker-type: aws-provisioner-v1/gecko-{level}-b-linux
     worker:
-        implementation: docker-worker
         max-run-time: 36000
     coalesce-name: dbg_linux32
     run:
         using: mozharness
         actions: [get-secrets build generate-build-stats check-test update]
         config:
             - builds/releng_base_linux_32_builds.py
             - balrog/production.py
@@ -153,17 +147,16 @@ linux/pgo:
     index:
         product: firefox
         job-name: linux-pgo
     treeherder:
         platform: linux32/pgo
         symbol: tc(B)
     worker-type: aws-provisioner-v1/gecko-{level}-b-linux
     worker:
-        implementation: docker-worker
         max-run-time: 36000
     coalesce-name: linux32-pgo
     run:
         using: mozharness
         actions: [get-secrets build generate-build-stats check-test update]
         options: [enable-pgo]
         config:
             - builds/releng_base_linux_32_builds.py
@@ -181,17 +174,16 @@ linux-devedition-nightly/opt:
         product: devedition
         job-name: linux-opt
         type: nightly
     treeherder:
         platform: linux32-devedition/opt
         symbol: tc(N)
     worker-type: aws-provisioner-v1/gecko-{level}-b-linux
     worker:
-        implementation: docker-worker
         max-run-time: 36000
     run:
         using: mozharness
         actions: [get-secrets build generate-build-stats check-test update]
         config:
             - builds/releng_base_linux_32_builds.py
             - disable_signing.py
             - balrog/production.py
@@ -210,17 +202,16 @@ linux-nightly/opt:
         product: firefox
         job-name: linux-opt
         type: nightly
     treeherder:
         platform: linux32/opt
         symbol: tc(N)
     worker-type: aws-provisioner-v1/gecko-{level}-b-linux
     worker:
-        implementation: docker-worker
         max-run-time: 36000
     run:
         using: mozharness
         actions: [get-secrets build generate-build-stats check-test update]
         config:
             - builds/releng_base_linux_32_builds.py
             - disable_signing.py
             - taskcluster_nightly.py
@@ -235,17 +226,16 @@ linux64-asan/opt:
     index:
         product: firefox
         job-name: linux64-asan-opt
     treeherder:
         platform: linux64/asan
         symbol: tc(Bo)
     worker-type: aws-provisioner-v1/gecko-{level}-b-linux
     worker:
-        implementation: docker-worker
         max-run-time: 36000
     run:
         using: mozharness
         actions: [get-secrets build generate-build-stats check-test update]
         config:
             - builds/releng_base_linux_64_builds.py
             - balrog/production.py
         script: "mozharness/scripts/fx_desktop_build.py"
@@ -259,17 +249,16 @@ linux64-asan/debug:
     index:
         product: firefox
         job-name: linux64-asan-debug
     treeherder:
         platform: linux64/asan
         symbol: tc(Bd)
     worker-type: aws-provisioner-v1/gecko-{level}-b-linux
     worker:
-        implementation: docker-worker
         max-run-time: 36000
     run:
         using: mozharness
         actions: [get-secrets build generate-build-stats check-test update]
         config:
             - builds/releng_base_linux_64_builds.py
             - balrog/production.py
         script: "mozharness/scripts/fx_desktop_build.py"
@@ -286,17 +275,16 @@ linux64-nightly/opt:
         product: firefox
         job-name: linux64-opt
         type: nightly
     treeherder:
         platform: linux64/opt
         symbol: tc(N)
     worker-type: aws-provisioner-v1/gecko-{level}-b-linux
     worker:
-        implementation: docker-worker
         max-run-time: 36000
     run:
         using: mozharness
         actions: [get-secrets build generate-build-stats check-test update]
         config:
             - builds/releng_base_linux_64_builds.py
             - disable_signing.py
             - taskcluster_nightly.py
@@ -311,17 +299,16 @@ linux64-stylo/opt:
         product: firefox
         job-name: linux64-stylo-opt
     treeherder:
         platform: linux64-stylo/opt
         symbol: tc(B)
         tier: 2
     worker-type: aws-provisioner-v1/gecko-{level}-b-linux
     worker:
-        implementation: docker-worker
         max-run-time: 3600
     run:
         using: mozharness
         actions: [get-secrets build generate-build-stats check-test update]
         config:
             - builds/releng_base_linux_64_builds.py
             - balrog/production.py
         script: "mozharness/scripts/fx_desktop_build.py"
@@ -337,17 +324,16 @@ linux64-stylo/debug:
         product: firefox
         job-name: linux64-stylo-debug
     treeherder:
         platform: linux64-stylo/debug
         symbol: tc(B)
         tier: 2
     worker-type: aws-provisioner-v1/gecko-{level}-b-linux
     worker:
-        implementation: docker-worker
         max-run-time: 3600
     run:
         using: mozharness
         actions: [get-secrets build generate-build-stats check-test update]
         config:
             - builds/releng_base_linux_64_builds.py
             - balrog/production.py
         script: "mozharness/scripts/fx_desktop_build.py"
@@ -364,17 +350,16 @@ linux64-jsdcov/opt:
         job-name: linux64-jsdcov-opt
     treeherder:
         platform: linux64-jsdcov/opt
         symbol: tc(B)
         tier: 2
     run-on-projects: [ ]
     worker-type: aws-provisioner-v1/gecko-{level}-b-linux
     worker:
-        implementation: docker-worker
         max-run-time: 36000
     run:
         using: mozharness
         actions: [get-secrets build generate-build-stats check-test update]
         config:
             - builds/releng_base_linux_64_builds.py
             - balrog/production.py
         script: "mozharness/scripts/fx_desktop_build.py"
@@ -390,17 +375,16 @@ linux64-ccov/opt:
     needs-sccache: false
     treeherder:
         platform: linux64-ccov/opt
         symbol: tc(B)
         tier: 2
     run-on-projects: [ ]
     worker-type: aws-provisioner-v1/gecko-{level}-b-linux
     worker:
-        implementation: docker-worker
         max-run-time: 36000
     run:
         using: mozharness
         actions: [get-secrets build generate-build-stats check-test update]
         config:
             - builds/releng_base_linux_64_builds.py
             - balrog/production.py
         script: "mozharness/scripts/fx_desktop_build.py"
@@ -415,17 +399,16 @@ linux64-add-on-devel/opt:
         product: firefox
         job-name: linux64-add-on-devel
     treeherder:
         platform: linux64-add-on-devel/opt
         symbol: tc(B)
         tier: 2
     worker-type: aws-provisioner-v1/gecko-{level}-b-linux
     worker:
-        implementation: docker-worker
         max-run-time: 36000
     run:
         using: mozharness
         actions: [get-secrets build generate-build-stats check-test update]
         config:
             - builds/releng_base_linux_64_builds.py
             - balrog/production.py
         script: "mozharness/scripts/fx_desktop_build.py"
@@ -441,17 +424,16 @@ linux-qr/opt:
         product: firefox
         job-name: linux-qr-opt
     treeherder:
         platform: linux32-qr/opt
         symbol: tc(B)
         tier: 2
     worker-type: aws-provisioner-v1/gecko-{level}-b-linux
     worker:
-        implementation: docker-worker
         max-run-time: 36000
     run:
         using: mozharness
         actions: [get-secrets build generate-build-stats check-test update]
         config:
             - builds/releng_base_linux_32_builds.py
             - balrog/production.py
         script: "mozharness/scripts/fx_desktop_build.py"
@@ -467,17 +449,16 @@ linux-qr/debug:
         product: firefox
         job-name: linux-qr-debug
     treeherder:
         platform: linux32-qr/debug
         symbol: tc(B)
         tier: 2
     worker-type: aws-provisioner-v1/gecko-{level}-b-linux
     worker:
-        implementation: docker-worker
         max-run-time: 36000
     coalesce-name: dbg_linux32
     run:
         using: mozharness
         actions: [get-secrets build generate-build-stats check-test update]
         config:
             - builds/releng_base_linux_32_builds.py
             - balrog/production.py
--- a/taskcluster/ci/build/macosx.yml
+++ b/taskcluster/ci/build/macosx.yml
@@ -4,17 +4,16 @@ macosx64/debug:
         product: firefox
         job-name: macosx64-debug
     treeherder:
         platform: osx-10-7/debug
         symbol: tc(B)
         tier: 1
     worker-type: aws-provisioner-v1/gecko-{level}-b-macosx64
     worker:
-        implementation: docker-worker
         max-run-time: 36000
     run:
         using: mozharness
         actions: [get-secrets build generate-build-stats update]
         config:
             - builds/releng_base_mac_64_cross_builds.py
             - balrog/production.py
         script: "mozharness/scripts/fx_desktop_build.py"
@@ -27,18 +26,16 @@ macosx64/opt:
     index:
         product: firefox
         job-name: macosx64-opt
     treeherder:
         platform: osx-10-7/opt
         symbol: tc(B)
         tier: 2
     worker-type: buildbot-bridge/buildbot-bridge
-    worker:
-        implementation: buildbot-bridge
     run:
         using: mozharness
         actions: [get-secrets build generate-build-stats update]
         config:
             - builds/releng_base_mac_64_builds.py
             - balrog/production.py
         script: "mozharness/scripts/fx_desktop_build.py"
         secrets: true
@@ -50,17 +47,16 @@ macosx64-qr/debug:
         product: firefox
         job-name: macosx64-qr-debug
     treeherder:
         platform: osx-10-7-qr/debug
         symbol: tc(B)
         tier: 2
     worker-type: aws-provisioner-v1/gecko-{level}-b-macosx64
     worker:
-        implementation: docker-worker
         max-run-time: 36000
     run:
         using: mozharness
         actions: [get-secrets build generate-build-stats update]
         config:
             - builds/releng_base_mac_64_cross_builds.py
             - balrog/production.py
         script: "mozharness/scripts/fx_desktop_build.py"
@@ -75,17 +71,16 @@ macosx64-qr/opt:
         product: firefox
         job-name: macosx64-qr-opt
     treeherder:
         platform: osx-10-7-qr/opt
         symbol: tc(B)
         tier: 2
     worker-type: aws-provisioner-v1/gecko-{level}-b-macosx64
     worker:
-        implementation: docker-worker
         max-run-time: 36000
     run:
         using: mozharness
         actions: [get-secrets build generate-build-stats update]
         config:
             - builds/releng_base_mac_64_cross_builds.py
             - balrog/production.py
         script: "mozharness/scripts/fx_desktop_build.py"
@@ -100,17 +95,16 @@ macosx64-add-on-devel/opt:
         product: firefox
         job-name: macosx64-add-on-devel
     treeherder:
         platform: osx-10-7-add-on-devel/opt
         symbol: tc(B)
         tier: 2
     worker-type: aws-provisioner-v1/gecko-{level}-b-macosx64
     worker:
-        implementation: docker-worker
         max-run-time: 36000
     run:
        using: mozharness
        actions: [get-secrets build generate-build-stats update]
        config:
             - builds/releng_base_mac_64_cross_builds.py
             - balrog/production.py
        script: "mozharness/scripts/fx_desktop_build.py"
@@ -128,17 +122,16 @@ macosx64-nightly/opt:
         job-name: macosx64-opt
         type: nightly
     treeherder:
         platform: osx-10-7/opt
         symbol: tc(N)
         tier: 2
     worker-type: aws-provisioner-v1/gecko-{level}-b-macosx64
     worker:
-        implementation: docker-worker
         max-run-time: 36000
     run:
         using: mozharness
         actions: [get-secrets build generate-build-stats update]
         config:
             - builds/releng_base_mac_64_cross_builds.py
             - disable_signing.py
             - taskcluster_nightly.py
--- a/taskcluster/ci/build/windows.yml
+++ b/taskcluster/ci/build/windows.yml
@@ -4,17 +4,16 @@ win32/debug:
         product: firefox
         job-name: win32-debug
     treeherder:
         platform: windows2012-32/debug
         symbol: tc(B)
         tier: 2
     worker-type: aws-provisioner-v1/gecko-{level}-b-win2012
     worker:
-        implementation: generic-worker
         max-run-time: 7200
     run:
         using: mozharness
         script: mozharness/scripts/fx_desktop_build.py
         config:
             - builds/taskcluster_firefox_windows_32_debug.py
 
 win32/opt:
@@ -23,17 +22,16 @@ win32/opt:
         product: firefox
         job-name: win32-opt
     treeherder:
         platform: windows2012-32/opt
         symbol: tc(B)
         tier: 2
     worker-type: aws-provisioner-v1/gecko-{level}-b-win2012
     worker:
-        implementation: generic-worker
         max-run-time: 7200
     run:
         using: mozharness
         script: mozharness/scripts/fx_desktop_build.py
         config:
             - builds/taskcluster_firefox_windows_32_opt.py
 
 win32/pgo:
@@ -42,17 +40,16 @@ win32/pgo:
         product: firefox
         job-name: win32-pgo
     treeherder:
         platform: windows2012-32/pgo
         symbol: tc(B)
         tier: 2
     worker-type: aws-provisioner-v1/gecko-{level}-b-win2012
     worker:
-        implementation: generic-worker
         max-run-time: 9000
     run:
         using: mozharness
         options: [enable-pgo]
         script: mozharness/scripts/fx_desktop_build.py
         config:
             - builds/taskcluster_firefox_windows_32_opt.py
 
@@ -62,17 +59,16 @@ win64/debug:
         product: firefox
         job-name: win64-debug
     treeherder:
         platform: windows2012-64/debug
         symbol: tc(B)
         tier: 2
     worker-type: aws-provisioner-v1/gecko-{level}-b-win2012
     worker:
-        implementation: generic-worker
         max-run-time: 7200
     run:
         using: mozharness
         script: mozharness/scripts/fx_desktop_build.py
         config:
             - builds/taskcluster_firefox_windows_64_debug.py
 
 win64/opt:
@@ -81,17 +77,16 @@ win64/opt:
         product: firefox
         job-name: win64-opt
     treeherder:
         platform: windows2012-64/opt
         symbol: tc(B)
         tier: 2
     worker-type: aws-provisioner-v1/gecko-{level}-b-win2012
     worker:
-        implementation: generic-worker
         max-run-time: 7200
     run:
         using: mozharness
         script: mozharness/scripts/fx_desktop_build.py
         config:
             - builds/taskcluster_firefox_windows_64_opt.py
 
 win64-nightly/opt:
@@ -103,17 +98,16 @@ win64-nightly/opt:
     attributes:
         nightly: true
     treeherder:
         platform: windows2012-64/opt
         symbol: tc(N)
         tier: 2
     worker-type: aws-provisioner-v1/gecko-{level}-b-win2012
     worker:
-        implementation: generic-worker
         max-run-time: 7200
     run:
         using: mozharness
         script: mozharness/scripts/fx_desktop_build.py
         config:
             - builds/taskcluster_firefox_windows_64_opt.py
             - disable_signing.py
             - taskcluster_nightly.py
@@ -124,17 +118,16 @@ win64/pgo:
         product: firefox
         job-name: win64-pgo
     treeherder:
         platform: windows2012-64/pgo
         symbol: tc(B)
         tier: 2
     worker-type: aws-provisioner-v1/gecko-{level}-b-win2012
     worker:
-        implementation: generic-worker
         max-run-time: 10800
     run:
         using: mozharness
         options: [enable-pgo]
         script: mozharness/scripts/fx_desktop_build.py
         config:
             - builds/taskcluster_firefox_windows_64_opt.py
 
@@ -144,17 +137,16 @@ win32-add-on-devel/opt:
           product: firefox
           job-name: win32-add-on-devel
       treeherder:
           platform: windows2012-32-add-on-devel/opt
           symbol: tc(B)
           tier: 2
       worker-type: aws-provisioner-v1/gecko-{level}-b-win2012
       worker:
-          implementation: generic-worker
           max-run-time: 10800
       run:
           using: mozharness
           script: "mozharness/scripts/fx_desktop_build.py"
           config:
               - builds/taskcluster_firefox_windows_32_addondevel.py
               - balrog/production.py
       run-on-projects: [ 'mozilla-beta', 'mozilla-release', 'mozilla-esr45' ]
@@ -165,17 +157,16 @@ win64-add-on-devel/opt:
          product: firefox
          job-name: win64-add-on-devel
      treeherder:
          platform: windows2012-64-add-on-devel/opt 
          symbol: tc(B)
          tier: 2
      worker-type: aws-provisioner-v1/gecko-{level}-b-win2012 
      worker:
-         implementation: generic-worker
          max-run-time: 10800
      run:
          using: mozharness
          script: "mozharness/scripts/fx_desktop_build.py"
          config:
              - builds/taskcluster_firefox_windows_64_addondevel.py 
              - balrog/production.py
      run-on-projects: [ 'mozilla-beta', 'mozilla-release', 'mozilla-esr45' ]
@@ -186,17 +177,16 @@ win64-qr/debug:
         product: firefox
         job-name: win64-qr-debug
     treeherder:
         platform: windows2012-64-qr/debug
         symbol: tc(B)
         tier: 2
     worker-type: aws-provisioner-v1/gecko-{level}-b-win2012
     worker:
-        implementation: generic-worker
         max-run-time: 7200
     run:
         using: mozharness
         script: mozharness/scripts/fx_desktop_build.py
         config:
             - builds/taskcluster_firefox_win64_qr_debug.py
     run-on-projects: [ 'graphics' ]
 
@@ -206,17 +196,16 @@ win64-qr/opt:
         product: firefox
         job-name: win64-qr-opt
     treeherder:
         platform: windows2012-64-qr/opt
         symbol: tc(B)
         tier: 2
     worker-type: aws-provisioner-v1/gecko-{level}-b-win2012
     worker:
-        implementation: generic-worker
         max-run-time: 7200
     run:
         using: mozharness
         script: mozharness/scripts/fx_desktop_build.py
         config:
             - builds/taskcluster_firefox_win64_qr_opt.py
     run-on-projects: [ 'graphics' ]
 
@@ -226,17 +215,16 @@ win32-qr/debug:
         product: firefox
         job-name: win32-qr-debug
     treeherder:
         platform: windows2012-32-qr/debug
         symbol: tc(B)
         tier: 2
     worker-type: aws-provisioner-v1/gecko-{level}-b-win2012
     worker:
-        implementation: generic-worker
         max-run-time: 7200
     run:
         using: mozharness
         script: mozharness/scripts/fx_desktop_build.py
         config:
             - builds/taskcluster_firefox_win32_qr_debug.py
     run-on-projects: [ 'graphics' ]
 
@@ -246,17 +234,16 @@ win32-qr/opt:
         product: firefox
         job-name: win32-qr-opt
     treeherder:
         platform: windows2012-32-qr/opt
         symbol: tc(B)
         tier: 2
     worker-type: aws-provisioner-v1/gecko-{level}-b-win2012
     worker:
-        implementation: generic-worker
         max-run-time: 7200
     run:
         using: mozharness
         script: mozharness/scripts/fx_desktop_build.py
         config:
             - builds/taskcluster_firefox_win32_qr_opt.py
     run-on-projects: [ 'graphics' ]
 
@@ -266,17 +253,16 @@ win64-asan/debug:
         product: firefox
         job-name: win64-asan-debug
     treeherder:
         platform: windows2012-64/asan
         symbol: tc(Bd)
         tier: 3
     worker-type: aws-provisioner-v1/gecko-{level}-b-win2012
     worker:
-        implementation: generic-worker
         max-run-time: 7200
     run:
         using: mozharness
         script: mozharness/scripts/fx_desktop_build.py
         config:
             - builds/taskcluster_firefox_win64_asan_debug.py
     run-on-projects: []
 
@@ -286,16 +272,15 @@ win64-asan/opt:
         product: firefox
         job-name: win64-asan-opt
     treeherder:
         platform: windows2012-64/asan
         symbol: tc(Bo)
         tier: 3
     worker-type: aws-provisioner-v1/gecko-{level}-b-win2012
     worker:
-        implementation: generic-worker
         max-run-time: 7200
     run:
         using: mozharness
         script: mozharness/scripts/fx_desktop_build.py
         config:
             - builds/taskcluster_firefox_win64_asan_opt.py
-    run-on-projects: []
\ No newline at end of file
+    run-on-projects: []
--- a/taskcluster/ci/hazard/kind.yml
+++ b/taskcluster/ci/hazard/kind.yml
@@ -10,17 +10,16 @@ transforms:
    - taskgraph.transforms.task:transforms
 
 job-defaults:
     treeherder:
         kind: build
         tier: 1
     worker-type: aws-provisioner-v1/gecko-{level}-b-linux
     worker:
-        implementation: docker-worker
         max-run-time: 36000
         docker-image: {in-tree: desktop-build}
 
 jobs:
     linux64-shell-haz/debug:
         description: "JS Shell Hazard Analysis Linux"
         index:
             product: firefox
--- a/taskcluster/ci/source-test/doc.yml
+++ b/taskcluster/ci/source-test/doc.yml
@@ -2,17 +2,16 @@ sphinx:
     description: Generate the Sphinx documentation
     platform: lint/opt
     treeherder:
         symbol: tc(Doc)
         kind: test
         tier: 1
     worker-type: aws-provisioner-v1/gecko-t-linux-xlarge
     worker:
-        implementation: docker-worker
         docker-image: {in-tree: "lint"}
         max-run-time: 1800
         artifacts:
             - type: file
               name: public/docs.tar.gz
               path: /home/worker/checkouts/gecko/docs.tar.gz
     run:
         using: run-task
--- a/taskcluster/ci/source-test/mozlint.yml
+++ b/taskcluster/ci/source-test/mozlint.yml
@@ -2,17 +2,16 @@ mozlint-eslint:
     description: JS lint check
     platform: lint/opt
     treeherder:
         symbol: ES
         kind: test
         tier: 1
     worker-type: aws-provisioner-v1/gecko-t-linux-xlarge
     worker:
-        implementation: docker-worker
         docker-image: {in-tree: "lint"}
         max-run-time: 1800
     run:
         using: run-task
         command: >
             cd /home/worker/checkouts/gecko/ &&
             /build/tooltool.py fetch -m tools/lint/eslint/manifest.tt &&
             tar xvfz eslint.tar.gz &&
@@ -46,17 +45,16 @@ mozlint-flake8:
     description: flake8 run over the gecko codebase
     platform: lint/opt
     treeherder:
         symbol: f8
         kind: test
         tier: 1
     worker-type: aws-provisioner-v1/gecko-t-linux-xlarge
     worker:
-        implementation: docker-worker
         docker-image: {in-tree: "lint"}
         max-run-time: 1800
     run:
         using: mach
         mach: lint -l flake8 -f treeherder
     run-on-projects:
         - integration
         - release
@@ -71,17 +69,16 @@ wptlint-gecko:
     description: web-platform-tests linter
     platform: lint/opt
     treeherder:
         symbol: W
         kind: test
         tier: 1
     worker-type: aws-provisioner-v1/gecko-t-linux-xlarge
     worker:
-        implementation: docker-worker
         docker-image: {in-tree: "lint"}
         max-run-time: 1800
     run:
         using: mach
         mach: lint -l wpt -l wpt_manifest -f treeherder
     run-on-projects:
         - integration
         - release
--- a/taskcluster/ci/source-test/python-tests.yml
+++ b/taskcluster/ci/source-test/python-tests.yml
@@ -2,17 +2,16 @@ taskgraph-tests:
     description: taskcluster/taskgraph unit tests
     platform: linux64/opt
     treeherder:
         symbol: py(tg)
         kind: test
         tier: 2
     worker-type: aws-provisioner-v1/gecko-t-linux-xlarge
     worker:
-        implementation: docker-worker
         docker-image: {in-tree: "lint"}
         max-run-time: 1800
     run:
         using: mach
         mach: taskgraph python-tests
     run-on-projects:
         - integration
         - release
@@ -30,17 +29,16 @@ marionette-harness:
         kind: test
         tier: 2
     worker-type:
         by-platform:
             linux64.*: aws-provisioner-v1/gecko-t-linux-xlarge
     worker:
         by-platform:
             linux64.*:
-                implementation: docker-worker
                 docker-image: {in-tree: "lint"}
                 max-run-time: 3600
     run:
         using: mach
         mach: python-test --subsuite marionette-harness
     run-on-projects:
         - integration
         - release
@@ -61,17 +59,16 @@ mozbase:
         kind: test
         tier: 2
     worker-type:
         by-platform:
             linux64.*: aws-provisioner-v1/gecko-t-linux-xlarge
     worker:
         by-platform:
             linux64.*:
-                implementation: docker-worker
                 docker-image: {in-tree: "lint"}
                 max-run-time: 3600
     run:
         using: mach
         mach: python-test --subsuite mozbase
     run-on-projects:
         - integration
         - release
@@ -85,17 +82,16 @@ mozharness:
     description: mozharness integration tests
     platform: lint/opt
     treeherder:
         symbol: py(MH)
         kind: test
         tier: 2
     worker-type: aws-provisioner-v1/gecko-t-linux-xlarge
     worker:
-        implementation: docker-worker
         docker-image: {in-tree: "lint"}
         max-run-time: 1800
     run:
         using: run-task
         cache-dotcache: true
         command: >
             cd /home/worker/checkouts/gecko/testing/mozharness &&
             /usr/local/bin/tox -e py27-hg4.1
@@ -114,17 +110,16 @@ mozlint:
         kind: test
         tier: 2
     worker-type:
         by-platform:
             linux64.*: aws-provisioner-v1/gecko-t-linux-xlarge
     worker:
         by-platform:
             linux64.*:
-                implementation: docker-worker
                 docker-image: {in-tree: "lint"}
                 max-run-time: 3600
     run:
         using: mach
         mach: python-test --subsuite mozlint
     run-on-projects:
         - integration
         - release
--- a/taskcluster/ci/source-test/webidl.yml
+++ b/taskcluster/ci/source-test/webidl.yml
@@ -2,17 +2,16 @@ webidl-test:
     description: WebIDL parser tests
     platform: lint/opt
     treeherder:
         symbol: Wp
         kind: test
         tier: 1
     worker-type: aws-provisioner-v1/gecko-t-linux-xlarge
     worker:
-        implementation: docker-worker
         docker-image: {in-tree: "lint"}
         max-run-time: 1800
     run:
         using: mach
         mach: webidl-parser-test --verbose
     run-on-projects:
         - integration
         - release
--- a/taskcluster/ci/spidermonkey/kind.yml
+++ b/taskcluster/ci/spidermonkey/kind.yml
@@ -13,17 +13,16 @@ job-defaults:
     treeherder:
         platform: linux64/opt
         kind: build
         tier: 1
     index:
         product: firefox
     worker-type: aws-provisioner-v1/gecko-{level}-b-linux
     worker:
-        implementation: docker-worker
         max-run-time: 36000
         docker-image: {in-tree: desktop-build}
     run:
         using: spidermonkey
     when:
         files-changed:
             # any when.files-changed specified below in a job will be
             # appended to this list
--- a/taskcluster/ci/static-analysis/kind.yml
+++ b/taskcluster/ci/static-analysis/kind.yml
@@ -21,17 +21,16 @@ jobs:
     macosx64-st-an/debug:
         description: "MacOS X x64 Debug Cross-compile Static Analysis"
         index:
             job-name: macosx64-st-an-debug
         treeherder:
             platform: osx-10-7/debug
         worker-type: aws-provisioner-v1/gecko-{level}-b-macosx64
         worker:
-            implementation: docker-worker
             docker-image: {in-tree: desktop-build}
             max-run-time: 36000
         run:
             using: mozharness
             actions: [build generate-build-stats update]
             config:
                 - builds/releng_base_mac_64_cross_builds.py
                 - balrog/production.py
@@ -44,17 +43,16 @@ jobs:
     macosx64-st-an/opt:
         description: "MacOS X x64 Opt Cross-compile Static Analysis"
         index:
             job-name: macosx64-st-an-opt
         treeherder:
             platform: osx-10-7/opt
         worker-type: aws-provisioner-v1/gecko-{level}-b-macosx64
         worker:
-            implementation: docker-worker
             docker-image: {in-tree: desktop-build}
             max-run-time: 36000
         run:
             using: mozharness
             actions: [build generate-build-stats update]
             config:
                 - builds/releng_base_mac_64_cross_builds.py
                 - balrog/production.py
@@ -67,17 +65,16 @@ jobs:
     linux64-st-an/debug:
         description: "Linux64 Debug Static Analysis"
         index:
             job-name: linux64-st-an-debug
         treeherder:
             platform: linux64/debug
         worker-type: aws-provisioner-v1/gecko-{level}-b-linux
         worker:
-            implementation: docker-worker
             docker-image: {in-tree: desktop-build}
             max-run-time: 36000
         run:
             using: mozharness
             actions: [build generate-build-stats]
             config:
                 - builds/releng_sub_linux_configs/64_stat_and_debug.py
                 - balrog/production.py
@@ -88,17 +85,16 @@ jobs:
     linux64-st-an/opt:
         description: "Linux64 Opt Static Analysis"
         index:
             job-name: linux64-st-an-opt
         treeherder:
             platform: linux64/opt
         worker-type: aws-provisioner-v1/gecko-{level}-b-linux
         worker:
-            implementation: docker-worker
             docker-image: {in-tree: desktop-build}
             max-run-time: 36000
         run:
             using: mozharness
             actions: [build generate-build-stats]
             config:
                 - builds/releng_sub_linux_configs/64_stat_and_opt.py
                 - balrog/production.py
@@ -112,17 +108,16 @@ jobs:
             product: firefox
             job-name: win32-st-an-debug
         treeherder:
             platform: windows2012-32/debug
             symbol: tc(S)
             tier: 1
         worker-type: aws-provisioner-v1/gecko-{level}-b-win2012
         worker:
-            implementation: generic-worker
             max-run-time: 7200
         run:
             using: mozharness
             script: mozharness/scripts/fx_desktop_build.py
             config:
                 - builds/taskcluster_firefox_win32_clang_debug.py
 
     win32-st-an/opt:
@@ -131,17 +126,16 @@ jobs:
             product: firefox
             job-name: win32-st-an-opt
         treeherder:
             platform: windows2012-32/opt
             symbol: tc(S)
             tier: 1
         worker-type: aws-provisioner-v1/gecko-{level}-b-win2012
         worker:
-            implementation: generic-worker
             max-run-time: 7200
         run:
             using: mozharness
             script: mozharness/scripts/fx_desktop_build.py
             config:
                 - builds/taskcluster_firefox_win32_clang.py
 
     win64-st-an/debug:
@@ -150,17 +144,16 @@ jobs:
             product: firefox
             job-name: win64-st-an-debug
         treeherder:
             platform: windows2012-64/debug
             symbol: tc(S)
             tier: 1
         worker-type: aws-provisioner-v1/gecko-{level}-b-win2012
         worker:
-            implementation: generic-worker
             max-run-time: 7200
         run:
             using: mozharness
             script: mozharness/scripts/fx_desktop_build.py
             config:
                 - builds/taskcluster_firefox_win64_clang_debug.py
 
     win64-st-an/opt:
@@ -169,15 +162,14 @@ jobs:
             product: firefox
             job-name: win64-st-an-opt
         treeherder:
             platform: windows2012-64/opt
             symbol: tc(S)
             tier: 1
         worker-type: aws-provisioner-v1/gecko-{level}-b-win2012
         worker:
-            implementation: generic-worker
             max-run-time: 7200
         run:
             using: mozharness
             script: mozharness/scripts/fx_desktop_build.py
             config:
                 - builds/taskcluster_firefox_win64_clang.py
--- a/taskcluster/ci/toolchain/linux.yml
+++ b/taskcluster/ci/toolchain/linux.yml
@@ -6,17 +6,16 @@ linux64-clang:
     description: "Clang toolchain build"
     treeherder:
         kind: build
         platform: toolchains/opt
         symbol: TL(clang)
         tier: 1
     worker-type: aws-provisioner-v1/gecko-{level}-b-linux
     worker:
-        implementation: docker-worker
         docker-image: {in-tree: desktop-build}
         max-run-time: 36000
     run:
         using: toolchain-script
         script: build-clang-linux.sh
         tooltool-downloads: public
         resources:
             - 'build/build-clang/**'
@@ -29,17 +28,16 @@ linux64-clang-tidy:
         job-name: linux64-clang-tidy
     treeherder:
         kind: build
         platform: toolchains/opt
         symbol: TL(clang-tidy)
         tier: 1
     worker-type: aws-provisioner-v1/gecko-{level}-b-linux
     worker:
-        implementation: docker-worker
         docker-image: {in-tree: desktop-build}
         max-run-time: 36000
     run:
         using: toolchain-script
         script: build-clang-tidy-linux.sh
         tooltool-downloads: public
         resources:
             - 'build/clang-plugin/**'
@@ -50,17 +48,16 @@ linux64-gcc:
     description: "GCC toolchain build"
     treeherder:
         kind: build
         platform: toolchains/opt
         symbol: TL(gcc)
         tier: 1
     worker-type: aws-provisioner-v1/gecko-{level}-b-linux
     worker:
-        implementation: docker-worker
         docker-image: {in-tree: desktop-build}
         max-run-time: 36000
     run:
         using: toolchain-script
         script: build-gcc-linux.sh
         resources:
             - 'build/unix/build-gcc/**'
 
@@ -68,17 +65,16 @@ linux64-binutils:
     description: "Binutils toolchain build"
     treeherder:
         kind: build
         platform: toolchains/opt
         symbol: TL(binutil)
         tier: 1
     worker-type: aws-provisioner-v1/gecko-{level}-b-linux
     worker:
-        implementation: docker-worker
         docker-image: {in-tree: desktop-build}
         max-run-time: 36000
     run:
         using: toolchain-script
         script: build-binutils-linux.sh
         resources:
             - 'build/unix/build-binutils/**'
 
@@ -86,17 +82,16 @@ linux64-cctools-port:
     description: "cctools-port toolchain build"
     treeherder:
         kind: build
         platform: toolchains/opt
         symbol: TL(cctools)
         tier: 1
     worker-type: aws-provisioner-v1/gecko-{level}-b-linux
     worker:
-        implementation: docker-worker
         docker-image: {in-tree: desktop-build}
         max-run-time: 36000
     run:
         using: toolchain-script
         script: build-cctools-port.sh
         tooltool-downloads: public
         resources:
             - 'taskcluster/scripts/misc/tooltool-download.sh'
@@ -105,17 +100,16 @@ linux64-hfsplus:
     description: "hfsplus toolchain build"
     treeherder:
         kind: build
         platform: toolchains/opt
         symbol: TL(hfs+)
         tier: 1
     worker-type: aws-provisioner-v1/gecko-{level}-b-linux
     worker:
-        implementation: docker-worker
         docker-image: {in-tree: desktop-build}
         max-run-time: 36000
     run:
         using: toolchain-script
         script: build-hfsplus-linux.sh
         tooltool-downloads: public
         resources:
             - 'build/unix/build-hfsplus/**'
@@ -125,14 +119,13 @@ linux64-libdmg:
     description: "libdmg-hfsplus toolchain build"
     treeherder:
         kind: build
         platform: toolchains/opt
         symbol: TL(libdmg-hfs+)
         tier: 1
     worker-type: aws-provisioner-v1/gecko-{level}-b-linux
     worker:
-        implementation: docker-worker
         docker-image: {in-tree: desktop-build}
         max-run-time: 36000
     run:
         using: toolchain-script
         script: build-libdmg-hfsplus.sh
--- a/taskcluster/ci/toolchain/macosx.yml
+++ b/taskcluster/ci/toolchain/macosx.yml
@@ -6,17 +6,16 @@ macosx64-clang:
     description: "Clang toolchain build"
     treeherder:
         kind: build
         platform: toolchains/opt
         symbol: TM(clang)
         tier: 1
     worker-type: aws-provisioner-v1/gecko-{level}-b-macosx64
     worker:
-        implementation: docker-worker
         docker-image: {in-tree: desktop-build}
         max-run-time: 36000
     run:
         using: toolchain-script
         script: build-clang-macosx.sh
         tooltool-downloads: internal
         resources:
             - 'build/build-clang/**'
@@ -29,17 +28,16 @@ macosx64-clang-tidy:
         job-name: macosx64-clang-tidy
     treeherder:
         kind: build
         platform: toolchains/opt
         symbol: TM(clang-tidy)
         tier: 1
     worker-type: aws-provisioner-v1/gecko-{level}-b-macosx64
     worker:
-        implementation: docker-worker
         docker-image: {in-tree: desktop-build}
         max-run-time: 36000
     run:
         using: toolchain-script
         script: build-clang-tidy-macosx.sh
         tooltool-downloads: internal
         resources:
             - 'build/clang-plugin/**'
@@ -50,17 +48,16 @@ macosx64-cctools-port:
     description: "cctools-port toolchain build"
     treeherder:
         kind: build
         platform: toolchains/opt
         symbol: TM(cctools)
         tier: 1
     worker-type: aws-provisioner-v1/gecko-{level}-b-macosx64
     worker:
-        implementation: docker-worker
         docker-image: {in-tree: desktop-build}
         max-run-time: 36000
     run:
         using: toolchain-script
         script: build-cctools-port-macosx.sh
         tooltool-downloads: internal
         resources:
             - 'taskcluster/scripts/misc/tooltool-download.sh'
--- a/taskcluster/ci/toolchain/windows.yml
+++ b/taskcluster/ci/toolchain/windows.yml
@@ -6,17 +6,16 @@ win32-clang-cl:
     description: "Clang-cl toolchain build"
     treeherder:
         kind: build
         platform: toolchains/opt
         symbol: TW32(clang-cl)
         tier: 2
     worker-type: aws-provisioner-v1/gecko-{level}-b-win2012
     worker:
-        implementation: generic-worker
         max-run-time: 36000
     run:
         using: toolchain-script
         script: build-clang32-windows.sh
         resources:
             - 'build/build-clang/**'
             - 'taskcluster/scripts/misc/build-clang-windows-helper32.sh'
 
@@ -24,17 +23,16 @@ win64-clang-cl:
     description: "Clang-cl toolchain build"
     treeherder:
         kind: build
         platform: toolchains/opt
         symbol: TW64(clang-cl)
         tier: 2
     worker-type: aws-provisioner-v1/gecko-{level}-b-win2012
     worker:
-        implementation: generic-worker
         max-run-time: 36000
     run:
         using: toolchain-script
         script: build-clang64-windows.sh
         resources:
             - 'build/build-clang/**'
             - 'taskcluster/scripts/misc/build-clang-windows-helper64.sh'
 
@@ -45,17 +43,16 @@ win32-clang-tidy:
         job-name: win32-clang-tidy
     treeherder:
         kind: build
         platform: toolchains/opt
         symbol: TW32(clang-tidy)
         tier: 2
     worker-type: aws-provisioner-v1/gecko-{level}-b-win2012
     worker:
-        implementation: generic-worker
         max-run-time: 36000
     run:
         using: toolchain-script
         script: build-clang-tidy32-windows.sh
         resources:
             - 'build/build-clang/**'
             - 'taskcluster/scripts/misc/build-clang-windows-helper32.sh'
 
@@ -66,16 +63,15 @@ win64-clang-tidy:
         job-name: win64-clang-tidy
     treeherder:
         kind: build
         platform: toolchains/opt
         symbol: TW64(clang-tidy)
         tier: 2
     worker-type: aws-provisioner-v1/gecko-{level}-b-win2012
     worker:
-        implementation: generic-worker
         max-run-time: 36000
     run:
         using: toolchain-script
         script: build-clang-tidy64-windows.sh
         resources:
             - 'build/build-clang/**'
             - 'taskcluster/scripts/misc/build-clang-windows-helper64.sh'
--- a/taskcluster/ci/upload-symbols/kind.yml
+++ b/taskcluster/ci/upload-symbols/kind.yml
@@ -32,16 +32,17 @@ job-template:
    expires-after: 7 days
    deadline-after: 24 hours
    run-on-projects:
        - try
        - release
    worker-type: aws-provisioner-v1/gecko-symbol-upload
    worker:
        implementation: docker-worker
+       os: linux
        max-run-time: 600
        command: ["/bin/bash", "bin/upload.sh"]
        docker-image: taskclusterprivate/upload_symbols:0.0.4
        env:
            GECKO_HEAD_REPOSITORY: # see transforms
            GECKO_HEAD_REV: # see transforms
            ARTIFACT_TASKID: {"task-reference": "<build>"}
    scopes:
--- a/taskcluster/ci/valgrind/kind.yml
+++ b/taskcluster/ci/valgrind/kind.yml
@@ -17,17 +17,16 @@ jobs:
             job-name: linux64-valgrind-opt
         treeherder:
             platform: linux64/opt
             symbol: tc(V)
             kind: build
             tier: 1
         worker-type: aws-provisioner-v1/gecko-{level}-b-linux
         worker:
-            implementation: docker-worker
             docker-image: {in-tree: desktop-build}
             max-run-time: 72000
         run:
             using: mozharness
             actions: [get-secrets build generate-build-stats valgrind-test]
             custom-build-variant-cfg: valgrind
             config:
                 - builds/releng_base_linux_64_builds.py
--- a/taskcluster/taskgraph/transforms/build.py
+++ b/taskcluster/taskgraph/transforms/build.py
@@ -4,37 +4,41 @@
 """
 Apply some defaults and minor modifications to the jobs defined in the build
 kind.
 """
 
 from __future__ import absolute_import, print_function, unicode_literals
 
 from taskgraph.transforms.base import TransformSequence
+from taskgraph.util.workertypes import worker_type_implementation
 
 transforms = TransformSequence()
 
 
 @transforms.add
 def set_defaults(config, jobs):
     """Set defaults, including those that differ per worker implementation"""
     for job in jobs:
         job['treeherder'].setdefault('kind', 'build')
         job['treeherder'].setdefault('tier', 1)
         job.setdefault('needs-sccache', True)
-        if job['worker']['implementation'] in ('docker-worker', 'docker-engine'):
-            job['worker'].setdefault('docker-image', {'in-tree': 'desktop-build'})
-            job['worker']['chain-of-trust'] = True
-            job.setdefault('extra', {})
-            job['extra'].setdefault('chainOfTrust', {})
-            job['extra']['chainOfTrust'].setdefault('inputs', {})
-            job['extra']['chainOfTrust']['inputs']['docker-image'] = {
+        _, worker_os = worker_type_implementation(job['worker-type'])
+        if worker_os == "linux":
+            worker = job.setdefault('worker')
+            worker.setdefault('docker-image', {'in-tree': 'desktop-build'})
+            worker['chain-of-trust'] = True
+            extra = job.setdefault('extra', {})
+            extra.setdefault('chainOfTrust', {})
+            extra['chainOfTrust'].setdefault('inputs', {})
+            extra['chainOfTrust']['inputs']['docker-image'] = {
                 "task-reference": "<docker-image>"
             }
-        job['worker'].setdefault('env', {})
+        elif worker_os in set(["macosx", "windows"]):
+            job['worker'].setdefault('env', {})
         yield job
 
 
 @transforms.add
 def set_env(config, jobs):
     """Set extra environment variables from try command line."""
     for job in jobs:
         env = config.config['args'].env
--- a/taskcluster/taskgraph/transforms/docker_image.py
+++ b/taskcluster/taskgraph/transforms/docker_image.py
@@ -89,16 +89,17 @@ def fill_template(config, tasks):
                 'tier': 1,
             },
             'run-on-projects': [],
             'worker-type': 'aws-provisioner-v1/gecko-images',
             # can't use {in-tree: ..} here, otherwise we might try to build
             # this image..
             'worker': {
                 'implementation': 'docker-worker',
+                'os': 'linux',
                 'docker-image': docker_image('image_builder'),
                 'caches': [{
                     'type': 'persistent',
                     'name': 'level-{}-imagebuilder-v1'.format(config.params['level']),
                     'mount-point': '/home/worker/checkouts',
                 }],
                 'artifacts': [{
                     'type': 'file',
--- a/taskcluster/taskgraph/transforms/job/__init__.py
+++ b/taskcluster/taskgraph/transforms/job/__init__.py
@@ -15,16 +15,17 @@ import copy
 import logging
 import os
 
 from taskgraph.transforms.base import TransformSequence
 from taskgraph.util.schema import (
     validate_schema,
     Schema,
 )
+from taskgraph.util.workertypes import worker_type_implementation
 from taskgraph.transforms.task import task_description_schema
 from voluptuous import (
     Any,
     Extra,
     Optional,
     Required,
 )
 
@@ -77,22 +78,19 @@ job_description_schema = Schema({
 
         # Any remaining content is verified against that job implementation's
         # own schema.
         Extra: object,
     },
 
     Required('worker-type'): task_description_schema['worker-type'],
 
-    # for `worker`, all we need is the implementation; the rest will be verified
-    # by the task description schema
-    Required('worker'): {
-        Required('implementation'): basestring,
-        Extra: object,
-    },
+    # This object will be passed through to the task description, with additions
+    # provided by the job's run-using function
+    Optional('worker'): dict,
 })
 
 transforms = TransformSequence()
 
 
 @transforms.add
 def validate(config, jobs):
     for job in jobs:
@@ -109,17 +107,17 @@ def rewrite_when_to_optimization(config,
             yield job
             continue
 
         # add some common files
         files_changed.extend([
             '{}/**'.format(config.path),
             'taskcluster/taskgraph/**',
         ])
-        if 'in-tree' in job['worker'].get('docker-image', {}):
+        if 'in-tree' in job.get('worker', {}).get('docker-image', {}):
             files_changed.append('taskcluster/docker/{}/**'.format(
                 job['worker']['docker-image']['in-tree']))
 
         # "only when files changed" implies "skip if files have not changed"
         job.setdefault('optimizations', []).append(['skip-unless-changed', files_changed])
 
         assert 'when' not in job
         yield job
@@ -132,28 +130,36 @@ def make_task_description(config, jobs):
     import_all()
     for job in jobs:
         if 'label' not in job:
             if 'name' not in job:
                 raise Exception("job has neither a name nor a label")
             job['label'] = '{}-{}'.format(config.kind, job['name'])
         if job['name']:
             del job['name']
+
+        impl, os = worker_type_implementation(job['worker-type'])
+        worker = job.setdefault('worker', {})
+        assert 'implementation' not in worker
+        worker['implementation'] = impl
+        if os:
+            worker['os'] = os
+
         taskdesc = copy.deepcopy(job)
 
         # fill in some empty defaults to make run implementations easier
         taskdesc.setdefault('attributes', {})
         taskdesc.setdefault('dependencies', {})
         taskdesc.setdefault('routes', [])
         taskdesc.setdefault('scopes', [])
         taskdesc.setdefault('extra', {})
 
         # give the function for job.run.using on this worker implementation a
         # chance to set up the task description.
-        configure_taskdesc_for_run(config, job, taskdesc)
+        configure_taskdesc_for_run(config, job, taskdesc, impl)
         del taskdesc['run']
 
         # yield only the task description, discarding the job description
         yield taskdesc
 
 # A registry of all functions decorated with run_job_using
 registry = {}
 
@@ -171,29 +177,28 @@ def run_job_using(worker_implementation,
         if worker_implementation in for_run_using:
             raise Exception("run_job_using({!r}, {!r}) already exists: {!r}".format(
                 run_using, worker_implementation, for_run_using[run_using]))
         for_run_using[worker_implementation] = (func, schema)
         return func
     return wrap
 
 
-def configure_taskdesc_for_run(config, job, taskdesc):
+def configure_taskdesc_for_run(config, job, taskdesc, worker_implementation):
     """
     Run the appropriate function for this job against the given task
     description.
 
     This will raise an appropriate error if no function exists, or if the job's
     run is not valid according to the schema.
     """
     run_using = job['run']['using']
     if run_using not in registry:
         raise Exception("no functions for run.using {!r}".format(run_using))
 
-    worker_implementation = job['worker']['implementation']
     if worker_implementation not in registry[run_using]:
         raise Exception("no functions for run.using {!r} on {!r}".format(
             run_using, worker_implementation))
 
     func, schema = registry[run_using][worker_implementation]
     if schema:
         job['run'] = validate_schema(
                 schema, job['run'],
--- a/taskcluster/taskgraph/transforms/job/mozharness.py
+++ b/taskcluster/taskgraph/transforms/job/mozharness.py
@@ -100,16 +100,17 @@ def mozharness_on_docker_worker_setup(co
     env = worker.setdefault('env', {})
     env.update({
         'MOZHARNESS_CONFIG': ' '.join(run['config']),
         'MOZHARNESS_SCRIPT': run['script'],
         'MH_BRANCH': config.params['project'],
         'MH_BUILD_POOL': 'taskcluster',
         'MOZ_BUILD_DATE': config.params['moz_build_date'],
         'MOZ_SCM_LEVEL': config.params['level'],
+        'MOZ_AUTOMATION': '1',
     })
 
     if 'actions' in run:
         env['MOZHARNESS_ACTIONS'] = ' '.join(run['actions'])
 
     if 'options' in run:
         env['MOZHARNESS_OPTIONS'] = ' '.join(run['options'])
 
@@ -164,19 +165,20 @@ def mozharness_on_docker_worker_setup(co
     command.append("/home/worker/workspace/build/src/{}".format(
         run.get('job-script',
                 "taskcluster/scripts/builder/build-linux.sh"
                 )))
 
     worker['command'] = command
 
 
-# We use the generic worker to run tasks on Windows
 @run_job_using("generic-worker", "mozharness", schema=mozharness_run_schema)
 def mozharness_on_generic_worker(config, job, taskdesc):
+    assert job['worker']['os'] == 'windows', 'only supports windows right now'
+
     run = job['run']
 
     # fail if invalid run options are included
     invalid = []
     for prop in ['actions', 'custom-build-variant-cfg',
                  'tooltool-downloads', 'secrets', 'taskcluster-proxy',
                  'need-xvfb']:
         if prop in run and run[prop]:
@@ -196,16 +198,17 @@ def mozharness_on_generic_worker(config,
 
     docker_worker_add_gecko_vcs_env_vars(config, job, taskdesc)
 
     env = worker['env']
     env.update({
         'MOZ_BUILD_DATE': config.params['moz_build_date'],
         'MOZ_SCM_LEVEL': config.params['level'],
         'MOZ_SIMPLE_PACKAGE_NAME': 'target',
+        'MOZ_AUTOMATION': '1',
     })
 
     if not job['attributes']['build_platform'].startswith('win'):
         raise Exception(
             "Task generation for mozharness build jobs currently only supported on Windows"
         )
 
     mh_command = [r'c:\mozilla-build\python\python.exe']
--- a/taskcluster/taskgraph/transforms/job/mozharness_test.py
+++ b/taskcluster/taskgraph/transforms/job/mozharness_test.py
@@ -36,33 +36,53 @@ BUILDER_NAME_PREFIX = {
 test_description_schema = {str(k): v for k, v in test_description_schema.schema.iteritems()}
 
 mozharness_test_run_schema = Schema({
     Required('using'): 'mozharness-test',
     Required('test'): test_description_schema,
 })
 
 
+def test_packages_url(taskdesc):
+    """Account for different platforms that name their test packages differently"""
+    build_platform = taskdesc['attributes']['build_platform']
+    build_type = taskdesc['attributes']['build_type']
+
+    if build_platform == 'macosx64' and build_type == 'opt':
+        target = 'firefox-{}.en-US.{}'.format(get_firefox_version(), 'mac')
+    else:
+        target = 'target'
+
+    return get_artifact_url(
+        '<build>', 'public/build/{}.test_packages.json'.format(target))
+
+
 @run_job_using('docker-engine', 'mozharness-test', schema=mozharness_test_run_schema)
 @run_job_using('docker-worker', 'mozharness-test', schema=mozharness_test_run_schema)
 def mozharness_test_on_docker(config, job, taskdesc):
     test = taskdesc['run']['test']
     mozharness = test['mozharness']
     worker = taskdesc['worker']
 
+    # apply some defaults
+    worker['docker-image'] = test['docker-image']
+    worker['allow-ptrace'] = True  # required for all tests, for crashreporter
+    worker['loopback-video'] = test['loopback-video']
+    worker['loopback-audio'] = test['loopback-audio']
+    worker['max-run-time'] = test['max-run-time']
+    worker['retry-exit-status'] = test['retry-exit-status']
+
     artifacts = [
         # (artifact name prefix, in-image path)
         ("public/logs/", "/home/worker/workspace/build/upload/logs/"),
         ("public/test", "/home/worker/artifacts/"),
         ("public/test_info/", "/home/worker/workspace/build/blobber_upload_dir/"),
     ]
 
     installer_url = get_artifact_url('<build>', mozharness['build-artifact-name'])
-    test_packages_url = get_artifact_url('<build>',
-                                         'public/build/target.test_packages.json')
     mozharness_url = get_artifact_url('<build>',
                                       'public/build/mozharness.zip')
 
     worker['artifacts'] = [{
         'name': prefix,
         'path': os.path.join('/home/worker/workspace', path),
         'type': 'directory',
     } for (prefix, path) in artifacts]
@@ -76,16 +96,17 @@ def mozharness_test_on_docker(config, jo
 
     env = worker['env'] = {
         'MOZHARNESS_CONFIG': ' '.join(mozharness['config']),
         'MOZHARNESS_SCRIPT': mozharness['script'],
         'MOZILLA_BUILD_URL': {'task-reference': installer_url},
         'NEED_PULSEAUDIO': 'true',
         'NEED_WINDOW_MANAGER': 'true',
         'ENABLE_E10S': str(bool(test.get('e10s'))).lower(),
+        'MOZ_AUTOMATION': '1',
     }
 
     if mozharness.get('mochitest-flavor'):
         env['MOCHITEST_FLAVOR'] = mozharness['mochitest-flavor']
 
     if mozharness['set-moz-node-path']:
         env['MOZ_NODE_PATH'] = '/usr/local/bin/node'
 
@@ -135,17 +156,17 @@ def mozharness_test_on_docker(config, jo
         '--',
         '/home/worker/bin/test-linux.sh',
     ])
 
     if mozharness.get('no-read-buildbot-config'):
         command.append("--no-read-buildbot-config")
     command.extend([
         {"task-reference": "--installer-url=" + installer_url},
-        {"task-reference": "--test-packages-url=" + test_packages_url},
+        {"task-reference": "--test-packages-url=" + test_packages_url(taskdesc)},
     ])
     command.extend(mozharness.get('extra-options', []))
 
     # TODO: remove the need for run['chunked']
     if mozharness.get('chunked') or test['chunks'] > 1:
         # Implement mozharness['chunking-args'], modifying command in place
         if mozharness['chunking-args'] == 'this-chunk':
             command.append('--total-chunk={}'.format(test['chunks']))
@@ -165,103 +186,93 @@ def mozharness_test_on_docker(config, jo
 
 
 @run_job_using('generic-worker', 'mozharness-test', schema=mozharness_test_run_schema)
 def mozharness_test_on_generic_worker(config, job, taskdesc):
     test = taskdesc['run']['test']
     mozharness = test['mozharness']
     worker = taskdesc['worker']
 
+    is_macosx = worker['os'] == 'macosx'
+    is_windows = worker['os'] == 'windows'
+    assert is_macosx or is_windows
+
     artifacts = [
         {
             'name': 'public/logs',
             'path': 'logs',
             'type': 'directory'
         },
     ]
 
     # jittest doesn't have blob_upload_dir
     if test['test-name'] != 'jittest':
         artifacts.append({
             'name': 'public/test_info',
             'path': 'build/blobber_upload_dir',
             'type': 'directory'
         })
 
-    build_platform = taskdesc['attributes']['build_platform']
-    build_type = taskdesc['attributes']['build_type']
-
-    if build_platform == 'macosx64' and build_type == 'opt':
-        target = 'firefox-{}.en-US.{}'.format(get_firefox_version(), 'mac')
-    else:
-        target = 'target'
-
     installer_url = get_artifact_url('<build>', mozharness['build-artifact-name'])
 
-    test_packages_url = get_artifact_url(
-        '<build>', 'public/build/{}.test_packages.json'.format(target))
-
     taskdesc['scopes'].extend(
         ['generic-worker:os-group:{}'.format(group) for group in test['os-groups']])
 
     worker['os-groups'] = test['os-groups']
 
     if test['reboot']:
         raise Exception('reboot: {} not supported on generic-worker'.format(test['reboot']))
 
     worker['max-run-time'] = test['max-run-time']
     worker['artifacts'] = artifacts
 
+    env = worker.setdefault('env', {})
+    env['MOZ_AUTOMATION'] = '1'
+
     # this list will get cleaned up / reduced / removed in bug 1354088
-    if build_platform.startswith('macosx'):
-        worker['env'] = {
+    if is_macosx:
+        env.update({
             'IDLEIZER_DISABLE_SHUTDOWN': 'true',
             'LANG': 'en_US.UTF-8',
             'LC_ALL': 'en_US.UTF-8',
             'MOZ_HIDE_RESULTS_TABLE': '1',
             'MOZ_NODE_PATH': '/usr/local/bin/node',
             'MOZ_NO_REMOTE': '1',
             'NO_EM_RESTART': '1',
             'NO_FAIL_ON_TEST_ERRORS': '1',
             'PATH': '/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin',
             'SHELL': '/bin/bash',
             'XPCOM_DEBUG_BREAK': 'warn',
             'XPC_FLAGS': '0x0',
-            'XPC_SERVICE_NAME': '0'
-        }
+            'XPC_SERVICE_NAME': '0',
+        })
 
-    if build_platform.startswith('macosx'):
+    if is_macosx:
         mh_command = [
             'python2.7',
             '-u',
             'mozharness/scripts/' + mozharness['script']
         ]
-    elif build_platform.startswith('win'):
+    elif is_windows:
         mh_command = [
             'c:\\mozilla-build\\python\\python.exe',
             '-u',
             'mozharness\\scripts\\' + normpath(mozharness['script'])
         ]
-    else:
-        mh_command = [
-            'python',
-            '-u',
-            'mozharness/scripts/' + mozharness['script']
-        ]
 
     for mh_config in mozharness['config']:
         cfg_path = 'mozharness/configs/' + mh_config
-        if build_platform.startswith('win'):
+        if is_windows:
             cfg_path = normpath(cfg_path)
         mh_command.extend(['--cfg', cfg_path])
     mh_command.extend(mozharness.get('extra-options', []))
     if mozharness.get('no-read-buildbot-config'):
         mh_command.append('--no-read-buildbot-config')
     mh_command.extend(['--installer-url', installer_url])
-    mh_command.extend(['--test-packages-url', test_packages_url])
+    mh_command.extend(['--test-packages-url', test_packages_url(taskdesc)])
     if mozharness.get('download-symbols'):
         if isinstance(mozharness['download-symbols'], basestring):
             mh_command.extend(['--download-symbols', mozharness['download-symbols']])
         else:
             mh_command.extend(['--download-symbols', 'true'])
     if mozharness.get('include-blob-upload-branch'):
         mh_command.append('--blob-upload-branch=' + config.params['project'])
     mh_command.extend(mozharness.get('extra-options', []))
@@ -284,44 +295,39 @@ def mozharness_test_on_generic_worker(co
             'artifact': 'public/build/mozharness.zip',
             'task-id': {
                 'task-reference': '<build>'
             }
         },
         'format': 'zip'
     }]
 
-    if build_platform.startswith('win'):
+    if is_windows:
         worker['command'] = [
             {'task-reference': ' '.join(mh_command)}
         ]
-    else:
+    else:  # is_macosx
         mh_command_task_ref = []
         for token in mh_command:
             mh_command_task_ref.append({'task-reference': token})
         worker['command'] = [
             mh_command_task_ref
         ]
 
 
 @run_job_using('native-engine', 'mozharness-test', schema=mozharness_test_run_schema)
 def mozharness_test_on_native_engine(config, job, taskdesc):
     test = taskdesc['run']['test']
     mozharness = test['mozharness']
     worker = taskdesc['worker']
     is_talos = test['suite'] == 'talos'
 
-    build_platform = taskdesc['attributes']['build_platform']
-    build_type = taskdesc['attributes']['build_type']
-    target = 'firefox-{}.en-US.{}'.format(get_firefox_version(), 'mac') \
-        if build_platform == 'macosx64' and build_type == 'opt' else 'target'
+    assert worker['os'] == 'macosx'
 
     installer_url = get_artifact_url('<build>', mozharness['build-artifact-name'])
-    test_packages_url = get_artifact_url('<build>',
-                                         'public/build/{}.test_packages.json'.format(target))
     mozharness_url = get_artifact_url('<build>',
                                       'public/build/mozharness.zip')
 
     worker['artifacts'] = [{
         'name': prefix.rstrip('/'),
         'path': path.rstrip('/'),
         'type': 'directory',
     } for (prefix, path) in [
@@ -342,32 +348,33 @@ def mozharness_test_on_native_engine(con
         'MOZHARNESS_URL': {'task-reference': mozharness_url},
         'MOZILLA_BUILD_URL': {'task-reference': installer_url},
         "MOZ_NO_REMOTE": '1',
         "NO_EM_RESTART": '1',
         "XPCOM_DEBUG_BREAK": 'warn',
         "NO_FAIL_ON_TEST_ERRORS": '1',
         "MOZ_HIDE_RESULTS_TABLE": '1',
         "MOZ_NODE_PATH": "/usr/local/bin/node",
+        'MOZ_AUTOMATION': '1',
     }
     # talos tests don't need Xvfb
     if is_talos:
         env['NEED_XVFB'] = 'false'
 
     script = 'test-macosx.sh' if test['test-platform'].startswith('macosx') else 'test-linux.sh'
     worker['context'] = '{}/raw-file/{}/taskcluster/scripts/tester/{}'.format(
         config.params['head_repository'], config.params['head_rev'], script
     )
 
     command = worker['command'] = ["./{}".format(script)]
     if mozharness.get('no-read-buildbot-config'):
         command.append("--no-read-buildbot-config")
     command.extend([
         {"task-reference": "--installer-url=" + installer_url},
-        {"task-reference": "--test-packages-url=" + test_packages_url},
+        {"task-reference": "--test-packages-url=" + test_packages_url(taskdesc)},
     ])
     if mozharness.get('include-blob-upload-branch'):
         command.append('--blob-upload-branch=' + config.params['project'])
     command.extend(mozharness.get('extra-options', []))
 
     # TODO: remove the need for run['chunked']
     if mozharness.get('chunked') or test['chunks'] > 1:
         # Implement mozharness['chunking-args'], modifying command in place
--- a/taskcluster/taskgraph/transforms/job/toolchain.py
+++ b/taskcluster/taskgraph/transforms/job/toolchain.py
@@ -86,16 +86,17 @@ def docker_worker_toolchain(config, job,
     docker_worker_add_gecko_vcs_env_vars(config, job, taskdesc)
     support_vcs_checkout(config, job, taskdesc)
 
     env = worker['env']
     env.update({
         'MOZ_BUILD_DATE': config.params['moz_build_date'],
         'MOZ_SCM_LEVEL': config.params['level'],
         'TOOLS_DISABLE': 'true',
+        'MOZ_AUTOMATION': '1',
     })
 
     # tooltool downloads.  By default we download using the API endpoint, but
     # the job can optionally request relengapi-proxy (for example when downloading
     # internal tooltool resources.  So we define the tooltool cache unconditionally.
     worker['caches'].append({
         'type': 'persistent',
         'name': 'tooltool-cache',
@@ -153,16 +154,17 @@ def windows_toolchain(config, job, taskd
     taskdesc['scopes'].extend([
         'generic-worker:cache:' + svn_cache,
     ])
 
     env = worker['env']
     env.update({
         'MOZ_BUILD_DATE': config.params['moz_build_date'],
         'MOZ_SCM_LEVEL': config.params['level'],
+        'MOZ_AUTOMATION': '1',
     })
 
     hg = r'c:\Program Files\Mercurial\hg.exe'
     hg_command = ['"{}"'.format(hg)]
     hg_command.append('robustcheckout')
     hg_command.extend(['--sharebase', 'y:\\hg-shared'])
     hg_command.append('--purge')
     hg_command.extend(['--upstream', 'https://hg.mozilla.org/mozilla-unified'])
--- a/taskcluster/taskgraph/transforms/l10n.py
+++ b/taskcluster/taskgraph/transforms/l10n.py
@@ -343,17 +343,16 @@ def validate_again(config, jobs):
 
 
 @transforms.add
 def make_job_description(config, jobs):
     for job in jobs:
         job_description = {
             'name': job['name'],
             'worker': {
-                'implementation': 'docker-worker',
                 'docker-image': {'in-tree': 'desktop-build'},
                 'max-run-time': job['run-time'],
                 'chain-of-trust': True,
             },
             'extra': job['extra'],
             'worker-type': job['worker-type'],
             'description': job['description'],
             'run': {
--- a/taskcluster/taskgraph/transforms/repackage.py
+++ b/taskcluster/taskgraph/transforms/repackage.py
@@ -125,16 +125,17 @@ def make_task_description(config, jobs):
             'routes': job.get('routes', []),
             'extra': job.get('extra', {}),
             'scopes':
             ['docker-worker:relengapi-proxy:tooltool.download.internal',
              'secrets:get:project/taskcluster/gecko/hgfingerprint',
              'docker-worker:relengapi-proxy:tooltool.download.public',
              'project:releng:signing:format:dmg'],
             'worker': {'implementation': 'docker-worker',
+                       'os': 'linux',
                        'docker-image': {"in-tree": "desktop-build"},
                        'caches': [{
                                    'type': 'persistent',
                                    'name': 'tooltool-cache',
                                    'mount-point': '/home/worker/tooltool-cache',
                                  }, {
                                    'type': 'persistent',
                                    'name': 'level-%s-checkouts-v1' % level,
--- a/taskcluster/taskgraph/transforms/task.py
+++ b/taskcluster/taskgraph/transforms/task.py
@@ -149,16 +149,17 @@ task_description_schema = Schema({
     'worker-type': basestring,
 
     # Whether the job should use sccache compiler caching.
     Required('needs-sccache', default=False): bool,
 
     # information specific to the worker implementation that will run this task
     'worker': Any({
         Required('implementation'): Any('docker-worker', 'docker-engine'),
+        Required('os'): 'linux',
 
         # For tasks that will run in docker-worker or docker-engine, this is the
         # name of the docker image or in-tree docker image to run the task in.  If
         # in-tree, then a dependency will be created automatically.  This is
         # generally `desktop-test`, or an image that acts an awful lot like it.
         Required('docker-image'): Any(
             # a raw Docker image path (repo/image:tag)
             basestring,
@@ -210,19 +211,20 @@ task_description_schema = Schema({
 
         # the maximum time to run, in seconds
         Required('max-run-time'): int,
 
         # the exit status code that indicates the task should be retried
         Optional('retry-exit-status'): int,
 
     }, {
+        Required('implementation'): 'generic-worker',
+        Required('os'): Any('windows', 'macosx'),
         # see http://schemas.taskcluster.net/generic-worker/v1/payload.json
         # and https://docs.taskcluster.net/reference/workers/generic-worker/payload
-        Required('implementation'): 'generic-worker',
 
         # command is a list of commands to run, sequentially
         # on Windows, each command is a string, on OS X and Linux, each command is
         # a string array
         Required('command'): Any(
             [taskref_or_string],   # Windows
             [[taskref_or_string]]  # Linux / OS X
         ),
@@ -303,16 +305,17 @@ task_description_schema = Schema({
             Optional('project'): basestring,
         },
         Required('properties'): {
             'product': basestring,
             Extra: basestring,  # additional properties are allowed
         },
     }, {
         Required('implementation'): 'native-engine',
+        Required('os'): Any('macosx', 'linux'),
 
         # A link for an executable to download
         Optional('context'): basestring,
 
         # Tells the worker whether machine should reboot
         # after the task is finished.
         Optional('reboot'):
             Any('always', 'on-exception', 'on-failure'),
@@ -392,16 +395,22 @@ task_description_schema = Schema({
             # Paths to the artifacts to sign
             Required('paths'): [basestring],
         }],
     }, {
         Required('implementation'): 'push-apk-breakpoint',
         Required('payload'): object,
 
     }, {
+        Required('implementation'): 'invalid',
+        # an invalid task is one which should never actually be created; this is used in
+        # release automation on branches where the task just doesn't make sense
+        Extra: object,
+
+    }, {
         Required('implementation'): 'push-apk',
 
         # list of artifact URLs for the artifacts that should be beetmoved
         Required('upstream-artifacts'): [{
             # taskId of the task with the artifact
             Required('taskId'): taskref_or_string,
 
             # type of signing task (for CoT)
@@ -736,16 +745,21 @@ def build_push_apk_payload(config, task,
         task_def['payload']['rollout_percentage'] = worker['rollout-percentage']
 
 
 @payload_builder('push-apk-breakpoint')
 def build_push_apk_breakpoint_payload(config, task, task_def):
     task_def['payload'] = task['worker']['payload']
 
 
+@payload_builder('invalid')
+def build_invalid_payload(config, task, task_def):
+    task_def['payload'] = 'invalid task - should never be created'
+
+
 @payload_builder('native-engine')
 def build_macosx_engine_payload(config, task, task_def):
     worker = task['worker']
     artifacts = map(lambda artifact: {
         'name': artifact['name'],
         'path': artifact['path'],
         'type': artifact['type'],
         'expires': task_def['expires'],
--- a/taskcluster/taskgraph/transforms/tests.py
+++ b/taskcluster/taskgraph/transforms/tests.py
@@ -33,23 +33,26 @@ from voluptuous import (
     Required,
 )
 
 import copy
 import logging
 import requests
 from collections import defaultdict
 
-WORKER_TYPE = {
-    # default worker types keyed by instance-size
+# default worker types keyed by instance-size
+LINUX_WORKER_TYPES = {
     'large': 'aws-provisioner-v1/gecko-t-linux-large',
     'xlarge': 'aws-provisioner-v1/gecko-t-linux-xlarge',
     'legacy': 'aws-provisioner-v1/gecko-t-linux-medium',
     'default': 'aws-provisioner-v1/gecko-t-linux-large',
-    # windows / os x worker types keyed by test-platform
+}
+
+# windows / os x worker types keyed by test-platform
+WINDOWS_WORKER_TYPES = {
     'windows7-32-vm': 'aws-provisioner-v1/gecko-t-win7-32',
     'windows7-32': 'aws-provisioner-v1/gecko-t-win7-32-gpu',
     'windows10-64-vm': 'aws-provisioner-v1/gecko-t-win10-64',
     'windows10-64': 'aws-provisioner-v1/gecko-t-win10-64-gpu',
     'windows10-64-asan': 'aws-provisioner-v1/gecko-t-win10-64-gpu',
     'macosx64': 'scl3-puppet/os-x-10-10-gw'
 }
 
@@ -145,27 +148,16 @@ test_description_schema = Schema({
     Required('loopback-video', default=False): bool,
 
     # Whether the test can run using a software GL implementation on Linux
     # using the GL compositor. May not be used with "legacy" sized instances
     # due to poor LLVMPipe performance (bug 1296086).  Defaults to true for
     # unit tests on linux platforms and false otherwise
     Optional('allow-software-gl-layers'): bool,
 
-    # The worker implementation for this test, as dictated by policy and by the
-    # test platform.
-    Optional('worker-implementation'): Any(
-        'docker-worker',
-        'native-engine',
-        'generic-worker',
-        # coming soon:
-        'docker-engine',
-        'buildbot-bridge',
-    ),
-
     # For tasks that will run in docker-worker or docker-engine, this is the
     # name of the docker image or in-tree docker image to run the task in.  If
     # in-tree, then a dependency will be created automatically.  This is
     # generally `desktop-test`, or an image that acts an awful lot like it.
     Required('docker-image', default={'in-tree': 'desktop-test'}): optionally_keyed_by(
         'test-platform',
         Any(
             # a raw Docker image path (repo/image:tag)
@@ -423,39 +415,16 @@ def set_treeherder_machine_platform(conf
     }
     for test in tests:
         test['treeherder-machine-platform'] = translation.get(
             test['build-platform'], test['test-platform'])
         yield test
 
 
 @transforms.add
-def set_worker_implementation(config, tests):
-    """Set the worker implementation based on the test platform."""
-    for test in tests:
-        test_platform = test['test-platform']
-        if test_platform.startswith('macosx'):
-            if config.config['args'].taskcluster_worker:
-                test['worker-implementation'] = 'native-engine'
-            else:
-                test['worker-implementation'] = 'generic-worker'
-        elif test.get('suite', '') == 'talos':
-            if config.config['args'].taskcluster_worker:
-                test['worker-implementation'] = 'native-engine'
-            else:
-                test['worker-implementation'] = 'buildbot-bridge'
-        elif test_platform.startswith('win'):
-            test['worker-implementation'] = 'generic-worker'
-        else:
-            test['worker-implementation'] = 'docker-worker'
-
-        yield test
-
-
-@transforms.add
 def set_tier(config, tests):
     """Set the tier based on policy for all test descriptions that do not
     specify a tier otherwise."""
     for test in tests:
         if 'tier' in test:
             resolve_keyed_by(test, 'tier', item_name=test['test-name'])
 
         # only override if not set for the test
@@ -469,18 +438,16 @@ def set_tier(config, tests):
                                          'linux64/debug',
                                          'linux64-pgo/opt',
                                          'linux64-devedition/opt',
                                          'linux64-asan/opt',
                                          'android-4.3-arm7-api-15/opt',
                                          'android-4.3-arm7-api-15/debug',
                                          'android-4.2-x86/opt']:
                 test['tier'] = 1
-            elif test['worker-implementation'] == 'native-engine':
-                test['tier'] = 3
             else:
                 test['tier'] = 2
         yield test
 
 
 @transforms.add
 def set_expires_after(config, tests):
     """Try jobs expire after 2 weeks; everything else lasts 1 year.  This helps
@@ -718,16 +685,45 @@ def parallel_stylo_tests(config, tests):
         if test['test-platform'].startswith('linux64-stylo/'):
             # add parallel stylo tests
             test['mozharness'].setdefault('extra-options', [])\
                               .append('--parallel-stylo-traversal')
             yield test
 
 
 @transforms.add
+def set_worker_type(config, tests):
+    """Set the worker type based on the test platform."""
+    for test in tests:
+        # during the taskcluuster migration, this is a bit tortured, but it
+        # will get simpler eventually!
+        test_platform = test['test-platform']
+        if test_platform.startswith('macosx'):
+            # note that some portion of these will be allocated to BBB below
+            test['worker-type'] = 'tc-worker-provisioner/gecko-t-osx-10-10'
+        elif test_platform.startswith('win'):
+            if test.get('suite', '') == 'talos':
+                test['worker-type'] = 'buildbot-bridge/buildbot-bridge'
+            else:
+                test['worker-type'] = WINDOWS_WORKER_TYPES[test_platform.split('/')[0]]
+        elif test_platform.startswith('linux') or test_platform.startswith('android'):
+            if test.get('suite', '') == 'talos':
+                if config.config['args'].taskcluster_worker:
+                    test['worker-type'] = 'releng-hardware/gecko-t-linux-talos'
+                else:
+                    test['worker-type'] = 'buildbot-bridge/buildbot-bridge'
+            else:
+                test['worker-type'] = LINUX_WORKER_TYPES[test['instance-size']]
+        else:
+            raise Exception("unknown test_platform {}".format(test_platform))
+
+        yield test
+
+
+@transforms.add
 def allocate_to_bbb(config, tests):
     """Make the load balancing between taskcluster and buildbot"""
     j = get_load_balacing_settings()
 
     tests_set = defaultdict(list)
     for test in tests:
         tests_set[test['test-platform']].append(test)
 
@@ -738,17 +734,17 @@ def allocate_to_bbb(config, tests):
         # The json file tells the percentage of tasks that run on
         # taskcluster. The logic here is inverted, as tasks have been
         # previously assigned to taskcluster. Therefore we assign the
         # 1-p tasks to buildbot-bridge.
         n = j.get(test_platform, 1.0)
         if not (test_platform.startswith('mac')
                 and config.config['args'].taskcluster_worker):
             for i in range(int(n * len(t)), len(t)):
-                t[i]['worker-implementation'] = 'buildbot-bridge'
+                t[i]['worker-type'] = 'buildbot-bridge/buildbot-bridge'
 
         for y in t:
             yield y
 
 
 @transforms.add
 def make_job_description(config, tests):
     """Convert *test* descriptions to *job* descriptions (input to
@@ -819,39 +815,19 @@ def make_job_description(config, tests):
         # run SETA unless this is a try push
         jobdesc['optimizations'] = optimizations = []
         if config.params['project'] != 'try':
             optimizations.append(['seta'])
 
         run = jobdesc['run'] = {}
         run['using'] = 'mozharness-test'
         run['test'] = test
-        worker = jobdesc['worker'] = {}
-        implementation = worker['implementation'] = test['worker-implementation']
 
-        # TODO: need some better way to express this...
-        if implementation == 'buildbot-bridge':
-            jobdesc['worker-type'] = 'buildbot-bridge/buildbot-bridge'
-        elif implementation == 'native-engine':
-            if test['test-platform'].startswith('linux'):
-                jobdesc['worker-type'] = 'releng-hardware/gecko-t-linux-talos'
-            else:
-                jobdesc['worker-type'] = 'tc-worker-provisioner/gecko-t-osx-10-10'
-        elif implementation == 'generic-worker':
-            test_platform = test['test-platform'].split('/')[0]
-            jobdesc['worker-type'] = WORKER_TYPE[test_platform]
-        elif implementation == 'docker-worker' or implementation == 'docker-engine':
-            jobdesc['worker-type'] = WORKER_TYPE[test['instance-size']]
-            worker = jobdesc['worker']
-            worker['docker-image'] = test['docker-image']
-            worker['allow-ptrace'] = True  # required for all tests, for crashreporter
-            worker['loopback-video'] = test['loopback-video']
-            worker['loopback-audio'] = test['loopback-audio']
-            worker['max-run-time'] = test['max-run-time']
-            worker['retry-exit-status'] = test['retry-exit-status']
+        jobdesc['worker-type'] = test.pop('worker-type')
+
         yield jobdesc
 
 
 def normpath(path):
     return path.replace('/', '\\')
 
 
 def get_firefox_version():
new file mode 100644
--- /dev/null
+++ b/taskcluster/taskgraph/util/workertypes.py
@@ -0,0 +1,49 @@
+# 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/.
+
+from __future__ import absolute_import, print_function, unicode_literals
+
+WORKER_TYPES = {
+    'aws-provisioner-v1/gecko-images': ('docker-worker', 'linux'),
+    'aws-provisioner-v1/gecko-1-b-android': ('docker-worker', 'linux'),
+    'aws-provisioner-v1/gecko-1-b-linux': ('docker-worker', 'linux'),
+    'aws-provisioner-v1/gecko-1-b-macosx64': ('docker-worker', 'linux'),
+    'aws-provisioner-v1/gecko-1-b-win2012': ('generic-worker', 'windows'),
+    'aws-provisioner-v1/gecko-2-b-android': ('docker-worker', 'linux'),
+    'aws-provisioner-v1/gecko-2-b-linux': ('docker-worker', 'linux'),
+    'aws-provisioner-v1/gecko-2-b-macosx64': ('docker-worker', 'linux'),
+    'aws-provisioner-v1/gecko-2-b-win2012': ('generic-worker', 'windows'),
+    'aws-provisioner-v1/gecko-3-b-android': ('docker-worker', 'linux'),
+    'aws-provisioner-v1/gecko-3-b-linux': ('docker-worker', 'linux'),
+    'aws-provisioner-v1/gecko-3-b-macosx64': ('docker-worker', 'linux'),
+    'aws-provisioner-v1/gecko-3-b-win2012': ('generic-worker', 'windows'),
+    'aws-provisioner-v1/gecko-symbol-upload': ('docker-worker', 'linux'),
+    'aws-provisioner-v1/gecko-t-linux-large': ('docker-worker', 'linux'),
+    'aws-provisioner-v1/gecko-t-linux-medium': ('docker-worker', 'linux'),
+    'aws-provisioner-v1/gecko-t-linux-xlarge': ('docker-worker', 'linux'),
+    'aws-provisioner-v1/gecko-t-win10-64': ('generic-worker', 'windows'),
+    'aws-provisioner-v1/gecko-t-win10-64-gpu': ('generic-worker', 'windows'),
+    'aws-provisioner-v1/gecko-t-win7-32': ('generic-worker', 'windows'),
+    'aws-provisioner-v1/gecko-t-win7-32-gpu': ('generic-worker', 'windows'),
+    'aws-provisioner-v1/taskcluster-generic': ('docker-worker', 'linux'),
+    'buildbot-bridge/buildbot-bridge': ('buildbot-bridge', None),
+    'invalid/invalid': ('invalid', None),
+    'null-provisioner/human-breakpoint': ('push-apk-breakpoint', None),
+    'null-provisioner/human-breakpoint': ('push-apk-breakpoint', None),
+    'releng-hardware/gecko-t-linux-talos': ('native-engine', 'linux'),
+    'scriptworker-prov-v1/balrogworker-v1': ('balrog', None),
+    'scriptworker-prov-v1/beetmoverworker-v1': ('beetmover', None),
+    'scriptworker-prov-v1/pushapk-v1': ('push-apk', None),
+    "scriptworker-prov-v1/signing-linux-v1": ('scriptworker-signing', None),
+    'tc-worker-provisioner/gecko-t-osx-10-10': ('native-engine', 'macosx'),
+}
+
+
+def worker_type_implementation(worker_type):
+    """Get the worker implementation and OS for the given workerType, where the
+    OS represents the host system, not the target OS, in the case of
+    cross-compiles."""
+    # assume that worker types for all levels are the same implementation
+    worker_type = worker_type.replace('{level}', '1')
+    return WORKER_TYPES[worker_type]