Skip to content

Commit

Permalink
Allow to pass extra environment variables when running commands.
Browse files Browse the repository at this point in the history
  • Loading branch information
felixfontein committed Jul 25, 2024
1 parent 2ddadf1 commit c625e54
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 1 deletion.
2 changes: 2 additions & 0 deletions changelogs/fragments/940-connection-env.yml
Original file line number Diff line number Diff line change
@@ -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)."
26 changes: 25 additions & 1 deletion plugins/connection/docker.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,18 @@
cli:
- name: timeout
type: integer
extra_env:
description:
- Provide extra environment variables to set when running commands in the Docker container.
env:
- name: ANSIBLE_DOCKER_EXTRA_ENV
ini:
- key: extra_env
section: docker_connection
vars:
- name: ansible_docker_extra_env
type: dict
version_added: 3.12.0
'''

import fcntl
Expand All @@ -83,8 +95,9 @@
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
Expand Down Expand Up @@ -210,6 +223,17 @@ def _build_exec_cmd(self, cmd):
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'{0}={1}'.format(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

Expand Down
25 changes: 25 additions & 0 deletions plugins/connection/docker_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,26 @@
cli:
- name: timeout
type: integer
extra_env:
description:
- Provide extra environment variables to set when running commands in the Docker container.
env:
- name: ANSIBLE_DOCKER_EXTRA_ENV
ini:
- key: extra_env
section: docker_connection
vars:
- name: ansible_docker_extra_env
type: dict
version_added: 3.12.0
'''

import os
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

Expand Down Expand Up @@ -203,6 +216,18 @@ def exec_command(self, cmd, in_data=None, sudoable=False):
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']

Expand Down

0 comments on commit c625e54

Please sign in to comment.