linuxwindowsautomationrundeck

Run different Command-Step depending on OS-type of node


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>

Solution

  • 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)