def run_playbook(playbook_path,
                 inventory_path,
                 a_cfg_path,
                 connection,
                 extra_variables=None,
                 ansible_args=None,
                 debug=False,
                 environment=None):
    """
    run selected ansible playbook and return output from ansible-playbook run

    :param playbook_path:
    :param inventory_path:
    :param a_cfg_path:
    :param connection:
    :param extra_variables:
    :param ansible_args:
    :param debug:
    :param environment:

    :return: output
    """
    ap = ap_command_exists()
    cmd_args = [
        ap,
        "-i",
        inventory_path,
        "-c",
        connection,
    ]
    if debug:
        cmd_args += ["-vvv"]
    if extra_variables:
        cmd_args += ["--extra-vars"] + \
                    [" ".join(
                        ["{}={}".format(k, v)
                         for k, v in extra_variables.items()]
                    )]
    cmd_args += [playbook_path]
    logger.debug("%s", " ".join(cmd_args))

    env = os.environ.copy()
    if environment:
        env.update(environment)
    env["ANSIBLE_CONFIG"] = a_cfg_path

    # TODO: does ansible have an API?
    try:
        return run_cmd(
            cmd_args,
            print_output=True,
            env=env,
            return_all_output=True,
        )
    except subprocess.CalledProcessError as ex:
        raise AbBuildUnsuccesful("ansible-playbook execution failed: %s" % ex,
                                 ex.output)
def test_ansibles_python(m, is_py2):
    m()
    cmd = ap_command_exists()
    assert is_ansibles_python_2(cmd) == is_py2
Beispiel #3
0
def run_playbook(playbook_path,
                 inventory_path,
                 a_cfg_path,
                 connection,
                 extra_variables=None,
                 ansible_args=None,
                 debug=False,
                 environment=None,
                 try_unshare=True,
                 provide_output=True,
                 log_stderr=False):
    """
    run selected ansible playbook and return output from ansible-playbook run

    :param playbook_path:
    :param inventory_path:
    :param a_cfg_path:
    :param connection:
    :param extra_variables:
    :param ansible_args: list of str, extra arguments for a-p
    :param debug:
    :param environment:
    :param try_unshare: bool, do `buildah unshare` if uid > 0
    :param provide_output: bool, present output to user
    :param log_stderr: bool, log errors coming from stderr to our logger

    :return: output
    """
    ap = ap_command_exists()
    if is_ansibles_python_2(ap):
        # I just realized it could work, we would just had to disable the
        # callback plugin: no caching and layering
        raise RuntimeError(
            "ansible-bender is written in python 3 and does not work in python 2,\n"
            f"it seems that {ap} is using python 2 - ansible-bender will not"
            "work in such environment\n")
    cmd_args = [
        ap,
        "-c",
        connection,
    ]
    if inventory_path:
        cmd_args += ["-i", inventory_path]
    if debug:
        cmd_args += ["-vvv"]
    if extra_variables:
        cmd_args += ["--extra-vars"] + \
                    [" ".join(
                        ["{}={}".format(k, v)
                         for k, v in extra_variables.items()]
                    )]
    if ansible_args:
        cmd_args += ansible_args
    cmd_args += [playbook_path]
    logger.debug("%s", " ".join(cmd_args))

    env = os.environ.copy()
    env["ANSIBLE_RETRY_FILES_ENABLED"] = "0"
    if debug:
        env["ANSIBLE_STDOUT_CALLBACK"] = "debug"
    if environment:
        env.update(environment)
    if a_cfg_path:
        env["ANSIBLE_CONFIG"] = a_cfg_path

    if try_unshare and os.getuid() != 0:
        logger.info("we are running rootless, prepending `buildah unshare`")
        # rootless, we need to `buildah unshare` for sake of `buildah mount`
        # https://github.com/containers/buildah/issues/1271
        # the need for `--` https://github.com/containers/buildah/issues/1374
        cmd_args = ["buildah", "unshare", "--"] + cmd_args

    # ansible has no official python API, the API they have is internal and said to break compat
    try:
        return run_cmd(
            cmd_args,
            print_output=provide_output,
            save_output_in_exc=True,
            env=env,
            return_all_output=provide_output,
            log_stderr=log_stderr,
        )
    except subprocess.CalledProcessError as ex:
        raise ABBuildUnsuccesful("ansible-playbook execution failed: %s" % ex,
                                 ex.output)