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))
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)
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' )
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)
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)
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
def exit(self, message=None, status=0): raise FailedCommandError(message, exit_code=status)
def error(self, msg): raise FailedCommandError(msg)