1---
2- name: Registering image name
3  set_fact:
4    iname: "{{ name_prefix ~ '-options' }}"
5    iname_1: "{{ name_prefix ~ '-options-1' }}"
6
7- name: Registering image name
8  set_fact:
9    inames: "{{ inames + [iname, iname_1] }}"
10
11####################################################################
12## build.args ######################################################
13####################################################################
14
15- name: cleanup
16  docker_image:
17    name: "{{ iname }}"
18    state: absent
19    force_absent: yes
20
21- name: buildargs
22  docker_image:
23    name: "{{ iname }}"
24    build:
25      path: "{{ remote_tmp_dir }}/files"
26      args:
27        TEST1: val1
28        TEST2: val2
29        TEST3: "True"
30      pull: no
31    source: build
32  register: buildargs_1
33  ignore_errors: yes
34
35- name: buildargs (idempotency)
36  docker_image:
37    name: "{{ iname }}"
38    build:
39      path: "{{ remote_tmp_dir }}/files"
40      args:
41        TEST1: val1
42        TEST2: val2
43        TEST3: "True"
44      pull: no
45    source: build
46  register: buildargs_2
47  ignore_errors: yes
48
49- name: cleanup
50  docker_image:
51    name: "{{ iname }}"
52    state: absent
53    force_absent: yes
54
55- assert:
56    that:
57    - buildargs_1 is changed
58    - buildargs_2 is not failed and buildargs_2 is not changed
59  when: docker_py_version is version('1.6.0', '>=')
60
61- assert:
62    that:
63    - buildargs_1 is failed
64    - buildargs_2 is failed
65  when: docker_py_version is version('1.6.0', '<')
66
67####################################################################
68## build.container_limits ##########################################
69####################################################################
70
71- name: container_limits (Failed due to min memory limit)
72  docker_image:
73    name: "{{ iname }}"
74    build:
75      path: "{{ remote_tmp_dir }}/files"
76      container_limits:
77        memory: 4000
78      pull: no
79    source: build
80  ignore_errors: yes
81  register: container_limits_1
82
83- name: container_limits
84  docker_image:
85    name: "{{ iname }}"
86    build:
87      path: "{{ remote_tmp_dir }}/files"
88      container_limits:
89        memory: 7000000
90        memswap: 8000000
91      pull: no
92    source: build
93  register: container_limits_2
94
95- name: cleanup
96  docker_image:
97    name: "{{ iname }}"
98    state: absent
99    force_absent: yes
100
101- assert:
102    that:
103    # It *sometimes* happens that the first task does not fail.
104    # For now, we work around this by
105    #   a) requiring that if it fails, the message must
106    #      contain 'Minimum memory limit allowed is (4|6)MB', and
107    #   b) requiring that either the first task, or the second
108    #      task is changed, but not both.
109    - "not container_limits_1 is failed or ('Minimum memory limit allowed is ') in container_limits_1.msg"
110    - "container_limits_1 is changed or container_limits_2 is changed and not (container_limits_1 is changed and container_limits_2 is changed)"
111
112####################################################################
113## build.dockerfile ################################################
114####################################################################
115
116- name: dockerfile
117  docker_image:
118    name: "{{ iname }}"
119    build:
120      path: "{{ remote_tmp_dir }}/files"
121      dockerfile: "MyDockerfile"
122      pull: no
123    source: build
124  register: dockerfile_1
125
126- name: cleanup
127  docker_image:
128    name: "{{ iname }}"
129    state: absent
130    force_absent: yes
131
132- assert:
133    that:
134    - dockerfile_1 is changed
135    - "('FROM ' ~ docker_test_image_alpine) in dockerfile_1.stdout"
136    - dockerfile_1['image']['Config']['WorkingDir'] == '/newdata'
137
138####################################################################
139## build.platform ##################################################
140####################################################################
141
142- name: cleanup
143  docker_image:
144    name: "{{ iname }}"
145    state: absent
146    force_absent: yes
147
148- name: build.platform
149  docker_image:
150    name: "{{ iname }}"
151    build:
152      path: "{{ remote_tmp_dir }}/files"
153      platform: linux
154      pull: no
155    source: build
156  register: platform_1
157  ignore_errors: yes
158
159- name: build.platform (idempotency)
160  docker_image:
161    name: "{{ iname }}"
162    build:
163      path: "{{ remote_tmp_dir }}/files"
164      platform: linux
165      pull: no
166    source: build
167  register: platform_2
168  ignore_errors: yes
169
170- name: cleanup
171  docker_image:
172    name: "{{ iname }}"
173    state: absent
174    force_absent: yes
175
176- assert:
177    that:
178    - platform_1 is changed
179    - platform_2 is not failed and platform_2 is not changed
180  when: docker_py_version is version('3.0.0', '>=')
181
182- assert:
183    that:
184    - platform_1 is failed
185    - platform_2 is failed
186  when: docker_py_version is version('3.0.0', '<')
187
188####################################################################
189## force ###########################################################
190####################################################################
191
192- name: Build an image
193  docker_image:
194    name: "{{ iname }}"
195    build:
196      path: "{{ remote_tmp_dir }}/files"
197      pull: no
198    source: build
199
200- name: force (changed)
201  docker_image:
202    name: "{{ iname }}"
203    build:
204      path: "{{ remote_tmp_dir }}/files"
205      dockerfile: "MyDockerfile"
206      pull: no
207    source: build
208    force_source: yes
209  register: force_1
210
211- name: force (unchanged)
212  docker_image:
213    name: "{{ iname }}"
214    build:
215      path: "{{ remote_tmp_dir }}/files"
216      dockerfile: "MyDockerfile"
217      pull: no
218    source: build
219    force_source: yes
220  register: force_2
221
222- name: cleanup
223  docker_image:
224    name: "{{ iname }}"
225    state: absent
226    force_absent: yes
227
228- assert:
229    that:
230    - force_1 is changed
231    - force_2 is not changed
232
233####################################################################
234## load path #######################################################
235####################################################################
236
237- name: Archive image
238  docker_image:
239    name: "{{ docker_test_image_hello_world }}"
240    archive_path: "{{ remote_tmp_dir }}/image.tar"
241    source: pull
242  register: archive_image
243
244- name: Archive image by ID
245  docker_image:
246    name: "{{ archive_image.image.Id }}"
247    archive_path: "{{ remote_tmp_dir }}/image_id.tar"
248    source: local
249  register: archive_image_id
250
251- name: Create invalid archive
252  copy:
253    dest: "{{ remote_tmp_dir }}/image-invalid.tar"
254    content: "this is not a valid image"
255
256- name: remove image
257  docker_image:
258    name: "{{ docker_test_image_hello_world }}"
259    state: absent
260    force_absent: yes
261
262- name: load image (changed)
263  docker_image:
264    name: "{{ docker_test_image_hello_world }}"
265    load_path: "{{ remote_tmp_dir }}/image.tar"
266    source: load
267  register: load_image
268
269- name: load image (idempotency)
270  docker_image:
271    name: "{{ docker_test_image_hello_world }}"
272    load_path: "{{ remote_tmp_dir }}/image.tar"
273    source: load
274  register: load_image_1
275
276- name: load image (wrong name)
277  docker_image:
278    name: foo:bar
279    load_path: "{{ remote_tmp_dir }}/image.tar"
280    source: load
281  register: load_image_2
282  ignore_errors: true
283
284- name: load image (invalid image)
285  docker_image:
286    name: foo:bar
287    load_path: "{{ remote_tmp_dir }}/image-invalid.tar"
288    source: load
289  register: load_image_3
290  ignore_errors: true
291
292- name: load image (invalid image, old API version)
293  docker_image:
294    name: foo:bar
295    load_path: "{{ remote_tmp_dir }}/image-invalid.tar"
296    source: load
297    api_version: "1.22"
298  register: load_image_4
299
300- name: load image (ID, idempotency)
301  docker_image:
302    name: "{{ archive_image.image.Id }}"
303    load_path: "{{ remote_tmp_dir }}/image_id.tar"
304    source: load
305  register: load_image_5
306
307- assert:
308    that:
309    - load_image is changed
310    - archive_image['image']['Id'] == load_image['image']['Id']
311    - load_image_1 is not changed
312    - load_image_2 is failed
313    - >-
314      "The archive did not contain image 'foo:bar'. Instead, found '" ~ docker_test_image_hello_world ~ "'." == load_image_2.msg
315    - load_image_3 is failed
316    - '"Detected no loaded images. Archive potentially corrupt?" == load_image_3.msg'
317    - load_image_4 is changed
318    - "'The API version of your Docker daemon is < 1.23, which does not return the image loading result from the Docker daemon. Therefore, we cannot verify whether the expected image was loaded, whether multiple images where loaded, or whether the load actually succeeded. You should consider upgrading your Docker daemon.' in load_image_4.warnings"
319    - load_image_5 is not changed
320
321####################################################################
322## build.path ######################################################
323####################################################################
324
325- name: Build image
326  docker_image:
327    name: "{{ iname }}"
328    build:
329      path: "{{ remote_tmp_dir }}/files"
330      pull: no
331    source: build
332  register: path_1
333
334- name: Build image (idempotency)
335  docker_image:
336    name: "{{ iname }}"
337    build:
338      path: "{{ remote_tmp_dir }}/files"
339      pull: no
340    source: build
341  register: path_2
342
343- name: cleanup
344  docker_image:
345    name: "{{ iname }}"
346    state: absent
347    force_absent: yes
348
349- assert:
350    that:
351      - path_1 is changed
352      - path_2 is not changed
353
354####################################################################
355## build.target ####################################################
356####################################################################
357
358- name: Build multi-stage image
359  docker_image:
360    name: "{{ iname }}"
361    build:
362      path: "{{ remote_tmp_dir }}/files"
363      dockerfile: "StagedDockerfile"
364      target: first
365      pull: no
366    source: build
367  register: dockerfile_2
368
369- name: cleanup
370  docker_image:
371    name: "{{ iname }}"
372    state: absent
373    force_absent: yes
374
375- assert:
376    that:
377    - dockerfile_2 is changed
378    - dockerfile_2.image.Config.WorkingDir == '/first'
379
380####################################################################
381## build.etc_hosts #################################################
382####################################################################
383
384- name: Build image with custom etc_hosts
385  docker_image:
386    name: "{{ iname }}"
387    build:
388      path: "{{ remote_tmp_dir }}/files"
389      dockerfile: "EtcHostsDockerfile"
390      pull: no
391      etc_hosts:
392        some-custom-host: "127.0.0.1"
393    source: build
394  register: path_1
395
396- name: cleanup
397  docker_image:
398    name: "{{ iname }}"
399    state: absent
400    force_absent: yes
401
402- assert:
403    that:
404      - path_1 is changed
405