Ejemplo n.º 1
0
def _perform_mockings() -> None:
    """Mock modules and roles."""
    for role_name in options.mock_roles:
        if re.match(r"\w+\.\w+\.\w+", role_name):
            namespace, collection, role_dir = role_name.split(".")
            path = f".cache/collections/ansible_collections/{ namespace }/{ collection }/roles/{ role_dir }/"
        else:
            path = f".cache/roles/{role_name}"
        os.makedirs(path, exist_ok=True)

    if options.mock_modules:
        for module_name in options.mock_modules:
            _make_module_stub(module_name)

    # if inside a collection repo, symlink it to simulate its installed state
    if not os.path.exists("galaxy.yml"):
        return
    yaml = yaml_from_file("galaxy.yml")
    if not yaml:
        # ignore empty galaxy.yml file
        return
    namespace = yaml.get('namespace', None)
    collection = yaml.get('name', None)
    if not namespace or not collection:
        return
    p = pathlib.Path(
        f"{options.project_dir}/.cache/collections/ansible_collections/{ namespace }"
    )
    p.mkdir(parents=True, exist_ok=True)
    link_path = p / collection
    if not link_path.exists():
        link_path.symlink_to(
            pathlib.Path("../../../..", target_is_directory=True))
Ejemplo n.º 2
0
def _install_galaxy_role() -> None:
    """Detect standalone galaxy role and installs it."""
    if not os.path.exists("meta/main.yml"):
        return
    yaml = yaml_from_file("meta/main.yml")
    if 'galaxy_info' not in yaml:
        return

    fqrn = _get_role_fqrn(yaml['galaxy_info'])

    if 'role-name' not in options.skip_list:
        if not re.match(r"[a-z0-9][a-z0-9_]+\.[a-z][a-z0-9_]+$", fqrn):
            msg = (
                """\
Computed fully qualified role name of %s does not follow current galaxy requirements.
Please edit meta/main.yml and assure we can correctly determine full role name:

galaxy_info:
role_name: my_name  # if absent directory name hosting role is used instead
namespace: my_galaxy_namespace  # if absent, author is used instead

Namespace: https://galaxy.ansible.com/docs/contributing/namespaces.html#galaxy-namespace-limitations
Role: https://galaxy.ansible.com/docs/contributing/creating_role.html#role-names

As an alternative, you can add 'role-name' to either skip_list or warn_list.
"""
                % fqrn
            )
            if 'role-name' in options.warn_list:
                _logger.warning(msg)
            else:
                _logger.error(msg)
                sys.exit(INVALID_PREREQUISITES_RC)
    else:
        # when 'role-name' is in skip_list, we stick to plain role names
        if 'role_name' in yaml['galaxy_info']:
            role_namespace = _get_galaxy_role_ns(yaml['galaxy_info'])
            role_name = _get_galaxy_role_name(yaml['galaxy_info'])
            fqrn = f"{role_namespace}{role_name}"
        else:
            fqrn = pathlib.Path(".").absolute().name
    p = pathlib.Path(f"{options.cache_dir}/roles")
    p.mkdir(parents=True, exist_ok=True)
    link_path = p / fqrn
    # despite documentation stating that is_file() reports true for symlinks,
    # it appears that is_dir() reports true instead, so we rely on exits().
    target = pathlib.Path(options.project_dir).absolute()
    if not link_path.exists() or os.readlink(link_path) != str(target):
        if link_path.exists():
            link_path.unlink()
        link_path.symlink_to(target, target_is_directory=True)
    _logger.info(
        "Using %s symlink to current repository in order to enable Ansible to find the role using its expected full name.",
        link_path,
    )
Ejemplo n.º 3
0
def prepare_environment() -> None:
    """Make dependencies available if needed."""
    if not options.offline and os.path.exists("requirements.yml"):

        cmd = [
            "ansible-galaxy",
            "role",
            "install",
            "--roles-path",
            f"{options.project_dir}/.cache/roles",
            "-vr",
            "requirements.yml",
        ]

        print("Running %s" % " ".join(cmd), file=sys.stderr)
        run = subprocess.run(
            cmd,
            universal_newlines=True,
            check=False,
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT,
        )
        if run.returncode != 0:
            print(run.stdout, file=sys.stderr)
            sys.exit(run.returncode)

        # Run galaxy collection install works on v2 requirements.yml
        if "collections" in yaml_from_file("requirements.yml"):

            cmd = [
                "ansible-galaxy",
                "collection",
                "install",
                "-p",
                f"{options.project_dir}/.cache/collections",
                "-vr",
                "requirements.yml",
            ]

            print("Running %s" % " ".join(cmd), file=sys.stderr)
            run = subprocess.run(
                cmd,
                universal_newlines=True,
                check=False,
                stdout=subprocess.PIPE,
                stderr=subprocess.STDOUT,
            )
            if run.returncode != 0:
                print(run.stdout, file=sys.stderr)
                sys.exit(run.returncode)

    _install_galaxy_role()
    _perform_mockings()
    _prepare_ansible_paths()
Ejemplo n.º 4
0
def install_requirements(requirement: str) -> None:
    """Install dependencies from a requirements.yml."""
    if not os.path.exists(requirement):
        return

    cmd = [
        "ansible-galaxy",
        "role",
        "install",
        "--roles-path",
        f"{options.cache_dir}/roles",
        "-vr",
        f"{requirement}",
    ]

    _logger.info("Running %s", " ".join(cmd))
    run = subprocess.run(
        cmd,
        universal_newlines=True,
        check=False,
        stdout=subprocess.PIPE,
        stderr=subprocess.STDOUT,
    )
    if run.returncode != 0:
        _logger.error(run.stdout)
        raise RuntimeError(run.returncode)

    # Run galaxy collection install works on v2 requirements.yml
    if "collections" in yaml_from_file(requirement):

        cmd = [
            "ansible-galaxy",
            "collection",
            "install",
            "-p",
            f"{options.cache_dir}/collections",
            "-vr",
            f"{requirement}",
        ]

        _logger.info("Running %s", " ".join(cmd))
        run = subprocess.run(
            cmd,
            universal_newlines=True,
            check=False,
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT,
        )
        if run.returncode != 0:
            _logger.error(run.stdout)
            raise RuntimeError(run.returncode)
Ejemplo n.º 5
0
def _install_galaxy_role() -> None:
    """Detect standalone galaxy role and installs it."""
    if not os.path.exists("meta/main.yml"):
        return
    yaml = yaml_from_file("meta/main.yml")
    if 'galaxy_info' not in yaml:
        return
    role_name = yaml['galaxy_info'].get('role_name', None)
    role_author = yaml['galaxy_info'].get('author', None)
    if not role_name:
        role_name = pathlib.Path(".").absolute().name
        role_name = re.sub(r'^{0}'.format(re.escape('ansible-role-')), '',
                           role_name)
    fqrn = f"{role_author}.{role_name}"
    if not re.match(r"[a-z0-9][a-z0-9_]+\.[a-z][a-z0-9_]+$", fqrn):
        print(
            f"""\
Computed fully qualified role name of {fqrn} is not valid.
Please edit meta/main.yml and assure we can correctly determine full role name:

galaxy_info:
  role_name: my_name  # if absent directory name hosting role is used instead
  author: my_galaxy_namespace

Namespace: https://galaxy.ansible.com/docs/contributing/namespaces.html#galaxy-namespace-limitations
Role: https://galaxy.ansible.com/docs/contributing/creating_role.html#role-names
""",
            file=sys.stderr,
        )
        sys.exit(INVALID_PREREQUISITES_RC)
    p = pathlib.Path(f"{options.project_dir}/.cache/roles")
    p.mkdir(parents=True, exist_ok=True)
    link_path = p / f"{role_author}.{role_name}"
    # despite documentation stating that is_file() reports true for symlinks,
    # it appears that is_dir() reports true instead, so we rely on exits().
    if not link_path.exists():
        link_path.symlink_to(pathlib.Path("../..", target_is_directory=True))
    print(
        f"Using {link_path} symlink to current repository in order to enable Ansible to find the role using its expected full name.",
        file=sys.stderr,
    )
Ejemplo n.º 6
0
def prepare_environment() -> None:
    """Make dependencies available if needed."""
    if not options.configured:
        # Allow method to be used without calling the command line, so we can
        # reuse it in other tools, like molecule.
        # pylint: disable=import-outside-toplevel,cyclic-import
        from ansiblelint.__main__ import initialize_options

        initialize_options()

    if not options.offline and os.path.exists("requirements.yml"):

        cmd = [
            "ansible-galaxy",
            "role",
            "install",
            "--roles-path",
            f"{options.project_dir}/.cache/roles",
            "-vr",
            "requirements.yml",
        ]

        _logger.info("Running %s", " ".join(cmd))
        run = subprocess.run(
            cmd,
            universal_newlines=True,
            check=False,
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT,
        )
        if run.returncode != 0:
            _logger.error(run.stdout)
            sys.exit(run.returncode)

        # Run galaxy collection install works on v2 requirements.yml
        if "collections" in yaml_from_file("requirements.yml"):

            cmd = [
                "ansible-galaxy",
                "collection",
                "install",
                "-p",
                f"{options.project_dir}/.cache/collections",
                "-vr",
                "requirements.yml",
            ]

            _logger.info("Running %s", " ".join(cmd))
            run = subprocess.run(
                cmd,
                universal_newlines=True,
                check=False,
                stdout=subprocess.PIPE,
                stderr=subprocess.STDOUT,
            )
            if run.returncode != 0:
                _logger.error(run.stdout)
                sys.exit(run.returncode)

    _install_galaxy_role()
    _perform_mockings()
    _prepare_ansible_paths()