跳至内容

配置

Config 类。

Molecule 通过 glob `molecule/*/molecule.yml` 在当前目录中搜索 `molecule.yml` 文件。这些文件被实例化为 Molecule molecule.config.Config 对象列表,每个 Molecule 子命令都对此列表进行操作。

`molecule.yml` 所在的目录是场景的目录。Molecule 在此目录中执行大部分功能。

molecule.config.Config 对象实例化 Dependency、Driver、Platforms、Provisioner、Verifier_、scenario 和 State_ 引用。

初始化一个新的配置类并返回 None。

参数:molecule_file:包含要解析的 Molecule 文件路径的字符串。args:来自 CLI 的选项、参数和命令的可选字典。command_args:来自 CLI 传递给子命令的可选选项字典。ansible_args:提供给 `ansible-playbook` 命令的可选参数元组。

源代码位于 `src/molecule/config.py`
def __init__(
    self,
    molecule_file: str,  # pylint: disable=redefined-outer-name
    args: MoleculeArgs = {},  # noqa: B006
    command_args: CommandArgs = {},  # noqa: B006
    ansible_args: tuple[str, ...] = (),
) -> None:
    """Initialize a new config class and returns None.

    Args:
        molecule_file: A string containing the path to the Molecule file to be parsed.
        args: An optional dict of options, arguments and commands from the CLI.
        command_args: An optional dict of options passed to the subcommand from the CLI.
        ansible_args: An optional tuple of arguments provided to the `ansible-playbook` command.
    """
    self.molecule_file = molecule_file
    self.args = args
    self.command_args = command_args
    self.ansible_args = ansible_args
    self.config = self._get_config()
    self._action: str | None = None
    self._run_uuid = str(uuid4())
    self.project_directory = os.getenv(
        "MOLECULE_PROJECT_DIRECTORY",
        os.getcwd(),  # noqa: PTH109
    )
    self.runtime = app.runtime
    self.scenario_path = Path(molecule_file).parent

    # Former after_init() contents
    self.config = self._reget_config()
    if self.molecule_file:
        self._validate()

action 属性 可写

Action 值。

返回:action 的值。

ansible_collections_path 属性

返回当前 Ansible 版本的集合路径变量。

返回:要使用的正确的 ansible 集合路径。

cache_directory 属性

要使用的正确的缓存目录。

返回:如果处于并行模式,则返回 "molecule" 或 "molecule_parallel"。

collection_directory 属性

包含 molecule 文件的集合的位置。

返回:包含 molecule 文件的集合的根目录。

config_file 属性

配置文件的路径。

返回:配置文件的路径。

debug 属性

Molecule 是否处于调试模式。

返回:Molecule 是否处于调试模式。

env 属性

环境变量。

返回:计算出的环境变量的总集合。

env_file 属性

返回 env 文件的路径。

返回:配置的 env 文件的路径。

is_parallel 属性

Molecule 是否处于并行模式。

返回:Molecule 是否处于并行模式。

molecule_directory 属性

此项目的 Molecule 目录。

返回:此项目的相应 Molecule 目录。

platform_name 属性

配置的平台。

返回:指定的平台插件的名称。

subcommand 属性

正在使用的子命令。

返回:当前正在运行的子命令。

collection()

从 galaxy.yml 获取的集合元数据。

返回:关于 Molecule 在其中运行的集合(如果有)的信息字典。

源代码位于 `src/molecule/config.py`
@cached_property
def collection(self) -> CollectionData | None:
    """Collection metadata sourced from galaxy.yml.

    Returns:
        A dictionary of information about the collection molecule is running inside, if any.
    """
    collection_directory = self.collection_directory
    if not collection_directory:
        return None

    galaxy_file = collection_directory / "galaxy.yml"
    galaxy_data: CollectionData = util.safe_load_file(galaxy_file)

    important_keys = {"name", "namespace"}
    if missing_keys := important_keys.difference(galaxy_data.keys()):
        LOG.warning(
            "The detected galaxy.yml file (%s) is invalid, missing mandatory field %s",
            galaxy_file,
            util.oxford_comma(missing_keys),
        )
        return None  # pragma: no cover

    return galaxy_data

dependency()

正在使用的依赖项管理器。

返回:Molecule 依赖项插件的实例。

源代码位于 `src/molecule/config.py`
@cached_property
def dependency(self) -> Dependency | None:
    """Dependency manager in use.

    Returns:
        Instance of a molecule dependency plugin.
    """
    dependency_name = self.config["dependency"]["name"]
    if dependency_name == "galaxy":
        return ansible_galaxy.AnsibleGalaxy(self)
    if dependency_name == "shell":
        return shell.Shell(self)
    return None

driver()

返回驱动程序。

返回:此场景的驱动程序。

源代码位于 `src/molecule/config.py`
@cached_property
def driver(self) -> Driver:
    """Return driver.

    Returns:
        The driver for this scenario.
    """
    driver_name = self._get_driver_name()
    driver = None

    api_drivers = api.drivers(config=self)
    if driver_name not in api_drivers:
        msg = f"Failed to find driver {driver_name}. Please ensure that the driver is correctly installed."  # noqa: E501
        util.sysexit_with_message(msg)

    driver = api_drivers[driver_name]
    driver.name = driver_name

    return driver

platforms()

此运行的平台。

返回:Molecule Platforms 实例。

源代码位于 `src/molecule/config.py`
@cached_property
def platforms(self) -> platforms.Platforms:
    """Platforms for this run.

    Returns:
        A molecule Platforms instance.
    """
    return platforms.Platforms(
        self,
        parallelize_platforms=self.is_parallel,
        platform_name=self.platform_name,
    )

provisioner()

此运行的供应器。

返回:Ansible 供应器的实例。

源代码位于 `src/molecule/config.py`
@cached_property
def provisioner(self) -> ansible.Ansible | None:
    """Provisioner for this run.

    Returns:
        An instance of the Ansible provisioner.
    """
    provisioner_name = self.config["provisioner"]["name"]
    if provisioner_name == "ansible":
        return ansible.Ansible(self)
    return None

scenario()

此运行的场景。

返回:Molecule 场景实例。

源代码位于 `src/molecule/config.py`
@cached_property
def scenario(self) -> scenario.Scenario:
    """Scenario for this run.

    Returns:
        A molecule Scenario instance.
    """
    return scenario.Scenario(self)

state()

Molecule 状态对象。

返回:Molecule 状态实例。

源代码位于 `src/molecule/config.py`
@cached_property
def state(self) -> State:
    """Molecule state object.

    Returns:
        A molecule State instance.
    """
    myState = state.State(self)  # noqa: N806
    # look at state file for molecule.yml date modified and warn if they do not match
    if self.molecule_file and os.path.isfile(self.molecule_file):  # noqa: PTH113
        modTime = os.path.getmtime(self.molecule_file)  # noqa: PTH204, N806
        if myState.molecule_yml_date_modified is None:
            myState.change_state("molecule_yml_date_modified", modTime)
        elif myState.molecule_yml_date_modified != modTime:
            LOG.warning(
                "The scenario config file ('%s') has been modified since the scenario was created. "  # noqa: E501
                "If recent changes are important, reset the scenario with 'molecule destroy' to clean up created items or "  # noqa: E501
                "'molecule reset' to clear current configuration.",
                self.molecule_file,
            )

    return state.State(self)

verifier()

检索当前验证器。

引发:RuntimeError:如果无法找到驱动程序。

返回:Verifier 驱动程序的实例。

源代码位于 `src/molecule/config.py`
@cached_property
def verifier(self) -> Verifier:
    """Retrieve current verifier.

    Raises:
        RuntimeError: If is not able to find the driver.

    Returns:
        Instance of Verifier driver.
    """
    name = self.config["verifier"]["name"]
    if name not in api.verifiers(self):
        msg = f"Unable to find '{name}' verifier driver."
        raise RuntimeError(msg)
    return api.verifiers(self)[name]

write()

将配置文件写入文件系统。

源代码位于 `src/molecule/config.py`
def write(self) -> None:
    """Write config file to filesystem."""
    util.write_file(self.config_file, util.safe_dump(self.config))

预运行

为了帮助 Ansible 找到使用的模块和角色,Molecule 将执行一组预运行操作。这包括安装项目级别指定的 `requirements.yml` 中的依赖项,安装独立角色或集合。目标是 `project_dir/.cache`,代码本身是从 ansible-lint 重用的,ansible-lint 也必须执行相同的操作。(注意:Molecule 不包含 ansible-lint。)

这确保当您在 Molecule playbook 中包含角色时,Ansible 能够找到该角色,并且包含的内容与您期望在生产中使用的内容完全相同。

如果出于某种原因预运行操作不符合您的需求,您仍然可以通过在配置文件中添加 `prerun: false` 来禁用它。

请记住,您可以将此值添加到 `$HOME` 中的 `.config/molecule/config.yml` 文件或项目的根目录中,以避免将其添加到每个场景中。

角色名称检查

默认情况下,`Molecule` 将检查角色名称是否符合名称标准。如果不符合,它将引发错误。

如果计算出的完全限定角色名称不符合当前的 Galaxy 要求,您可以通过在配置文件中添加 `role_name_check:1` 来忽略它。

强烈建议遵循命名空间角色的名称标准。`计算出的完全限定角色名称` 还可以包含点字符。

变量替换

配置选项可能包含环境变量。

例如,假设 shell 包含VERIFIER_NAME=testinfra,并提供了以下 molecule.yml 文件。

    verifier:
      - name: ${VERIFIER_NAME}

Molecule 将用VERIFIER_NAME环境变量的值替换$VERIFIER_NAME

警告

如果未设置环境变量,Molecule 将用空字符串替换。

同时支持$VARIABLE${VARIABLE}语法。还支持扩展的 shell 风格特性,例如${VARIABLE-default}${VARIABLE:-default}。甚至也支持将默认值设置为另一个环境变量,例如${VARIABLE-$DEFAULT}${VARIABLE:-$DEFAULT}。当两个变量均未定义时,返回空字符串。

如果在配置中需要字面美元符号,请使用双美元符号 ($$)。

Molecule 将替换在molecule.yml中定义的特殊MOLECULE_环境变量。

注意

请记住,MOLECULE_命名空间保留给 Molecule 使用。请不要以MOLECULE_作为您自己的变量前缀。

可以在项目根目录中放置一个名为.env.yml的文件,Molecule 在渲染molecule.yml时将读取其中的变量。请参见命令用法。

构造 Interpolator。

参数:templater: 一个模板引擎类。mapping: 一个映射对象。

源代码位于src/molecule/interpolation.py
def __init__(
    self,
    templater: type[TemplateWithDefaults],
    mapping: MutableMapping[str, str],
) -> None:
    """Construct Interpolator.

    Args:
        templater: A templater class.
        mapping: A mapping object.
    """
    self.templater = templater
    self.mapping = mapping

interpolate(string, keep_string=None)

使用此 Interpolator 的映射对字符串进行模板化。

参数:string: 要修改的字符串。keep_string: 要保持不变的子字符串,无论映射如何。

返回值:修改后的字符串。

引发异常:InvalidInterpolation: 当插值失败时。

源代码位于src/molecule/interpolation.py
def interpolate(
    self,
    string: str,  # pylint: disable=redefined-outer-name
    keep_string: str | None = None,
) -> str:
    """Template string with this Interpolator's mapping.

    Args:
        string: The string to modify.
        keep_string: A substring to keep intact, regardless of mapping.

    Returns:
        The modified string.

    Raises:
        InvalidInterpolation: When the interpolation fails.
    """
    try:
        return self.templater(string).substitute(self.mapping, keep_string)
    except ValueError as e:
        raise InvalidInterpolation(string, e) from e

以下是molecule.yml中可用的环境变量

MOLECULE_DEBUG

是否开启调试模式

MOLECULE_FILE

Molecule 配置文件路径,通常为~/.cache/molecule/<role-name>/<scenario-name>/molecule.yml

MOLECULE_ENV_FILE

Molecule 环境文件路径,通常为<role_path>/.env.yml

MOLECULE_STATE_FILE

Molecule 状态文件路径,包含实例的状态(已创建、已收敛等)。通常为~/.cache/molecule/<role-name>/<scenario-name>/state.yml

MOLECULE_INVENTORY_FILE

生成的清单文件路径,通常为~/.cache/molecule/<role-name>/<scenario-name>/inventory/ansible_inventory.yml

MOLECULE_EPHEMERAL_DIRECTORY

生成的目录路径,通常为~/.cache/molecule/<role-name>/<scenario-name>

MOLECULE_SCENARIO_DIRECTORY

场景目录路径,通常为<role_path>/molecule/<scenario-name>

MOLECULE_PROJECT_DIRECTORY

项目(角色)目录路径,通常为<role_path>

MOLECULE_INSTANCE_CONFIG

实例配置文件路径,包含实例名称、连接、用户、端口等(由驱动程序填充)。通常为~/.cache/molecule/<role-name>/<scenario-name>/instance_config.yml

MOLECULE_DEPENDENCY_NAME

依赖类型名称,通常为 'galaxy'

MOLECULE_DRIVER_NAME

Molecule 场景驱动的名称

MOLECULE_PROVISIONER_NAME

供应工具的名称(通常为 'ansible')

MOLECULE_REPORT

用于转储执行报告的 HTML 文件名。

MOLECULE_SCENARIO_NAME

场景的名称

MOLECULE_VERBOSITY

确定 Ansible 的详细程度。

MOLECULE_VERIFIER_NAME

验证工具的名称(通常为 'ansible')

MOLECULE_VERIFIER_TEST_DIRECTORY

包含验证器测试的目录路径,通常为<role_path>/<scenario-name>/<verifier-name>

依赖项

测试角色可能依赖于其他依赖项。Molecule 通过调用可配置的依赖项管理器来处理这些依赖项的管理。

Ansible Galaxy

基类:Base

Galaxy 是默认的依赖项管理器。

从 v6.0.0 开始,依赖项安装在 Ansible 配置中定义的目录中。默认安装目录是DEFAULT_ROLES_PATH(ANSIBLE_HOME)。如果需要同一依赖项的两个版本,则如果使用默认安装目录,则会发生冲突,因为两个版本都尝试安装到同一个目录中。

可以通过 options 字典将附加选项传递给ansible-galaxy install。此部分中设置的任何选项都将覆盖默认值。

role-filerequirements-file的搜索路径是<role-name>目录。role-file的默认值为requirements.ymlrequirements-file的默认值为collections.yml

  1. 如果它们未在options中定义,molecule将从<role-name>目录中查找它们,例如<role-name>/requirements.yml<role-name>/collections.yml
  2. 如果它们在options中定义,molecule将从<role-name>/<the-value-of-role-file><role-name>/<the-value-of-requirements-file>查找它们。

注意

Molecule 将删除所有匹配'^[v]+$'的选项,并在执行molecule --debug时将-vvv传递给底层的ansible-galaxy命令。

    dependency:
      name: galaxy
      options:
        ignore-certs: True
        ignore-errors: True
        role-file: requirements.yml
        requirements-file: collections.yml

如果您只有角色,请使用“role-file”。如果您需要安装集合,请使用“requirements-file”。请注意,借助 Ansible Galaxy 的集合支持,如果您文件的格式如下所示,您现在可以将这两个列表组合成一个需求

    roles:
      - dep.role1
      - dep.role2
    collections:
      - ns.collection
      - ns2.collection2

如果您想将它们组合起来,只需将role-filerequirements-file指向同一路径即可。默认情况下不会这样做,因为旧的role-file只需要角色列表,而集合必须位于文件中的collections:键下,并且默认情况下将两者都指向同一个文件可能会破坏现有代码。

可以通过将enabled设置为 False 来禁用依赖项管理器。

    dependency:
      name: galaxy
      enabled: False

可以将环境变量传递给依赖项。

    dependency:
      name: galaxy
      env:
        FOO: bar

构造 AnsibleGalaxy。

参数:config: Molecule 配置实例。

源代码位于src/molecule/dependency/ansible_galaxy/__init__.py
def __init__(self, config: Config) -> None:
    """Construct AnsibleGalaxy.

    Args:
        config: Molecule Config instance.
    """
    super().__init__(config)
    self.invocations = [Roles(config), Collections(config)]

default_env property

所有调用者的默认环境变量。

返回值:所有调用者的默认环境变量的合并字典。

default_options property

所有调用者的默认选项。

返回值:所有调用者的默认选项的合并字典。

execute(action_args=None)

执行所有 Ansible Galaxy 依赖项。

参数:action_args: 调用者的参数。未使用。

源代码位于src/molecule/dependency/ansible_galaxy/__init__.py
def execute(self, action_args: list[str] | None = None) -> None:  # noqa: ARG002
    """Execute all Ansible Galaxy dependencies.

    Args:
        action_args: Arguments for invokers. Unused.
    """
    for invoker in self.invocations:
        invoker.execute()

Shell

基类:Base

Shell 是另一种依赖项管理器。

它旨在在Ansible Galaxy_不足的情况下运行命令。

需要执行的command,在引用不在 $PATH 中的脚本时,它是相对于 Molecule 项目目录的。

注意

与其他依赖项管理器不同,options将被忽略,不会传递给shell。附加标志/子命令应简单地添加到command中。

    dependency:
      name: shell
      command: path/to/command --flag1 subcommand --flag2

可以通过将enabled设置为 False 来禁用依赖项管理器。

    dependency:
      name: shell
      command: path/to/command --flag1 subcommand --flag2
      enabled: False
可以将环境变量传递给依赖项。

    dependency:
      name: shell
      command: path/to/command --flag1 subcommand --flag2
      env:
        FOO: bar

构造 Shell。

参数:config: Molecule 配置实例。

源代码位于src/molecule/dependency/shell.py
def __init__(self, config: Config) -> None:
    """Construct Shell.

    Args:
        config: Molecule Config instance.
    """
    super().__init__(config)
    self._sh_command = ""

command property

返回 shell 命令。

返回值:在 Molecule 配置中定义的命令。

default_options property

获取 shell 依赖项的默认选项(无)。

返回值:空字典。

bake()

烘焙shell命令,使其准备好执行。

源代码位于src/molecule/dependency/shell.py
def bake(self) -> None:
    """Bake a ``shell`` command so it's ready to execute."""
    self._sh_command = self.command

execute(action_args=None)

执行依赖项求解器。

参数:action_args: 依赖项的参数。未使用。

源代码位于src/molecule/dependency/shell.py
def execute(self, action_args: list[str] | None = None) -> None:  # noqa: ARG002
    """Execute the dependency solver.

    Args:
        action_args: Arguments for the dependency. Unused.
    """
    if not self.enabled:
        msg = "Skipping, dependency is disabled."
        LOG.warning(msg)
        return
    super().execute()

    if not self._sh_command:
        self.bake()
    self.execute_with_retries()

驱动程序

Molecule 使用Ansible 来管理要操作的实例。Molecule 支持Ansible 支持的任何提供程序。这项工作被卸载到provisioner

驱动程序的名称在molecule.yml中指定,可以在命令行中覆盖。Molecule 将记住上次成功使用的驱动程序,并继续对所有后续子命令使用该驱动程序,或者直到 Molecule 销毁实例为止。

警告

为了正确集成 Molecule,验证程序必须支持 Ansible 提供程序。

驱动程序的 Python 包需要安装。

委托

基类:Driver

负责管理默认实例的类。

Delegated 是 Molecule 中使用的默认驱动程序。

在此驱动程序下,开发人员有责任实现创建和销毁 playbook。Managed是所有驱动程序的默认行为。

    driver:
      name: de

但是,开发人员必须遵守 instance-config API。开发人员的创建 playbook 必须提供以下 instance-config 数据,而开发人员的销毁 playbook 必须重置 instance-config。

    - address: ssh_endpoint
      identity_file: ssh_identity_file  # mutually exclusive with password
      instance: instance_name
      port: ssh_port_as_string
      user: ssh_user
      shell_type: sh
      password: ssh_password  # mutually exclusive with identity_file
      become_method: valid_ansible_become_method  # optional
      become_pass: password_if_required  # optional

    - address: winrm_endpoint
      instance: instance_name
      connection: 'winrm'
      port: winrm_port_as_string
      user: winrm_user
      password: winrm_password
      shell_type: powershell
      winrm_transport: ntlm/credssp/kerberos
      winrm_cert_pem: <path to the credssp public certificate key>
      winrm_cert_key_pem: <path to the credssp private certificate key>
      winrm_server_cert_validation: validate/ignore

本文介绍如何使用 Ansible 配置和使用 WinRM:https://docs.ansible.org.cn/ansible/latest/user_guide/windows_winrm.html

Molecule 还可以跳过配置/取消配置步骤。开发人员有责任管理实例,并正确配置 Molecule 以连接到这些实例。

    driver:
      name: default
      options:
        managed: False
        login_cmd_template: 'docker exec -ti {instance} bash'
        ansible_connection_options:
          ansible_connection: docker
    platforms:
      - name: instance-docker
    $ docker run \
        -d \
        --name instance-docker \
        --hostname instance-docker \
        -it molecule_local/ubuntu:latest sleep infinity & wait

将 Molecule 与可通过 ssh 访问的委托实例一起使用。

注意

开发人员有责任配置 ssh 配置文件。

    driver:
      name: default
      options:
        managed: False
        login_cmd_template: 'ssh {instance} -F /tmp/ssh-config'
        ansible_connection_options:
          ansible_connection: ssh
          ansible_ssh_common_args: '-F /path/to/ssh-config'
    platforms:
      - name: instance

提供 Molecule 将在destroy操作后保留的文件。

    driver:
      name: default
      safe_files:
        - foo
为了将 localhost 用作 Molecule 的目标

    driver:
      name: default
      options:
        managed: False
        ansible_connection_options:
          ansible_connection: local

属性:title: 驱动程序的简短描述。

构造 Delegated。

参数:config: Molecule 配置的实例。

源代码位于src/molecule/driver/delegated.py
def __init__(self, config: Config) -> None:
    """Construct Delegated.

    Args:
        config: An instance of a Molecule config.
    """
    super().__init__(config)
    self._name = "default"

default_safe_files property

生成要保留的文件。

返回值:要保留的文件列表。

default_ssh_connection_options property

SSH 客户端选项。

返回值:SSH 连接选项列表。

login_cmd_template property

获取登录命令模板,该模板将被login_options填充为字符串。

返回值:登录命令模板(如有)。

name property writable

驱动程序的名称。

返回值:驱动程序的名称。

ansible_connection_options(instance_name)

Ansible 连接选项。

参数:instance_name: 要查找 Ansible 连接选项的实例的名称。

返回值:与 Ansible 连接到实例相关的选项字典。

源代码位于src/molecule/driver/delegated.py
def ansible_connection_options(
    self,
    instance_name: str,
) -> dict[str, str]:
    """Ansible connection options.

    Args:
        instance_name: The name of the instance to look up Ansible connection options for.

    Returns:
        Dictionary of options related to ansible connection to the instance.
    """
    # list of tuples describing mappable instance params and default values
    instance_params = [
        ("become_pass", None),
        ("become_method", False),
        ("winrm_transport", None),
        ("winrm_cert_pem", None),
        ("winrm_cert_key_pem", None),
        ("winrm_server_cert_validation", None),
        ("shell_type", None),
        ("connection", "smart"),
    ]
    if self.managed:
        try:
            d = self._get_instance_config(instance_name)
            conn_dict = {}
            # Check if optional mappable params are in the instance config
            for i in instance_params:
                if d.get(i[0], i[1]):
                    conn_dict["ansible_" + i[0]] = d.get(i[0], i[1])

            conn_dict["ansible_user"] = d.get("user")
            conn_dict["ansible_host"] = d.get("address")
            conn_dict["ansible_port"] = d.get("port")

            if d.get("identity_file", None):
                conn_dict["ansible_private_key_file"] = d.get("identity_file")
            if d.get("password", None):
                conn_dict["ansible_password"] = d.get("password")
                # Based on testinfra documentation, ansible password must be passed via ansible_ssh_pass  # noqa: E501
                # issue to fix this can be found https://github.com/pytest-dev/pytest-testinfra/issues/580
                conn_dict["ansible_ssh_pass"] = d.get("password")

            conn_dict["ansible_ssh_common_args"] = " ".join(
                self.ssh_connection_options,
            )

            return conn_dict  # noqa: TRY300

        except StopIteration:
            return {}
        except OSError:
            # Instance has yet to be provisioned , therefore the
            # instance_config is not on disk.
            return {}
    return self.options.get("ansible_connection_options", {})

login_options(instance_name)

登录选项。

参数:instance_name: 需要查找登录选项的实例名称。

返回值:与登录实例相关的选项字典。

源代码位于src/molecule/driver/delegated.py
def login_options(self, instance_name: str) -> dict[str, str]:
    """Login options.

    Args:
        instance_name: The name of the instance to look up login options for.

    Returns:
        Dictionary of options related to logging into the instance.
    """
    if self.managed:
        d = {"instance": instance_name}

        return util.merge_dicts(d, self._get_instance_config(instance_name))
    return {"instance": instance_name}

sanity_checks()

运行完整性检查。

源代码位于src/molecule/driver/delegated.py
def sanity_checks(self) -> None:
    """Run sanity checks."""

schema_file()

返回模式文件路径。

返回值:模式文件路径。

源代码位于src/molecule/driver/delegated.py
def schema_file(self) -> str:
    """Return schema file path.

    Returns:
        Path to schema file.
    """
    return str(Path(data_module).parent / "driver.json")

平台

平台定义了要测试的实例以及实例所属的组。

    platforms:
      - name: instance-1

可以提供多个实例。

    platforms:
      - name: instance-1
      - name: instance-2

将实例映射到组。这些组将由_配置器_用于编排目的。

    platforms:
      - name: instance-1
        groups:
          - group1
          - group2

子项允许创建组的组。

    platforms:
      - name: instance-1
        groups:
          - group1
          - group2
        children:
          - child_group1

初始化一个新的平台类并返回 None。

参数:config: Molecule 配置的实例。parallelize_platforms: 并行模式。默认为 False。platform_name: 只需目标的一个平台,默认为 None。

源代码位于 src/molecule/platforms.py
def __init__(
    self,
    config: Config,
    parallelize_platforms: bool = False,  # noqa: FBT001, FBT002
    platform_name: str | None = None,
) -> None:
    """Initialize a new platform class and returns None.

    Args:
        config: An instance of a Molecule config.
        parallelize_platforms: Parallel mode. Default is False.
        platform_name: One platform to target only, defaults to None.
    """
    if platform_name:
        config.config["platforms"] = util._filter_platforms(  # noqa: SLF001
            config.config,
            platform_name,
        )
    if parallelize_platforms:
        config.config["platforms"] = util._parallelize_platforms(  # noqa: SLF001
            config.config,
            config._run_uuid,  # noqa: SLF001
        )
    self._config = config

instances property

在配置中定义的平台。

返回值:配置中的平台列表。

配置器

Molecule 处理角色的配置和收敛。

Ansible

基类:Base

Ansible 是默认的配置器。将不支持其他配置器。

Molecule 的配置器管理实例的生命周期。但是,用户必须提供创建、销毁和收敛剧本。Molecule 的 init 子命令将提供必要的便利文件。

Molecule 将跳过标记为 molecule-notestnotest 的任务。使用标记 molecule-idempotence-notest 的任务仅在幂等性操作步骤中跳过。

警告

保留创建和销毁剧本用于配置。不要尝试在这些剧本中收集事实或对已配置的节点执行操作。由于在 Ansible 和 Molecule 之间同步状态所需的体操,最好在准备或收敛剧本中执行这些任务。

开发人员有责任将模块的事实数据正确地映射到创建剧本中的 instance_conf_dict 事实中。这允许 Molecule 正确配置 Ansible 清单。

可以通过 options 字典将其他选项传递给 ansible-playbook。此部分中设置的任何选项都将覆盖默认值。

注意

选项不影响创建和销毁操作。

注意

Molecule 将删除任何与 ^[v]+$ 匹配的选项,并在执行 molecule --debug 时将 -vvv 传递给底层的 ansible-playbook 命令。

Molecule 将使日志输出静默,除非使用 --debug 标志调用。但是,这会导致相当多的输出。要启用 Ansible 日志输出,请将以下内容添加到 molecule.ymlprovisioner 部分。

    provisioner:
      name: ansible
      log: True

Docker 和 Podman 的创建/销毁剧本与 Molecule 捆绑在一起。这些剧本具有来自 molecule.yml 的清晰 API,并且是最常用的。捆绑的剧本仍然可以被覆盖。

剧本加载顺序为

  1. provisioner.playbooks.$driver_name.$action
  2. provisioner.playbooks.$action
  3. bundled_playbook.$driver_name.$action
    provisioner:
      name: ansible
      options:
        vvv: True
      playbooks:
        create: create.yml
        converge: converge.yml
        destroy: destroy.yml

在角色之间共享剧本。

    provisioner:
      name: ansible
      playbooks:
        create: ../default/create.yml
        destroy: ../default/destroy.yml
        converge: converge.yml

多个驱动程序剧本。在某些情况下,开发人员可以选择针对不同的后端测试相同的角色。如果确定的驱动程序在配置器的 playbooks 部分具有键,则 Molecule 将选择特定于驱动程序的创建/销毁剧本。

注意

如果确定的驱动程序在 playbooks 字典中具有键,Molecule 将使用此字典来解析所有配置剧本(创建/销毁)。

    provisioner:
      name: ansible
      playbooks:
        docker:
          create: create.yml
          destroy: destroy.yml
        create: create.yml
        destroy: destroy.yml
        converge: converge.yml

注意

此部分中的路径将转换为绝对路径,其中相对父级为 $scenario_directory。

副作用剧本执行对实例(s)产生副作用的操作。旨在测试 HA 故障转移场景等。默认情况下未启用。将以下内容添加到配置器的 playbooks 部分以启用。

    provisioner:
      name: ansible
      playbooks:
        side_effect: side_effect.yml

注意

此功能应视为实验性功能。

准备剧本执行在收敛之前将系统带到给定状态的操作。它在创建之后执行,并且在实例生命周期内仅执行一次。

这可用于在测试之前将实例带入特定状态。

    provisioner:
      name: ansible
      playbooks:
        prepare: prepare.yml

清理剧本用于清理可能不在将要销毁的实例上存在的测试基础设施。主要用例是用于清理在 Molecule 测试环境之外所做的更改。例如,远程数据库连接或用户帐户。旨在与 prepare 结合使用,在需要时修改外部资源。

清理步骤在每个销毁步骤之前直接执行。就像销毁步骤一样,它将运行两次。在收敛之前进行初始清理,然后在最后一个销毁步骤之前进行清理。这意味着清理剧本必须处理尚未创建的资源的清理失败。

将以下内容添加到配置器的 playbooks 部分以启用。

    provisioner:
      name: ansible
      playbooks:
        cleanup: cleanup.yml

注意

此功能应视为实验性功能。

环境变量。Molecule 尽最大努力处理常见的 Ansible 路径。默认值如下。

::

ANSIBLE_ROLES_PATH:
  $runtime_cache_dir/roles:$ephemeral_directory/roles/:$project_directory/../:~/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles
ANSIBLE_LIBRARY:
  $ephemeral_directory/modules/:$project_directory/library/:~/.ansible/plugins/modules:/usr/share/ansible/plugins/modules
ANSIBLE_FILTER_PLUGINS:
  $ephemeral_directory/plugins/filter/:$project_directory/filter/plugins/:~/.ansible/plugins/filter:/usr/share/ansible/plugins/modules

环境变量可以传递给配置器。此部分中与上述名称匹配的变量将附加到上述默认值,并转换为绝对路径,其中相对父级为 $scenario_directory。

注意

此部分中的路径将转换为绝对路径,其中相对父级为 $scenario_directory。

    provisioner:
      name: ansible
      env:
        FOO: bar

修改 ansible.cfg。

    provisioner:
      name: ansible
      config_options:
        defaults:
          fact_caching: jsonfile
        ssh_connection:
          scp_if_ssh: True

注意

以下键不允许使用,以防止 Molecule 功能异常。它们可以通过上面描述的配置器的 env 设置指定,但 privilege_escalation 除外。

    provisioner:
      name: ansible
      config_options:
        defaults:
          library: /path/to/library
          filter_plugins: /path/to/filter_plugins
        privilege_escalation: {}

需要主机/组设置某些变量的角色。Molecule 使用与Ansible_相同的剧本中定义的变量语法。

    provisioner:
      name: ansible
      inventory:
        group_vars:
          all:
            bar: foo
          group1:
            foo: bar
          group2:
            foo: bar
            baz:
              qux: zzyzx
        host_vars:
          group1-01:
            foo: baz

Molecule 根据平台_下定义的主机自动生成清单。使用hosts键允许向清单中添加不受Molecule管理的额外主机。

一个典型的用例是,如果要从清单中的另一个主机访问某些变量(使用 hostvars)而不创建它。

注意

hosts的内容应遵循基于YAML的清单语法:以all组开头,并具有主机/变量/子项条目。

    provisioner:
      name: ansible
      inventory:
        hosts:
          all:
            hosts:
              extra_host:
                foo: hello

注意

使用此键添加到清单中的额外主机不会被 Molecule 创建/销毁。开发人员有责任在剧本中定位正确的主机。应定位平台_下定义的主机,而不是all

上述方法的替代方法是符号链接。Molecule 在清单目录中创建指向指定目录的符号链接。这允许 Ansible 利用其内置的主机/group_vars 解析来收敛。这两种清单管理形式是互斥的。

与上述一样,可以使用hosts键传递额外的清单文件(甚至动态清单脚本)。Ansible_将自动将此清单与Molecule生成的清单合并。如果要定义不受Molecule管理的额外主机,这将非常有用。

注意

同样,开发人员有责任在剧本中定位正确的主机。应定位平台_下定义的主机,而不是all

注意

源目录链接相对于场景目录。

唯一有效的键是hostsgroup_varshost_vars。Molecule 的模式验证器将强制执行此操作。

    provisioner:
      name: ansible
      inventory:
        links:
          hosts: ../../../inventory/hosts
          group_vars: ../../../inventory/group_vars/
          host_vars: ../../../inventory/host_vars/

注意

您可以使用清单的hosts/group_vars/host_vars部分或links。如果同时使用两者,则链接将获胜。

    provisioner:
      name: ansible
      hosts:
        all:
          hosts:
            ignored:
               important: this host is ignored
      inventory:
        links:
          hosts: ../../../inventory/hosts

覆盖连接选项

    provisioner:
      name: ansible
      connection_options:
        ansible_ssh_user: foo
        ansible_ssh_common_args: -o IdentitiesOnly=no

覆盖标签

    provisioner:
    name: ansible
    config_options:
      tags:
        run: tag1,tag2,tag3

一个典型的用例是如果要在场景中使用标签。不要忘记在converge.yml中添加标签always,如下所示。

    ---
    - name: Converge
      hosts: all
      tasks:
        - name: "Include acme.my_role_name"
          ansible.builtin.include_role:
            name: "acme.my_role_name"
          tags:
            - always

.. _剧本中定义的变量: https://docs.ansible.org.cn/ansible/latest/user_guide/playbooks_variables.html#defining-variables-in-a-playbook

在运行收敛时向 ansible-playbook 添加参数

    provisioner:
      name: ansible
      ansible_args:
        - --inventory=mygroups.yml
        - --limit=host1,host2
源代码位于 src/molecule/provisioner/base.py
def __init__(self, config: Config) -> None:
    """Initialize code for all :ref:`Provisioner` classes.

    Args:
        config: An instance of a Molecule config.
    """
    self._config = config

ansible_args property

配置器 ansible 参数。

返回值:配置器 ansible_args。

config_file property

配置文件路径。

返回值:ansible.cfg 的路径。

config_options property

配置器配置选项。

返回值:配置器配置选项。

default_config_options property

提供默认选项以构建 ansible.cfg。

返回值:默认配置选项。

default_env property

提供默认环境变量。

返回值:默认的环境变量集。

default_options property

提供默认选项。

返回值:默认选项。

directory property

Ansible 配置器目录。

返回值:Ansible 配置器目录的路径。

env property

供应器的完整计算环境变量。

返回:收集到的完整环境变量集。

group_vars 属性

供应器清单组变量。

返回:组变量字典。

host_vars 属性

供应器清单主机变量。

返回:主机变量字典。

hosts 属性

供应器清单主机。

返回:主机名字典。

inventory 属性

创建清单结构并返回字典。

    ungrouped:
      vars:
        foo: bar
      hosts:
        instance-1:
        instance-2:
      children:
        $child_group_name:
          hosts:
            instance-1:
            instance-2:
    $group_name:
      hosts:
        instance-1:
          ansible_connection: docker
        instance-2:
          ansible_connection: docker

inventory_directory 属性

清单目录路径。

返回:包含清单文件的目录路径。

inventory_file 属性

清单文件路径。

返回:ansible_inventory.yml 的路径。

供应器清单链接。

返回:链接字典。

name 属性

供应器名称。

返回:供应器名称。

options 属性

供应器的相应选项。

返回:供应器选项字典。

abs_path(path)

返回绝对场景相邻路径。

参数:path: 场景相邻相对路径。

返回:绝对路径。

源代码位于 src/molecule/provisioner/ansible.py
def abs_path(self, path: str | Path) -> str:
    """Return absolute scenario-adjacent path.

    Args:
        path: Scenario-adjacent relative path.

    Returns:
        Absolute path.
    """
    path = Path(self._config.scenario.directory) / path
    return str(util.abs_path(path))

check()

使用--check标志对收敛剧本执行ansible-playbook

源代码位于 src/molecule/provisioner/ansible.py
def check(self) -> None:
    """Execute ``ansible-playbook`` against the converge playbook with the ``--check`` flag."""
    pb = self._get_ansible_playbook(self.playbooks.converge)
    pb.add_cli_arg("check", value=True)
    pb.execute()

cleanup()

对清理剧本执行ansible-playbook并返回None。

源代码位于 src/molecule/provisioner/ansible.py
def cleanup(self) -> None:
    """Execute `ansible-playbook` against the cleanup playbook and returns None."""
    pb = self._get_ansible_playbook(self.playbooks.cleanup)
    pb.execute()

connection_options(instance_name)

组合实例和供应器选项的计算连接选项。

参数:instance_name: 用于连接选项的实例。

返回:组合的连接选项。

源代码位于 src/molecule/provisioner/ansible.py
def connection_options(
    self,
    instance_name: str,
) -> dict[str, Any]:
    """Computed connection options combining instance and provisioner options.

    Args:
        instance_name: The instance to base the connection options on.

    Returns:
        The combined connection options.
    """
    d = self._config.driver.ansible_connection_options(instance_name)

    return util.merge_dicts(
        d,
        self._config.config["provisioner"]["connection_options"],
    )

converge(playbook='', **kwargs)

对收敛剧本执行ansible-playbook,除非另有说明。

参数:playbook: 包含剧本绝对路径的可选字符串。 **kwargs: 可选关键字参数。

返回:str: 来自ansible-playbook命令的输出。

源代码位于 src/molecule/provisioner/ansible.py
def converge(self, playbook: str = "", **kwargs: object) -> str:
    """Execute ``ansible-playbook`` against the converge playbook. unless specified otherwise.

    Args:
        playbook: An optional string containing an absolute path to a playbook.
        **kwargs: An optional keyword arguments.

    Returns:
        str: The output from the ``ansible-playbook`` command.
    """
    pb = self._get_ansible_playbook(playbook or self.playbooks.converge, **kwargs)  # type: ignore[arg-type]

    return pb.execute()

create()

对创建剧本执行ansible-playbook并返回None。

源代码位于 src/molecule/provisioner/ansible.py
def create(self) -> None:
    """Execute ``ansible-playbook`` against the create playbook and returns None."""
    pb = self._get_ansible_playbook(self.playbooks.create)
    pb.execute()

destroy()

对销毁剧本执行ansible-playbook并返回None。

源代码位于 src/molecule/provisioner/ansible.py
def destroy(self) -> None:
    """Execute ``ansible-playbook`` against the destroy playbook and returns None."""
    pb = self._get_ansible_playbook(self.playbooks.destroy)
    pb.execute()

manage_inventory()

管理Ansible的清单并返回None。

源代码位于 src/molecule/provisioner/ansible.py
def manage_inventory(self) -> None:
    """Manage inventory for Ansible and returns None."""
    self._write_inventory()
    self._remove_vars()
    if not self.links:
        self._add_or_update_vars()
    else:
        self._link_or_update_vars()

playbooks()

Ansible 剧本供应器实例。

返回:基于此配置的 AnsiblePlaybooks 实例。

源代码位于 src/molecule/provisioner/ansible.py
@cached_property
def playbooks(self) -> ansible_playbooks.AnsiblePlaybooks:
    """Ansible playbooks provisioner instance.

    Returns:
        AnsiblePlaybooks instance based on this config.
    """
    return ansible_playbooks.AnsiblePlaybooks(self._config)

prepare()

对准备剧本执行ansible-playbook并返回None。

源代码位于 src/molecule/provisioner/ansible.py
def prepare(self) -> None:
    """Execute ``ansible-playbook`` against the prepare playbook and returns None."""
    pb = self._get_ansible_playbook(self.playbooks.prepare)
    pb.execute()

side_effect(action_args=None)

对副作用剧本执行ansible-playbook

参数:action_args: 传递给副作用剧本的参数。

源代码位于 src/molecule/provisioner/ansible.py
def side_effect(self, action_args: list[str] | None = None) -> None:
    """Execute ``ansible-playbook`` against the side_effect playbook.

    Args:
        action_args: Arguments to pass to the side_effect playbook.
    """
    playbooks = []
    if action_args:
        playbooks = [
            self._get_ansible_playbook(self.abs_path(playbook)) for playbook in action_args
        ]
    playbooks = [self._get_ansible_playbook(self.playbooks.side_effect)]
    for pb in playbooks:
        pb.execute()

syntax()

使用 -syntax-check 标志对收敛剧本执行 ansible-playbook

源代码位于 src/molecule/provisioner/ansible.py
def syntax(self) -> None:
    """Execute `ansible-playbook` against the converge playbook with the -syntax-check flag."""
    pb = self._get_ansible_playbook(self.playbooks.converge)
    pb.add_cli_arg("syntax-check", value=True)
    pb.execute()

verify(action_args=None)

对验证剧本执行ansible-playbook

参数:action_args: 传递给验证剧本的参数。

源代码位于 src/molecule/provisioner/ansible.py
def verify(self, action_args: list[str] | None = None) -> None:
    """Execute ``ansible-playbook`` against the verify playbook.

    Args:
        action_args: Arguments to pass on to the verify playbook.
    """
    playbooks = []
    if action_args:
        playbooks = [self.abs_path(playbook) for playbook in action_args]
    elif self.playbooks.verify:
        playbooks = [self.playbooks.verify]
    if not playbooks:
        LOG.warning("Skipping, verify playbook not configured.")
        return
    for playbook in playbooks:
        # Get ansible playbooks for `verify` instead of `provision`
        pb = self._get_ansible_playbook(playbook, verify=True)
        pb.execute()

write_config()

将供应器的配置文件写入磁盘并返回None。

源代码位于 src/molecule/provisioner/ansible.py
def write_config(self) -> None:
    """Write the provisioner's config file to disk and returns None."""
    template = util.render_template(
        self._get_config_template(),
        config_options=self.config_options,
    )
    util.write_file(self.config_file, template)

场景

Molecule 将场景视为一等公民,具有顶级配置语法。

场景允许 Molecule 以特定方式测试角色,这是与 Molecule v1 的根本区别。

场景是一个自包含的目录,其中包含以特定方式测试角色所需的一切。默认场景名为default,每个角色都应该包含一个默认场景。

除非明确提及,否则场景名称将是托管文件的目录名称。

本节中设置的任何选项都将覆盖默认值。

scenario:
  create_sequence:
    - dependency
    - create
    - prepare
  check_sequence:
    - dependency
    - cleanup
    - destroy
    - create
    - prepare
    - converge
    - check
    - destroy
  converge_sequence:
    - dependency
    - create
    - prepare
    - converge
  destroy_sequence:
    - dependency
    - cleanup
    - destroy
  test_sequence:
    - dependency
    - cleanup
    - destroy
    - syntax
    - create
    - prepare
    - converge
    - idempotence
    - side_effect
    - verify
    - cleanup
    - destroy

高级测试

如果需要,Molecule 可以在一个场景中运行多个副作用和测试。这允许对角色/剧本管理下的有状态软件执行高级测试。操作side_effectverify可以接受可选参数来更改它们执行的剧本/测试。

具有多个副作用和测试的测试序列示例

test_sequence:
  - converge
  - side_effect reboot.yaml
  - verify after_reboot/
  - side_effect alter_configs.yaml
  - converge
  - verify other_test1.py other_test2.py
  - side_effect
  - verify

不带参数的side_effect将执行 molecule.yml 的 provisioner.playbooks 部分中配置的常用side_effect

side_effect可以有一个或多个参数(用空格分隔),它是一个要执行的剧本(剧本)。如果存在side_effect的参数,则执行它。剧本的路径相对于 molecule.yml 位置。对于带有参数的操作,将忽略正常的副作用设置(来自provisioner.playbooks)。

不带参数的verify将执行 molecule.yml 的验证器部分中配置的常用测试。

如果存在一个或多个参数(用空格分隔),则每个参数都将被视为要传递给验证器(Ansible 或 Testinfra)的测试名称(文件或目录)。验证器的类型在 molecule.yml 的verifier部分中设置,并应用于场景中的所有verify操作。

测试的路径相对于 molecule.yml 文件位置。如果verify操作提供了参数,则忽略验证器的additional_files_or_dirs设置。

可以使用多个side_effectverify操作来创建剧本和测试的组合,例如,用于端到端剧本测试。

可以多次使用额外的convergeidempotence操作

test_sequence:
  - converge
  - idempotence
  - side_effect
  - verify
  - converge
  - idempotence
  - side_effect effect2.yml
  - converge
  - idempotence
  - verify test2/
  - side_effect effect3.yml
  - verify test3/
  - idempotence

验证器

Molecule 通过调用可配置的验证器来处理角色测试。

Ansible

基础:Verifier

Ansible_ 是默认的测试验证器。

Molecule 执行位于角色scenario.directory中的剧本(verify.yml)。

    verifier:
      name: ansible

可以通过将enabled设置为 False 来禁用测试。

    verifier:
      name: ansible
      enabled: False

可以将环境变量传递给验证器。

    verifier:
      name: ansible
      env:
        FOO: bar
源代码位于 src/molecule/verifier/base.py
def __init__(self, config: Config) -> None:
    """Initialize code for all :ref:`Verifier` classes.

    Args:
        config: An instance of a Molecule config.
    """
    self._config = config

default_env 属性

获取提供给cmd的默认环境变量。

返回:默认验证器环境变量。

default_options 属性

获取提供给cmd的默认CLI参数。

返回:默认验证器选项。

name 属性

验证器的名称。

返回:验证器的名称。

execute(action_args=None)

执行cmd

参数:action_args: 要传递的参数列表。

源代码位于 src/molecule/verifier/ansible.py
def execute(self, action_args: list[str] | None = None) -> None:
    """Execute ``cmd``.

    Args:
        action_args: list of arguments to be passed.
    """
    if not self.enabled:
        msg = "Skipping, verifier is disabled."
        log.warning(msg)
        return

    msg = "Running Ansible Verifier"
    log.info(msg)

    if self._config.provisioner:
        self._config.provisioner.verify(action_args)

        msg = "Verifier completed successfully."
        log.info(msg)

schema()

返回验证模式。

返回:验证器模式。

源代码位于 src/molecule/verifier/ansible.py
def schema(self) -> Schema:
    """Return validation schema.

    Returns:
        Verifier schema.
    """
    return {
        "verifier": {
            "type": "dict",
            "schema": {"name": {"type": "string", "allowed": ["ansible"]}},
        },
    }

Testinfra

基础:Verifier

自 3.0 版本以来,Testinfra_ 不再是默认的测试验证器。

可以通过 `options` 字典向 `testinfra` 传递附加选项。本节中设置的任何选项都将覆盖默认值。

注意

Molecule 将删除任何与 '^[v]+$' 匹配的选项,并在执行 `molecule --debug` 时将 `-vvv` 传递给底层的 `pytest` 命令。

    verifier:
      name: testinfra
      options:
        n: 1

可以通过将enabled设置为 False 来禁用测试。

    verifier:
      name: testinfra
      enabled: False

可以将环境变量传递给验证器。

    verifier:
      name: testinfra
      env:
        FOO: bar

更改测试目录的路径。

    verifier:
      name: testinfra
      directory: /foo/bar/

来自场景测试目录中另一个文件或目录的其他测试(支持正则表达式)。

    verifier:
      name: testinfra
      additional_files_or_dirs:
        - ../path/to/test_1.py
        - ../path/to/test_2.py
        - ../path/to/directory/*
.. _`Testinfra` : https://testinfra.readthedocs.io

设置执行 `testinfra` 的要求并返回 None。

参数:config: Molecule 配置的实例。

源代码位于 `src/molecule/verifier/testinfra.py`
def __init__(self, config: Config) -> None:
    """Set up the requirements to execute ``testinfra`` and returns None.

    Args:
        config: An instance of a Molecule config.
    """
    super().__init__(config)
    self._testinfra_command: list[str] = []
    self._tests = []  # type: ignore[var-annotated]

additional_files_or_dirs 属性

与验证器相关的附加路径。

返回:要与此验证器一起使用的文件和目录列表。

default_env 属性

获取提供给cmd的默认环境变量。

返回:默认验证器环境变量。

default_options 属性

获取提供给cmd的默认CLI参数。

返回:默认验证器选项。

name 属性

验证器的名称。

返回:验证器的名称。

options 属性

此验证器的计算选项。

返回:默认选项和在配置中指定的选项的组合字典。

bake()

烘焙 `testinfra` 命令,使其准备好执行。

源代码位于 `src/molecule/verifier/testinfra.py`
def bake(self) -> None:
    """Bake a ``testinfra`` command so it's ready to execute."""
    options = self.options
    verbose_flag = util.verbose_flag(options)
    args = verbose_flag

    self._testinfra_command = [
        "pytest",
        *util.dict2args(options),
        *self._tests,
        *args,
    ]

execute(action_args=None)

执行cmd

参数:action_args: 要传递的参数列表。

源代码位于 `src/molecule/verifier/testinfra.py`
def execute(self, action_args: list[str] | None = None) -> None:
    """Execute ``cmd``.

    Args:
        action_args: list of arguments to be passed.
    """
    if not self.enabled:
        msg = "Skipping, verifier is disabled."
        LOG.warning(msg)
        return

    if self._config:
        self._tests = self._get_tests(action_args)
    else:
        self._tests = []
    if not len(self._tests) > 0:
        msg = "Skipping, no tests found."
        LOG.warning(msg)
        return

    self.bake()

    msg = f"Executing Testinfra tests found in {self.directory}/..."
    LOG.info(msg)

    result = util.run_command(
        self._testinfra_command,
        env=self.env,
        debug=self._config.debug,
        cwd=Path(self._config.scenario.directory),
    )
    if result.returncode == 0:
        msg = "Verifier completed successfully."
        LOG.info(msg)
    else:
        util.sysexit(result.returncode)

schema()

返回验证模式。

返回:验证器模式。

源代码位于 `src/molecule/verifier/testinfra.py`
def schema(self) -> Schema:
    """Return validation schema.

    Returns:
        Verifier schema.
    """
    return {
        "verifier": {
            "type": "dict",
            "schema": {"name": {"type": "string", "allowed": ["testinfra"]}},
        },
    }