fixed documentation and arg issues
This commit is contained in:
parent
9f1cfe07bb
commit
c03e1bd2d5
1 changed files with 115 additions and 104 deletions
|
@ -48,10 +48,12 @@ options:
|
|||
description:
|
||||
- Limit CPU CFS (Completely Fair Scheduler) period
|
||||
default: 0
|
||||
required: false
|
||||
cpu_quota:
|
||||
description:
|
||||
- Limit CPU CFS (Completely Fair Scheduler) quota
|
||||
default: 0
|
||||
required: false
|
||||
cpuset_cpus:
|
||||
description:
|
||||
- CPUs in which to allow execution C(1,3) or C(1-3).
|
||||
|
@ -70,8 +72,9 @@ options:
|
|||
detach:
|
||||
description:
|
||||
- Enable detached mode to leave the container running in background.
|
||||
If disabled, fail unless the process exits cleanly.
|
||||
If disabled, the task will reflect the status of the container run (failed if the command failed).
|
||||
default: true
|
||||
required: false
|
||||
devices:
|
||||
description:
|
||||
- "List of host device bindings to add to the container. Each binding is a mapping expressed
|
||||
|
@ -100,24 +103,24 @@ options:
|
|||
required: false
|
||||
etc_hosts:
|
||||
description:
|
||||
- Dict of host-to-IP mappings, where each host name is key in the dictionary. Hostname will be added to the
|
||||
container's /etc/hosts file.
|
||||
- Dict of host-to-IP mappings, where each host name is key in the dictionary.
|
||||
Hostname will be added to the container's /etc/hosts file.
|
||||
default: null
|
||||
required: false
|
||||
exposed_ports:
|
||||
description:
|
||||
- List of additional container ports to expose for port mappings or links.
|
||||
If the port is already exposed using EXPOSE in a Dockerfile, it does not
|
||||
need to be exposed again.
|
||||
need to be xposed again.
|
||||
default: null
|
||||
required: false
|
||||
aliases:
|
||||
- exposed
|
||||
force_kill:
|
||||
description:
|
||||
- Use with absent, present, started and stopped states to use the kill command rather
|
||||
than the stop command.
|
||||
- Use with absent, present, started and stopped states to use the kill command rather than the stop command.
|
||||
default: false
|
||||
required: false
|
||||
groups:
|
||||
description:
|
||||
- List of additional group names and/or IDs that the container process will run as.
|
||||
|
@ -135,6 +138,7 @@ options:
|
|||
the image vesion in the registry does not match the container, the container will be
|
||||
rebuilt. To stop this behavior set ignore_image to true.
|
||||
default: false
|
||||
required: false
|
||||
image:
|
||||
description:
|
||||
- Repository path and tag used to create the container. If an image is not found or pull is true, the image
|
||||
|
@ -145,17 +149,18 @@ options:
|
|||
description:
|
||||
- Keep stdin open after a container is launched, even if not attached.
|
||||
default: false
|
||||
required: false
|
||||
ipc_mode:
|
||||
description:
|
||||
- Set the IPC mode for the container. Can be one of
|
||||
'container:<name|id>' to reuse another container's IPC namespace
|
||||
or 'host' to use the host's IPC namespace within the container.
|
||||
- Set the IPC mode for the container. Can be one of 'container:<name|id>' to reuse another
|
||||
container's IPC namespace or 'host' to use the host's IPC namespace within the container.
|
||||
default: null
|
||||
required: false
|
||||
keep_volumes:
|
||||
description:
|
||||
- Retain volumes associated with a removed container.
|
||||
default: true
|
||||
required: false
|
||||
kill_signal:
|
||||
description:
|
||||
- Override default signal used to kill a running container.
|
||||
|
@ -166,6 +171,7 @@ options:
|
|||
- "Kernel memory limit (format: <number>[<unit>]). Number is a positive integer.
|
||||
Unit can be one of b, k, m, or g. Minimum is 4M."
|
||||
default: 0
|
||||
required: false
|
||||
labels:
|
||||
description:
|
||||
- Dictionary of key value pairs.
|
||||
|
@ -188,6 +194,7 @@ options:
|
|||
- awslogs
|
||||
- splunk
|
||||
defult: json-file
|
||||
required: false
|
||||
log_options:
|
||||
description:
|
||||
- Dictionary of options specific to the chosen log_driver. See https://docs.docker.com/engine/admin/logging/overview/
|
||||
|
@ -198,25 +205,30 @@ options:
|
|||
description:
|
||||
- Container MAC address (e.g. 92:d0:c6:0a:29:33)
|
||||
default: null
|
||||
required: false
|
||||
memory:
|
||||
description:
|
||||
- "Memory limit (format: <number>[<unit>]). Number is a positive integer.
|
||||
Unit can be one of b, k, m, or g"
|
||||
default: 0
|
||||
required: false
|
||||
memory_reservation:
|
||||
description:
|
||||
- "Memory soft limit (format: <number>[<unit>]). Number is a positive integer.
|
||||
Unit can be one of b, k, m, or g"
|
||||
default: 0
|
||||
required: false
|
||||
memory_swap:
|
||||
description:
|
||||
- Total memory limit (memory + swap, format:<number>[<unit>]).
|
||||
Number is a positive integer. Unit can be one of b, k, m, or g.
|
||||
default: 0
|
||||
required: false
|
||||
memory_swappiness:
|
||||
description:
|
||||
description:
|
||||
- Tune a container's memory swappiness behavior. Accepts an integer between 0 and 100.
|
||||
default: 0
|
||||
default: 0
|
||||
required: false
|
||||
name:
|
||||
description:
|
||||
- Assign a name to a new container or match an existing container.
|
||||
|
@ -232,20 +244,16 @@ options:
|
|||
- none
|
||||
default: null
|
||||
required: false
|
||||
# networks:
|
||||
# description:
|
||||
# - "Dictionary of networks to which the container will be connected. The dictionary must have a name key (the name of the network).
|
||||
# Optional keys include: aliases (a list of container aliases), and links (a list of links in the format C(container_name:alias))."
|
||||
# default: null
|
||||
# required: false
|
||||
oom_killer:
|
||||
description:
|
||||
- Whether or not to disable OOM Killer for the container.
|
||||
default: false
|
||||
required: false
|
||||
paused:
|
||||
description:
|
||||
- Use with the started state to pause running processes inside the container.
|
||||
default: false
|
||||
required: false
|
||||
pid_mode:
|
||||
description:
|
||||
- Set the PID namespace mode for the container. Currenly only supports 'host'.
|
||||
|
@ -255,6 +263,7 @@ options:
|
|||
description:
|
||||
- Give extended privileges to the container.
|
||||
default: false
|
||||
required: false
|
||||
published_ports:
|
||||
description:
|
||||
- List of ports to publish from the container to the host.
|
||||
|
@ -266,19 +275,22 @@ options:
|
|||
aliases:
|
||||
- ports
|
||||
required: false
|
||||
default: null
|
||||
pull:
|
||||
description:
|
||||
- If true, always pull the latest version of an image. Otherwise, will only pull an image
|
||||
when missing.
|
||||
default: false
|
||||
description:
|
||||
- If true, always pull the latest version of an image. Otherwise, will only pull an image when missing.
|
||||
default: false
|
||||
required: false
|
||||
read_only:
|
||||
description:
|
||||
- Mount the container's root file system as read-only.
|
||||
default: false
|
||||
required: false
|
||||
recreate:
|
||||
description:
|
||||
- Use with present and started states to force the re-creation of an existing container.
|
||||
default: false
|
||||
required: false
|
||||
registry:
|
||||
description:
|
||||
- Registry URL from which to pull images. If not specified, images will be pulled from
|
||||
|
@ -289,6 +301,7 @@ options:
|
|||
description:
|
||||
- Use with started state to force a matching container to be stopped and restarted.
|
||||
default: false
|
||||
required: false
|
||||
restart_policy:
|
||||
description:
|
||||
- Container restart policy.
|
||||
|
@ -296,10 +309,12 @@ options:
|
|||
- on-failure
|
||||
- always
|
||||
default: on-failure
|
||||
required: false
|
||||
restart_retries:
|
||||
description:
|
||||
description:
|
||||
- Use with restart policy to control maximum number of restart attempts.
|
||||
default: 0
|
||||
default: 0
|
||||
required: false
|
||||
shm_size:
|
||||
description:
|
||||
- Size of `/dev/shm`. The format is `<number><unit>`. `number` must be greater than `0`.
|
||||
|
@ -349,14 +364,17 @@ options:
|
|||
description:
|
||||
- Number of seconds to wait for the container to stop before sending SIGKILL.
|
||||
required: false
|
||||
default: null
|
||||
trust_image_content:
|
||||
description:
|
||||
- If true, skip image verification.
|
||||
default: false
|
||||
requried: false
|
||||
tty:
|
||||
description:
|
||||
- Allocate a psuedo-TTY.
|
||||
default: false
|
||||
required: false
|
||||
ulimits:
|
||||
description:
|
||||
- "List of ulimit options. A ulimit is specified as C(nofile:262144:262144)"
|
||||
|
@ -392,7 +410,6 @@ options:
|
|||
- List of container names or Ids to get volumes from.
|
||||
default: null
|
||||
required: false
|
||||
|
||||
extends_documentation_fragment:
|
||||
- docker
|
||||
|
||||
|
@ -427,7 +444,7 @@ EXAMPLES = '''
|
|||
command: redis-server --appendonly yes
|
||||
state: present
|
||||
recreate: yes
|
||||
expose:
|
||||
exposed_ports:
|
||||
- 6379
|
||||
volumes_from:
|
||||
- mydata
|
||||
|
@ -453,7 +470,7 @@ EXAMPLES = '''
|
|||
name: mycontainer
|
||||
state: present
|
||||
recreate: yes
|
||||
forcekill: yes
|
||||
force_kill: yes
|
||||
image: someplace/image
|
||||
command: echo "I'm here!"
|
||||
|
||||
|
@ -466,7 +483,7 @@ EXAMPLES = '''
|
|||
command: sleep 1d
|
||||
with_sequence: count=4
|
||||
|
||||
-name: remove container
|
||||
- name: remove container
|
||||
docker_container:
|
||||
name: ohno
|
||||
state: absent
|
||||
|
@ -476,7 +493,7 @@ EXAMPLES = '''
|
|||
name: myservice
|
||||
state: started
|
||||
log_driver: syslog
|
||||
log_opt:
|
||||
log_options:
|
||||
syslog-address: tcp://my-syslog-server:514
|
||||
syslog-facility: daemon
|
||||
syslog-tag: myservice
|
||||
|
@ -484,20 +501,11 @@ EXAMPLES = '''
|
|||
'''
|
||||
|
||||
RETURN = '''
|
||||
actions:
|
||||
description: List of actions taken by the module.
|
||||
returned: always
|
||||
type: list
|
||||
sample: [
|
||||
{
|
||||
"started": "8e47bf643eb95e2da60758f022629179605c336f04410c3e8ed120c376f1570b"
|
||||
}
|
||||
]
|
||||
container:
|
||||
description: Facts representing the current state of the container.
|
||||
ansible_docker_container:
|
||||
description: Facts representing the current state of the container. Note that facts are not part of registred vars but accessible directly.
|
||||
returned: always
|
||||
type: dict
|
||||
sample: {
|
||||
sample: '{
|
||||
"AppArmorProfile": "",
|
||||
"Args": [],
|
||||
"Config": {
|
||||
|
@ -528,16 +536,12 @@ container:
|
|||
"/tmp/lnmp/nginx-sites/logs/": {}
|
||||
},
|
||||
...
|
||||
}
|
||||
}
|
||||
}'
|
||||
'''
|
||||
|
||||
import logging
|
||||
|
||||
from ansible.module_utils.docker_common import *
|
||||
|
||||
try:
|
||||
from docker import auth
|
||||
from docker import utils
|
||||
from docker.utils.types import Ulimit
|
||||
except:
|
||||
|
@ -570,7 +574,6 @@ class TaskParameters(DockerBaseClass):
|
|||
self.cpuset_cpus = None
|
||||
self.cpuset_mems = None
|
||||
self.cpu_shares = None
|
||||
self.debug = False
|
||||
self.detach = None
|
||||
self.devices = None
|
||||
self.dns_servers = None
|
||||
|
@ -620,10 +623,9 @@ class TaskParameters(DockerBaseClass):
|
|||
self.user = None
|
||||
self.uts = None
|
||||
self.volumes = None
|
||||
self.volume_binds = dict()
|
||||
self.volumes_from = None
|
||||
self.volume_driver = None
|
||||
self.debug = None
|
||||
self.debug_file = None
|
||||
|
||||
for key, value in client.module.params.items():
|
||||
setattr(self, key, value)
|
||||
|
@ -655,7 +657,7 @@ class TaskParameters(DockerBaseClass):
|
|||
self.ulimits = self._parse_ulimits()
|
||||
self.log_config = self._parse_log_config()
|
||||
self.exp_links = None
|
||||
self.volume_binds = self._parse_volumes()
|
||||
self._parse_volumes()
|
||||
|
||||
def fail(self, msg):
|
||||
self.client.module.fail_json(msg=msg)
|
||||
|
@ -716,28 +718,33 @@ class TaskParameters(DockerBaseClass):
|
|||
for key, value in create_params.iteritems():
|
||||
if getattr(self, value, None) is not None:
|
||||
result[key] = getattr(self, value)
|
||||
|
||||
return result
|
||||
|
||||
def _expand_host_paths(self):
|
||||
new_vols = []
|
||||
for vol in self.volumes:
|
||||
if len(vol.split(':')) == 3:
|
||||
host, container, mode = vol.split(':')
|
||||
host = os.path.abspath(host)
|
||||
new_vols.append(host + ':' + container + ':' + mode)
|
||||
if ':' in vol:
|
||||
if len(vol.split(':')) == 3:
|
||||
host, container, mode = vol.split(':')
|
||||
host = os.path.abspath(host)
|
||||
new_vols.append(host + ':' + container + ':' + mode)
|
||||
else:
|
||||
host, container = vol.split(':')
|
||||
host = os.path.abspath(host)
|
||||
new_vols.append(host + ':' + container)
|
||||
else:
|
||||
host, container = vol.split(':')
|
||||
host = os.path.abspath(host)
|
||||
new_vols.append(host + ':' + container)
|
||||
new_vols.append(os.path.abspath(vol))
|
||||
return new_vols
|
||||
|
||||
def _get_mounts(self):
|
||||
result = []
|
||||
if self.volumes:
|
||||
for vol in self.volumes:
|
||||
host, container = vol.split(':')
|
||||
result.append(host)
|
||||
if ':' in vol:
|
||||
host, container, _ = vol.split(':')
|
||||
result.append(host)
|
||||
else:
|
||||
result.append(vol)
|
||||
return result
|
||||
|
||||
def _host_config(self):
|
||||
|
@ -815,23 +822,22 @@ class TaskParameters(DockerBaseClass):
|
|||
def _parse_volumes(self):
|
||||
'''
|
||||
Convert volumes parameter to host_config bind format.
|
||||
|
||||
https://docker-py.readthedocs.org/en/latest/volumes/
|
||||
|
||||
:return: array of binds
|
||||
'''
|
||||
results = dict()
|
||||
if self.volumes:
|
||||
for vol in self.volumes:
|
||||
if len(vol.split(':')) == 3:
|
||||
host, container, mode = vol.split(':')
|
||||
else:
|
||||
host, container, mode = vol.split(':') + ['rw']
|
||||
results[host] = dict(
|
||||
bind=container,
|
||||
mode=mode
|
||||
)
|
||||
return results
|
||||
if ':' in vol:
|
||||
volumespec = vol.split(':')
|
||||
if len(volumespec) == 3:
|
||||
host, container, mode = vol.split(':')
|
||||
else:
|
||||
host, container, mode = (vol.split(':') + ['rw'])
|
||||
self.volume_binds[host] = dict(
|
||||
bind=container,
|
||||
mode=mode
|
||||
)
|
||||
|
||||
|
||||
def _parse_exposed_ports(self):
|
||||
'''
|
||||
|
@ -902,7 +908,7 @@ class TaskParameters(DockerBaseClass):
|
|||
)
|
||||
|
||||
if self.log_options is not None:
|
||||
options['Config'] = self.log_opts
|
||||
options['Config'] = self.log_options
|
||||
|
||||
try:
|
||||
return LogConfig(**options)
|
||||
|
@ -922,7 +928,6 @@ class Container(DockerBaseClass):
|
|||
self.Image = container['Image']
|
||||
self.log(self.container, pretty_print=True)
|
||||
self.parameters = parameters
|
||||
self.debug = self.parameters.debug
|
||||
self.parameters.expected_links = None
|
||||
self.parameters.expected_ports = None
|
||||
self.parameters.expected_exposed = None
|
||||
|
@ -1223,12 +1228,15 @@ class Container(DockerBaseClass):
|
|||
param_vols = []
|
||||
if self.parameters.volumes:
|
||||
for vol in self.parameters.volumes:
|
||||
if len(vol.split(':')) == 3:
|
||||
host, container, mode = vol.split(':')
|
||||
if ':' in vol:
|
||||
if len(vol.split(':')) == 3:
|
||||
host, container, mode = vol.split(':')
|
||||
else:
|
||||
host, container, mode = vol.split(':') + ['rw']
|
||||
param_vols.append("%s:%s:%s" % (host, container, mode))
|
||||
else:
|
||||
host, container, mode = vol.split(':') + ['rw']
|
||||
param_vols.append(vol)
|
||||
# flip to container first
|
||||
param_vols.append("%s:%s:%s" % (host, container, mode))
|
||||
return list(set(image_vols + param_vols))
|
||||
|
||||
def _get_volumes_from_binds(self, volumes):
|
||||
|
@ -1321,15 +1329,16 @@ class ContainerManager(DockerBaseClass):
|
|||
Perform container management tasks
|
||||
'''
|
||||
|
||||
def __init__(self, client, results):
|
||||
def __init__(self, client):
|
||||
|
||||
super(ContainerManager, self).__init__()
|
||||
|
||||
self.client = client
|
||||
self.results = results
|
||||
self.parameters = TaskParameters(client)
|
||||
self.check_mode = self.client.check_mode
|
||||
self.debug = self.parameters.debug
|
||||
self.results = {'changed': False, 'actions': []}
|
||||
self.diff = {}
|
||||
self.facts = {}
|
||||
|
||||
state = self.parameters.state
|
||||
if state in ('started', 'present'):
|
||||
|
@ -1337,6 +1346,17 @@ class ContainerManager(DockerBaseClass):
|
|||
elif state == 'absent':
|
||||
self.absent()
|
||||
|
||||
# remove for now, until we decide about general framework
|
||||
try:
|
||||
del results['actions']
|
||||
except:
|
||||
pass
|
||||
|
||||
if self.client.module._diff:
|
||||
self.results['diff'] = self.diff
|
||||
if self.facts:
|
||||
self.results['ansbile_facts'] = {'ansible_docker_container': self.facts}
|
||||
|
||||
def present(self, state):
|
||||
container = self._get_container(self.parameters.name)
|
||||
image = self._get_image()
|
||||
|
@ -1351,22 +1371,22 @@ class ContainerManager(DockerBaseClass):
|
|||
container = self.update_networks(container)
|
||||
if state == 'started':
|
||||
container = self.container_start(container.Id)
|
||||
self.results['container'] = container.raw
|
||||
self.facts = container.raw
|
||||
return True
|
||||
|
||||
# Existing container
|
||||
self.log(container.raw, pretty_print=True)
|
||||
different, differences = container.has_different_configuration(image)
|
||||
image_different = self._image_is_different(image, container)
|
||||
if image_different:
|
||||
self.results['image_different'] = True
|
||||
if image_different or different or self.parameters.recreate:
|
||||
self.results['config_differences'] = differences
|
||||
self.diff = differences
|
||||
self.container_stop(container.Id)
|
||||
self.container_remove(container.Id)
|
||||
new_container = self.container_create(self.parameters.create_parameters)
|
||||
if new_container:
|
||||
container = new_container
|
||||
if image_different:
|
||||
self.diff['image_different'] = True
|
||||
|
||||
container = self.update_limits(container)
|
||||
container = self.update_networks(container)
|
||||
|
@ -1382,7 +1402,7 @@ class ContainerManager(DockerBaseClass):
|
|||
self.container_stop(container.Id)
|
||||
container = self._get_container(container.Id)
|
||||
|
||||
self.results['container'] = container.raw
|
||||
self.facts = container.raw
|
||||
|
||||
def absent(self):
|
||||
container = Container(self.client.get_container(self.parameters.name), self.parameters)
|
||||
|
@ -1451,13 +1471,12 @@ class ContainerManager(DockerBaseClass):
|
|||
self.log(create_parameters, pretty_print=True)
|
||||
if not self.check_mode:
|
||||
try:
|
||||
new_container = self.client.create_container(**create_parameters)
|
||||
self.results['actions'].append(dict(created=new_container.get('Id'),
|
||||
create_parameters=create_parameters))
|
||||
new_container = self.client.create_container(create_parameters)
|
||||
self.results['actions'].append(dict(created=new_container.get('Id'), create_parameters=create_parameters))
|
||||
self.results['changed'] = True
|
||||
return self._get_container(new_container['Id'])
|
||||
except Exception, exc:
|
||||
self.fail("Error creating container: %s" % str(exc))
|
||||
return self._get_container(new_container['Id'])
|
||||
|
||||
def container_start(self, container_id):
|
||||
self.log("start container %s" % (container_id))
|
||||
|
@ -1550,8 +1569,8 @@ def main():
|
|||
env=dict(type='dict'),
|
||||
entrypoint=dict(type='list'),
|
||||
etc_hosts=dict(type='dict'),
|
||||
exposed_ports=dict(type='list', aliases=['exposed']),
|
||||
force_kill=dict(type='bool', default=False),
|
||||
exposed_ports=dict(type='list', aliases=['exposed', 'expose']),
|
||||
force_kill=dict(type='bool', default=False, aliases=['forcekill']),
|
||||
groups=dict(type='list'),
|
||||
hostname=dict(type='str'),
|
||||
image=dict(type='str'),
|
||||
|
@ -1562,11 +1581,10 @@ def main():
|
|||
kill_signal=dict(type='str'),
|
||||
labels=dict(type='dict'),
|
||||
links=dict(type='list'),
|
||||
log_driver=dict(type='str', choices=['json-file', 'syslog', 'journald', 'gelf', 'fluentd',
|
||||
'awslogs', 'splunk'], default='json-file'),
|
||||
log_options=dict(type='str'),
|
||||
log_driver=dict(type='str', choices=['json-file', 'syslog', 'journald', 'gelf', 'fluentd', 'awslogs', 'splunk'], default='json-file'),
|
||||
log_options=dict(type='dict', aliases=['log_opt']),
|
||||
mac_address=dict(type='str'),
|
||||
memory=dict(type='str'),
|
||||
memory=dict(type='str', default='0'),
|
||||
memory_reservation=dict(type='str'),
|
||||
memory_swap=dict(type='str'),
|
||||
memory_swappiness=dict(type='int'),
|
||||
|
@ -1609,15 +1627,8 @@ def main():
|
|||
supports_check_mode=True
|
||||
)
|
||||
|
||||
results = dict(
|
||||
changed=False,
|
||||
actions=[],
|
||||
container={}
|
||||
)
|
||||
|
||||
ContainerManager(client, results)
|
||||
client.module.exit_json(**results)
|
||||
|
||||
cm = ContainerManager(client)
|
||||
client.module.exit_json(**cm.results)
|
||||
|
||||
# import module snippets
|
||||
from ansible.module_utils.basic import *
|
||||
|
|
Loading…
Reference in a new issue