docker_container: add networks_cli_compatible option (#54198)

* Adding networks_cli_compatible option.

* Move network tests into own test file.

* Extend tests (for networks_cli_compatible=no).

* Adding tests for networks_cli_compatible=yes.

* There seems to be no way to create a container without at least one network attached.

* Integrate networks / purge_networks with comparisons.

* Speed up tests.

* Removing double dot.

* Add changelog.

* Use comparisons value only if the networks option has been specified. purge_networks on the other hand also removes networks if it has not been specified.
This commit is contained in:
Felix Fontein 2019-03-25 20:06:21 +01:00 committed by ansibot
parent af669dec24
commit 4fac91bed5
4 changed files with 624 additions and 204 deletions

View file

@ -0,0 +1,5 @@
minor_changes:
- "docker_container - a new option ``networks_cli_compatible`` with default value ``no`` has been added. The default value
will change to ``yes`` in Ansible 2.12. Setting it to ``yes`` lets the module behave similar to ``docker create --network``
when at least one network is specified, i.e. the default network is not automatically attached to the container in this
case."

View file

@ -61,7 +61,7 @@ options:
- Allows to specify how properties of existing containers are compared with - Allows to specify how properties of existing containers are compared with
module options to decide whether the container should be recreated / updated module options to decide whether the container should be recreated / updated
or not. Only options which correspond to the state of a container as handled or not. Only options which correspond to the state of a container as handled
by the Docker daemon can be specified. by the Docker daemon can be specified, as well as C(networks).
- Must be a dictionary specifying for an option one of the keys C(strict), C(ignore) - Must be a dictionary specifying for an option one of the keys C(strict), C(ignore)
and C(allow_more_present). and C(allow_more_present).
- If C(strict) is specified, values are tested for equality, and changes always - If C(strict) is specified, values are tested for equality, and changes always
@ -423,6 +423,20 @@ options:
can be used in the network to reach this container. can be used in the network to reach this container.
type: list type: list
version_added: "2.2" version_added: "2.2"
networks_cli_compatible:
description:
- "When networks are provided to the module via the I(networks) option, the module
behaves differently than C(docker run --network): C(docker run --network other)
will create a container with network C(other) attached, but the default network
not attached. This module with C(networks: {name: other}) will create a container
with both C(default) and C(other) attached. If I(purge_networks) is set to C(yes),
the C(default) network will be removed afterwards."
- "If I(networks_cli_compatible) is set to C(yes), this module will behave as
C(docker run --network) and will I(not) add the default network if C(networks) is
specified. If C(networks) is not specified, the default network will be attached."
- Current value is C(no). A new default of C(yes) will be set in Ansible 2.12.
type: bool
version_added: "2.8"
oom_killer: oom_killer:
description: description:
- Whether or not to disable OOM Killer for the container. - Whether or not to disable OOM Killer for the container.
@ -1076,6 +1090,7 @@ class TaskParameters(DockerBaseClass):
self.network_mode = None self.network_mode = None
self.userns_mode = None self.userns_mode = None
self.networks = None self.networks = None
self.networks_cli_compatible = None
self.oom_killer = None self.oom_killer = None
self.oom_score_adj = None self.oom_score_adj = None
self.paused = None self.paused = None
@ -1260,6 +1275,16 @@ class TaskParameters(DockerBaseClass):
if getattr(self, value, None) is not None: if getattr(self, value, None) is not None:
if self.client.option_minimal_versions[value]['supported']: if self.client.option_minimal_versions[value]['supported']:
result[key] = getattr(self, value) result[key] = getattr(self, value)
if self.networks_cli_compatible and self.networks:
network = self.networks[0]
params = dict()
for para in ('ipv4_address', 'ipv6_address', 'links', 'aliases'):
if network.get(para):
params[para] = network[para]
network_config = dict()
network_config[network['name']] = self.client.create_endpoint_config(params)
result['networking_config'] = self.client.create_networking_config(network_config)
return result return result
def _expand_host_paths(self): def _expand_host_paths(self):
@ -2265,6 +2290,7 @@ class ContainerManager(DockerBaseClass):
container = self._get_container(self.parameters.name) container = self._get_container(self.parameters.name)
was_running = container.running was_running = container.running
was_paused = container.paused was_paused = container.paused
container_created = False
# If the image parameter was passed then we need to deal with the image # If the image parameter was passed then we need to deal with the image
# version comparison. Otherwise we handle this depending on whether # version comparison. Otherwise we handle this depending on whether
@ -2282,6 +2308,7 @@ class ContainerManager(DockerBaseClass):
new_container = self.container_create(self.parameters.image, self.parameters.create_parameters) new_container = self.container_create(self.parameters.image, self.parameters.create_parameters)
if new_container: if new_container:
container = new_container container = new_container
container_created = True
else: else:
# Existing container # Existing container
different, differences = container.has_different_configuration(image) different, differences = container.has_different_configuration(image)
@ -2306,10 +2333,11 @@ class ContainerManager(DockerBaseClass):
new_container = self.container_create(image_to_use, self.parameters.create_parameters) new_container = self.container_create(image_to_use, self.parameters.create_parameters)
if new_container: if new_container:
container = new_container container = new_container
container_created = True
if container and container.exists: if container and container.exists:
container = self.update_limits(container) container = self.update_limits(container)
container = self.update_networks(container) container = self.update_networks(container, container_created)
if state == 'started' and not container.running: if state == 'started' and not container.running:
self.diff_tracker.add('running', parameter=True, active=was_running) self.diff_tracker.add('running', parameter=True, active=was_running)
@ -2405,9 +2433,10 @@ class ContainerManager(DockerBaseClass):
return self._get_container(container.Id) return self._get_container(container.Id)
return container return container
def update_networks(self, container): def update_networks(self, container, container_created):
has_network_differences, network_differences = container.has_network_differences()
updated_container = container updated_container = container
if self.parameters.comparisons['networks']['comparison'] != 'ignore' or container_created:
has_network_differences, network_differences = container.has_network_differences()
if has_network_differences: if has_network_differences:
if self.diff.get('differences'): if self.diff.get('differences'):
self.diff['differences'].append(dict(network_differences=network_differences)) self.diff['differences'].append(dict(network_differences=network_differences))
@ -2422,7 +2451,7 @@ class ContainerManager(DockerBaseClass):
self.results['changed'] = True self.results['changed'] = True
updated_container = self._add_networks(container, network_differences) updated_container = self._add_networks(container, network_differences)
if self.parameters.purge_networks: if (self.parameters.comparisons['networks']['comparison'] == 'strict' and self.parameters.networks is not None) or self.parameters.purge_networks:
has_extra_networks, extra_networks = container.has_extra_networks() has_extra_networks, extra_networks = container.has_extra_networks()
if has_extra_networks: if has_extra_networks:
if self.diff.get('differences'): if self.diff.get('differences'):
@ -2665,6 +2694,7 @@ class AnsibleDockerClientContainer(AnsibleDockerClient):
env='set', env='set',
entrypoint='list', entrypoint='list',
etc_hosts='set', etc_hosts='set',
networks='set(dict)',
ulimits='set(dict)', ulimits='set(dict)',
device_read_bps='set(dict)', device_read_bps='set(dict)',
device_write_bps='set(dict)', device_write_bps='set(dict)',
@ -2680,7 +2710,7 @@ class AnsibleDockerClientContainer(AnsibleDockerClient):
for alias in data.get('aliases', []): for alias in data.get('aliases', []):
all_options.add(alias) all_options.add(alias)
# Ignore options which aren't used as container properties # Ignore options which aren't used as container properties
if option in self.__NON_CONTAINER_PROPERTY_OPTIONS: if option in self.__NON_CONTAINER_PROPERTY_OPTIONS and option != 'networks':
continue continue
# Determine option type # Determine option type
if option in explicit_types: if option in explicit_types:
@ -2706,6 +2736,8 @@ class AnsibleDockerClientContainer(AnsibleDockerClient):
# Process legacy ignore options # Process legacy ignore options
if self.module.params['ignore_image']: if self.module.params['ignore_image']:
comparisons['image']['comparison'] = 'ignore' comparisons['image']['comparison'] = 'ignore'
if self.module.params['purge_networks']:
comparisons['networks']['comparison'] = 'strict'
# Process options # Process options
if self.module.params.get('comparisons'): if self.module.params.get('comparisons'):
# If '*' appears in comparisons, process it first # If '*' appears in comparisons, process it first
@ -2713,7 +2745,12 @@ class AnsibleDockerClientContainer(AnsibleDockerClient):
value = self.module.params['comparisons']['*'] value = self.module.params['comparisons']['*']
if value not in ('strict', 'ignore'): if value not in ('strict', 'ignore'):
self.fail("The wildcard can only be used with comparison modes 'strict' and 'ignore'!") self.fail("The wildcard can only be used with comparison modes 'strict' and 'ignore'!")
for dummy, v in comparisons.items(): for option, v in comparisons.items():
if option == 'networks':
# `networks` is special: only update if
# some value is actually specified
if self.module.params['networks'] is None:
continue
v['comparison'] = value v['comparison'] = value
# Now process all other comparisons. # Now process all other comparisons.
comp_aliases_used = {} comp_aliases_used = {}
@ -2748,6 +2785,8 @@ class AnsibleDockerClientContainer(AnsibleDockerClient):
# Check legacy values # Check legacy values
if self.module.params['ignore_image'] and comparisons['image']['comparison'] != 'ignore': if self.module.params['ignore_image'] and comparisons['image']['comparison'] != 'ignore':
self.module.warn('The ignore_image option has been overridden by the comparisons option!') self.module.warn('The ignore_image option has been overridden by the comparisons option!')
if self.module.params['purge_networks'] and comparisons['networks']['comparison'] != 'strict':
self.module.warn('The purge_networks option has been overridden by the comparisons option!')
self.comparisons = comparisons self.comparisons = comparisons
def _get_additional_minimal_versions(self): def _get_additional_minimal_versions(self):
@ -2893,6 +2932,7 @@ def main():
aliases=dict(type='list', elements='str'), aliases=dict(type='list', elements='str'),
links=dict(type='list', elements='str'), links=dict(type='list', elements='str'),
)), )),
networks_cli_compatible=dict(type='bool'),
oom_killer=dict(type='bool'), oom_killer=dict(type='bool'),
oom_score_adj=dict(type='int'), oom_score_adj=dict(type='int'),
output_logs=dict(type='bool', default=False), output_logs=dict(type='bool', default=False),
@ -2938,6 +2978,16 @@ def main():
supports_check_mode=True, supports_check_mode=True,
min_docker_api_version='1.20', min_docker_api_version='1.20',
) )
if client.module.params['networks_cli_compatible'] is None and client.module.params['networks']:
client.module.deprecate(
'Please note that docker_container handles networks slightly different than docker CLI. '
'If you specify networks, the default network will still be attached as the first network. '
'(You can specify purge_networks to remove all networks not explicitly listed.) '
'This behavior will change in Ansible 2.12. You can change the behavior now by setting '
'the new `networks_cli_compatible` option to `yes`, and remove this warning by setting '
'it to `no`',
version='2.12'
)
cm = ContainerManager(client) cm = ContainerManager(client)
client.module.exit_json(**sanitize_result(cm.results)) client.module.exit_json(**sanitize_result(cm.results))

View file

@ -0,0 +1,549 @@
---
- name: Registering container name
set_fact:
cname: "{{ cname_prefix ~ '-network' }}"
cname_h1: "{{ cname_prefix ~ '-network-h1' }}"
nname_1: "{{ cname_prefix ~ '-network-1' }}"
nname_2: "{{ cname_prefix ~ '-network-2' }}"
- name: Registering container name
set_fact:
cnames: "{{ cnames }} + [cname, cname_h1]"
dnetworks: "{{ dnetworks }} + [nname_1, nname_2]"
- name: Create networks
docker_network:
name: "{{ network_name }}"
state: present
loop:
- "{{ nname_1 }}"
- "{{ nname_2 }}"
loop_control:
loop_var: network_name
when: docker_py_version is version('1.10.0', '>=')
####################################################################
## network_mode ####################################################
####################################################################
- name: network_mode
docker_container:
image: alpine:3.8
command: '/bin/sh -c "sleep 10m"'
name: "{{ cname }}"
state: started
network_mode: host
register: network_mode_1
- name: network_mode (idempotency)
docker_container:
image: alpine:3.8
command: '/bin/sh -c "sleep 10m"'
name: "{{ cname }}"
state: started
network_mode: host
register: network_mode_2
- name: network_mode (change)
docker_container:
image: alpine:3.8
command: '/bin/sh -c "sleep 10m"'
name: "{{ cname }}"
state: started
network_mode: none
force_kill: yes
register: network_mode_3
- name: network_mode (container mode setup)
docker_container:
image: alpine:3.8
command: '/bin/sh -c "sleep 10m"'
name: "{{ cname_h1 }}"
state: started
register: cname_h1_id
- name: network_mode (container mode)
docker_container:
image: alpine:3.8
command: '/bin/sh -c "sleep 10m"'
name: "{{ cname }}"
state: started
network_mode: "container:{{ cname_h1_id.container.Id }}"
force_kill: yes
register: network_mode_4
- name: network_mode (container mode idempotency)
docker_container:
image: alpine:3.8
command: '/bin/sh -c "sleep 10m"'
name: "{{ cname }}"
state: started
network_mode: "container:{{ cname_h1 }}"
register: network_mode_5
- name: cleanup
docker_container:
name: "{{ container_name }}"
state: absent
force_kill: yes
loop:
- "{{ cname }}"
- "{{ cname_h1 }}"
loop_control:
loop_var: container_name
diff: no
- assert:
that:
- network_mode_1 is changed
- network_mode_1.container.HostConfig.NetworkMode == 'host'
- network_mode_2 is not changed
- network_mode_2.container.HostConfig.NetworkMode == 'host'
- network_mode_3 is changed
- network_mode_3.container.HostConfig.NetworkMode == 'none'
- network_mode_4 is changed
- network_mode_4.container.HostConfig.NetworkMode == 'container:' ~ cname_h1_id.container.Id
- network_mode_5 is not changed
- network_mode_5.container.HostConfig.NetworkMode == 'container:' ~ cname_h1_id.container.Id
####################################################################
## networks, purge_networks for networks_cli_compatible=no #########
####################################################################
- block:
- name: networks_cli_compatible=no, networks w/o purge_networks
docker_container:
image: alpine:3.8
command: '/bin/sh -c "sleep 10m"'
name: "{{ cname }}"
state: started
networks:
- name: "{{ nname_1 }}"
- name: "{{ nname_2 }}"
networks_cli_compatible: no
register: networks_1
- name: networks_cli_compatible=no, networks w/o purge_networks
docker_container:
image: alpine:3.8
command: '/bin/sh -c "sleep 10m"'
name: "{{ cname }}"
state: started
networks:
- name: "{{ nname_1 }}"
- name: "{{ nname_2 }}"
networks_cli_compatible: no
register: networks_2
- name: networks_cli_compatible=no, networks, purge_networks
docker_container:
image: alpine:3.8
command: '/bin/sh -c "sleep 10m"'
name: "{{ cname }}"
state: started
purge_networks: yes
networks:
- name: bridge
- name: "{{ nname_1 }}"
networks_cli_compatible: no
force_kill: yes
register: networks_3
- name: networks_cli_compatible=no, networks, purge_networks (idempotency)
docker_container:
image: alpine:3.8
command: '/bin/sh -c "sleep 10m"'
name: "{{ cname }}"
state: started
purge_networks: yes
networks:
- name: "{{ nname_1 }}"
- name: bridge
networks_cli_compatible: no
register: networks_4
- name: networks_cli_compatible=no, networks (less networks)
docker_container:
image: alpine:3.8
command: '/bin/sh -c "sleep 10m"'
name: "{{ cname }}"
state: started
networks:
- name: bridge
networks_cli_compatible: no
register: networks_5
- name: networks_cli_compatible=no, networks, purge_networks (less networks)
docker_container:
image: alpine:3.8
command: '/bin/sh -c "sleep 10m"'
name: "{{ cname }}"
state: started
purge_networks: yes
networks:
- name: bridge
networks_cli_compatible: no
force_kill: yes
register: networks_6
- name: networks_cli_compatible=no, networks, purge_networks (more networks)
docker_container:
image: alpine:3.8
command: '/bin/sh -c "sleep 10m"'
name: "{{ cname }}"
state: started
purge_networks: yes
networks:
- name: bridge
- name: "{{ nname_2 }}"
networks_cli_compatible: no
force_kill: yes
register: networks_7
- name: cleanup
docker_container:
name: "{{ cname }}"
state: absent
force_kill: yes
diff: no
- assert:
that:
# networks_1 has networks default, 'bridge', nname_1
- networks_1 is changed
- networks_1.container.NetworkSettings.Networks | length == 3
- nname_1 in networks_1.container.NetworkSettings.Networks
- nname_2 in networks_1.container.NetworkSettings.Networks
- "'default' in networks_1.container.NetworkSettings.Networks or 'bridge' in networks_1.container.NetworkSettings.Networks"
# networks_2 has networks default, 'bridge', nname_1
- networks_2 is not changed
- networks_2.container.NetworkSettings.Networks | length == 3
- nname_1 in networks_2.container.NetworkSettings.Networks
- nname_2 in networks_1.container.NetworkSettings.Networks
- "'default' in networks_1.container.NetworkSettings.Networks or 'bridge' in networks_1.container.NetworkSettings.Networks"
# networks_3 has networks 'bridge', nname_1
- networks_3 is changed
- networks_3.container.NetworkSettings.Networks | length == 2
- nname_1 in networks_3.container.NetworkSettings.Networks
- "'default' in networks_3.container.NetworkSettings.Networks or 'bridge' in networks_3.container.NetworkSettings.Networks"
# networks_4 has networks 'bridge', nname_1
- networks_4 is not changed
- networks_4.container.NetworkSettings.Networks | length == 2
- nname_1 in networks_4.container.NetworkSettings.Networks
- "'default' in networks_4.container.NetworkSettings.Networks or 'bridge' in networks_4.container.NetworkSettings.Networks"
# networks_5 has networks 'bridge', nname_1
- networks_5 is not changed
- networks_5.container.NetworkSettings.Networks | length == 2
- nname_1 in networks_5.container.NetworkSettings.Networks
- "'default' in networks_5.container.NetworkSettings.Networks or 'bridge' in networks_5.container.NetworkSettings.Networks"
# networks_6 has networks 'bridge'
- networks_6 is changed
- networks_6.container.NetworkSettings.Networks | length == 1
- "'default' in networks_6.container.NetworkSettings.Networks or 'bridge' in networks_6.container.NetworkSettings.Networks"
# networks_7 has networks 'bridge', nname_2
- networks_7 is changed
- networks_7.container.NetworkSettings.Networks | length == 2
- nname_2 in networks_7.container.NetworkSettings.Networks
- "'default' in networks_7.container.NetworkSettings.Networks or 'bridge' in networks_7.container.NetworkSettings.Networks"
when: docker_py_version is version('1.10.0', '>=')
####################################################################
## networks for networks_cli_compatible=yes ########################
####################################################################
- block:
- name: networks_cli_compatible=yes, networks specified
docker_container:
image: alpine:3.8
command: '/bin/sh -c "sleep 10m"'
name: "{{ cname }}"
state: started
networks:
- name: "{{ nname_1 }}"
- name: "{{ nname_2 }}"
networks_cli_compatible: yes
register: networks_1
- name: networks_cli_compatible=yes, networks specified
docker_container:
image: alpine:3.8
command: '/bin/sh -c "sleep 10m"'
name: "{{ cname }}"
state: started
networks:
- name: "{{ nname_1 }}"
- name: "{{ nname_2 }}"
networks_cli_compatible: yes
register: networks_2
- name: cleanup
docker_container:
name: "{{ cname }}"
state: absent
force_kill: yes
diff: no
- name: networks_cli_compatible=yes, empty networks list specified
docker_container:
image: alpine:3.8
command: '/bin/sh -c "sleep 10m"'
name: "{{ cname }}"
state: started
networks: []
networks_cli_compatible: yes
register: networks_3
- name: networks_cli_compatible=yes, empty networks list specified
docker_container:
image: alpine:3.8
command: '/bin/sh -c "sleep 10m"'
name: "{{ cname }}"
state: started
networks: []
networks_cli_compatible: yes
register: networks_4
- name: networks_cli_compatible=yes, empty networks list specified, purge_networks
docker_container:
image: alpine:3.8
command: '/bin/sh -c "sleep 10m"'
name: "{{ cname }}"
state: started
networks: []
networks_cli_compatible: yes
purge_networks: yes
force_kill: yes
register: networks_5
- name: cleanup
docker_container:
name: "{{ cname }}"
state: absent
force_kill: yes
diff: no
- name: networks_cli_compatible=yes, networks not specified
docker_container:
image: alpine:3.8
command: '/bin/sh -c "sleep 10m"'
name: "{{ cname }}"
state: started
networks_cli_compatible: yes
force_kill: yes
register: networks_6
- name: networks_cli_compatible=yes, networks not specified
docker_container:
image: alpine:3.8
command: '/bin/sh -c "sleep 10m"'
name: "{{ cname }}"
state: started
networks_cli_compatible: yes
register: networks_7
- name: networks_cli_compatible=yes, networks not specified, purge_networks
docker_container:
image: alpine:3.8
command: '/bin/sh -c "sleep 10m"'
name: "{{ cname }}"
state: started
networks_cli_compatible: yes
purge_networks: yes
force_kill: yes
register: networks_8
- name: cleanup
docker_container:
name: "{{ cname }}"
state: absent
force_kill: yes
diff: no
- debug: var=networks_3
- assert:
that:
# networks_1 has networks nname_1, nname_2
- networks_1 is changed
- networks_1.container.NetworkSettings.Networks | length == 2
- nname_1 in networks_1.container.NetworkSettings.Networks
- nname_2 in networks_1.container.NetworkSettings.Networks
# networks_2 has networks nname_1, nname_2
- networks_2 is not changed
- networks_2.container.NetworkSettings.Networks | length == 2
- nname_1 in networks_2.container.NetworkSettings.Networks
- nname_2 in networks_1.container.NetworkSettings.Networks
# networks_3 has networks 'bridge'
- networks_3 is changed
- networks_3.container.NetworkSettings.Networks | length == 1
- "'default' in networks_3.container.NetworkSettings.Networks or 'bridge' in networks_3.container.NetworkSettings.Networks"
# networks_4 has networks 'bridge'
- networks_4 is not changed
- networks_4.container.NetworkSettings.Networks | length == 1
- "'default' in networks_4.container.NetworkSettings.Networks or 'bridge' in networks_4.container.NetworkSettings.Networks"
# networks_5 has no networks
- networks_5 is changed
- networks_5.container.NetworkSettings.Networks | length == 0
# networks_6 has networks 'bridge'
- networks_6 is changed
- networks_6.container.NetworkSettings.Networks | length == 1
- "'default' in networks_6.container.NetworkSettings.Networks or 'bridge' in networks_6.container.NetworkSettings.Networks"
# networks_7 has networks 'bridge'
- networks_7 is not changed
- networks_7.container.NetworkSettings.Networks | length == 1
- "'default' in networks_7.container.NetworkSettings.Networks or 'bridge' in networks_7.container.NetworkSettings.Networks"
# networks_8 has no networks
- networks_8 is changed
- networks_8.container.NetworkSettings.Networks | length == 0
when: docker_py_version is version('1.10.0', '>=')
####################################################################
## networks with comparisons #######################################
####################################################################
- block:
- name: create container with one network
docker_container:
image: alpine:3.8
command: '/bin/sh -c "sleep 10m"'
name: "{{ cname }}"
state: started
networks:
- name: "{{ nname_1 }}"
networks_cli_compatible: yes
register: networks_1
- name: different networks, comparisons=ignore
docker_container:
image: alpine:3.8
command: '/bin/sh -c "sleep 10m"'
name: "{{ cname }}"
state: started
networks:
- name: "{{ nname_2 }}"
networks_cli_compatible: yes
comparisons:
networks: ignore
register: networks_2
- name: less networks, comparisons=ignore
docker_container:
image: alpine:3.8
command: '/bin/sh -c "sleep 10m"'
name: "{{ cname }}"
state: started
networks: []
networks_cli_compatible: yes
comparisons:
networks: ignore
register: networks_3
- name: less networks, comparisons=allow_more_present
docker_container:
image: alpine:3.8
command: '/bin/sh -c "sleep 10m"'
name: "{{ cname }}"
state: started
networks: []
networks_cli_compatible: yes
comparisons:
networks: allow_more_present
register: networks_4
- name: different networks, comparisons=allow_more_present
docker_container:
image: alpine:3.8
command: '/bin/sh -c "sleep 10m"'
name: "{{ cname }}"
state: started
networks:
- name: "{{ nname_2 }}"
networks_cli_compatible: yes
comparisons:
networks: allow_more_present
force_kill: yes
register: networks_5
- name: different networks, comparisons=strict
docker_container:
image: alpine:3.8
command: '/bin/sh -c "sleep 10m"'
name: "{{ cname }}"
state: started
networks:
- name: "{{ nname_2 }}"
networks_cli_compatible: yes
comparisons:
networks: strict
force_kill: yes
register: networks_6
- name: less networks, comparisons=strict
docker_container:
image: alpine:3.8
command: '/bin/sh -c "sleep 10m"'
name: "{{ cname }}"
state: started
networks: []
networks_cli_compatible: yes
comparisons:
networks: strict
force_kill: yes
register: networks_7
- name: cleanup
docker_container:
name: "{{ cname }}"
state: absent
force_kill: yes
diff: no
- assert:
that:
# networks_1 has networks nname_1
- networks_1 is changed
- networks_1.container.NetworkSettings.Networks | length == 1
- nname_1 in networks_1.container.NetworkSettings.Networks
# networks_2 has networks nname_1
- networks_2 is not changed
- networks_2.container.NetworkSettings.Networks | length == 1
- nname_1 in networks_2.container.NetworkSettings.Networks
# networks_3 has networks nname_1
- networks_3 is not changed
- networks_3.container.NetworkSettings.Networks | length == 1
- nname_1 in networks_3.container.NetworkSettings.Networks
# networks_4 has networks nname_1
- networks_4 is not changed
- networks_4.container.NetworkSettings.Networks | length == 1
- nname_1 in networks_4.container.NetworkSettings.Networks
# networks_5 has networks nname_1, nname_2
- networks_5 is changed
- networks_5.container.NetworkSettings.Networks | length == 2
- nname_1 in networks_5.container.NetworkSettings.Networks
- nname_2 in networks_5.container.NetworkSettings.Networks
# networks_6 has networks nname_2
- networks_6 is changed
- networks_6.container.NetworkSettings.Networks | length == 1
- nname_2 in networks_6.container.NetworkSettings.Networks
# networks_7 has no networks
- networks_7 is changed
- networks_7.container.NetworkSettings.Networks | length == 0
when: docker_py_version is version('1.10.0', '>=')
####################################################################
####################################################################
####################################################################
- name: Delete networks
docker_network:
name: "{{ network_name }}"
state: absent
force: yes
loop:
- "{{ nname_1 }}"
- "{{ nname_2 }}"
loop_control:
loop_var: network_name
when: docker_py_version is version('1.10.0', '>=')

View file

@ -5,23 +5,9 @@
cname_h1: "{{ cname_prefix ~ '-options-h1' }}" cname_h1: "{{ cname_prefix ~ '-options-h1' }}"
cname_h2: "{{ cname_prefix ~ '-options-h2' }}" cname_h2: "{{ cname_prefix ~ '-options-h2' }}"
cname_h3: "{{ cname_prefix ~ '-options-h3' }}" cname_h3: "{{ cname_prefix ~ '-options-h3' }}"
nname_1: "{{ cname_prefix ~ '-network-1' }}"
nname_2: "{{ cname_prefix ~ '-network-2' }}"
- name: Registering container name - name: Registering container name
set_fact: set_fact:
cnames: "{{ cnames }} + [cname, cname_h1, cname_h2, cname_h3]" cnames: "{{ cnames }} + [cname, cname_h1, cname_h2, cname_h3]"
dnetworks: "{{ dnetworks }} + [nname_1, nname_2]"
- name: Create networks
docker_network:
name: "{{ network_name }}"
state: present
loop:
- "{{ nname_1 }}"
- "{{ nname_2 }}"
loop_control:
loop_var: network_name
when: docker_py_version is version('1.10.0', '>=')
#################################################################### ####################################################################
## auto_remove ##################################################### ## auto_remove #####################################################
@ -2434,164 +2420,6 @@
- memory_swappiness_2 is not changed - memory_swappiness_2 is not changed
- memory_swappiness_3 is changed - memory_swappiness_3 is changed
####################################################################
## network_mode ####################################################
####################################################################
- name: network_mode
docker_container:
image: alpine:3.8
command: '/bin/sh -c "sleep 10m"'
name: "{{ cname }}"
state: started
network_mode: host
register: network_mode_1
- name: network_mode (idempotency)
docker_container:
image: alpine:3.8
command: '/bin/sh -c "sleep 10m"'
name: "{{ cname }}"
state: started
network_mode: host
register: network_mode_2
- name: network_mode (change)
docker_container:
image: alpine:3.8
command: '/bin/sh -c "sleep 10m"'
name: "{{ cname }}"
state: started
network_mode: none
force_kill: yes
register: network_mode_3
- name: network_mode (container mode setup)
docker_container:
image: alpine:3.8
command: '/bin/sh -c "sleep 10m"'
name: "{{ cname_h1 }}"
state: started
- name: network_mode (container mode)
docker_container:
image: alpine:3.8
command: '/bin/sh -c "sleep 10m"'
name: "{{ cname }}"
state: started
network_mode: "container:{{ cname_h1 }}"
force_kill: yes
register: network_mode_4
- name: network_mode (container mode idempotency)
docker_container:
image: alpine:3.8
command: '/bin/sh -c "sleep 10m"'
name: "{{ cname }}"
state: started
network_mode: "container:{{ cname_h1 }}"
register: network_mode_5
- name: cleanup
docker_container:
name: "{{ container_name }}"
state: absent
force_kill: yes
loop:
- "{{ cname }}"
- "{{ cname_h1 }}"
loop_control:
loop_var: container_name
diff: no
- assert:
that:
- network_mode_1 is changed
- network_mode_2 is not changed
- network_mode_3 is changed
- network_mode_4 is changed
- network_mode_5 is not changed
####################################################################
## networks, purge_networks ########################################
####################################################################
- block:
- name: networks, purge_networks
docker_container:
image: alpine:3.8
command: '/bin/sh -c "sleep 10m"'
name: "{{ cname }}"
state: started
purge_networks: yes
networks:
- name: bridge
- name: "{{ nname_1 }}"
register: networks_1
- name: networks, purge_networks (idempotency)
docker_container:
image: alpine:3.8
command: '/bin/sh -c "sleep 10m"'
name: "{{ cname }}"
state: started
purge_networks: yes
networks:
- name: "{{ nname_1 }}"
- name: bridge
register: networks_2
- name: networks (less networks)
docker_container:
image: alpine:3.8
command: '/bin/sh -c "sleep 10m"'
name: "{{ cname }}"
state: started
networks:
- name: bridge
register: networks_3
- name: networks, purge_networks (less networks)
docker_container:
image: alpine:3.8
command: '/bin/sh -c "sleep 10m"'
name: "{{ cname }}"
state: started
purge_networks: yes
networks:
- name: bridge
register: networks_4
- name: networks, purge_networks (more networks)
docker_container:
image: alpine:3.8
command: '/bin/sh -c "sleep 10m"'
name: "{{ cname }}"
state: started
purge_networks: yes
networks:
- name: bridge
- name: "{{ nname_2 }}"
force_kill: yes
register: networks_5
- name: cleanup
docker_container:
name: "{{ cname }}"
state: absent
force_kill: yes
diff: no
- assert:
that:
- networks_1 is changed
- networks_2 is not changed
- networks_3 is not changed
- networks_4 is changed
- networks_5 is changed
when: docker_py_version is version('1.10.0', '>=')
#################################################################### ####################################################################
## oom_killer ###################################################### ## oom_killer ######################################################
#################################################################### ####################################################################
@ -4144,15 +3972,3 @@
#################################################################### ####################################################################
#################################################################### ####################################################################
#################################################################### ####################################################################
- name: Delete networks
docker_network:
name: "{{ network_name }}"
state: absent
force: yes
loop:
- "{{ nname_1 }}"
- "{{ nname_2 }}"
loop_control:
loop_var: network_name
when: docker_py_version is version('1.10.0', '>=')