Beispiel #1
0
    def check_application(self, requested_app, objdir=None):
        '''Verify that the objdir and work dir are for the expected application
        '''

        try:
            work_dir_app = self.read_json_file('app.json')['application']
            if work_dir_app != requested_app:
                raise FailedCommandError(
                    'work dir {} is for the wrong app {}'.format(
                        self.work_dir, work_dir_app
                    )
                )
        except IOError:
            # work dir has not been created or initialized yet, so we're good.
            pass

        try:
            if not objdir:
                objdir = self.topobjdir
            mozinfo = self.read_json_file(os.path.join(objdir, 'mozinfo.json'))
            if mozinfo.get('buildapp') != requested_app:
                raise FailedCommandError(
                    'objdir {} is for the wrong app {}, clobber required'.format(
                        objdir, mozinfo.get('buildapp')
                    )
                )
        except (OSError, IOError):
            pass
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,
            )
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))
Beispiel #4
0
    def build_shell(self, command_context, **kwargs):
        """Build a JS shell to use to run the rooting hazard analysis."""
        # The JS shell requires some specific configuration settings to execute
        # the hazard analysis code, and configuration is done via mozconfig.
        # Subprocesses find MOZCONFIG in the environment, so we can't just
        # modify the settings in this process's loaded version. Pass it through
        # the environment.

        default_mozconfig = "js/src/devtools/rootAnalysis/mozconfig.haz_shell"
        mozconfig_path = (kwargs.pop("mozconfig", None)
                          or os.environ.get("MOZCONFIG") or default_mozconfig)
        mozconfig_path = os.path.join(self.topsrcdir, mozconfig_path)
        loader = MozconfigLoader(self.topsrcdir)
        mozconfig = loader.read_mozconfig(mozconfig_path)

        # Validate the mozconfig settings in case the user overrode the default.
        configure_args = mozconfig["configure_args"]
        if "--enable-ctypes" not in configure_args:
            raise FailedCommandError(
                "ctypes required in hazard JS shell, mozconfig=" +
                mozconfig_path)

        # Transmit the mozconfig location to build subprocesses.
        os.environ["MOZCONFIG"] = mozconfig_path

        self.setup_env_for_tools(os.environ)

        # Set a default objdir for the shell, for developer builds.
        os.environ.setdefault("MOZ_OBJDIR",
                              os.path.join(self.topsrcdir, "obj-haz-shell"))

        return self._mach_context.commands.dispatch("build",
                                                    self._mach_context,
                                                    **kwargs)
Beispiel #5
0
 def ensure_shell(self):
     try:
         return self.read_json_file("shell.json")['js']
     except OSError:
         raise FailedCommandError(
             'must build the JS shell with `mach hazards build-shell` first'
         )
Beispiel #6
0
    def build_shell(self, **kwargs):
        '''Build a JS shell to use to run the rooting hazard analysis.'''
        # The JS shell requires some specific configuration settings to execute
        # the hazard analysis code, and configuration is done via mozconfig.
        # Subprocesses find MOZCONFIG in the environment, so we can't just
        # modify the settings in this process's loaded version. Pass it through
        # the environment.

        default_mozconfig = 'js/src/devtools/rootAnalysis/mozconfig.haz_shell'
        mozconfig_path = kwargs.pop('mozconfig', None) \
            or os.environ.get('MOZCONFIG') \
            or default_mozconfig
        mozconfig_path = os.path.join(self.topsrcdir, mozconfig_path)
        loader = MozconfigLoader(self.topsrcdir)
        mozconfig = loader.read_mozconfig(mozconfig_path)

        # Validate the mozconfig settings in case the user overrode the default.
        configure_args = mozconfig['configure_args']
        if '--enable-ctypes' not in configure_args:
            raise FailedCommandError('ctypes required in hazard JS shell')

        # Transmit the mozconfig location to build subprocesses.
        os.environ['MOZCONFIG'] = mozconfig_path

        # Record the location of the JS shell in the analysis work dir.
        self.write_json_file(
            "shell.json",
            {'js': os.path.join(mozconfig['topobjdir'], "dist/bin/js")})

        return self._mach_context.commands.dispatch('build',
                                                    self._mach_context,
                                                    **kwargs)
Beispiel #7
0
    def ensure_shell(self, objdir):
        if objdir is None:
            objdir = os.path.join(self.topsrcdir, "obj-haz-shell")

        try:
            binaries = self.read_json_file(
                os.path.join(objdir, "binaries.json"))
            info = [b for b in binaries["programs"] if b["program"] == "js"][0]
            return os.path.join(objdir, info["install_target"], "js")
        except (OSError, KeyError):
            raise FailedCommandError("""\
no shell found in %s -- must build the JS shell with `mach hazards build-shell` first"""
                                     % objdir)
Beispiel #8
0
def cross_channel(
    command_context,
    strings_path,
    outgoing_path,
    actions,
    attempts,
    ssh_secret,
    **kwargs,
):
    """Run l10n cross-channel content generation."""
    # This can be any path, as long as the name of the directory is en-US.
    # Not entirely sure where this is a requirement; perhaps in l10n
    # string manipulation logic?
    if strings_path.name != "en-US":
        raise FailedCommandError("strings_path needs to be named `en-US`")
    command_context.activate_virtualenv()
    # XXX pin python requirements
    command_context.virtualenv_manager.install_pip_requirements(
        Path(os.path.dirname(__file__)) / "requirements.in")
    strings_path = strings_path.resolve()  # abspath
    if outgoing_path:
        outgoing_path = outgoing_path.resolve()  # abspath
    try:
        with tempfile.TemporaryDirectory() as ssh_key_dir:
            retry(
                _do_create_content,
                attempts=attempts,
                retry_exceptions=(RetryError, ),
                args=(
                    command_context,
                    strings_path,
                    outgoing_path,
                    ssh_secret,
                    Path(ssh_key_dir),
                    actions,
                ),
            )
    except RetryError as exc:
        raise FailedCommandError(exc) from exc
Beispiel #9
0
 def exit(self, message=None, status=0):
     raise FailedCommandError(message, exit_code=status)
Beispiel #10
0
 def error(self, msg):
     raise FailedCommandError(msg)