Source code

Revision control

Other Tools

# -*- coding: utf-8 -*-
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
from __future__ import absolute_import, print_function, unicode_literals
import logging
import os
import shutil
import subprocess
import tempfile
from contextlib import contextmanager
from pathlib import Path
from appdirs import user_config_dir
import taskcluster
from mach.base import FailedCommandError
from gecko_taskgraph import GECKO
logger = logging.getLogger(__name__)
TASK_TYPES = {
"signing": ["linux-signing", "linux-signing-partial"],
"beetmover": ["beetmover-candidates"],
"bouncer": ["bouncer-submit"],
"balrog": ["balrog-submit"],
"tree": ["tree"],
}
def get_secret(secret):
# use proxy if configured, otherwise local credentials from env vars
if "TASKCLUSTER_PROXY_URL" in os.environ:
secrets_options = {"rootUrl": os.environ["TASKCLUSTER_PROXY_URL"]}
else:
secrets_options = taskcluster.optionsFromEnvironment()
secrets = taskcluster.Secrets(secrets_options)
return secrets.get(secret)["secret"]
@contextmanager
def configure_ssh(ssh_key_secret):
if ssh_key_secret is None:
yield
# If we get here, we are runnig in automation.
# We use a user hgrc, so that we are also get the system-wide hgrc
# settings.
hgrc = Path(user_config_dir("hg")).joinpath("hgrc")
if hgrc.exists():
raise FailedCommandError(
"Not overwriting `{}`; cannot configure ssh.".format(hgrc)
)
try:
ssh_key_dir = Path(tempfile.mkdtemp())
ssh_key = get_secret(ssh_key_secret)
ssh_key_file = ssh_key_dir.joinpath("id_rsa")
ssh_key_file.write_text(ssh_key["ssh_privkey"])
ssh_key_file.chmod(0o600)
hgrc_content = (
"[ui]\n"
"username = trybld\n"
"ssh = ssh -i {path} -l {user}\n".format(
path=ssh_key_file, user=ssh_key["user"]
)
)
hgrc.write_text(hgrc_content)
yield
finally:
shutil.rmtree(str(ssh_key_dir))
os.remove(str(hgrc))
def push_canary(scriptworkers, addresses, ssh_key_secret):
if ssh_key_secret and os.environ.get("MOZ_AUTOMATION", "0") != "1":
# We make assumptions about the layout of the docker image
# for creating the hgrc that we use for the key.
raise FailedCommandError("Cannot use ssh-key-secret outside of automation.")
# Collect the set of `mach try scriptworker` task sets to run.
tasks = []
for scriptworker in scriptworkers:
worker_tasks = TASK_TYPES.get(scriptworker)
if worker_tasks:
logger.info("Running tasks for {}: {}".format(scriptworker, worker_tasks))
tasks.extend(worker_tasks)
else:
logger.info("No tasks for {}.".format(scriptworker))
mach = Path(GECKO).joinpath("mach")
base_command = [str(mach), "try", "scriptworker"]
for address in addresses:
base_command.extend(
[
"--route",
"notify.email.{}.on-failed".format(address),
"--route",
"notify.email.{}.on-exception".format(address),
]
)
with configure_ssh(ssh_key_secret):
env = os.environ.copy()
for task in tasks:
subprocess.check_call(base_command + [task], env=env)