mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
Ziploader subprocess.Popen
* Run the module as a script from the wrapper instead of executing in the same process. Fixes cornercases where the module could potentially be executed twice if we import and then run the main() function without calling sys.exit() somewhere. Also fixes problem with concurrent.futures() hanging. Not sure precisely how this is being triggered but it is related to invoking the main() function outside of an if __name__ == '__main__' conditional. * Fix for python-2.6
This commit is contained in:
parent
8d46bcaa65
commit
647123ee18
1 changed files with 42 additions and 10 deletions
|
@ -61,6 +61,12 @@ import os
|
|||
import sys
|
||||
import base64
|
||||
import tempfile
|
||||
import subprocess
|
||||
|
||||
if sys.version_info < (3,):
|
||||
bytes = str
|
||||
else:
|
||||
unicode = str
|
||||
|
||||
ZIPDATA = """%(zipdata)s"""
|
||||
|
||||
|
@ -93,9 +99,20 @@ def debug(command, zipped_mod):
|
|||
f.close()
|
||||
print('Module expanded into: %%s' %% os.path.join(basedir, 'ansible'))
|
||||
elif command == 'execute':
|
||||
sys.path.insert(0, basedir)
|
||||
from ansible.module_exec.%(ansible_module)s.__main__ import main
|
||||
main()
|
||||
pythonpath = os.environ.get('PYTHONPATH')
|
||||
if pythonpath:
|
||||
os.environ['PYTHONPATH'] = ':'.join((basedir, pythonpath))
|
||||
else:
|
||||
os.environ['PYTHONPATH'] = basedir
|
||||
p = subprocess.Popen(['%(interpreter)s', '-m', 'ansible.module_exec.%(ansible_module)s.__main__'], env=os.environ, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
(stdout, stderr) = p.communicate()
|
||||
if not isinstance(stderr, (bytes, unicode)):
|
||||
stderr = stderr.read()
|
||||
if not isinstance(stdout, (bytes, unicode)):
|
||||
stdout = stdout.read()
|
||||
sys.stderr.write(stderr)
|
||||
sys.stdout.write(stdout)
|
||||
sys.exit(p.returncode)
|
||||
|
||||
os.environ['ANSIBLE_MODULE_ARGS'] = %(args)s
|
||||
os.environ['ANSIBLE_MODULE_CONSTANTS'] = %(constants)s
|
||||
|
@ -106,9 +123,21 @@ try:
|
|||
if len(sys.argv) == 2:
|
||||
debug(sys.argv[1], temp_path)
|
||||
else:
|
||||
sys.path.insert(0, temp_path)
|
||||
from ansible.module_exec.%(ansible_module)s.__main__ import main
|
||||
main()
|
||||
pythonpath = os.environ.get('PYTHONPATH')
|
||||
if pythonpath:
|
||||
os.environ['PYTHONPATH'] = ':'.join((temp_path, pythonpath))
|
||||
else:
|
||||
os.environ['PYTHONPATH'] = temp_path
|
||||
p = subprocess.Popen(['%(interpreter)s', '-m', 'ansible.module_exec.%(ansible_module)s.__main__'], env=os.environ, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
(stdout, stderr) = p.communicate()
|
||||
if not isinstance(stderr, (bytes, unicode)):
|
||||
stderr = stderr.read()
|
||||
if not isinstance(stdout, (bytes, unicode)):
|
||||
stdout = stdout.read()
|
||||
sys.stderr.write(stderr)
|
||||
sys.stdout.write(stdout)
|
||||
sys.exit(p.returncode)
|
||||
|
||||
finally:
|
||||
try:
|
||||
os.close(temp_fd)
|
||||
|
@ -150,7 +179,7 @@ def _get_shebang(interpreter, task_vars, args=tuple()):
|
|||
interpreter_config = u'ansible_%s_interpreter' % os.path.basename(interpreter)
|
||||
|
||||
if interpreter_config not in task_vars:
|
||||
return None
|
||||
return (None, interpreter)
|
||||
|
||||
interpreter = task_vars[interpreter_config]
|
||||
shebang = u'#!' + interpreter
|
||||
|
@ -158,7 +187,7 @@ def _get_shebang(interpreter, task_vars, args=tuple()):
|
|||
if args:
|
||||
shebang = shebang + u' ' + u' '.join(args)
|
||||
|
||||
return shebang
|
||||
return (shebang, interpreter)
|
||||
|
||||
def _get_facility(task_vars):
|
||||
facility = C.DEFAULT_SYSLOG_FACILITY
|
||||
|
@ -247,13 +276,16 @@ def _find_snippet_imports(module_name, module_data, module_path, module_args, ta
|
|||
|
||||
zf.writestr('ansible/module_exec/%s/__main__.py' % module_name, b"\n".join(final_data))
|
||||
zf.close()
|
||||
shebang = _get_shebang(u'/usr/bin/python', task_vars) or u'#!/usr/bin/python'
|
||||
shebang, interpreter = _get_shebang(u'/usr/bin/python', task_vars)
|
||||
if shebang is None:
|
||||
shebang = u'#!/usr/bin/python'
|
||||
output.write(to_bytes(STRIPPED_ZIPLOADER_TEMPLATE % dict(
|
||||
zipdata=base64.b64encode(zipoutput.getvalue()),
|
||||
ansible_module=module_name,
|
||||
args=python_repred_args,
|
||||
constants=python_repred_constants,
|
||||
shebang=shebang,
|
||||
interpreter=interpreter,
|
||||
)))
|
||||
module_data = output.getvalue()
|
||||
|
||||
|
@ -356,7 +388,7 @@ def modify_module(module_name, module_path, module_args, task_vars=dict(), modul
|
|||
interpreter = args[0]
|
||||
interpreter = to_bytes(interpreter)
|
||||
|
||||
new_shebang = to_bytes(_get_shebang(interpreter, task_vars, args[1:]), errors='strict', nonstring='passthru')
|
||||
new_shebang = to_bytes(_get_shebang(interpreter, task_vars, args[1:])[0], errors='strict', nonstring='passthru')
|
||||
if new_shebang:
|
||||
lines[0] = shebang = new_shebang
|
||||
|
||||
|
|
Loading…
Reference in a new issue