I'd like to create a Rundeck job that allows to reboot multiple nodes. The target nodes are running with Windows and Linux.
Simply adding a Command step with sudo reboot
or shutdown /r /t 0
wont work, as the command depends on the OS the node is running with.
Is it possible in Rundeck to run a step only on a subset of selected nodes? Perhaps using the tags or other metadata stored for that node as a filter? If not, is it possible to achieve what I want to do, or is there a workaround available?
Example job.xml with both commands defined:
<joblist>
<job>
<defaultTab>nodes</defaultTab>
<description>Restarts the selected target hosts</description>
<dispatch>
<excludePrecedence>true</excludePrecedence>
<keepgoing>true</keepgoing>
<rankOrder>ascending</rankOrder>
<successOnEmptyNodeFilter>false</successOnEmptyNodeFilter>
<threadcount>1</threadcount>
</dispatch>
<executionEnabled>true</executionEnabled>
<group>Service</group>
<id>6d757927-6879-4375-91da-dbd0fcf79c79</id>
<loglevel>INFO</loglevel>
<name>Restart Hosts</name>
<nodeFilterEditable>false</nodeFilterEditable>
<nodefilters>
<filter></filter>
</nodefilters>
<nodesSelectedByDefault>false</nodesSelectedByDefault>
<plugins />
<scheduleEnabled>true</scheduleEnabled>
<sequence keepgoing='true' strategy='parallel'>
<command>
<exec>sudo reboot</exec>
</command>
<command>
<exec>shutdown /r /t 0</exec>
</command>
</sequence>
<uuid>6d757927-6879-4375-91da-dbd0fcf79c79</uuid>
</job>
</joblist>
The best approach to accomplish this is to utilize ruleset strategy (available only on Runbook Automation commercial products). In this method, you can define two alternative script-steps and specify which steps should be executed based on a node attribute value.
Now, on the OSS product, a nice "alternative" is to employ a Windows-based script as error handler if an initial evaluation differs from a specific attribute value (a node tag in my following example).
This example launches the error handler if the "tags" value is different from linux
assuming a Windows box; however, you can use any other attribute, including custom attributes.
- defaultTab: nodes
description: ''
executionEnabled: true
id: 2f5f9101-7ba5-4b3a-ad2f-d9928db209d9
loglevel: INFO
name: Example
nodeFilterEditable: false
nodefilters:
dispatch:
excludePrecedence: true
keepgoing: false
rankOrder: ascending
successOnEmptyNodeFilter: false
threadcount: '1'
filter: 'name: node.*'
nodesSelectedByDefault: true
plugins:
ExecutionLifecycle: {}
scheduleEnabled: true
sequence:
commands:
- autoSecureInput: 'false'
errorhandler:
autoSecureInput: 'false'
fileExtension: .ps1
interpreterArgsQuoted: false
passSecureInput: 'false'
script: Write-Output "any windows command"
scriptInterpreter: pwsh
fileExtension: .sh
interpreterArgsQuoted: false
passSecureInput: 'false'
script: |-
if [ "@node.tags@" = "linux" ]; then
echo "any unix command"
exit 0
else
echo "not unix, trying windows..."
exit 1
fi
scriptInterpreter: /bin/bash
keepgoing: false
strategy: node-first
uuid: 2f5f9101-7ba5-4b3a-ad2f-d9928db209d9
In the example, I chose pwsh
as the PowerShell interpreter because I tested it on PowerShell on Linux machines emulating Windows boxes, but you can also use powershell.exe
in genuine Windows boxes.
<?xml version="1.0" encoding="UTF-8"?>
<project>
<node name="node00" description="Node 00" tags="linux" hostname="192.168.56.20" osArch="amd64" osFamily="unix" osName="Linux" osVersion="5.14.0-284.30.1.el9_2.x86_64" username="vagrant"/>
<node name="node01" description="Node 01" tags="linux" hostname="192.168.56.21" osArch="amd64" osFamily="unix" osName="Linux" osVersion="5.14.0-284.30.1.el9_2.x86_64" username="vagrant"/>
<node name="node02" description="Node 02" tags="windows" hostname="192.168.56.22" osArch="amd64" osFamily="unix" osName="Linux" osVersion="5.14.0-284.30.1.el9_2.x86_64" username="vagrant"/>
</project>
Result. (it "fails" because the error handler is launched only if the job fails, but executes the Windows-specific script)