Project

General

Profile

Actions

Question #3661

closed

Need help with new technique: Commands Management

Added by Dennis Cabooter over 11 years ago. Updated almost 7 years ago.

Status:
Resolved
Priority:
N/A
Assignee:
-
Category:
Techniques
Regression:

Description

I've started to create a new technique called Commands Management:

- Define a (shell) command to run. E.g. /usr/bin/getent passwd $username
- Define the exit status which you should get back to run the second command. E.g. if set to 0, the next command will only run if the previous command has exit status 0
- Define a (shell) command to run if the first command exits with the defined status. E.g. /usr/bin/mail -s "$username does exist" $recipient

This is where I came up with untill now. From this point on I don't know how to finish this technique.

- /var/rudder/configuration-repository/techniques/systemSettings/process/commandsManagement/1.0/metadata.xml

<TECHNIQUE name="Commands Management">
  <DESCRIPTION>Run a command based on the exit status of another command</DESCRIPTION>
  <COMPATIBLE>
    <OS version=">= 4 (Etch)">Debian</OS>
    <OS version=">= 4 (Nahant)">RHEL / CentOS</OS>
    <OS version=">= 10 SP1 (Agama Lizard)">SuSE LES / DES / OpenSuSE</OS>
    <AGENT version=">= 3.2">cfengine-community</AGENT>
  </COMPATIBLE>

  <MULTIINSTANCE>true</MULTIINSTANCE>
  <BUNDLES>
    <NAME>commands_management</NAME>
  </BUNDLES>

  <TMLS>
    <TML name="commandsManagement"/>
  </TMLS>

  <TRACKINGVARIABLE>
    <SAMESIZEAS>COMMAND_EXECUTE_FIRST</SAMESIZEAS>
  </TRACKINGVARIABLE>

  <SECTIONS>
    <SECTION name="Command to execute first" multivalued="true">

    <INPUT>
        <NAME>COMMAND_EXECUTE_FIRST</NAME>
        <DESCRIPTION>Command to execute first</DESCRIPTION>
    </INPUT>

    <SECTION name="Command to execute next"  multivalued="false"  component="true" componentKey="COMMAND_EXECUTE_FIRST">
      <INPUT>
        <NAME>EXIT_STATUS</NAME>
        <DESCRIPTION>The exit status to run the second command should be</DESCRIPTION>
        <CONSTRAINT>
          <TYPE>integer</TYPE>
          <DEFAULT>0</DEFAULT>
        </CONSTRAINT>
      </INPUT>

      <INPUT>
        <NAME>COMMAND_EXECUTE_NEXT</NAME>
        <DESCRIPTION>Command to execute next</DESCRIPTION>
      </INPUT>
    </SECTION>
    </SECTION>
  </SECTIONS>
</TECHNIQUE>

- /var/rudder/configuration-repository/techniques/systemSettings/process/commandsManagement/1.0/commandsManagement.st

bundle agent commands_management
{
  commands:
    "&COMMAND_EXECUTE_FIRST&" 
    contain => in_shell,
    classes => get_exit_status;

    execute_next::
      "&COMMAND_EXECUTE_NEXT&" 
      contain => in_shell;
}

body classes get_exit_status
{
  kept_returncodes => { "&EXIT_STATUS&" };
  promise_kept => { "execute_next" };
}
Actions #1

Updated by Nicolas PERRON over 11 years ago

  • Project changed from Rudder to 24

This is a great news to know that you make some Techniques by yourself ! Furthermore, you seems to be on the good way to create yours !

Here some counsels to continue your work:
  • The Stringtemplate variables should be used to initialize a CFEngine variable. This is not an obligation since the Stringtemplate variables are not multivalued except for the TRACKINGKEY (as this Technique is multiinstance).
    Example:
    [...]
          &TRACKINGKEY:{directiveId |"commands_management[&i&][uuid]" string => "&directiveId&";
    }&
    [...]
    
  • The Technique will probably do what you want but you will not have any reporting to know it.
  • On the command you want ot execute, you should use the body class rudder_common_classes (defined in techniques/system/common/1.0/rudder_stdlib.st) which will define the classes to know if the command has been launched or not.
  • You will need a reporting to know if the second command should not be launched (with the class !execute_next) then you will cover all the cases and in the WebUI, you will not get a 'No Answer' state in case of second command to not be executed
  • To get more informations about the use of Reporting, check this link out: http://www.rudder-project.org/foswiki/Development/ReportsInTechniques
Actions #2

Updated by Dennis Cabooter over 11 years ago

The first point I don't really understand.. About the reporting - I did not start to work on that. I think I'm still missing things in the technique to make it a useful one.

Actions #3

Updated by Nicolas PERRON over 11 years ago

Dennis Cabooter wrote:

The first point I don't really understand.. About the reporting - I did not start to work on that. I think I'm still missing things in the technique to make it a useful one.

The TRACKINGKEY is an auto generated UUID by Rudder for each Directive. Then, with this, it will be possible to link the reporting to the good Directive.

Example:
  • Technique A is not multiinstance
  • Technique B is multiinstance
  • Directives A1 and A2 based on Technique A
  • Directive B1 and B2 based on Technique B
  • Rule R will include A1, A2, B1 and B2 into the Group G
On the nodes of the Group G, they will have two generated promises:
  • A promise Pa based on A with only A1 or A2 (based on the priority of A1 and A2)
  • A promise Pb based on B with a concatenation of B1 and B2

On the promise Pa, the TRACKINGKEY will contain R-UUID@A1-UUID@R-Version or R-UUID@A2-UUID@R-Version then the reporting:

@@Policy@@Type@@&TRACKINGKEY&@@Component@@Key@@ExecutionTimeStamp##NodeId@#HumanReadableMessage

Will be interpreted as:
@@Policy@@Type@@R-UUID@@A1-UUID@@R-Version@@Component@@Key@@ExecutionTimeStamp##NodeId@#HumanReadableMessage

or
@@Policy@@Type@@R-UUID@@A2-UUID@@R-Version@@Component@@Key@@ExecutionTimeStamp##NodeId@#HumanReadableMessage

Which is good.

On the other hand, the promise Pb will have a TRACKINGKEY wich will contain R-UUID@B1-UUID@R-VersionR-UUID@B2-UUID@R-Version. Then the the reporting:

@@Policy@@Type@@&TRACKINGKEY&@@Component@@Key@@ExecutionTimeStamp##NodeId@#HumanReadableMessage

Will be interpreted as:
@@Policy@@Type@@R-UUID@@B1-UUID@@R-VersionR-UUID@@B2-UUID@@R-Version@@Component@@Key@@ExecutionTimeStamp##NodeId@#HumanReadableMessage

Which is wrong.

The solution is to use a CFEngine variable:

[...]
      &TRACKINGKEY:{directiveId |"commands_management[&i&][uuid]" string => "&directiveId&";
}&
[...]

and to use it in the reporting:

@@Policy@@Type@@commands_management[&i&][uuid]@@Component@@Key@@ExecutionTimeStamp##NodeId@#HumanReadableMessage

The CFEngine will automagically convert it into:

@@Policy@@Type@@R-UUID@@B1-UUID@@R-Version@@Component@@Key@@ExecutionTimeStamp##NodeId@#HumanReadableMessage
@@Policy@@Type@@R-UUID@@B2-UUID@@R-Version@@Component@@Key@@ExecutionTimeStamp##NodeId@#HumanReadableMessage

Actions #4

Updated by Benoît PECCATTE almost 10 years ago

  • Project changed from 24 to Rudder
  • Category set to Techniques
Actions #5

Updated by Benoît PECCATTE over 8 years ago

  • Target version set to Ideas (not version specific)
Actions #6

Updated by Benoît PECCATTE almost 7 years ago

  • Tracker changed from User story to Question
  • Status changed from New to Resolved

This seems to be a question answered a long time ago

Actions

Also available in: Atom PDF