mirror of
https://github.com/ansible-collections/community.docker.git
synced 2026-09-12 19:07:24 +00:00
docker_container: refactoring preparing better comparisons (#713)
* Always get the container's image as well to allow get_value() to use that one too. * Allow options and engines to overwrite comparison functions. * Do not fail if image (by ID) cannot be found. * Allow to control when container image is needed. * Pass option to compare function. * Allow to pass the host info for retrieving a value. * Add changelog fragment.
This commit is contained in:
@@ -268,6 +268,20 @@ class ContainerManager(DockerBaseClass):
|
||||
parameters.append((options, values))
|
||||
return parameters
|
||||
|
||||
def _needs_container_image(self):
|
||||
for options, values in self.parameters:
|
||||
engine = options.get_engine(self.engine_driver.name)
|
||||
if engine.needs_container_image(values):
|
||||
return True
|
||||
return False
|
||||
|
||||
def _needs_host_info(self):
|
||||
for options, values in self.parameters:
|
||||
engine = options.get_engine(self.engine_driver.name)
|
||||
if engine.needs_host_info(values):
|
||||
return True
|
||||
return False
|
||||
|
||||
def present(self, state):
|
||||
self.parameters = self._collect_params(self.options)
|
||||
container = self._get_container(self.param_name)
|
||||
@@ -280,8 +294,10 @@ class ContainerManager(DockerBaseClass):
|
||||
# the container already runs or not; in the former case, in case the
|
||||
# container needs to be restarted, we use the existing container's
|
||||
# image ID.
|
||||
image, comparison_image = self._get_image(container)
|
||||
image, container_image, comparison_image = self._get_image(
|
||||
container, needs_container_image=self._needs_container_image())
|
||||
self.log(image, pretty_print=True)
|
||||
host_info = self.engine_driver.get_host_info(self.client) if self._needs_host_info() else None
|
||||
if not container.exists or container.removing:
|
||||
# New container
|
||||
if container.removing:
|
||||
@@ -301,7 +317,7 @@ class ContainerManager(DockerBaseClass):
|
||||
container_created = True
|
||||
else:
|
||||
# Existing container
|
||||
different, differences = self.has_different_configuration(container, comparison_image)
|
||||
different, differences = self.has_different_configuration(container, container_image, comparison_image, host_info)
|
||||
image_different = False
|
||||
if self.all_options['image'].comparison == 'strict':
|
||||
image_different = self._image_is_different(image, container)
|
||||
@@ -333,7 +349,7 @@ class ContainerManager(DockerBaseClass):
|
||||
comparison_image = image
|
||||
|
||||
if container and container.exists:
|
||||
container = self.update_limits(container, comparison_image)
|
||||
container = self.update_limits(container, container_image, comparison_image, host_info)
|
||||
container = self.update_networks(container, container_created)
|
||||
|
||||
if state == 'started' and not container.running:
|
||||
@@ -398,13 +414,20 @@ class ContainerManager(DockerBaseClass):
|
||||
image = self.engine_driver.inspect_image_by_name(self.client, repository, tag)
|
||||
return image or fallback
|
||||
|
||||
def _get_image(self, container):
|
||||
def _get_image(self, container, needs_container_image=False):
|
||||
image_parameter = self.param_image
|
||||
get_container_image = needs_container_image or not image_parameter
|
||||
container_image = self._get_container_image(container) if get_container_image else None
|
||||
if container_image:
|
||||
self.log("current image")
|
||||
self.log(container_image, pretty_print=True)
|
||||
if not image_parameter:
|
||||
self.log('No image specified')
|
||||
return None, self._get_container_image(container)
|
||||
return None, container_image, container_image
|
||||
if is_image_name_id(image_parameter):
|
||||
image = self.engine_driver.inspect_image_by_id(self.client, image_parameter)
|
||||
if image is None:
|
||||
self.client.fail("Cannot find image with ID %s" % (image_parameter, ))
|
||||
else:
|
||||
repository, tag = parse_repository_tag(image_parameter)
|
||||
if not tag:
|
||||
@@ -431,12 +454,11 @@ class ContainerManager(DockerBaseClass):
|
||||
|
||||
comparison_image = image
|
||||
if self.param_image_comparison == 'current-image':
|
||||
comparison_image = self._get_container_image(container, image)
|
||||
if comparison_image != image:
|
||||
self.log("current image")
|
||||
self.log(comparison_image, pretty_print=True)
|
||||
if not get_container_image:
|
||||
container_image = self._get_container_image(container)
|
||||
comparison_image = container_image
|
||||
|
||||
return image, comparison_image
|
||||
return image, container_image, comparison_image
|
||||
|
||||
def _image_is_different(self, image, container):
|
||||
if image and image.get('Id'):
|
||||
@@ -455,15 +477,16 @@ class ContainerManager(DockerBaseClass):
|
||||
params['Image'] = image
|
||||
return params
|
||||
|
||||
def _record_differences(self, differences, options, param_values, engine, container, image):
|
||||
container_values = engine.get_value(self.module, container.raw, self.engine_driver.get_api_version(self.client), options.options)
|
||||
def _record_differences(self, differences, options, param_values, engine, container, container_image, image, host_info):
|
||||
container_values = engine.get_value(
|
||||
self.module, container.raw, self.engine_driver.get_api_version(self.client), options.options, container_image, host_info)
|
||||
expected_values = engine.get_expected_values(
|
||||
self.module, self.client, self.engine_driver.get_api_version(self.client), options.options, image, param_values.copy())
|
||||
self.module, self.client, self.engine_driver.get_api_version(self.client), options.options, image, param_values.copy(), host_info)
|
||||
for option in options.options:
|
||||
if option.name in expected_values:
|
||||
param_value = expected_values[option.name]
|
||||
container_value = container_values.get(option.name)
|
||||
match = compare_generic(param_value, container_value, option.comparison, option.comparison_type)
|
||||
match = engine.compare_value(option, param_value, container_value)
|
||||
|
||||
if not match:
|
||||
# No match.
|
||||
@@ -497,28 +520,28 @@ class ContainerManager(DockerBaseClass):
|
||||
c = sorted(c, key=sort_key_fn)
|
||||
differences.add(option.name, parameter=p, active=c)
|
||||
|
||||
def has_different_configuration(self, container, image):
|
||||
def has_different_configuration(self, container, container_image, image, host_info):
|
||||
differences = DifferenceTracker()
|
||||
update_differences = DifferenceTracker()
|
||||
for options, param_values in self.parameters:
|
||||
engine = options.get_engine(self.engine_driver.name)
|
||||
if engine.can_update_value(self.engine_driver.get_api_version(self.client)):
|
||||
self._record_differences(update_differences, options, param_values, engine, container, image)
|
||||
self._record_differences(update_differences, options, param_values, engine, container, container_image, image, host_info)
|
||||
else:
|
||||
self._record_differences(differences, options, param_values, engine, container, image)
|
||||
self._record_differences(differences, options, param_values, engine, container, container_image, image, host_info)
|
||||
has_differences = not differences.empty
|
||||
# Only consider differences of properties that can be updated when there are also other differences
|
||||
if has_differences:
|
||||
differences.merge(update_differences)
|
||||
return has_differences, differences
|
||||
|
||||
def has_different_resource_limits(self, container, image):
|
||||
def has_different_resource_limits(self, container, container_image, image, host_info):
|
||||
differences = DifferenceTracker()
|
||||
for options, param_values in self.parameters:
|
||||
engine = options.get_engine(self.engine_driver.name)
|
||||
if not engine.can_update_value(self.engine_driver.get_api_version(self.client)):
|
||||
continue
|
||||
self._record_differences(differences, options, param_values, engine, container, image)
|
||||
self._record_differences(differences, options, param_values, engine, container, container_image, image, host_info)
|
||||
has_differences = not differences.empty
|
||||
return has_differences, differences
|
||||
|
||||
@@ -531,8 +554,8 @@ class ContainerManager(DockerBaseClass):
|
||||
engine.update_value(self.module, result, self.engine_driver.get_api_version(self.client), options.options, values)
|
||||
return result
|
||||
|
||||
def update_limits(self, container, image):
|
||||
limits_differ, different_limits = self.has_different_resource_limits(container, image)
|
||||
def update_limits(self, container, container_image, image, host_info):
|
||||
limits_differ, different_limits = self.has_different_resource_limits(container, container_image, image, host_info)
|
||||
if limits_differ:
|
||||
self.log("limit differences:")
|
||||
self.log(different_limits.get_legacy_docker_container_diffs(), pretty_print=True)
|
||||
|
||||
Reference in New Issue
Block a user