跳至内容

使用 Podman 容器

下面您可以看到一个使用 Podman 容器作为测试主机的场景。当您运行 `molecule test --scenario-name podman` 时,`create`、`converge` 和 `destroy` 步骤将依次运行。

此示例使用 Ansible 剧本,无需任何 Molecule 插件即可运行。您可以完全控制需要安装哪些测试依赖项。

配置剧本

molecule.yml
dependency:
  name: galaxy
  options:
    requirements-file: requirements.yml
platforms:
  - name: molecule-ubuntu
    image: ubuntu:18.04
driver:
  options:
    managed: false
    login_cmd_template: "podman exec -ti {instance} bash"
    ansible_connection_options:
      ansible_connection: podman
requirements.yml
collections:
  - containers.podman

创建剧本

create.yml
- name: Create
  hosts: localhost
  gather_facts: false
  vars:
    molecule_inventory:
      all:
        hosts: {}
        children:
          molecule:
            hosts: {}

  tasks:
    - name: Create a container
      containers.podman.podman_container:
        name: "{{ item.name }}"
        image: "{{ item.image }}"
        privileged: "{{ item.privileged | default(omit) }}"
        volumes: "{{ item.volumes | default(omit) }}"
        capabilities: "{{ item.capabilities | default(omit) }}"
        systemd: "{{ item.systemd | default(omit) }}"
        state: started
        command: "{{ item.command | default('sleep 1d') }}"
        # bash -c "while true; do sleep 10000; done"
        log_driver: json-file
      register: result
      loop: "{{ molecule_yml.platforms }}"

    - name: Print some info
      ansible.builtin.debug:
        msg: "{{ result.results }}"

    - name: Fail if container is not running
      when: >
        item.container.State.ExitCode != 0 or
        not item.container.State.Running
      ansible.builtin.include_tasks:
        file: tasks/create-fail.yml
      loop: "{{ result.results }}"
      loop_control:
        label: "{{ item.container.Name }}"

    - name: Add container to molecule_inventory
      vars:
        inventory_partial_yaml: |
          all:
            children:
              molecule:
                hosts:
                  "{{ item.name }}":
                    ansible_connection: containers.podman.podman
      ansible.builtin.set_fact:
        molecule_inventory: >
          {{ molecule_inventory | combine(inventory_partial_yaml | from_yaml, recursive=true) }}
      loop: "{{ molecule_yml.platforms }}"
      loop_control:
        label: "{{ item.name }}"

    - name: Dump molecule_inventory
      ansible.builtin.copy:
        content: |
          {{ molecule_inventory | to_yaml }}
        dest: "{{ molecule_ephemeral_directory }}/inventory/molecule_inventory.yml"
        mode: "0600"

    - name: Force inventory refresh
      ansible.builtin.meta: refresh_inventory

    - name: Fail if molecule group is missing
      ansible.builtin.assert:
        that: "'molecule' in groups"
        fail_msg: |
          molecule group was not found inside inventory groups: {{ groups }}
      run_once: true # noqa: run-once[task]

# we want to avoid errors like "Failed to create temporary directory"
- name: Validate that inventory was refreshed
  hosts: molecule
  gather_facts: false
  tasks:
    - name: Check uname
      ansible.builtin.raw: uname -a
      register: result
      changed_when: false

    - name: Display uname info
      ansible.builtin.debug:
        msg: "{{ result.stdout }}"
tasks/create-fail.yml
- name: Retrieve container log
  ansible.builtin.command:
    cmd: >-
      {% raw %}
      podman logs
      {% endraw %}
      {{ item.stdout_lines[0] }}
    # podman inspect --format='{{.HostConfig.LogConfig.Path}}'
  changed_when: false
  register: logfile_cmd

- name: Display container log
  ansible.builtin.fail:
    msg: "{{ logfile_cmd.stderr }}"

收敛剧本

converge.yml
- name: Fail if molecule group is missing
  hosts: localhost
  tasks:
    - name: Print some info
      ansible.builtin.debug:
        msg: "{{ groups }}"

    - name: Assert group existence
      ansible.builtin.assert:
        that: "'molecule' in groups"
        fail_msg: |
          molecule group was not found inside inventory groups: {{ groups }}

- name: Converge
  hosts: molecule
  # We disable gather facts because it would fail due to our container not
  # having python installed. This will not prevent use from running 'raw'
  # commands. Most molecule users are expected to use containers that already
  # have python installed in order to avoid notable delays installing it.
  gather_facts: false
  tasks:
    - name: Check uname
      ansible.builtin.raw: uname -a
      register: result
      changed_when: false

    - name: Print some info
      ansible.builtin.assert:
        that: result.stdout | regex_search("^Linux")

销毁剧本

destroy.yml
- name: Destroy molecule containers
  hosts: molecule
  gather_facts: false
  tasks:
    - name: Stop and remove container
      delegate_to: localhost
      containers.podman.podman_container:
        name: "{{ inventory_hostname }}"
        state: absent
        rm: true
    - name: Remove potentially stopped container
      delegate_to: localhost
      ansible.builtin.command:
        cmd: podman container rm --ignore {{ inventory_hostname }}
      changed_when: false

- name: Remove dynamic molecule inventory
  hosts: localhost
  gather_facts: false
  tasks:
    - name: Remove dynamic inventory file
      ansible.builtin.file:
        path: "{{ molecule_ephemeral_directory }}/inventory/molecule_inventory.yml"
        state: absent