mirror of
https://github.com/ansible-collections/community.docker.git
synced 2025-12-15 19:42:06 +00:00
Docker* connection plugins: allow to pass extra environment variables when running commands (#940)
* Allow to pass extra environment variables when running commands. * Make compatible with older Python. * Remove env and ini sources for extra_env.
This commit is contained in:
parent
0fe84b510b
commit
7464002bc3
2
changelogs/fragments/940-connection-env.yml
Normal file
2
changelogs/fragments/940-connection-env.yml
Normal file
@ -0,0 +1,2 @@
|
||||
minor_changes:
|
||||
- "docker, docker_api connection plugins - allow to pass extra environment variables when executing commands with the new ``extra_env`` option (https://github.com/ansible-collections/community.docker/issues/937, https://github.com/ansible-collections/community.docker/pull/940)."
|
||||
@ -75,6 +75,23 @@ options:
|
||||
cli:
|
||||
- name: timeout
|
||||
type: integer
|
||||
extra_env:
|
||||
description:
|
||||
- Provide extra environment variables to set when running commands in the Docker container.
|
||||
- This option can currently only be provided as Ansible variables due to limitations of
|
||||
ansible-core's configuration manager.
|
||||
# env:
|
||||
# - name: ANSIBLE_DOCKER_EXTRA_ENV
|
||||
# ini:
|
||||
# - key: extra_env
|
||||
# section: docker_connection
|
||||
# ansible-core's config manager does NOT support converting JSON strings (or other things) to dictionaries,
|
||||
# it only accepts actual dictionaries (which don't happen to come from env and ini vars). So there's no way
|
||||
# to actually provide this parameter from env and ini sources... :-(
|
||||
vars:
|
||||
- name: ansible_docker_extra_env
|
||||
type: dict
|
||||
version_added: 3.12.0
|
||||
'''
|
||||
|
||||
import fcntl
|
||||
@ -83,8 +100,9 @@ import os.path
|
||||
import subprocess
|
||||
import re
|
||||
|
||||
from ansible.errors import AnsibleError, AnsibleFileNotFound
|
||||
from ansible.errors import AnsibleError, AnsibleFileNotFound, AnsibleConnectionFailure
|
||||
from ansible.module_utils.six.moves import shlex_quote
|
||||
from ansible.module_utils.six import string_types
|
||||
from ansible.module_utils.common.process import get_bin_path
|
||||
from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text
|
||||
from ansible.plugins.connection import ConnectionBase, BUFSIZE
|
||||
@ -210,6 +228,17 @@ class Connection(ConnectionBase):
|
||||
if self.remote_user is not None:
|
||||
local_cmd += [b'-u', self.remote_user]
|
||||
|
||||
if self.get_option('extra_env'):
|
||||
for k, v in self.get_option('extra_env').items():
|
||||
for val, what in ((k, 'Key'), (v, 'Value')):
|
||||
if not isinstance(val, string_types):
|
||||
raise AnsibleConnectionFailure(
|
||||
'Non-string {0} found for extra_env option. Ambiguous env options must be '
|
||||
'wrapped in quotes to avoid them being interpreted. {1}: {2!r}'
|
||||
.format(what.lower(), what, val)
|
||||
)
|
||||
local_cmd += [b'-e', b'%s=%s' % (to_bytes(k, errors='surrogate_or_strict'), to_bytes(v, errors='surrogate_or_strict'))]
|
||||
|
||||
# -i is needed to keep stdin open which allows pipelining to work
|
||||
local_cmd += [b'-i', self.get_option('remote_addr')] + cmd
|
||||
|
||||
|
||||
@ -69,6 +69,23 @@ options:
|
||||
cli:
|
||||
- name: timeout
|
||||
type: integer
|
||||
extra_env:
|
||||
description:
|
||||
- Provide extra environment variables to set when running commands in the Docker container.
|
||||
- This option can currently only be provided as Ansible variables due to limitations of
|
||||
ansible-core's configuration manager.
|
||||
# env:
|
||||
# - name: ANSIBLE_DOCKER_EXTRA_ENV
|
||||
# ini:
|
||||
# - key: extra_env
|
||||
# section: docker_connection
|
||||
# ansible-core's config manager does NOT support converting JSON strings (or other things) to dictionaries,
|
||||
# it only accepts actual dictionaries (which don't happen to come from env and ini vars). So there's no way
|
||||
# to actually provide this parameter from env and ini sources... :-(
|
||||
vars:
|
||||
- name: ansible_docker_extra_env
|
||||
type: dict
|
||||
version_added: 3.12.0
|
||||
'''
|
||||
|
||||
import os
|
||||
@ -76,6 +93,7 @@ import os.path
|
||||
|
||||
from ansible.errors import AnsibleFileNotFound, AnsibleConnectionFailure
|
||||
from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text
|
||||
from ansible.module_utils.six import string_types
|
||||
from ansible.plugins.connection import ConnectionBase
|
||||
from ansible.utils.display import Display
|
||||
|
||||
@ -203,6 +221,18 @@ class Connection(ConnectionBase):
|
||||
if 'detachKeys' in self.client._general_configs:
|
||||
data['detachKeys'] = self.client._general_configs['detachKeys']
|
||||
|
||||
if self.get_option('extra_env'):
|
||||
data['Env'] = []
|
||||
for k, v in self.get_option('extra_env').items():
|
||||
for val, what in ((k, 'Key'), (v, 'Value')):
|
||||
if not isinstance(val, string_types):
|
||||
raise AnsibleConnectionFailure(
|
||||
'Non-string {0} found for extra_env option. Ambiguous env options must be '
|
||||
'wrapped in quotes to avoid them being interpreted. {1}: {2!r}'
|
||||
.format(what.lower(), what, val)
|
||||
)
|
||||
data['Env'].append(u'{0}={1}'.format(to_text(k, errors='surrogate_or_strict'), to_text(v, errors='surrogate_or_strict')))
|
||||
|
||||
exec_data = self._call_client(lambda: self.client.post_json_to_json('/containers/{0}/exec', self.get_option('remote_addr'), data=data))
|
||||
exec_id = exec_data['Id']
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user