Fix shebang. shebang and interpreter path weren't being templated (#33698)

* Fix shebang.  shebang and interpreter path weren't being templated

Fixes #18665
Fixes #33696
This commit is contained in:
Toshio Kuratomi 2017-12-08 06:59:24 -08:00 committed by GitHub
parent c8a5e689e3
commit b455901904
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 34 additions and 22 deletions

View file

@ -435,7 +435,7 @@ def _slurp(path):
return data return data
def _get_shebang(interpreter, task_vars, args=tuple()): def _get_shebang(interpreter, task_vars, templar, args=tuple()):
""" """
Note not stellar API: Note not stellar API:
Returns None instead of always returning a shebang line. Doing it this Returns None instead of always returning a shebang line. Doing it this
@ -448,7 +448,7 @@ def _get_shebang(interpreter, task_vars, args=tuple()):
if interpreter_config not in task_vars: if interpreter_config not in task_vars:
return (None, interpreter) return (None, interpreter)
interpreter = task_vars[interpreter_config].strip() interpreter = templar.template(task_vars[interpreter_config].strip())
shebang = u'#!' + interpreter shebang = u'#!' + interpreter
if args: if args:
@ -598,7 +598,7 @@ def _is_binary(b_module_data):
return bool(start.translate(None, textchars)) return bool(start.translate(None, textchars))
def _find_module_utils(module_name, b_module_data, module_path, module_args, task_vars, module_compression, async_timeout, become, def _find_module_utils(module_name, b_module_data, module_path, module_args, task_vars, templar, module_compression, async_timeout, become,
become_method, become_user, become_password, environment): become_method, become_user, become_password, environment):
""" """
Given the source of the module, convert it to a Jinja2 template to insert Given the source of the module, convert it to a Jinja2 template to insert
@ -732,7 +732,7 @@ def _find_module_utils(module_name, b_module_data, module_path, module_args, tas
'Look at traceback for that process for debugging information.') 'Look at traceback for that process for debugging information.')
zipdata = to_text(zipdata, errors='surrogate_or_strict') zipdata = to_text(zipdata, errors='surrogate_or_strict')
shebang, interpreter = _get_shebang(u'/usr/bin/python', task_vars) shebang, interpreter = _get_shebang(u'/usr/bin/python', task_vars, templar)
if shebang is None: if shebang is None:
shebang = u'#!/usr/bin/python' shebang = u'#!/usr/bin/python'
@ -871,7 +871,7 @@ def _find_module_utils(module_name, b_module_data, module_path, module_args, tas
return (b_module_data, module_style, shebang) return (b_module_data, module_style, shebang)
def modify_module(module_name, module_path, module_args, task_vars=None, module_compression='ZIP_STORED', async_timeout=0, become=False, def modify_module(module_name, module_path, module_args, task_vars=None, templar=None, module_compression='ZIP_STORED', async_timeout=0, become=False,
become_method=None, become_user=None, become_password=None, environment=None): become_method=None, become_user=None, become_password=None, environment=None):
""" """
Used to insert chunks of code into modules before transfer rather than Used to insert chunks of code into modules before transfer rather than
@ -901,7 +901,7 @@ def modify_module(module_name, module_path, module_args, task_vars=None, module_
# read in the module source # read in the module source
b_module_data = f.read() b_module_data = f.read()
(b_module_data, module_style, shebang) = _find_module_utils(module_name, b_module_data, module_path, module_args, task_vars, module_compression, (b_module_data, module_style, shebang) = _find_module_utils(module_name, b_module_data, module_path, module_args, task_vars, templar, module_compression,
async_timeout=async_timeout, become=become, become_method=become_method, async_timeout=async_timeout, become=become, become_method=become_method,
become_user=become_user, become_password=become_password, become_user=become_user, become_password=become_password,
environment=environment) environment=environment)
@ -916,7 +916,7 @@ def modify_module(module_name, module_path, module_args, task_vars=None, module_
interpreter = args[0] interpreter = args[0]
interpreter = to_bytes(interpreter) interpreter = to_bytes(interpreter)
new_shebang = to_bytes(_get_shebang(interpreter, task_vars, args[1:])[0], errors='surrogate_or_strict', nonstring='passthru') new_shebang = to_bytes(_get_shebang(interpreter, task_vars, templar, args[1:])[0], errors='surrogate_or_strict', nonstring='passthru')
if new_shebang: if new_shebang:
lines[0] = shebang = new_shebang lines[0] = shebang = new_shebang

View file

@ -158,9 +158,12 @@ class ActionBase(with_metaclass(ABCMeta, object)):
self._compute_environment_string(final_environment) self._compute_environment_string(final_environment)
(module_data, module_style, module_shebang) = modify_module(module_name, module_path, module_args, (module_data, module_style, module_shebang) = modify_module(module_name, module_path, module_args,
task_vars=task_vars, module_compression=self._play_context.module_compression, task_vars=task_vars, templar=self._templar,
async_timeout=self._task.async_val, become=self._play_context.become, module_compression=self._play_context.module_compression,
become_method=self._play_context.become_method, become_user=self._play_context.become_user, async_timeout=self._task.async_val,
become=self._play_context.become,
become_method=self._play_context.become_method,
become_user=self._play_context.become_user,
become_password=self._play_context.become_pass, become_password=self._play_context.become_pass,
environment=final_environment) environment=final_environment)

View file

@ -93,26 +93,35 @@ class TestSlurp(object):
assert amc._slurp('some_file') == '#!/usr/bin/python\ndef test(args):\nprint("hi")\n' assert amc._slurp('some_file') == '#!/usr/bin/python\ndef test(args):\nprint("hi")\n'
@pytest.fixture
def templar():
class FakeTemplar(object):
def template(self, template_string, *args, **kwargs):
return template_string
return FakeTemplar()
class TestGetShebang(object): class TestGetShebang(object):
"""Note: We may want to change the API of this function in the future. It isn't a great API""" """Note: We may want to change the API of this function in the future. It isn't a great API"""
def test_no_interpreter_set(self): def test_no_interpreter_set(self, templar):
assert amc._get_shebang(u'/usr/bin/python', {}) == (None, u'/usr/bin/python') assert amc._get_shebang(u'/usr/bin/python', {}, templar) == (None, u'/usr/bin/python')
def test_non_python_interpreter(self): def test_non_python_interpreter(self, templar):
assert amc._get_shebang(u'/usr/bin/ruby', {}) == (None, u'/usr/bin/ruby') assert amc._get_shebang(u'/usr/bin/ruby', {}, templar) == (None, u'/usr/bin/ruby')
def test_interpreter_set_in_task_vars(self): def test_interpreter_set_in_task_vars(self, templar):
assert amc._get_shebang(u'/usr/bin/python', {u'ansible_python_interpreter': u'/usr/bin/pypy'}) == \ assert amc._get_shebang(u'/usr/bin/python', {u'ansible_python_interpreter': u'/usr/bin/pypy'}, templar) == \
(u'#!/usr/bin/pypy', u'/usr/bin/pypy') (u'#!/usr/bin/pypy', u'/usr/bin/pypy')
def test_non_python_interpreter_in_task_vars(self): def test_non_python_interpreter_in_task_vars(self, templar):
assert amc._get_shebang(u'/usr/bin/ruby', {u'ansible_ruby_interpreter': u'/usr/local/bin/ruby'}) == \ assert amc._get_shebang(u'/usr/bin/ruby', {u'ansible_ruby_interpreter': u'/usr/local/bin/ruby'}, templar) == \
(u'#!/usr/local/bin/ruby', u'/usr/local/bin/ruby') (u'#!/usr/local/bin/ruby', u'/usr/local/bin/ruby')
def test_with_args(self): def test_with_args(self, templar):
assert amc._get_shebang(u'/usr/bin/python', {u'ansible_python_interpreter': u'/usr/bin/python3'}, args=('-tt', '-OO')) == \ assert amc._get_shebang(u'/usr/bin/python', {u'ansible_python_interpreter': u'/usr/bin/python3'}, templar, args=('-tt', '-OO')) == \
(u'#!/usr/bin/python3 -tt -OO', u'/usr/bin/python3') (u'#!/usr/bin/python3 -tt -OO', u'/usr/bin/python3')
def test_python_via_env(self): def test_python_via_env(self, templar):
assert amc._get_shebang(u'/usr/bin/python', {u'ansible_python_interpreter': u'/usr/bin/env python'}) == \ assert amc._get_shebang(u'/usr/bin/python', {u'ansible_python_interpreter': u'/usr/bin/env python'}, templar) == \
(u'#!/usr/bin/env python', u'/usr/bin/env python') (u'#!/usr/bin/env python', u'/usr/bin/env python')