--- # yamllint disable rule:line-length - name: Update platforms hosts: localhost tasks: - name: Filtering platforms list using the group defined in the MOLECULE_GROUP environment variable set_fact: molecule_yml: "{{ molecule_yml | combine({'platforms': (molecule_yml.platforms | selectattr('groups', 'contains', lookup('env', 'MOLECULE_GROUP')))}) }}" when: ansible_env.MOLECULE_GROUP is defined - name: Create hosts: localhost connection: local gather_facts: false no_log: '{{ molecule_no_log }}' vars: molecule_labels: owner: molecule tasks: - name: Log into a Docker registry community.docker.docker_login: username: '{{ item.registry.credentials.username }}' password: '{{ item.registry.credentials.password }}' email: '{{ item.registry.credentials.email | default(omit) }}' registry: '{{ item.registry.url }}' docker_host: "{{ item.docker_host | default(lookup('env', 'DOCKER_HOST') or 'unix://var/run/docker.sock') }}" cacert_path: "{{ item.cacert_path | default((lookup('env', 'DOCKER_CERT_PATH') + '/ca.pem') if lookup('env', 'DOCKER_CERT_PATH') else omit) }}" cert_path: "{{ item.cert_path | default((lookup('env', 'DOCKER_CERT_PATH') + '/cert.pem') if lookup('env', 'DOCKER_CERT_PATH') else omit) }}" key_path: "{{ item.key_path | default((lookup('env', 'DOCKER_CERT_PATH') + '/key.pem') if lookup('env', 'DOCKER_CERT_PATH') else omit) }}" tls_verify: "{{ item.tls_verify | default(lookup('env', 'DOCKER_TLS_VERIFY')) or false }}" with_items: '{{ molecule_yml.platforms }}' when: - item.registry is defined - item.registry.credentials is defined - item.registry.credentials.username is defined no_log: true - name: Check presence of custom Dockerfiles ansible.builtin.stat: path: "{{ molecule_scenario_directory + '/' + (item.dockerfile | default( 'Dockerfile.j2')) }}" loop: '{{ molecule_yml.platforms }}' register: dockerfile_stats - name: Create Dockerfiles from image names ansible.builtin.template: # when using embedded playbooks the dockerfile is alonside them src: >- {%- if dockerfile_stats.results[i].stat.exists -%} {{ molecule_scenario_directory + '/' + (item.dockerfile | default( 'Dockerfile.j2')) }} {%- else -%} {{ playbook_dir + '/Dockerfile.j2' }} {%- endif -%} dest: "{{ molecule_ephemeral_directory }}/Dockerfile_{{ item.image | regex_replace('[^a-zA-Z0-9_]', '_') }}" mode: '0600' loop: '{{ molecule_yml.platforms }}' loop_control: index_var: i when: not item.pre_build_image | default(false) register: platforms - name: Discover local Docker images community.docker.docker_image_info: name: 'molecule_local/{{ item.item.name }}' docker_host: "{{ item.item.docker_host | default(lookup('env', 'DOCKER_HOST') or 'unix://var/run/docker.sock') }}" cacert_path: "{{ item.cacert_path | default((lookup('env', 'DOCKER_CERT_PATH') + '/ca.pem') if lookup('env', 'DOCKER_CERT_PATH') else omit) }}" cert_path: "{{ item.cert_path | default((lookup('env', 'DOCKER_CERT_PATH') + '/cert.pem') if lookup('env', 'DOCKER_CERT_PATH') else omit) }}" key_path: "{{ item.key_path | default((lookup('env', 'DOCKER_CERT_PATH') + '/key.pem') if lookup('env', 'DOCKER_CERT_PATH') else omit) }}" tls_verify: "{{ item.tls_verify | default(lookup('env', 'DOCKER_TLS_VERIFY')) or false }}" with_items: '{{ platforms.results }}' when: - not item.pre_build_image | default(false) register: docker_images - name: Build an Ansible compatible image (new) # noqa: no-handler when: - platforms.changed or docker_images.results | map(attribute='images') | select('equalto', []) | list | count >= 0 - not item.item.pre_build_image | default(false) community.docker.docker_image: build: path: '{{ molecule_ephemeral_directory }}' dockerfile: '{{ item.invocation.module_args.dest }}' pull: '{{ item.item.pull | default(true) }}' network: '{{ item.item.network_mode | default(omit) }}' args: '{{ item.item.buildargs | default(omit) }}' name: 'molecule_local/{{ item.item.image }}' docker_host: "{{ item.item.docker_host | default(lookup('env', 'DOCKER_HOST') or 'unix://var/run/docker.sock') }}" cacert_path: "{{ item.cacert_path | default((lookup('env', 'DOCKER_CERT_PATH') + '/ca.pem') if lookup('env', 'DOCKER_CERT_PATH') else omit) }}" cert_path: "{{ item.cert_path | default((lookup('env', 'DOCKER_CERT_PATH') + '/cert.pem') if lookup('env', 'DOCKER_CERT_PATH') else omit) }}" key_path: "{{ item.key_path | default((lookup('env', 'DOCKER_CERT_PATH') + '/key.pem') if lookup('env', 'DOCKER_CERT_PATH') else omit) }}" tls_verify: "{{ item.tls_verify | default(lookup('env', 'DOCKER_TLS_VERIFY')) or false }}" force_source: '{{ item.item.force | default(true) }}' source: build with_items: '{{ platforms.results }}' loop_control: label: 'molecule_local/{{ item.item.image }}' no_log: false register: result until: result is not failed retries: 3 delay: 30 - name: Create docker network(s) ansible.builtin.include_tasks: tasks/create_network.yml with_items: '{{ molecule_yml.platforms | molecule_get_docker_networks(molecule_labels) }}' loop_control: label: '{{ item.name }}' no_log: false - name: Determine the CMD directives ansible.builtin.set_fact: command_directives_dict: >- {{ command_directives_dict | default({}) | combine({ item.name: item.command | default('bash -c "while true; do sleep 10000; done"') }) }} with_items: '{{ molecule_yml.platforms }}' when: item.override_command | default(true) - name: Create molecule instance(s) community.docker.docker_container: name: '{{ item.name }}' docker_host: "{{ item.docker_host | default(lookup('env', 'DOCKER_HOST') or 'unix://var/run/docker.sock') }}" cacert_path: "{{ item.cacert_path | default((lookup('env', 'DOCKER_CERT_PATH') + '/ca.pem') if lookup('env', 'DOCKER_CERT_PATH') else omit) }}" cert_path: "{{ item.cert_path | default((lookup('env', 'DOCKER_CERT_PATH') + '/cert.pem') if lookup('env', 'DOCKER_CERT_PATH') else omit) }}" key_path: "{{ item.key_path | default((lookup('env', 'DOCKER_CERT_PATH') + '/key.pem') if lookup('env', 'DOCKER_CERT_PATH') else omit) }}" tls_verify: "{{ item.tls_verify | default(lookup('env', 'DOCKER_TLS_VERIFY')) or false }}" hostname: '{{ item.hostname | default(item.name) }}' image: "{{ item.pre_build_image | default(false) | ternary('', 'molecule_local/') }}{{ item.image }}" pull: '{{ item.pull | default(omit) }}' memory: '{{ item.memory | default(omit) }}' memory_swap: '{{ item.memory_swap | default(omit) }}' state: started recreate: false log_driver: json-file command: '{{ (command_directives_dict | default({}))[item.name] | default(omit) }}' command_handling: "{{ item.command_handling | default('compatibility') }}" user: '{{ item.user | default(omit) }}' pid_mode: '{{ item.pid_mode | default(omit) }}' privileged: '{{ item.privileged | default(omit) }}' security_opts: '{{ item.security_opts | default(omit) }}' devices: '{{ item.devices | default(omit) }}' links: '{{ item.links | default(omit) }}' volumes: '{{ item.volumes | default(omit) }}' mounts: '{{ item.mounts | default(omit) }}' tmpfs: '{{ item.tmpfs | default(omit) }}' capabilities: '{{ item.capabilities | default(omit) }}' sysctls: '{{ item.sysctls | default(omit) }}' exposed_ports: '{{ item.exposed_ports | default(omit) }}' published_ports: '{{ item.published_ports | default(omit) }}' ulimits: '{{ item.ulimits | default(omit) }}' networks: '{{ item.networks | default(omit) }}' network_mode: '{{ item.network_mode | default(omit) }}' networks_cli_compatible: '{{ item.networks_cli_compatible | default(true) }}' purge_networks: '{{ item.purge_networks | default(omit) }}' dns_servers: '{{ item.dns_servers | default(omit) }}' etc_hosts: '{{ item.etc_hosts | default(omit) }}' env: '{{ item.env | default(omit) }}' restart_policy: '{{ item.restart_policy | default(omit) }}' restart_retries: '{{ item.restart_retries | default(omit) }}' tty: '{{ item.tty | default(omit) }}' labels: '{{ molecule_labels | combine(item.labels | default({})) }}' container_default_behavior: "{{ item.container_default_behavior | default('compatibility' if ansible_version.full is version_compare('2.10', '>=') else omit) }}" stop_signal: '{{ item.stop_signal | default(omit) }}' kill_signal: '{{ item.kill_signal | default(omit) }}' register: server with_items: '{{ molecule_yml.platforms }}' loop_control: label: '{{ item.name }}' no_log: false async: 7200 poll: 0 - name: Wait for instance(s) creation to complete ansible.builtin.async_status: jid: '{{ item.ansible_job_id }}' register: docker_jobs until: docker_jobs.finished retries: 300 with_items: '{{ server.results }}'