Add detach parameter. (#255)

This commit is contained in:
Felix Fontein 2021-12-22 17:37:08 +01:00 committed by GitHub
parent 5a23c4d336
commit 02596835b1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 90 additions and 40 deletions

View File

@ -0,0 +1,2 @@
minor_changes:
- docker_container_exec - add ``detach`` parameter (https://github.com/ansible-collections/community.docker/issues/250, https://github.com/ansible-collections/community.docker/pull/255).

View File

@ -40,6 +40,14 @@ options:
type: str type: str
description: description:
- The directory to run the command in. - The directory to run the command in.
detach:
description:
- Whether to run the command synchronously (I(detach=false), default) or asynchronously (I(detach=true)).
- If set to C(true), I(stdin) cannot be provided, and the return values C(stdout), C(stderr) and
C(rc) are not returned.
type: bool
default: false
version_added: 2.1.0
user: user:
type: str type: str
description: description:
@ -48,6 +56,7 @@ options:
type: str type: str
description: description:
- Set the stdin of the command directly to the specified value. - Set the stdin of the command directly to the specified value.
- Can only be used if I(detach=false).
stdin_add_newline: stdin_add_newline:
type: bool type: bool
default: true default: true
@ -107,20 +116,27 @@ EXAMPLES = '''
RETURN = ''' RETURN = '''
stdout: stdout:
type: str type: str
returned: success returned: success and I(detach=false)
description: description:
- The standard output of the container command. - The standard output of the container command.
stderr: stderr:
type: str type: str
returned: success returned: success and I(detach=false)
description: description:
- The standard error output of the container command. - The standard error output of the container command.
rc: rc:
type: int type: int
returned: success returned: success and I(detach=false)
sample: 0 sample: 0
description: description:
- The exit code of the command. - The exit code of the command.
exec_id:
type: str
returned: success and I(detach=true)
sample: 249d9e3075655baf705ed8f40488c5e9434049cf3431976f1bfdb73741c574c5
description:
- The execution ID of the command.
version_added: 2.1.0
''' '''
import shlex import shlex
@ -156,6 +172,7 @@ def main():
argv=dict(type='list', elements='str'), argv=dict(type='list', elements='str'),
command=dict(type='str'), command=dict(type='str'),
chdir=dict(type='str'), chdir=dict(type='str'),
detach=dict(type='bool', default=False),
user=dict(type='str'), user=dict(type='str'),
stdin=dict(type='str'), stdin=dict(type='str'),
stdin_add_newline=dict(type='bool', default=True), stdin_add_newline=dict(type='bool', default=True),
@ -179,6 +196,7 @@ def main():
argv = client.module.params['argv'] argv = client.module.params['argv']
command = client.module.params['command'] command = client.module.params['command']
chdir = client.module.params['chdir'] chdir = client.module.params['chdir']
detach = client.module.params['detach']
user = client.module.params['user'] user = client.module.params['user']
stdin = client.module.params['stdin'] stdin = client.module.params['stdin']
strip_empty_ends = client.module.params['strip_empty_ends'] strip_empty_ends = client.module.params['strip_empty_ends']
@ -187,11 +205,14 @@ def main():
if command is not None: if command is not None:
argv = shlex.split(command) argv = shlex.split(command)
if detach and stdin is not None:
client.module.fail_json(msg='If detach=true, stdin cannot be provided.')
if stdin is not None and client.module.params['stdin_add_newline']: if stdin is not None and client.module.params['stdin_add_newline']:
stdin += '\n' stdin += '\n'
selectors = None selectors = None
if stdin: if stdin and not detach:
selectors = find_selectors(client.module) selectors = find_selectors(client.module)
try: try:
@ -209,45 +230,50 @@ def main():
) )
exec_id = exec_data['Id'] exec_id = exec_data['Id']
if selectors: if detach:
exec_socket = client.exec_start( client.exec_start(exec_id, tty=tty, detach=True)
exec_id, client.module.exit_json(changed=True, exec_id=exec_id)
tty=tty,
detach=False,
socket=True,
)
try:
with DockerSocketHandlerModule(exec_socket, client.module, selectors) as exec_socket_handler:
if stdin:
exec_socket_handler.write(to_bytes(stdin))
stdout, stderr = exec_socket_handler.consume()
finally:
exec_socket.close()
else: else:
stdout, stderr = client.exec_start( if selectors:
exec_id, exec_socket = client.exec_start(
tty=tty, exec_id,
detach=False, tty=tty,
stream=False, detach=False,
socket=False, socket=True,
demux=True, )
try:
with DockerSocketHandlerModule(exec_socket, client.module, selectors) as exec_socket_handler:
if stdin:
exec_socket_handler.write(to_bytes(stdin))
stdout, stderr = exec_socket_handler.consume()
finally:
exec_socket.close()
else:
stdout, stderr = client.exec_start(
exec_id,
tty=tty,
detach=False,
stream=False,
socket=False,
demux=True,
)
result = client.exec_inspect(exec_id)
stdout = to_text(stdout or b'')
stderr = to_text(stderr or b'')
if strip_empty_ends:
stdout = stdout.rstrip('\r\n')
stderr = stderr.rstrip('\r\n')
client.module.exit_json(
changed=True,
stdout=stdout,
stderr=stderr,
rc=result.get('ExitCode') or 0,
) )
result = client.exec_inspect(exec_id)
stdout = to_text(stdout or b'')
stderr = to_text(stderr or b'')
if strip_empty_ends:
stdout = stdout.rstrip('\r\n')
stderr = stderr.rstrip('\r\n')
client.module.exit_json(
changed=True,
stdout=stdout,
stderr=stderr,
rc=result.get('ExitCode') or 0,
)
except NotFound: except NotFound:
client.fail('Could not find container "{0}"'.format(container)) client.fail('Could not find container "{0}"'.format(container))
except APIError as e: except APIError as e:

View File

@ -162,11 +162,33 @@
- assert: - assert:
that: that:
- result is changed
- result.rc == 0 - result.rc == 0
- result.stdout == very_long_string ~ '\n' ~ very_long_string2 - result.stdout == very_long_string ~ '\n' ~ very_long_string2
- result.stdout_lines == [very_long_string, very_long_string2] - result.stdout_lines == [very_long_string, very_long_string2]
- result.stderr == '' - result.stderr == ''
- result.stderr_lines == [] - result.stderr_lines == []
- "'exec_id' not in result"
- name: Execute in a present container (detached)
docker_container_exec:
container: "{{ cname }}"
argv:
- /bin/sh
- '-c'
- sleep 1m
detach: true
register: result
- debug: var=result
- assert:
that:
- result is changed
- "'rc' not in result"
- "'stdout' not in result"
- "'stderr' not in result"
- result.exec_id is string
always: always:
- name: Cleanup - name: Cleanup