1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
|
# 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/.
import logging
import os
import shutil
import subprocess
import tempfile
from contextlib import contextmanager
from pathlib import Path
import taskcluster
from appdirs import user_config_dir
from gecko_taskgraph import GECKO
from mach.base import FailedCommandError
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 use 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 running in automation.
# We use a user hgrc, so that we also get the system-wide hgrc settings.
hgrc = Path(user_config_dir("hg")) / "hgrc"
if hgrc.exists():
raise FailedCommandError(f"Not overwriting `{hgrc}`; cannot configure ssh.")
try:
ssh_key_dir = Path(tempfile.mkdtemp())
ssh_key = get_secret(ssh_key_secret)
ssh_key_file = ssh_key_dir / "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))
hgrc.unlink()
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(f"Running tasks for {scriptworker}: {worker_tasks}")
tasks.extend(worker_tasks)
else:
logger.info(f"No tasks for {scriptworker}.")
mach = Path(GECKO) / "mach"
base_command = [str(mach), "try", "scriptworker", "--closed-tree", "--push-to-vcs"]
for address in addresses:
base_command.extend(
[
"--route",
f"notify.email.{address}.on-failed",
"--route",
f"notify.email.{address}.on-exception",
]
)
with configure_ssh(ssh_key_secret):
env = os.environ.copy()
for task in tasks:
subprocess.check_call(base_command + [task], env=env)
|