Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docker_container: handle network_mode=default correctly for Docker 26.1.0+ #936

Merged
merged 1 commit into from
Jul 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions changelogs/fragments/936-network_mode-default.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
bugfixes:
- "docker_container - fix idempotency if ``network_mode=default`` and Docker 26.1.0 or later is used. There was a breaking change in
Docker 26.1.0 regarding normalization of ``NetworkMode``
(https://github.com/ansible-collections/community.docker/issues/934, https://github.com/ansible-collections/community.docker/pull/936)."
19 changes: 15 additions & 4 deletions plugins/module_utils/module_container/docker_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ def __init__(
self.set_value = set_value
self.get_expected_values = get_expected_values or (lambda module, client, api_version, options, image, values, host_info: values)
self.ignore_mismatching_result = ignore_mismatching_result or \
(lambda module, client, api_version, option, image, container_value, expected_value: False)
(lambda module, client, api_version, option, image, container_value, expected_value, host_info: False)
self.preprocess_value = preprocess_value or (lambda module, client, api_version, options, values: values)
self.update_value = update_value
self.can_set_value = can_set_value or (lambda api_version: set_value is not None)
Expand Down Expand Up @@ -816,7 +816,7 @@ def _preprocess_links(module, client, api_version, value):
return result


def _ignore_mismatching_label_result(module, client, api_version, option, image, container_value, expected_value):
def _ignore_mismatching_label_result(module, client, api_version, option, image, container_value, expected_value, host_info):
if option.comparison == 'strict' and module.params['image_label_mismatch'] == 'fail':
# If there are labels from the base image that should be removed and
# base_image_mismatch is fail we want raise an error.
Expand All @@ -834,10 +834,20 @@ def _ignore_mismatching_label_result(module, client, api_version, option, image,
return False


def _ignore_mismatching_network_result(module, client, api_version, option, image, container_value, expected_value):
def _needs_host_info_network(values):
return values.get('network_mode') == 'default'


def _ignore_mismatching_network_result(module, client, api_version, option, image, container_value, expected_value, host_info):
# 'networks' is handled out-of-band
if option.name == 'networks':
return True
# The 'default' network_mode value is translated by the Docker daemon to 'bridge' on Linux and 'nat' on Windows.
# This happens since Docker 26.1.0 due to https://github.com/moby/moby/pull/47431; before, 'default' was returned.
if option.name == 'network_mode' and expected_value == 'default':
os_type = host_info.get('OSType') if host_info else None
if (container_value, os_type) in (('bridge', 'linux'), ('nat', 'windows')):
return True
return False


Expand Down Expand Up @@ -1322,7 +1332,7 @@ def _preprocess_container_names(module, client, api_version, value):
OPTION_HOSTNAME.add_engine('docker_api', DockerAPIEngine.config_value('Hostname'))

OPTION_IMAGE.add_engine('docker_api', DockerAPIEngine.config_value(
'Image', ignore_mismatching_result=lambda module, client, api_version, option, image, container_value, expected_value: True))
'Image', ignore_mismatching_result=lambda module, client, api_version, option, image, container_value, expected_value, host_info: True))

OPTION_INIT.add_engine('docker_api', DockerAPIEngine.host_config_value('Init'))

Expand Down Expand Up @@ -1357,6 +1367,7 @@ def _preprocess_container_names(module, client, api_version, value):
get_value=_get_values_network,
set_value=_set_values_network,
ignore_mismatching_result=_ignore_mismatching_network_result,
needs_host_info=_needs_host_info_network,
extra_option_minimal_versions={
'networks.mac_address': {
'docker_api_version': '1.44',
Expand Down
2 changes: 1 addition & 1 deletion plugins/module_utils/module_container/module.py
Original file line number Diff line number Diff line change
Expand Up @@ -533,7 +533,7 @@ def _record_differences(self, differences, options, param_values, engine, contai
if not match:
# No match.
if engine.ignore_mismatching_result(self.module, self.client, self.engine_driver.get_api_version(self.client),
option, image, container_value, param_value):
option, image, container_value, param_value, host_info):
# Ignore the result
continue

Expand Down
Loading