--- # Copyright (c) Ansible Project # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # SPDX-License-Identifier: GPL-3.0-or-later - name: Registering image name set_fact: iname: "{{ name_prefix ~ '-options' }}" iname_1: "{{ name_prefix ~ '-options-1' }}" hello_world_alt: "{{ name_prefix }}-hello-world-alt:v1.2.3-foo" - name: Registering image name set_fact: inames: "{{ inames + [iname, iname_1, hello_world_alt] }}" #################################################################### ## build.args ###################################################### #################################################################### - name: cleanup docker_image: name: "{{ iname }}" state: absent force_absent: true - name: buildargs docker_image: name: "{{ iname }}" build: path: "{{ remote_tmp_dir }}/files" dockerfile: "ArgsDockerfile" args: IMAGE: "{{ docker_test_image_busybox }}" TEST1: val1 TEST2: val2 TEST3: "True" pull: false source: build register: buildargs_1 ignore_errors: true - name: buildargs (idempotency) docker_image: name: "{{ iname }}" build: path: "{{ remote_tmp_dir }}/files" dockerfile: "ArgsDockerfile" args: IMAGE: "{{ docker_test_image_busybox }}" TEST1: val1 TEST2: val2 TEST3: "True" pull: false source: build register: buildargs_2 ignore_errors: true - name: cleanup docker_image: name: "{{ iname }}" state: absent force_absent: true - assert: that: - buildargs_1 is changed - buildargs_2 is not failed and buildargs_2 is not changed #################################################################### ## build.container_limits ########################################## #################################################################### - name: container_limits (Failed due to min memory limit) docker_image: name: "{{ iname }}" build: path: "{{ remote_tmp_dir }}/files" container_limits: memory: 4000 pull: false source: build ignore_errors: true register: container_limits_1 - name: container_limits docker_image: name: "{{ iname }}" build: path: "{{ remote_tmp_dir }}/files" container_limits: memory: 7000000 memswap: 8000000 pull: false source: build register: container_limits_2 - name: cleanup docker_image: name: "{{ iname }}" state: absent force_absent: true - assert: that: # It *sometimes* happens that the first task does not fail. # For now, we work around this by # a) requiring that if it fails, the message must # contain 'Minimum memory limit allowed is (4|6)MB', and # b) requiring that either the first task, or the second # task is changed, but not both. - "not container_limits_1 is failed or ('Minimum memory limit allowed is ') in container_limits_1.msg" - "container_limits_1 is changed or container_limits_2 is changed and not (container_limits_1 is changed and container_limits_2 is changed)" #################################################################### ## build.dockerfile ################################################ #################################################################### - name: dockerfile docker_image: name: "{{ iname }}" build: path: "{{ remote_tmp_dir }}/files" dockerfile: "MyDockerfile" pull: false source: build register: dockerfile_1 - name: cleanup docker_image: name: "{{ iname }}" state: absent force_absent: true - assert: that: - dockerfile_1 is changed - "('FROM ' ~ docker_test_image_alpine) in dockerfile_1.stdout" - dockerfile_1['image']['Config']['WorkingDir'] == '/newdata' #################################################################### ## build.platform ################################################## #################################################################### - name: cleanup docker_image: name: "{{ iname }}" state: absent force_absent: true - name: build.platform docker_image: name: "{{ iname }}" build: path: "{{ remote_tmp_dir }}/files" platform: linux pull: false source: build register: platform_1 ignore_errors: true - name: build.platform (idempotency) docker_image: name: "{{ iname }}" build: path: "{{ remote_tmp_dir }}/files" platform: linux pull: false source: build register: platform_2 ignore_errors: true - name: cleanup docker_image: name: "{{ iname }}" state: absent force_absent: true - assert: that: - platform_1 is changed - platform_2 is not failed and platform_2 is not changed #################################################################### ## force ########################################################### #################################################################### - name: Build an image docker_image: name: "{{ iname }}" build: path: "{{ remote_tmp_dir }}/files" pull: false source: build - name: force (changed) docker_image: name: "{{ iname }}" build: path: "{{ remote_tmp_dir }}/files" dockerfile: "MyDockerfile" pull: false source: build force_source: true register: force_1 - name: force (unchanged) docker_image: name: "{{ iname }}" build: path: "{{ remote_tmp_dir }}/files" dockerfile: "MyDockerfile" pull: false source: build force_source: true register: force_2 - name: cleanup docker_image: name: "{{ iname }}" state: absent force_absent: true - assert: that: - force_1 is changed - force_2 is not changed #################################################################### ## load path ####################################################### #################################################################### - name: Archive image docker_image: name: "{{ docker_test_image_hello_world }}" archive_path: "{{ remote_tmp_dir }}/image.tar" source: pull register: archive_image - assert: that: - archive_image is changed - name: Copy archive because we will mutate it but other tests need the original copy: remote_src: true src: "{{ remote_tmp_dir }}/image.tar" dest: "{{ remote_tmp_dir }}/image_mutated.tar" - name: Archive image again (idempotent) docker_image: name: "{{ docker_test_image_hello_world }}" archive_path: "{{ remote_tmp_dir }}/image_mutated.tar" source: local register: archive_image_2 - assert: that: - archive_image_2 is not changed - name: Archive image 3rd time, should overwrite due to different id docker_image: name: "{{ docker_test_image_alpine_different }}" archive_path: "{{ remote_tmp_dir }}/image_mutated.tar" source: pull register: archive_image_3 - assert: that: - archive_image_3 is changed - name: Reset archive copy: remote_src: true src: "{{ remote_tmp_dir }}/image.tar" dest: "{{ remote_tmp_dir }}/image_mutated.tar" - name: Tag image with different name docker_image: name: "{{ docker_test_image_hello_world }}" repository: "{{ hello_world_alt }}" source: local - name: Archive image 4th time, should overwrite due to different name even when ID is same docker_image: name: "{{ hello_world_alt }}" # Tagged as docker_test_image_hello_world but has same hash/id (before this task overwrites it) archive_path: "{{ remote_tmp_dir }}/image_mutated.tar" source: local register: archive_image_4 - assert: that: - archive_image_4 is changed # This is the test that needs the original, non-mutated archive - name: Archive image by ID docker_image: name: "{{ archive_image.image.Id }}" archive_path: "{{ remote_tmp_dir }}/image_id.tar" source: local register: archive_image_id - name: Create invalid archive copy: dest: "{{ remote_tmp_dir }}/image-invalid.tar" content: "this is not a valid image" - name: remove image docker_image: name: "{{ docker_test_image_hello_world }}" state: absent force_absent: true - name: load image (changed) docker_image: name: "{{ docker_test_image_hello_world }}" load_path: "{{ remote_tmp_dir }}/image.tar" source: load register: load_image - name: load image (idempotency) docker_image: name: "{{ docker_test_image_hello_world }}" load_path: "{{ remote_tmp_dir }}/image.tar" source: load register: load_image_1 - name: load image (wrong name) docker_image: name: foo:bar load_path: "{{ remote_tmp_dir }}/image.tar" source: load register: load_image_2 ignore_errors: true - name: load image (invalid image) docker_image: name: foo:bar load_path: "{{ remote_tmp_dir }}/image-invalid.tar" source: load register: load_image_3 ignore_errors: true - name: load image (ID, idempotency) docker_image: name: "{{ archive_image.image.Id }}" load_path: "{{ remote_tmp_dir }}/image_id.tar" source: load register: load_image_4 - assert: that: - load_image is changed - archive_image['image']['Id'] == load_image['image']['Id'] - load_image_1 is not changed - load_image_2 is failed - >- "The archive did not contain image 'foo:bar'. Instead, found '" ~ docker_test_image_hello_world ~ "'." == load_image_2.msg - load_image_3 is failed - '"Detected no loaded images. Archive potentially corrupt?" == load_image_3.msg' - load_image_4 is not changed #################################################################### ## build.path ###################################################### #################################################################### - name: Build image docker_image: name: "{{ iname }}" build: path: "{{ remote_tmp_dir }}/files" pull: false source: build register: path_1 - name: Build image (idempotency) docker_image: name: "{{ iname }}" build: path: "{{ remote_tmp_dir }}/files" pull: false source: build register: path_2 - name: cleanup docker_image: name: "{{ iname }}" state: absent force_absent: true - assert: that: - path_1 is changed - path_2 is not changed #################################################################### ## build.target #################################################### #################################################################### - name: Build multi-stage image docker_image: name: "{{ iname }}" build: path: "{{ remote_tmp_dir }}/files" dockerfile: "StagedDockerfile" target: first pull: false source: build register: dockerfile_2 - name: cleanup docker_image: name: "{{ iname }}" state: absent force_absent: true - assert: that: - dockerfile_2 is changed - dockerfile_2.image.Config.WorkingDir == '/first' #################################################################### ## build.etc_hosts ################################################# #################################################################### - name: Build image with custom etc_hosts docker_image: name: "{{ iname }}" build: path: "{{ remote_tmp_dir }}/files" dockerfile: "EtcHostsDockerfile" pull: false etc_hosts: some-custom-host: "127.0.0.1" source: build register: path_1 - name: cleanup docker_image: name: "{{ iname }}" state: absent force_absent: true - assert: that: - path_1 is changed