Guidelines

This site is for tech Q&A. Please keep your posts focused on the subject at hand.

Ask one question at a time. Don't conflate multiple problems into a single question.

Make sure to include all relevant information in your posts. Try to avoid linking to external sites.

Links to documentation are fine, but in addition you should also quote the relevant parts in your posts.

0 votes
144 views
144 views

Bolt task allow for returning structured output per the documentation:

To return structured data from your task, print only a single JSON object to stdout in your task.

#!/usr/bin/env python

import json
import sys
minor = sys.version_info
result = { "major": sys.version_info.major, "minor": sys.version_info.minor }
json.dump(result, sys.stdout)

Which in my Ruby task would look like this:

#!/usr/bin/env ruby

require 'json'
major, minor, patch = RUBY_VERSION.split('.')
result = { 'major' => major, 'minor' => minor }
puts result.to_json

Which works, and I can access the returned data as a structured value in the caller like this:

$data = run_task('foo::bar', 'localhost', {'_catch_errors'=>true}).first.value()

However, if I return an array from the task

require 'json'
result = [ '192.168.1.1', '192.168.1.2' ]
puts result.to_json

that doesn't seem to work, because when I output $data it seems to be "regular" output instead of structured data I expected:

{_output => ["192.168.1.1","192.168.1.2"]
}

Wrapping the array in curly brackets doesn't help either.

in Scripting
by (100)
1 6 20
edit history

Please log in or register to answer this question.

1 Answer

0 votes
 

This seems to be at least a gotcha, if not a bug, in the way Bolt handles JSON output from a task. In order to have Bolt turn task output into structured data you must return a single JSON object. If your task output is an array, assign that array to a property of that object:

result = {
  'baz' => [ '192.168.1.1', '192.168.1.2' ],
}
puts result.to_json

That will give you the result as a data structure, and you can get the array via the property you specified in the task (baz in the above example):

$data = run_task('foo::bar', 'localhost', {'_catch_errors'=>true}).first.value()
$value = $data['baz']

Bolt will not interpret your output correctly if it's a bare array, even though that is valid JSON.

Putting curly brackets around the JSON string from your array doesn't work because that isn't valid JSON in the first place (you can check with jq, e.g. echo '{["foo", "bar"]}' | jq -r .).


edited by
by (100)
1 6 20
edit history
...