diff --git a/lib/ansible/runner.rb b/lib/ansible/runner.rb index 432df502f18..d2933ae1172 100644 --- a/lib/ansible/runner.rb +++ b/lib/ansible/runner.rb @@ -24,13 +24,30 @@ def run_queue(env_vars, extra_vars, playbook_path, user_id, queue_opts) private def run_via_cli(env_vars, extra_vars, playbook_path) - result = AwesomeSpawn.run!(ansible_command, :env => env_vars, :params => [{:extra_vars => JSON.dump(extra_vars)}, playbook_path]) - JSON.parse(result.output) + Dir.mktmpdir("ansible-runner") do |base_dir| + Dir.mkdir(File.join(base_dir, 'project')) # without this, there is a silent fail of the ansible-runner command see https://github.com/ansible/ansible-runner/issues/88 + + result = AwesomeSpawn.run!(ansible_command(base_dir), + :env => env_vars, + :params => [{:cmdline => "--extra-vars '#{JSON.dump(extra_vars)}'", + :playbook => playbook_path}]) + + Ansible::Runner::Response.new(:return_code => return_code(base_dir), + :stdout => result.output, + :stderr => result.error) + end + end + + def return_code(base_dir) + File.read(File.join(base_dir, "artifacts/result/rc")).to_i + rescue + _log.warn("Couldn't find ansible-runner return code") + 1 end - def ansible_command + def ansible_command(base_dir) # TODO add possibility to use custom path, e.g. from virtualenv - "ansible-playbook" + "ansible-runner run #{base_dir} --json -i result" end end end diff --git a/lib/ansible/runner/response.rb b/lib/ansible/runner/response.rb new file mode 100644 index 00000000000..3323ae429b3 --- /dev/null +++ b/lib/ansible/runner/response.rb @@ -0,0 +1,36 @@ +module Ansible + class Runner + class Response + include Vmdb::Logging + + attr_reader :return_code, :stdout, :stderr, :parsed_stdout + + def initialize(return_code:, stdout:, stderr:) + @return_code = return_code + @stdout = stdout + @parsed_stdout = parse_stdout(stdout) + @stderr = stderr + end + + private + + def parse_stdout(stdout) + parsed_stdout = [] + + # output is JSON per new line + stdout.each_line do |line| + # TODO(lsmola) we can remove exception handling when this is fixed + # https://github.com/ansible/ansible-runner/issues/89#issuecomment-404236832 , so it fails early if there is + # a non json line + begin + parsed_stdout << JSON.parse(line) + rescue => e + _log.warn("Couldn't parse JSON from: #{e}") + end + end + + parsed_stdout + end + end + end +end