Ejemplo n.º 1
0
def run_process_activity(activity: Activity, configuration: Configuration,
                         secrets: Secrets) -> Any:
    """
    Run the a process activity.

    A process activity is an executable the current user is allowed to apply.
    The raw result of that command is returned as bytes of this activity.

    Raises :exc:`ActivityFailed` when a the process takes longer than the
    timeout defined in the activity. There is no timeout by default so be
    careful when you do not explicitly provide one.

    This should be considered as a private function.
    """
    provider = activity["provider"]
    timeout = provider.get("timeout", None)
    arguments = provider.get("arguments", [])

    if arguments and (configuration or secrets):
        arguments = substitute(arguments, configuration, secrets)

    shell = False
    path = shutil.which(os.path.expanduser(provider["path"]))
    if isinstance(arguments, str):
        shell = True
        arguments = "{} {}".format(path, arguments)
    else:
        if isinstance(arguments, dict):
            arguments = itertools.chain.from_iterable(arguments.items())

        arguments = list([str(p) for p in arguments if p not in (None, "")])
        arguments.insert(0, path)

    try:
        logger.debug("Running: {a}".format(a=str(arguments)))
        proc = subprocess.run(arguments,
                              timeout=timeout,
                              stdout=subprocess.PIPE,
                              stderr=subprocess.PIPE,
                              env=os.environ,
                              shell=shell)
    except subprocess.TimeoutExpired:
        raise ActivityFailed("process activity took too long to complete")

    # kind warning to the user that this process returned a non--zero
    # exit code, as traditionally used to indicate a failure,
    # but not during the hypothesis check because that could also be
    # exactly what the user want. This warning is helpful during the
    # method and rollbacks
    if "tolerance" not in activity and proc.returncode > 0:
        logger.warning(
            "This process returned a non-zero exit code. "
            "This may indicate some error and not what you expected. "
            "Please have a look at the logs.")

    stdout = decode_bytes(proc.stdout)
    stderr = decode_bytes(proc.stderr)

    return {"status": proc.returncode, "stdout": stdout, "stderr": stderr}
Ejemplo n.º 2
0
def run_process_activity(activity: Activity, configuration: Configuration,
                         secrets: Secrets) -> Any:
    """
    Run the a process activity.

    A process activity is an executable the current user is allowed to apply.
    The raw result of that command is returned as bytes of this activity.

    Raises :exc:`ActivityFailed` when a the process takes longer than the
    timeout defined in the activity. There is no timeout by default so be
    careful when you do not explicitly provide one.

    This should be considered as a private function.
    """
    provider = activity["provider"]
    timeout = provider.get("timeout", None)
    arguments = provider.get("arguments", [])

    if arguments and (configuration or secrets):
        arguments = substitute(arguments, configuration, secrets)

    shell = False
    path = shutil.which(provider["path"])
    if isinstance(arguments, str):
        shell = True
        arguments = "{} {}".format(path, arguments)
    else:
        if isinstance(arguments, dict):
            arguments = itertools.chain.from_iterable(arguments.items())

        arguments = list([str(p) for p in arguments if p not in (None, "")])
        arguments.insert(0, path)

    try:
        logger.debug("Running: {a}".format(a=str(arguments)))
        proc = subprocess.run(
            arguments, timeout=timeout, stdout=subprocess.PIPE,
            stderr=subprocess.PIPE, env=os.environ, shell=shell)
    except subprocess.TimeoutExpired:
        raise ActivityFailed("process activity took too long to complete")

    stdout = decode_bytes(proc.stdout)
    stderr = decode_bytes(proc.stderr)

    return {
        "status": proc.returncode,
        "stdout": stdout,
        "stderr": stderr
    }