def on_verbose_finish(res, res_kwargs): if not res: module_name, args, complex_args import pprint disvolvu.message( "ans_module error: %(module_name)s, %(args)s, %(complex_args)s: %(res_kwargs)s" % locals() ) on_finish(res)
def on_verbose_finish(res, res_kwargs): if not res: module_name, args, complex_args import pprint disvolvu.message("ans_module error: %(module_name)s, %(args)s, %(complex_args)s: %(res_kwargs)s" % locals()) on_finish(res)
def run_module(module_name, args, on_finish=None, with_sudo=False, **complex_args): if on_finish: def on_verbose_finish(res, res_kwargs): if not res: module_name, args, complex_args import pprint disvolvu.message( "ans_module error: %(module_name)s, %(args)s, %(complex_args)s: %(res_kwargs)s" % locals() ) on_finish(res) else: on_verbose_finish = None if with_sudo: # Опыт по выполнению команд с привилегиями: # - по умолчанию sudo не трогает stdin, а напрямую связывается с терминалом (tty) для получения пароля; # так что через sudo можно спокойно передавать данные от родительского процесса к дочернему через stdin # опция -S отключает это поведение # - ssh поступает аналогично, только ключа -S у нее нет; зато есть спец. программа sshpass, которая обманывает # ssh, создавая виртуальный терминал # - функционал become_user сделан на основе функции utils.make_become_cmd(), вот вариант: # >>> utils.make_become_cmd('whoami', 'root', '/bin/bash', 'sudo')[0] # /bin/bash -c 'sudo -k && sudo -H -S -p "[sudo via ansible, key=ptxobqqddlurcnjwbxulojkgmqzizdtj] password: "******"'"'echo BECOME-SUCCESS-ptxobqqddlurcnjwbxulojkgmqzizdtj; whoami'"'"'' # ; случайная последовательность (в данном случае ptxobqqddlurcnjwbxulojkgmqzizdtj) используется для # нахождения успеха при вводе пароля - строки echo BECOME-SUCCESS-ptxobqqddlurcnjwbxulojkgmqzizdtj, чтобы # после нее считывать stdout уже целевой программы (whoami) import subprocess import shlex import s_ cmd = "\nsudo %(sys.executable)s %(__file__)s --stdin %(module_name)s" % s_.EvalFormat() print(cmd) process = subprocess.Popen(shlex.split(cmd), stdin=subprocess.PIPE, stdout=subprocess.PIPE) args_struct = {"args": args, "complex_args": complex_args} json.dump(args_struct, process.stdin) # communicate() сам в любом случае закрывает stdin # process.stdin.close() output, unused_err = process.communicate() retcode = process.poll() if on_finish: json_ok = True try: res_kwargs = json.loads(output) except: json_ok = False res_kwargs = None res = retcode == 0 if json_ok: on_verbose_finish(res, res_kwargs) else: disvolvu.message( '''ans_module format error: %(module_name)s, %(args)s, %(complex_args)s: "%(output)s"''' % locals() ) on_finish(res) else: print(output, end="") sys.exit(retcode) else: run_module_do(module_name, args, on_finish=on_verbose_finish, **complex_args)
def run_module(module_name, args, on_finish=None, with_sudo=False, **complex_args): if on_finish: def on_verbose_finish(res, res_kwargs): if not res: module_name, args, complex_args import pprint disvolvu.message("ans_module error: %(module_name)s, %(args)s, %(complex_args)s: %(res_kwargs)s" % locals()) on_finish(res) else: on_verbose_finish = None if with_sudo: # Опыт по выполнению команд с привилегиями: # - по умолчанию sudo не трогает stdin, а напрямую связывается с терминалом (tty) для получения пароля; # так что через sudo можно спокойно передавать данные от родительского процесса к дочернему через stdin # опция -S отключает это поведение # - ssh поступает аналогично, только ключа -S у нее нет; зато есть спец. программа sshpass, которая обманывает # ssh, создавая виртуальный терминал # - функционал become_user сделан на основе функции utils.make_become_cmd(), вот вариант: # >>> utils.make_become_cmd('whoami', 'root', '/bin/bash', 'sudo')[0] # /bin/bash -c 'sudo -k && sudo -H -S -p "[sudo via ansible, key=ptxobqqddlurcnjwbxulojkgmqzizdtj] password: "******"'"'echo BECOME-SUCCESS-ptxobqqddlurcnjwbxulojkgmqzizdtj; whoami'"'"'' # ; случайная последовательность (в данном случае ptxobqqddlurcnjwbxulojkgmqzizdtj) используется для # нахождения успеха при вводе пароля - строки echo BECOME-SUCCESS-ptxobqqddlurcnjwbxulojkgmqzizdtj, чтобы # после нее считывать stdout уже целевой программы (whoami) import subprocess import shlex import s_ cmd = "\nsudo %(sys.executable)s %(__file__)s --stdin %(module_name)s" % s_.EvalFormat() print(cmd) process = subprocess.Popen(shlex.split(cmd), stdin=subprocess.PIPE, stdout=subprocess.PIPE) args_struct = { "args": args, "complex_args": complex_args } json.dump(args_struct, process.stdin) # communicate() сам в любом случае закрывает stdin #process.stdin.close() output, unused_err = process.communicate() retcode = process.poll() if on_finish: json_ok = True try: res_kwargs = json.loads(output) except: json_ok = False res_kwargs = None res = retcode == 0 if json_ok: on_verbose_finish(res, res_kwargs) else: disvolvu.message('''ans_module format error: %(module_name)s, %(args)s, %(complex_args)s: "%(output)s"''' % locals()) on_finish(res) else: print(output, end='') sys.exit(retcode) else: run_module_do(module_name, args, on_finish=on_verbose_finish, **complex_args)