diff --git a/changelogs/fragments/138-docker_container-allow-memory-swap-unlimited.yml b/changelogs/fragments/138-docker_container-allow-memory-swap-unlimited.yml new file mode 100644 index 00000000..3e7ea385 --- /dev/null +++ b/changelogs/fragments/138-docker_container-allow-memory-swap-unlimited.yml @@ -0,0 +1,2 @@ +minor_changes: +- "docker_container - allow ``memory_swap: -1`` to set memory swap limit to unlimited. This is useful when the user cannot set memory swap limits due to cgroup limitations or other reasons, as by default Docker will try to set swap usage to two times the value of ``memory`` (https://github.com/ansible-collections/community.docker/pull/138)." diff --git a/plugins/modules/docker_container.py b/plugins/modules/docker_container.py index 23ec2987..a7f00435 100644 --- a/plugins/modules/docker_container.py +++ b/plugins/modules/docker_container.py @@ -458,7 +458,8 @@ options: type: str memory_swap: description: - - "Total memory limit (memory + swap) in format C([]). + - "Total memory limit (memory + swap) in format C([]), or + the special values C(unlimited) or C(-1) for unlimited swap usage. Number is a positive integer. Unit can be C(B) (byte), C(K) (kibibyte, 1024B), C(M) (mebibyte), C(G) (gibibyte), C(T) (tebibyte), or C(P) (pebibyte)." - Omitting the unit defaults to bytes. @@ -1413,10 +1414,13 @@ class TaskParameters(DockerBaseClass): for param_name in REQUIRES_CONVERSION_TO_BYTES: if client.module.params.get(param_name): - try: - setattr(self, param_name, human_to_bytes(client.module.params.get(param_name))) - except ValueError as exc: - self.fail("Failed to convert %s to bytes: %s" % (param_name, to_native(exc))) + if param_name == 'memory_swap' and client.module.params.get(param_name) in ['unlimited', '-1']: + setattr(self, param_name, -1) + else: + try: + setattr(self, param_name, human_to_bytes(client.module.params.get(param_name))) + except ValueError as exc: + self.fail("Failed to convert %s to bytes: %s" % (param_name, to_native(exc))) self.publish_all_ports = False self.published_ports = self._parse_publish_ports() diff --git a/tests/integration/targets/docker_container/tasks/tests/options.yml b/tests/integration/targets/docker_container/tasks/tests/options.yml index b076325e..ea4fe34f 100644 --- a/tests/integration/targets/docker_container/tasks/tests/options.yml +++ b/tests/integration/targets/docker_container/tasks/tests/options.yml @@ -2520,6 +2520,32 @@ avoid such warnings, please quote the value.' in log_options_2.warnings" debug: yes register: memory_swap_3 +- name: memory_swap (unlimited) + docker_container: + image: "{{ docker_test_image_alpine }}" + command: '/bin/sh -c "sleep 10m"' + name: "{{ cname }}" + # Docker daemon does not accept memory_swap if memory is not specified + memory: 32M + memory_swap: unlimited + state: started + force_kill: yes + debug: yes + register: memory_swap_4 + +- name: memory_swap (unlimited via -1) + docker_container: + image: "{{ docker_test_image_alpine }}" + command: '/bin/sh -c "sleep 10m"' + name: "{{ cname }}" + # Docker daemon does not accept memory_swap if memory is not specified + memory: 32M + memory_swap: -1 + state: started + force_kill: yes + debug: yes + register: memory_swap_5 + - name: cleanup docker_container: name: "{{ cname }}" @@ -2534,6 +2560,11 @@ avoid such warnings, please quote the value.' in log_options_2.warnings" # on a proper VM), memory_swap cannot be set and will be -1 afterwards. - memory_swap_2 is not changed or memory_swap_2.container.HostConfig.MemorySwap == -1 - memory_swap_3 is changed + # Unlimited memory_swap (using 'unlimited') should be allowed + # (If the value was already -1 because of the above reasons, it won't change) + - (memory_swap_4 is changed or memory_swap_3.container.HostConfig.MemorySwap == -1) and memory_swap_4.container.HostConfig.MemorySwap == -1 + # Unlimited memory_swap (using '-1') should be allowed + - memory_swap_5 is not changed and memory_swap_5.container.HostConfig.MemorySwap == -1 - debug: var=memory_swap_1 when: memory_swap_2 is changed