diff --git a/changelogs/fragments/1085-docker_container-command-empty.yml b/changelogs/fragments/1085-docker_container-command-empty.yml new file mode 100644 index 00000000..c11d214f --- /dev/null +++ b/changelogs/fragments/1085-docker_container-command-empty.yml @@ -0,0 +1,2 @@ +bugfixes: + - "docker_container - fix idempotency if ``command=[]`` and ``command_handling=correct`` (https://github.com/ansible-collections/community.docker/issues/1080, https://github.com/ansible-collections/community.docker/pull/1085)." diff --git a/plugins/module_utils/module_container/docker_api.py b/plugins/module_utils/module_container/docker_api.py index 277ccd22..4ebfa572 100644 --- a/plugins/module_utils/module_container/docker_api.py +++ b/plugins/module_utils/module_container/docker_api.py @@ -1274,6 +1274,34 @@ def _preprocess_container_names(module, client, api_version, value): return 'container:{0}'.format(container['Id']) +def _get_value_command(module, container, api_version, options, image, host_info): + value = container['Config'].get('Cmd', _SENTRY) + if value is _SENTRY: + return {} + return {"command": value} + + +def _set_value_command(module, data, api_version, options, values): + if "command" not in values: + return + value = values["command"] + data['Cmd'] = value + + +def _get_expected_values_command(module, client, api_version, options, image, values, host_info): + expected_values = {} + if 'command' in values: + command = values['command'] + if command == [] and image and image["Config"].get("Cmd"): + command = image["Config"].get("Cmd") + expected_values['command'] = command + return expected_values + + +def _needs_container_image_command(values): + return values.get('command') == [] + + OPTION_AUTO_REMOVE.add_engine('docker_api', DockerAPIEngine.host_config_value('AutoRemove')) OPTION_BLKIO_WEIGHT.add_engine('docker_api', DockerAPIEngine.host_config_value('BlkioWeight', update_parameter='BlkioWeight')) @@ -1286,7 +1314,12 @@ OPTION_CGROUP_NS_MODE.add_engine('docker_api', DockerAPIEngine.host_config_value OPTION_CGROUP_PARENT.add_engine('docker_api', DockerAPIEngine.host_config_value('CgroupParent')) -OPTION_COMMAND.add_engine('docker_api', DockerAPIEngine.config_value('Cmd')) +OPTION_COMMAND.add_engine('docker_api', DockerAPIEngine( + get_value=_get_value_command, + set_value=_set_value_command, + get_expected_values=_get_expected_values_command, + needs_container_image=_needs_container_image_command, +)) OPTION_CPU_PERIOD.add_engine('docker_api', DockerAPIEngine.host_config_value('CpuPeriod', update_parameter='CpuPeriod')) diff --git a/tests/integration/targets/docker_container/tasks/tests/options.yml b/tests/integration/targets/docker_container/tasks/tests/options.yml index e3608b83..4aad9ef2 100644 --- a/tests/integration/targets/docker_container/tasks/tests/options.yml +++ b/tests/integration/targets/docker_container/tasks/tests/options.yml @@ -385,6 +385,16 @@ force_kill: true register: command_5 +- name: command (correct, empty list, idempotency) + docker_container: + image: "{{ docker_test_image_alpine }}" + command_handling: correct + command: [] + name: "{{ cname }}" + state: present # the container will use the default command and likely has been exited by this point, so don't use 'state: started' here + force_kill: true + register: command_6 + - name: cleanup docker_container: name: "{{ cname }}" @@ -399,6 +409,7 @@ - command_3 is not changed - command_4 is changed - command_5 is changed + - command_6 is not changed #################################################################### ## cpu_period ######################################################