diff --git a/changelogs/fragments/54198-docker_container-networks.yaml b/changelogs/fragments/54198-docker_container-networks.yaml new file mode 100644 index 0000000000..df7628b02b --- /dev/null +++ b/changelogs/fragments/54198-docker_container-networks.yaml @@ -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." diff --git a/lib/ansible/modules/cloud/docker/docker_container.py b/lib/ansible/modules/cloud/docker/docker_container.py index ceeadd215e..af4007fb05 100644 --- a/lib/ansible/modules/cloud/docker/docker_container.py +++ b/lib/ansible/modules/cloud/docker/docker_container.py @@ -61,7 +61,7 @@ options: - Allows to specify how properties of existing containers are compared with 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 - 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) and C(allow_more_present). - 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. type: list 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: description: - Whether or not to disable OOM Killer for the container. @@ -1076,6 +1090,7 @@ class TaskParameters(DockerBaseClass): self.network_mode = None self.userns_mode = None self.networks = None + self.networks_cli_compatible = None self.oom_killer = None self.oom_score_adj = None self.paused = None @@ -1260,6 +1275,16 @@ class TaskParameters(DockerBaseClass): if getattr(self, value, None) is not None: if self.client.option_minimal_versions[value]['supported']: 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 def _expand_host_paths(self): @@ -2265,6 +2290,7 @@ class ContainerManager(DockerBaseClass): container = self._get_container(self.parameters.name) was_running = container.running was_paused = container.paused + container_created = False # If the image parameter was passed then we need to deal with the image # 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) if new_container: container = new_container + container_created = True else: # Existing container 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) if new_container: container = new_container + container_created = True if container and container.exists: container = self.update_limits(container) - container = self.update_networks(container) + container = self.update_networks(container, container_created) if state == 'started' and not container.running: self.diff_tracker.add('running', parameter=True, active=was_running) @@ -2405,24 +2433,25 @@ class ContainerManager(DockerBaseClass): return self._get_container(container.Id) return container - def update_networks(self, container): - has_network_differences, network_differences = container.has_network_differences() + def update_networks(self, container, container_created): updated_container = container - if has_network_differences: - if self.diff.get('differences'): - self.diff['differences'].append(dict(network_differences=network_differences)) - else: - self.diff['differences'] = [dict(network_differences=network_differences)] - for netdiff in network_differences: - self.diff_tracker.add( - 'network.{0}'.format(netdiff['parameter']['name']), - parameter=netdiff['parameter'], - active=netdiff['container'] - ) - self.results['changed'] = True - updated_container = self._add_networks(container, network_differences) + if self.parameters.comparisons['networks']['comparison'] != 'ignore' or container_created: + has_network_differences, network_differences = container.has_network_differences() + if has_network_differences: + if self.diff.get('differences'): + self.diff['differences'].append(dict(network_differences=network_differences)) + else: + self.diff['differences'] = [dict(network_differences=network_differences)] + for netdiff in network_differences: + self.diff_tracker.add( + 'network.{0}'.format(netdiff['parameter']['name']), + parameter=netdiff['parameter'], + active=netdiff['container'] + ) + self.results['changed'] = True + 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() if has_extra_networks: if self.diff.get('differences'): @@ -2665,6 +2694,7 @@ class AnsibleDockerClientContainer(AnsibleDockerClient): env='set', entrypoint='list', etc_hosts='set', + networks='set(dict)', ulimits='set(dict)', device_read_bps='set(dict)', device_write_bps='set(dict)', @@ -2680,7 +2710,7 @@ class AnsibleDockerClientContainer(AnsibleDockerClient): for alias in data.get('aliases', []): all_options.add(alias) # 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 # Determine option type if option in explicit_types: @@ -2706,6 +2736,8 @@ class AnsibleDockerClientContainer(AnsibleDockerClient): # Process legacy ignore options if self.module.params['ignore_image']: comparisons['image']['comparison'] = 'ignore' + if self.module.params['purge_networks']: + comparisons['networks']['comparison'] = 'strict' # Process options if self.module.params.get('comparisons'): # If '*' appears in comparisons, process it first @@ -2713,7 +2745,12 @@ class AnsibleDockerClientContainer(AnsibleDockerClient): value = self.module.params['comparisons']['*'] if value not in ('strict', '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 # Now process all other comparisons. comp_aliases_used = {} @@ -2748,6 +2785,8 @@ class AnsibleDockerClientContainer(AnsibleDockerClient): # Check legacy values 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!') + 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 def _get_additional_minimal_versions(self): @@ -2893,6 +2932,7 @@ def main(): aliases=dict(type='list', elements='str'), links=dict(type='list', elements='str'), )), + networks_cli_compatible=dict(type='bool'), oom_killer=dict(type='bool'), oom_score_adj=dict(type='int'), output_logs=dict(type='bool', default=False), @@ -2938,6 +2978,16 @@ def main(): supports_check_mode=True, 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) client.module.exit_json(**sanitize_result(cm.results)) diff --git a/test/integration/targets/docker_container/tasks/tests/network.yml b/test/integration/targets/docker_container/tasks/tests/network.yml new file mode 100644 index 0000000000..4eefe68433 --- /dev/null +++ b/test/integration/targets/docker_container/tasks/tests/network.yml @@ -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', '>=') diff --git a/test/integration/targets/docker_container/tasks/tests/options.yml b/test/integration/targets/docker_container/tasks/tests/options.yml index a4ff5574f7..0f07f06277 100644 --- a/test/integration/targets/docker_container/tasks/tests/options.yml +++ b/test/integration/targets/docker_container/tasks/tests/options.yml @@ -5,23 +5,9 @@ cname_h1: "{{ cname_prefix ~ '-options-h1' }}" cname_h2: "{{ cname_prefix ~ '-options-h2' }}" cname_h3: "{{ cname_prefix ~ '-options-h3' }}" - nname_1: "{{ cname_prefix ~ '-network-1' }}" - nname_2: "{{ cname_prefix ~ '-network-2' }}" - name: Registering container name set_fact: 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 ##################################################### @@ -2434,164 +2420,6 @@ - memory_swappiness_2 is not 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 ###################################################### #################################################################### @@ -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', '>=')