mirror of
https://github.com/ansible-collections/community.docker.git
synced 2025-12-16 11:58:43 +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:
|
cli:
|
||||||
- name: timeout
|
- name: timeout
|
||||||
type: integer
|
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
|
import fcntl
|
||||||
@ -83,8 +100,9 @@ import os.path
|
|||||||
import subprocess
|
import subprocess
|
||||||
import re
|
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.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.process import get_bin_path
|
||||||
from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text
|
from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text
|
||||||
from ansible.plugins.connection import ConnectionBase, BUFSIZE
|
from ansible.plugins.connection import ConnectionBase, BUFSIZE
|
||||||
@ -210,6 +228,17 @@ class Connection(ConnectionBase):
|
|||||||
if self.remote_user is not None:
|
if self.remote_user is not None:
|
||||||
local_cmd += [b'-u', self.remote_user]
|
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
|
# -i is needed to keep stdin open which allows pipelining to work
|
||||||
local_cmd += [b'-i', self.get_option('remote_addr')] + cmd
|
local_cmd += [b'-i', self.get_option('remote_addr')] + cmd
|
||||||
|
|
||||||
|
|||||||
@ -69,6 +69,23 @@ options:
|
|||||||
cli:
|
cli:
|
||||||
- name: timeout
|
- name: timeout
|
||||||
type: integer
|
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
|
import os
|
||||||
@ -76,6 +93,7 @@ import os.path
|
|||||||
|
|
||||||
from ansible.errors import AnsibleFileNotFound, AnsibleConnectionFailure
|
from ansible.errors import AnsibleFileNotFound, AnsibleConnectionFailure
|
||||||
from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text
|
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.plugins.connection import ConnectionBase
|
||||||
from ansible.utils.display import Display
|
from ansible.utils.display import Display
|
||||||
|
|
||||||
@ -203,6 +221,18 @@ class Connection(ConnectionBase):
|
|||||||
if 'detachKeys' in self.client._general_configs:
|
if 'detachKeys' in self.client._general_configs:
|
||||||
data['detachKeys'] = self.client._general_configs['detachKeys']
|
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_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']
|
exec_id = exec_data['Id']
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user