Get Started Writing Robust Tasks
Lucy Wyman, Software Engineer - Bolt https://slides.lucywyman.me/writing-tasks.html
Lucy Wyman, Software Engineer - Bolt https://slides.lucywyman.me/writing-tasks.html
# bash.sh
echo "Hello my name is $PT_name"
# ruby.rb
params = JSON.parse(STDIN.read)
puts "Hello my name is #{params['name']}"
# powershell.ps1
param(
[Parameter(Mandatory = $true)]
[String]
$Name
)
Write-Host @"Hello my name is $Name"
result[:_error]
begin
params = JSON.parse(STDIN.read)
result = {}
result['result'] = params['dividend'] / params['divisor']
rescue ZeroDivisionError
result[:_error] = { msg: "Cannot divide by zero",
kind: "puppetlabs-example_modules/dividebyzero",
details: { divisor: divisor },
}
Invoke-Expression
or Add-Type
with user input.Resolve-Path
to verify that the path doesn't go outside the locations you expect the task to accessdescription
(duh)input_method
private
or supports_noop
if applicable{
"description": "Install the Puppet 5 agent package",
"parameters": {
"version": {
"description": "The version of puppet-agent to install",
"type": "Optional[String]"
}
},
"implementations": [
{"name": "install_shell.sh", "requirements": ["shell"]},
{"name": "install_powershell.ps1", "requirements": ["powershell"]}
]
}
Specify other files the task relies on, from module endpoints of any module in the modulepath
Path consists of
- the module name
- one of
lib
,files
, ortasks
for the directory within the module- the remaining path to a file or directory; directories must include a trailing slash /
{
"implementations": [
{"name": "sql_linux.sh", "requirements": ["shell"],
"files": ["mymodule/files/lib.sh"]},
{"name": "sql_windows.ps1", "requirements": ["powershell"],
"files": ["mymodule/files/lib.ps1"]}
],
"files": ["othermodule/files/emojis/"]
}
BoltSpec
ruby library to run bolt tasks, commands, and
scriptsrun_task
, run_plan
, run_command
, run_script
Result
and ResultSet
matchersinclude Bolt::Run
describe 'run_task' do
it 'should run a task on a node' do
result = run_task('sample::echo', 'ssh', config: config_data,
inventory: inventory_data)
expect(result[0]['status']).to eq('success')
end
end
{
"files": ["ruby_task_helper/lib/task_helper.rb"],
"input_method": "stdin"
}
#!/usr/bin/env ruby
require_relative '../../ruby_task_helper/lib/task_helper.rb'
class MyTask < TaskHelper
def task(name: nil, **kwargs)
{ greeting: "Hi, my name is #{name}" }
end
end
MyTask.run if __FILE__ == $0