operation
An “operation” is stored in the form of a directory, containing a manifest.
The manifest describes the operation, which may be a simple command or one or more bash scripts.
This directory may also contain any additional resources, such as binaries and templates. Arbitrarily, these elements are stored in the “resources” directory.
Depending on the type of execution, the operation directory may contain bash scripts.
Create an operation
Use the “cop” command, which will create the operation from an operation template (manifest.yaml and a bash script).
In the “OPSDirectory :
OPS=$(pwd) automation-cli cop "firstoperation" -c "[your comment]
OPS=$(pwd) : Determines the “OPSDirectory”, in this case the current directory.
cop “firstoperation” : Name of operation.
-c: The comment associated with this operation
This process creates, in the “OPS” directory, the ’./operations/firstoperation’ directory containing two files :
[...]│ └──operations│ └── firstoperation│ └── ./run.sh│ └── ./manifest.yaml[...]
Description of manifest.yaml file
This file respects YAML syntax, with attribute values predefined as follows :
Attributes | Mandatory | Type | Description |
---|---|---|---|
comment | non | string | Brief description of the operation. This value appears in the pre-execution report and the operation catalog. I strongly advise you to complete this value, which is why I have made the “-c” parameter mandatory for the “cop” command. |
command ou scripts | oui | string ou Array | more details in this chapter / more details in this chapter |
dependencies | non | Array | more details in this chapter |
when | non | string | more details in this chapter |
limitHosts | non | Array | more details in this chapter |
copyTo | non | Object[] | more details in this chapter |
parameters.required | non | Object | more details in this chapter |
parameters.optional | non | Object | more details in this chaptere |
Attribute details
command
The “command ‘ attribute accepts only one command or a series of simple commands, which can be concatenated with ’&&” and/or “;”.
Example of a “command” type “operation” manifest :
comment: "Une operation du type command"command: 'echo "Hello World" && ls /'
scripts
The “scripts” attribute is a list of file names, located in the operation directory.
Example of a “scripts” type “operation” manifest :
comment: "Une operation du type scripts"scripts: - "run.sh" - "run1.sh"
Scripts are executed in the order specified. Although an operation usually uses only one script, I’ve added this feature, which actually increases the level of complexity.
dependencies
Specify the list of packages on which the operation depends. These packages will be installed before execution.
Example:
curl is not installed by default on the Debian distribution. Your operation calls this command. To make sure the command exists at runtime, indicate the dependency in the manifest :
dependencies: - "curl"
when
String of the form “$key [condition] value”.
The “when” attribute is used to limit the execution of an operation to a condition. For the moment, my needs are limited to checking that an environment variable matches the specified value, or an inventory value.
Ex: I want the operation to be executed only if the environment contains “$REBOOT == 1”.
comment: "firstoperation"script: - "run.sh"when: "$REBOOT==1"
Example: I want the operation to be executed only if the “when” condition referring to an inventory is met: “#inv.attribute == 1”.
comment: "firstoperation"script: - "run.sh"when: "#inv.attribute == 1"
“when” supports the substitution of environment variables, including ‘$host’ which corresponds to the host name of the server on which the operation is executed. Example: “#inv.server.$host.ipaddress == 192.168.1.1”
For the moment, the only conditions supported are “==” (is equal) and “!=” (is different).
I’ve chosen to implement the conditions as bash. A tolerance is applied to the use of spaces, and using the previous example, the tool accepts “$REBOOT == 1”.
limitHosts
Some operations can only be performed on some hosts (hostname/IP address). Specify the list of authorized hosts. Ex: limitHosts: [‘server1’, ‘server2’]. This attribute cannot be overloaded in an operationBook.
Example: I want the operation to run exclusively on hosts “server1” and “server2”.
comment: "firstoperation"script: - "run.sh"limitHosts: ['server1', 'server2']# ORlimitHosts: - 'server1' - 'server2'
copyTo
Sends files to the host. This phase is performed on the host before the shell is executed. You can therefore send templates, which will be prepared and installed by the shell(s) involved in this operation.
List of objects with 3 attributes :
- src: absolute or relative path of local file
- dest: absolute full path to destination
Optional attributes :
- chmod: (string) executes chmod after transfer, unix notation: “755”, “600”, …
(Not yet implemented) :
- chown: (string:string) executes chown after transfer: [unix user] or [unix user]:[unix group].
- chgrp: (string) executes chgrp after transfer, unix group name
Example: I want to send the template “tpl.tpl” to the host and install it in ‘/usr/local/bin’. I first send it to /tmp, then the shell will replace the contents with the desired values and install the resulting file in “/usr/local/bin”.
- manifest.yaml :
comment: "firstoperation"script: - "run.sh"copyTo: - src: "./resources/tpl.tpl" dest: "/tmp/tpl.tpl"
- run.sh :
#!/usr/bin/env bashmyShell="/usr/local/bin/myshell.sh"tpl="/tmp/tpl.tpl"envsubst < "${tpl}" > "${myShell}"chmod +x "${myShell}"rm -f "${tpl}"
Another example, sending a “systemd” service type file:
comment: "firstoperation"script: - "run.sh"copyTo: - src: "./resources/myservice.service" dest: "/etc/systemd/system/myservice.service" chmod: "644"
parameters.required
Object composed of the names of required variables. These variables will be global environment variables for bash; by convention, these names are capitalized. Each object property (environment variable) is made up of an object with 2 attributes:
- type (mandatory): variable type (possible values: “string” | “number”)
- comment (not mandatory - recommended): comment for this parameter
- default (not mandatory): default value (string), can also be a shortcut to the inventory: “#inv.attr.$host.attr” ($host = host name at runtime). This value is overridden by theBook operation, then by the -e [variable name] switch.
comment: "firstoperation"script: - "run.sh"parameters: required: VERSION: type: string comment: "parseable version to update"
parameters.optional
Object composed of optional variable names. These variables will be global environment variables for bash; by convention, these names are capitalized. Each object property (environment variable) is made up of an object with 3 attributes:
- type (mandatory): variable type (possible values: “string” | “number”)
- comment (not mandatory - recommended): comment on this parameter
- default (not mandatory): default value (string), can also be a shortcut to the inventory: “#inv.attr.$host.attr” ($host = host name at runtime).
comment: "firstoperation"script: - "run.sh"parameters: optional: VERSION: type: string comment: "parseable version to update" # OR VERSION: type: string comment: "parseable version to update" default: "v1.5.2" # OR VERSION: type: string comment: "parseable version to update" default: "#inv.services.$host.parseable.version"
More details on the attribute “default” :
Due to the use of ‘set -u’ in the built shell, bash expects all variables used to be declared upstream. If a variable is not declared before execution, the shell will stop with the Unbound… error.
To avoid this type of error, assign a default value.
If you don’t specify a default value, you can handle undeclared variables as follows:
#!/usr/bin/env bashset -u # included in all shells built by automation-cli
myVersion=${VERSION:-"v1.5.2"}echo "${myVersion}"
Description of run.sh file
The name of this file is arbitrary. You can name it anything you like. The manifest will have to be adjusted (scripts) accordingly.
This file includes the Shebang, so that it can be run outside an automation-cli integration.
The final shell already has a header specifying :
#!/usr/bin/env bash ==> shebang
# defaultset -euo pipefail
As a result, you don’t have to worry about error interception. You can control error handling within your shells by disabling error interception: “set +e”. Don’t forget to re-enable it: “set -e”. If your shells frequently activate/deactivate error interception, you should review the design of your code.
The shell will stop at the first error encountered, even in pipes, and bash will check that all variables used in your shell are declared upstream.
In addition to the commands needed to complete your tasks, you can also insert all internal methods provided by “automation-cli”.