mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
docker_swarm_service: Add command option (#50984)
* Add command option * Fix test task name * Changelog fragment * Fix indendation * Add version_added * Better command description * Test passing command as list * Handle invalid command types * Cleaner command type checking * Check that all items in command list are strings * Better error about command list items * Better type checking errors * Add tests for command type checking * Update command tests * Fix messed up rebase
This commit is contained in:
parent
9c44dc371b
commit
e3f61f4480
4 changed files with 125 additions and 4 deletions
|
@ -0,0 +1,2 @@
|
|||
minor_changes:
|
||||
- "docker_swarm_service - Added support for ``command`` parameter."
|
|
@ -41,6 +41,12 @@ options:
|
|||
description:
|
||||
- List comprised of the command and the arguments to be run inside
|
||||
- the container
|
||||
command:
|
||||
required: false
|
||||
description:
|
||||
- Command to execute when the container starts.
|
||||
A command may be either a string or a list or a list of strings.
|
||||
version_added: 2.8
|
||||
constraints:
|
||||
required: false
|
||||
default: []
|
||||
|
@ -511,6 +517,7 @@ EXAMPLES = '''
|
|||
'''
|
||||
|
||||
import time
|
||||
import shlex
|
||||
import operator
|
||||
from ansible.module_utils.docker_common import (
|
||||
DockerBaseClass,
|
||||
|
@ -518,6 +525,7 @@ from ansible.module_utils.docker_common import (
|
|||
DifferenceTracker,
|
||||
)
|
||||
from ansible.module_utils.basic import human_to_bytes
|
||||
from ansible.module_utils.six import string_types
|
||||
from ansible.module_utils._text import to_text
|
||||
|
||||
try:
|
||||
|
@ -532,6 +540,7 @@ class DockerService(DockerBaseClass):
|
|||
def __init__(self):
|
||||
super(DockerService, self).__init__()
|
||||
self.image = ""
|
||||
self.command = None
|
||||
self.args = []
|
||||
self.endpoint_mode = "vip"
|
||||
self.dns = []
|
||||
|
@ -579,6 +588,7 @@ class DockerService(DockerBaseClass):
|
|||
'mounts': self.mounts,
|
||||
'configs': self.configs,
|
||||
'networks': self.networks,
|
||||
'command': self.command,
|
||||
'args': self.args,
|
||||
'tty': self.tty,
|
||||
'dns': self.dns,
|
||||
|
@ -646,6 +656,35 @@ class DockerService(DockerBaseClass):
|
|||
s.update_order = ap['update_order']
|
||||
s.user = ap['user']
|
||||
|
||||
s.command = ap['command']
|
||||
if isinstance(s.command, string_types):
|
||||
s.command = shlex.split(s.command)
|
||||
elif isinstance(s.command, list):
|
||||
invalid_items = [
|
||||
(index, item)
|
||||
for index, item in enumerate(s.command)
|
||||
if not isinstance(item, string_types)
|
||||
]
|
||||
if invalid_items:
|
||||
errors = ', '.join(
|
||||
[
|
||||
'%s (%s) at index %s' % (item, type(item), index)
|
||||
for index, item in invalid_items
|
||||
]
|
||||
)
|
||||
raise Exception(
|
||||
'All items in a command list need to be strings. '
|
||||
'Check quoting. Invalid items: %s.'
|
||||
% errors
|
||||
)
|
||||
s.command = ap['command']
|
||||
elif s.command is not None:
|
||||
raise ValueError(
|
||||
'Invalid type for command %s (%s). '
|
||||
'Only string or list allowed. Check quoting.'
|
||||
% (s.command, type(s.command))
|
||||
)
|
||||
|
||||
if ap['force_update']:
|
||||
s.force_update = int(str(time.time()).replace('.', ''))
|
||||
|
||||
|
@ -738,6 +777,8 @@ class DockerService(DockerBaseClass):
|
|||
needs_rebuild = True
|
||||
if self.replicas != os.replicas:
|
||||
differences.add('replicas', parameter=self.replicas, active=os.replicas)
|
||||
if self.command is not None and self.command != os.command:
|
||||
differences.add('command', parameter=self.command, active=os.command)
|
||||
if self.args != os.args:
|
||||
differences.add('args', parameter=self.args, active=os.args)
|
||||
if self.constraints != os.constraints:
|
||||
|
@ -866,17 +907,24 @@ class DockerService(DockerBaseClass):
|
|||
)
|
||||
)
|
||||
|
||||
dns_config = types.DNSConfig(
|
||||
nameservers=self.dns,
|
||||
search=self.dns_search,
|
||||
options=self.dns_options
|
||||
)
|
||||
|
||||
cspec = types.ContainerSpec(
|
||||
image=self.image,
|
||||
user=self.user,
|
||||
dns_config=types.DNSConfig(nameservers=self.dns, search=self.dns_search, options=self.dns_options),
|
||||
command=self.command,
|
||||
args=self.args,
|
||||
env=self.env,
|
||||
tty=self.tty,
|
||||
hostname=self.hostname,
|
||||
env=self.env,
|
||||
user=self.user,
|
||||
labels=self.container_labels,
|
||||
mounts=mounts,
|
||||
secrets=secrets,
|
||||
tty=self.tty,
|
||||
dns_config=dns_config,
|
||||
configs=configs
|
||||
)
|
||||
|
||||
|
@ -983,6 +1031,7 @@ class DockerServiceManager():
|
|||
ds.image = task_template_data['ContainerSpec']['Image']
|
||||
ds.user = task_template_data['ContainerSpec'].get('User', 'root')
|
||||
ds.env = task_template_data['ContainerSpec'].get('Env', [])
|
||||
ds.command = task_template_data['ContainerSpec'].get('Command')
|
||||
ds.args = task_template_data['ContainerSpec'].get('Args', [])
|
||||
ds.update_delay = update_config_data['Delay']
|
||||
ds.update_parallelism = update_config_data['Parallelism']
|
||||
|
@ -1216,6 +1265,7 @@ def main():
|
|||
configs=dict(default=None, type='list'),
|
||||
secrets=dict(default=[], type='list'),
|
||||
networks=dict(default=[], type='list'),
|
||||
command=dict(default=None, type='raw'),
|
||||
args=dict(default=[], type='list'),
|
||||
env=dict(default=[], type='list'),
|
||||
force_update=dict(default=False, type='bool'),
|
||||
|
|
|
@ -209,6 +209,74 @@
|
|||
- constraints_2 is not changed
|
||||
- constraints_3 is changed
|
||||
|
||||
####################################################################
|
||||
## command #########################################################
|
||||
####################################################################
|
||||
|
||||
- name: command
|
||||
docker_swarm_service:
|
||||
name: "{{ service_name }}"
|
||||
image: alpine:3.8
|
||||
command: '/bin/sh -v -c "sleep 10m"'
|
||||
register: command_1
|
||||
|
||||
- name: command (idempotency)
|
||||
docker_swarm_service:
|
||||
name: "{{ service_name }}"
|
||||
image: alpine:3.8
|
||||
command: '/bin/sh -v -c "sleep 10m"'
|
||||
register: command_2
|
||||
|
||||
- name: command (less parameters)
|
||||
docker_swarm_service:
|
||||
name: "{{ service_name }}"
|
||||
image: alpine:3.8
|
||||
command: '/bin/sh -c "sleep 10m"'
|
||||
register: command_3
|
||||
|
||||
- name: command (as list)
|
||||
docker_swarm_service:
|
||||
name: "{{ service_name }}"
|
||||
image: alpine:3.8
|
||||
command:
|
||||
- "/bin/sh"
|
||||
- "-c"
|
||||
- "sleep 10m"
|
||||
register: command_4
|
||||
|
||||
- name: command (string failure)
|
||||
docker_swarm_service:
|
||||
name: "{{ service_name }}"
|
||||
image: alpine:3.8
|
||||
command: yes
|
||||
register: command_5
|
||||
ignore_errors: yes
|
||||
|
||||
- name: command (list failure)
|
||||
docker_swarm_service:
|
||||
name: "{{ service_name }}"
|
||||
image: alpine:3.8
|
||||
command:
|
||||
- "/bin/sh"
|
||||
- yes
|
||||
register: command_6
|
||||
ignore_errors: yes
|
||||
|
||||
- name: cleanup
|
||||
docker_swarm_service:
|
||||
name: "{{ service_name }}"
|
||||
state: absent
|
||||
diff: no
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- command_1 is changed
|
||||
- command_2 is not changed
|
||||
- command_3 is changed
|
||||
- command_4 is not changed
|
||||
- command_5 is failed
|
||||
- command_6 is failed
|
||||
|
||||
####################################################################
|
||||
## container_labels ################################################
|
||||
####################################################################
|
||||
|
|
|
@ -5,6 +5,7 @@ service_expected_output:
|
|||
configs: null
|
||||
constraints: []
|
||||
container_labels: {}
|
||||
command: null
|
||||
dns: []
|
||||
dns_options: []
|
||||
dns_search: []
|
||||
|
|
Loading…
Reference in a new issue