diff --git a/changelogs/fragments/54-docker_image-build-platform.yml b/changelogs/fragments/54-docker_image-build-platform.yml new file mode 100644 index 00000000..fdd138dd --- /dev/null +++ b/changelogs/fragments/54-docker_image-build-platform.yml @@ -0,0 +1,2 @@ +minor_changes: +- "docker_image - support ``platform`` when building images (https://github.com/ansible-collections/community.docker/issues/22, https://github.com/ansible-collections/community.docker/pull/54)." diff --git a/plugins/modules/docker_image.py b/plugins/modules/docker_image.py index 3daf0090..949125ec 100644 --- a/plugins/modules/docker_image.py +++ b/plugins/modules/docker_image.py @@ -123,6 +123,11 @@ options: - When building an image specifies an intermediate build stage by name as a final stage for the resulting image. type: str + platform: + description: + - Platform in the format C(os[/arch[/variant]]). + type: str + version_added: 1.1.0 archive_path: description: - Use with state C(present) to archive an image to a .tar file. @@ -365,6 +370,7 @@ class ImageManager(DockerBaseClass): self.http_timeout = build.get('http_timeout') self.push = parameters.get('push') self.buildargs = build.get('args') + self.build_platform = build.get('platform') self.use_config_proxy = build.get('use_config_proxy') # If name contains a tag, it takes precedence over tag parameter. @@ -634,6 +640,8 @@ class ImageManager(DockerBaseClass): params['buildargs'] = {} if self.target: params['target'] = self.target + if self.build_platform is not None: + params['platform'] = self.build_platform build_output = [] for line in self.client.build(**params): @@ -702,6 +710,7 @@ def main(): use_config_proxy=dict(type='bool'), target=dict(type='str'), etc_hosts=dict(type='dict'), + platform=dict(type='str'), )), archive_path=dict(type='path'), force_source=dict(type='bool', default=False), @@ -736,12 +745,16 @@ def main(): def detect_etc_hosts(client): return client.module.params['build'] and bool(client.module.params['build'].get('etc_hosts')) + def detect_platform(client): + return client.module.params['build'] and client.module.params['build'].get('platform') is not None + option_minimal_versions = dict() option_minimal_versions["build.cache_from"] = dict(docker_py_version='2.1.0', docker_api_version='1.25', detect_usage=detect_build_cache_from) option_minimal_versions["build.network"] = dict(docker_py_version='2.4.0', docker_api_version='1.25', detect_usage=detect_build_network) option_minimal_versions["build.target"] = dict(docker_py_version='2.4.0', detect_usage=detect_build_target) option_minimal_versions["build.use_config_proxy"] = dict(docker_py_version='3.7.0', detect_usage=detect_use_config_proxy) option_minimal_versions["build.etc_hosts"] = dict(docker_py_version='2.6.0', docker_api_version='1.27', detect_usage=detect_etc_hosts) + option_minimal_versions["build.platform"] = dict(docker_py_version='3.0.0', docker_api_version='1.32', detect_usage=detect_platform) client = AnsibleDockerClient( argument_spec=argument_spec, diff --git a/tests/integration/targets/docker_image/tasks/tests/options.yml b/tests/integration/targets/docker_image/tasks/tests/options.yml index b04fa8ea..5122715e 100644 --- a/tests/integration/targets/docker_image/tasks/tests/options.yml +++ b/tests/integration/targets/docker_image/tasks/tests/options.yml @@ -30,6 +30,7 @@ pull: no source: build register: buildargs_1 + ignore_errors: yes - name: buildargs (idempotency) docker_image: @@ -43,6 +44,7 @@ pull: no source: build register: buildargs_2 + ignore_errors: yes - name: cleanup docker_image: @@ -53,7 +55,7 @@ - assert: that: - buildargs_1 is changed - - buildargs_2 is not changed + - buildargs_2 is not failed and buildargs_2 is not changed when: docker_py_version is version('1.6.0', '>=') - assert: @@ -63,7 +65,7 @@ when: docker_py_version is version('1.6.0', '<') #################################################################### -## container_limits ################################################ +## build.container_limits ########################################## #################################################################### - name: container_limits (Failed due to min memory limit) @@ -108,7 +110,7 @@ - "container_limits_1 is changed or container_limits_2 is changed and not (container_limits_1 is changed and container_limits_2 is changed)" #################################################################### -## dockerfile ###################################################### +## build.dockerfile ################################################ #################################################################### - name: dockerfile @@ -133,6 +135,56 @@ - "('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: yes + +- name: build.platform + docker_image: + name: "{{ iname }}" + build: + path: "{{ output_dir }}/files" + platform: linux + pull: no + source: build + register: platform_1 + ignore_errors: yes + +- name: build.platform (idempotency) + docker_image: + name: "{{ iname }}" + build: + path: "{{ output_dir }}/files" + platform: linux + pull: no + source: build + register: platform_2 + ignore_errors: yes + +- name: cleanup + docker_image: + name: "{{ iname }}" + state: absent + force_absent: yes + +- assert: + that: + - platform_1 is changed + - platform_2 is not failed and platform_2 is not changed + when: docker_py_version is version('3.0.0', '>=') + +- assert: + that: + - platform_1 is failed + - platform_2 is failed + when: docker_py_version is version('3.0.0', '<') + #################################################################### ## force ########################################################### #################################################################### @@ -216,7 +268,7 @@ - archive_image['image']['Id'] == load_image['image']['Id'] #################################################################### -## path ############################################################ +## build.path ###################################################### #################################################################### - name: Build image @@ -249,7 +301,7 @@ - path_2 is not changed #################################################################### -## target ########################################################## +## build.target #################################################### #################################################################### - name: Build multi-stage image