|
3 | 3 | hosts: localhost
|
4 | 4 | connection: local
|
5 | 5 | gather_facts: false
|
6 |
| - no_log: "{{ not (lookup('env', 'MOLECULE_DEBUG') | bool or molecule_yml.provisioner.log|default(false) | bool) }}" |
| 6 | + no_log: "{{ molecule_no_log }}" |
| 7 | + vars: |
| 8 | + molecule_labels: |
| 9 | + owner: molecule |
7 | 10 | tasks:
|
8 | 11 | - name: Apply global default parameters
|
9 | 12 | set_fact:
|
10 |
| - final_platforms: "{{ final_platforms | default([]) | union([platform_base.docker|combine(item)]) }}" |
| 13 | + final_platforms: "{{ final_platforms | default([]) | union([hostvars[item.name].platform_base.docker|combine(item)]) }}" |
11 | 14 | loop: "{{ molecule_yml.platforms }}"
|
12 | 15 |
|
13 | 16 | - name: Log into a Docker registry
|
|
17 | 20 | email: "{{ item.registry.credentials.email | default(omit) }}"
|
18 | 21 | registry: "{{ item.registry.url }}"
|
19 | 22 | docker_host: "{{ item.docker_host | default(lookup('env', 'DOCKER_HOST') or 'unix://var/run/docker.sock') }}"
|
| 23 | + cacert_path: "{{ item.cacert_path | default((lookup('env', 'DOCKER_CERT_PATH') + '/ca.pem') if lookup('env', 'DOCKER_CERT_PATH') else omit) }}" |
| 24 | + cert_path: "{{ item.cert_path | default((lookup('env', 'DOCKER_CERT_PATH') + '/cert.pem') if lookup('env', 'DOCKER_CERT_PATH') else omit) }}" |
| 25 | + key_path: "{{ item.key_path | default((lookup('env', 'DOCKER_CERT_PATH') + '/key.pem') if lookup('env', 'DOCKER_CERT_PATH') else omit) }}" |
| 26 | + tls_verify: "{{ item.tls_verify | default(lookup('env', 'DOCKER_TLS_VERIFY')) or false }}" |
20 | 27 | with_items: "{{ final_platforms }}"
|
21 | 28 | when:
|
22 | 29 | - item.registry is defined
|
23 | 30 | - item.registry.credentials is defined
|
24 | 31 | - item.registry.credentials.username is defined
|
25 | 32 |
|
| 33 | + - name: Check presence of custom Dockerfiles |
| 34 | + stat: |
| 35 | + path: "{{ molecule_scenario_directory + '/' + (item.dockerfile | default( 'Dockerfile.j2')) }}" |
| 36 | + loop: "{{ final_platforms }}" |
| 37 | + register: dockerfile_stats |
| 38 | + |
26 | 39 | - name: Create Dockerfiles from image names
|
| 40 | + vars: |
| 41 | + # TODO(ssbarnea): expose module dir so it can also be used by plugins |
| 42 | + molecule_module_directory: "{{ playbook_dir + '/../../../..' }}" |
27 | 43 | template:
|
28 |
| - # use a common recipe |
29 |
| - src: "{{ molecule_scenario_directory }}/../_resources/Dockerfile.j2" |
| 44 | + src: >- |
| 45 | + {%- if dockerfile_stats.results[i].stat.exists -%} |
| 46 | + {{ molecule_scenario_directory + '/' + (item.dockerfile | default( 'Dockerfile.j2')) }} |
| 47 | + {%- else -%} |
| 48 | + {{ molecule_module_directory + '/data/Dockerfile.j2' }} |
| 49 | + {%- endif -%} |
30 | 50 | dest: "{{ molecule_ephemeral_directory }}/Dockerfile_{{ item.image | regex_replace('[^a-zA-Z0-9_]', '_') }}"
|
31 |
| - with_items: "{{ final_platforms }}" |
| 51 | + loop: "{{ final_platforms }}" |
| 52 | + loop_control: |
| 53 | + index_var: i |
32 | 54 | when: not item.pre_build_image | default(false)
|
33 | 55 | register: platforms
|
34 | 56 |
|
35 | 57 | - name: Discover local Docker images
|
36 |
| - docker_image_facts: |
| 58 | + docker_image_info: |
37 | 59 | name: "molecule_local/{{ item.item.name }}"
|
38 | 60 | docker_host: "{{ item.item.docker_host | default(lookup('env', 'DOCKER_HOST') or 'unix://var/run/docker.sock') }}"
|
| 61 | + cacert_path: "{{ item.cacert_path | default((lookup('env', 'DOCKER_CERT_PATH') + '/ca.pem') if lookup('env', 'DOCKER_CERT_PATH') else omit) }}" |
| 62 | + cert_path: "{{ item.cert_path | default((lookup('env', 'DOCKER_CERT_PATH') + '/cert.pem') if lookup('env', 'DOCKER_CERT_PATH') else omit) }}" |
| 63 | + key_path: "{{ item.key_path | default((lookup('env', 'DOCKER_CERT_PATH') + '/key.pem') if lookup('env', 'DOCKER_CERT_PATH') else omit) }}" |
| 64 | + tls_verify: "{{ item.tls_verify | default(lookup('env', 'DOCKER_TLS_VERIFY')) or false }}" |
39 | 65 | with_items: "{{ platforms.results }}"
|
40 |
| - when: not item.pre_build_image | default(false) |
| 66 | + when: |
| 67 | + - not item.pre_build_image | default(false) |
41 | 68 | register: docker_images
|
42 | 69 |
|
43 |
| - - name: Build an Ansible compatible image |
| 70 | + - name: Build an Ansible compatible image (new) |
| 71 | + when: |
| 72 | + - platforms.changed or docker_images.results | map(attribute='images') | select('equalto', []) | list | count >= 0 |
| 73 | + - not item.item.pre_build_image | default(false) |
44 | 74 | docker_image:
|
45 |
| - path: "{{ molecule_ephemeral_directory }}" |
| 75 | + build: |
| 76 | + path: "{{ molecule_ephemeral_directory }}" |
| 77 | + dockerfile: "{{ item.invocation.module_args.dest }}" |
| 78 | + pull: "{{ item.item.pull | default(true) }}" |
| 79 | + network: "{{ item.item.network_mode | default(omit) }}" |
| 80 | + args: "{{ item.item.buildargs | default(omit) }}" |
46 | 81 | name: "molecule_local/{{ item.item.image }}"
|
47 | 82 | docker_host: "{{ item.item.docker_host | default(lookup('env', 'DOCKER_HOST') or 'unix://var/run/docker.sock') }}"
|
48 |
| - dockerfile: "{{ item.item.dockerfile | default(item.invocation.module_args.dest) }}" |
49 |
| - force: "{{ item.item.force | default(true) }}" |
50 |
| - pull: "{{ item.item.pull | default(omit) }}" |
| 83 | + cacert_path: "{{ item.cacert_path | default((lookup('env', 'DOCKER_CERT_PATH') + '/ca.pem') if lookup('env', 'DOCKER_CERT_PATH') else omit) }}" |
| 84 | + cert_path: "{{ item.cert_path | default((lookup('env', 'DOCKER_CERT_PATH') + '/cert.pem') if lookup('env', 'DOCKER_CERT_PATH') else omit) }}" |
| 85 | + key_path: "{{ item.key_path | default((lookup('env', 'DOCKER_CERT_PATH') + '/key.pem') if lookup('env', 'DOCKER_CERT_PATH') else omit) }}" |
| 86 | + tls_verify: "{{ item.tls_verify | default(lookup('env', 'DOCKER_TLS_VERIFY')) or false }}" |
| 87 | + force_source: "{{ item.item.force | default(true) }}" |
| 88 | + source: build |
51 | 89 | with_items: "{{ platforms.results }}"
|
52 |
| - when: |
53 |
| - - platforms.changed or docker_images.results | map(attribute='images') | select('equalto', []) | list | count >= 0 |
54 |
| - - not item.item.pre_build_image | default(false) |
| 90 | + loop_control: |
| 91 | + label: "molecule_local/{{ item.item.image }}" |
| 92 | + no_log: false |
| 93 | + register: result |
| 94 | + until: result is not failed |
| 95 | + retries: 3 |
| 96 | + delay: 30 |
55 | 97 |
|
56 | 98 | - name: Create docker network(s)
|
57 | 99 | docker_network:
|
58 | 100 | name: "{{ item }}"
|
59 | 101 | docker_host: "{{ item.docker_host | default(lookup('env', 'DOCKER_HOST') or 'unix://var/run/docker.sock') }}"
|
| 102 | + cacert_path: "{{ item.cacert_path | default((lookup('env', 'DOCKER_CERT_PATH') + '/ca.pem') if lookup('env', 'DOCKER_CERT_PATH') else omit) }}" |
| 103 | + cert_path: "{{ item.cert_path | default((lookup('env', 'DOCKER_CERT_PATH') + '/cert.pem') if lookup('env', 'DOCKER_CERT_PATH') else omit) }}" |
| 104 | + key_path: "{{ item.key_path | default((lookup('env', 'DOCKER_CERT_PATH') + '/key.pem') if lookup('env', 'DOCKER_CERT_PATH') else omit) }}" |
| 105 | + tls_verify: "{{ item.tls_verify | default(lookup('env', 'DOCKER_TLS_VERIFY')) or false }}" |
| 106 | + labels: "{{ molecule_labels | combine(item.labels | default({})) }}" |
60 | 107 | state: present
|
| 108 | + # Duck: we need IPv6 |
| 109 | + enable_ipv6: True |
| 110 | + ipam_config: |
| 111 | + # RFC 4193 |
| 112 | + - subnet: fdd1:0:0:0::/64 |
61 | 113 | with_items: "{{ final_platforms | molecule_get_docker_networks }}"
|
| 114 | + loop_control: |
| 115 | + label: "{{ item }}" |
| 116 | + no_log: false |
| 117 | + |
| 118 | + - name: Determine the CMD directives |
| 119 | + set_fact: |
| 120 | + command_directives_dict: >- |
| 121 | + {{ command_directives_dict | default({}) | |
| 122 | + combine({ item.name: item.command | default('bash -c "while true; do sleep 10000; done"') }) |
| 123 | + }} |
| 124 | + with_items: "{{ final_platforms }}" |
| 125 | + when: item.override_command | default(true) |
62 | 126 |
|
63 | 127 | - name: Create molecule instance(s)
|
64 | 128 | docker_container:
|
65 | 129 | name: "{{ item.name }}"
|
66 | 130 | docker_host: "{{ item.docker_host | default(lookup('env', 'DOCKER_HOST') or 'unix://var/run/docker.sock') }}"
|
67 |
| - hostname: "{{ item.hostname | default(item.name) }}" |
| 131 | + cacert_path: "{{ item.cacert_path | default((lookup('env', 'DOCKER_CERT_PATH') + '/ca.pem') if lookup('env', 'DOCKER_CERT_PATH') else omit) }}" |
| 132 | + cert_path: "{{ item.cert_path | default((lookup('env', 'DOCKER_CERT_PATH') + '/cert.pem') if lookup('env', 'DOCKER_CERT_PATH') else omit) }}" |
| 133 | + key_path: "{{ item.key_path | default((lookup('env', 'DOCKER_CERT_PATH') + '/key.pem') if lookup('env', 'DOCKER_CERT_PATH') else omit) }}" |
| 134 | + tls_verify: "{{ item.tls_verify | default(lookup('env', 'DOCKER_TLS_VERIFY')) or false }}" |
| 135 | + hostname: "{{ item.hostname | default(item.name) | replace('@NAME@', item.name) }}" |
68 | 136 | image: "{{ item.pre_build_image | default(false) | ternary('', 'molecule_local/') }}{{ item.image }}"
|
| 137 | + pull: "{{ item.pull | default(omit) }}" |
| 138 | + memory: "{{ item.memory | default(omit) }}" |
69 | 139 | state: started
|
70 | 140 | recreate: false
|
71 | 141 | log_driver: json-file
|
72 |
| - command: "{{ item.command | default('bash -c \"while true; do sleep 10000; done\"') }}" |
| 142 | + command: "{{ (command_directives_dict | default({}))[item.name] | default(omit) }}" |
| 143 | + user: "{{ item.user | default(omit) }}" |
| 144 | + pid_mode: "{{ item.pid_mode | default(omit) }}" |
73 | 145 | privileged: "{{ item.privileged | default(omit) }}"
|
74 | 146 | security_opts: "{{ item.security_opts | default(omit) }}"
|
| 147 | + devices: "{{ item.devices | default(omit) }}" |
75 | 148 | volumes: "{{ item.volumes | default(omit) }}"
|
76 | 149 | tmpfs: "{{ item.tmpfs | default(omit) }}"
|
77 | 150 | capabilities: "{{ item.capabilities | default(omit) }}"
|
| 151 | + sysctls: "{{ item.sysctls | default(omit) }}" |
78 | 152 | exposed_ports: "{{ item.exposed_ports | default(omit) }}"
|
79 | 153 | published_ports: "{{ item.published_ports | default(omit) }}"
|
80 | 154 | ulimits: "{{ item.ulimits | default(omit) }}"
|
81 | 155 | networks: "{{ item.networks | default(omit) }}"
|
82 | 156 | network_mode: "{{ item.network_mode | default(omit) }}"
|
| 157 | + networks_cli_compatible: "{{ item.networks_cli_compatible | default(true) }}" |
| 158 | + purge_networks: "{{ item.purge_networks | default(omit) }}" |
83 | 159 | dns_servers: "{{ item.dns_servers | default(omit) }}"
|
| 160 | + etc_hosts: "{{ item.etc_hosts | default(omit) }}" |
84 | 161 | env: "{{ item.env | default(omit) }}"
|
85 | 162 | restart_policy: "{{ item.restart_policy | default(omit) }}"
|
86 | 163 | restart_retries: "{{ item.restart_retries | default(omit) }}"
|
| 164 | + tty: "{{ item.tty | default(omit) }}" |
| 165 | + labels: "{{ molecule_labels | combine(item.labels | default({})) }}" |
| 166 | + container_default_behavior: "{{ item.container_default_behavior | default('compatibility' if ansible_version.full is version_compare('2.10', '>=') else omit) }}" |
| 167 | + # Duck: missing parameters |
| 168 | + dns_search_domains: "{{ item.dns_search_domains | default(omit) }}" |
87 | 169 | register: server
|
88 | 170 | with_items: "{{ final_platforms }}"
|
| 171 | + loop_control: |
| 172 | + label: "{{ item.name }}" |
| 173 | + no_log: false |
89 | 174 | async: 7200
|
90 | 175 | poll: 0
|
91 | 176 |
|
|
0 commit comments