Adds ulimit to the docker module

The ulimit will be specified as a list and separated by colons. The
hard limit is optional, in which case it is equal to the soft limit.

The ulimits are compared to the ulimits of the container and added
or adjusted accordingly on by a reload.

The module ensures that ulimits are available in the capabilities
iff ulimits is passes as a parameter.
This commit is contained in:
Daan Oosterveld 2016-02-09 10:19:59 +01:00
parent 08fd378479
commit 90153a2ca5

View file

@ -370,6 +370,14 @@ options:
required: false required: false
default: 0 default: 0
version_added: "2.1" version_added: "2.1"
ulimits:
description:
- ulimits, list ulimits with name, soft and optionally
hard limit separated by colons. e.g. nofile:1024:2048
Requires docker-py >= 1.2.0 and docker >= 1.6.0
required: false
default: null
version_added: "2.1"
author: author:
- "Cove Schneider (@cove)" - "Cove Schneider (@cove)"
@ -378,6 +386,7 @@ author:
- "Ash Wilson (@smashwilson)" - "Ash Wilson (@smashwilson)"
- "Thomas Steinbach (@ThomasSteinbach)" - "Thomas Steinbach (@ThomasSteinbach)"
- "Philippe Jandot (@zfil)" - "Philippe Jandot (@zfil)"
- "Daan Oosterveld (@dusdanig)
requirements: requirements:
- "python >= 2.6" - "python >= 2.6"
- "docker-py >= 0.3.0" - "docker-py >= 0.3.0"
@ -660,6 +669,7 @@ class DockerManager(object):
'read_only': ((1, 0, 0), '1.17'), 'read_only': ((1, 0, 0), '1.17'),
'labels': ((1, 2, 0), '1.18'), 'labels': ((1, 2, 0), '1.18'),
'stop_timeout': ((0, 5, 0), '1.0'), 'stop_timeout': ((0, 5, 0), '1.0'),
'ulimits': ((1, 2, 0), '1.18'),
# Clientside only # Clientside only
'insecure_registry': ((0, 5, 0), '0.0') 'insecure_registry': ((0, 5, 0), '0.0')
} }
@ -714,6 +724,19 @@ class DockerManager(object):
self.env = self.module.params.get('env', None) self.env = self.module.params.get('env', None)
self.ulimits = None
if self.module.params.get('ulimits'):
self.ulimits = []
ulimits = self.module.params.get('ulimits')
for ulimit in ulimits:
parts = ulimit.split(":")
if len(parts) == 2:
self.ulimits.append({'name': parts[0], 'soft': int(parts[1]), 'hard': int(parts[1])})
elif len(parts) == 3:
self.ulimits.append({'name': parts[0], 'soft': int(parts[1]), 'hard': int(parts[2])})
else:
self.module.fail_json(msg='ulimits support 2 to 3 arguments')
# Connect to the docker server using any configured host and TLS settings. # Connect to the docker server using any configured host and TLS settings.
env_host = os.getenv('DOCKER_HOST') env_host = os.getenv('DOCKER_HOST')
@ -1165,6 +1188,16 @@ class DockerManager(object):
differing.append(container) differing.append(container)
continue continue
# ULIMITS
expected_ulimit_keys = set(map(lambda x: '%s:%s:%s' % (x['name'],x['soft'],x['hard']), self.ulimits or []))
actual_ulimit_keys = set(map(lambda x: '%s:%s:%s' % (x['Name'],x['Soft'],x['Hard']), (container['HostConfig']['Ulimits'] or [])))
if actual_ulimit_keys != expected_ulimit_keys:
self.reload_reasons.append('ulimits ({0} => {1})'.format(actual_ulimit_keys, expected_ulimit_keys))
differing.append(container)
continue
# CPU_SHARES # CPU_SHARES
expected_cpu_shares = self.module.params.get('cpu_shares') expected_cpu_shares = self.module.params.get('cpu_shares')
@ -1566,6 +1599,9 @@ class DockerManager(object):
else: else:
params['host_config']['Memory'] = mem_limit params['host_config']['Memory'] = mem_limit
if self.ulimits is not None:
self.ensure_capability('ulimits')
params['host_config']['ulimits'] = self.ulimits
def do_create(count, params): def do_create(count, params):
results = [] results = []
@ -1813,6 +1849,7 @@ def main():
labels = dict(default={}, type='dict'), labels = dict(default={}, type='dict'),
stop_timeout = dict(default=10, type='int'), stop_timeout = dict(default=10, type='int'),
timeout = dict(required=False, default=DEFAULT_TIMEOUT_SECONDS, type='int'), timeout = dict(required=False, default=DEFAULT_TIMEOUT_SECONDS, type='int'),
ulimits = dict(default=None, type='list'),
), ),
required_together = ( required_together = (
['tls_client_cert', 'tls_client_key'], ['tls_client_cert', 'tls_client_key'],