Aller au contenu

operation

Une opération de type “operation” est stockée sous la forme d’un répertoire, dans lequel se trouve un manifeste.

Ce manifeste décrit l’opération, qui peut être une commande simple (command) ou bien un/plusieurs scripts bash (scripts).

Ce répertoire peut aussi contenir toutes les ressources complémentaires : binaires, templates. Arbitrairement, ces éléments sont stockés dans le répertoire “resources”.

Selon le type d’exécution, le répertoire d’une opération contient des scripts bash.

Créer une opération

Utiliser la commande “cop”, qui se chargera de créer l’opération à partir d’un modèle d’opération (manifest.yaml et un script bash).

Dans l‘“OPSDirectory” :

Fenêtre de terminal
OPS=$(pwd) automation-cli cop "firstoperation" -c "[your comment]

OPS=$(pwd) : Permet de déterminer l‘“OPSDirectory”, ici, il s’agit du répertoire courant.

cop “firstoperation” : Nom de l’opération.

-c: Le commentaire associé à cette opération

Ce processus crée, dans le répertoire “OPS”, le répertoire ’./operations/firstoperation’ contenant deux fichiers :

[...]
│ └──operations
│ └── firstoperation
│ └── ./run.sh
│ └── ./manifest.yaml
[...]

Description du fichier manifest.yaml

Ce fichier respecte la syntaxe YAML, la valeur des attributs est prédéfinie comme suit :

AttributsObligatoireTypeDescription
commentnonstringDescription succincte de l’opération. Cette valeur apparaît dans le rapport de pré-exécution et le catalogue des opérations. Je vous conseille fortement de bien compléter cette valeur, c’est pourquoi j’ai rendu le paramètre “-c” obligatoire de la commande “cop”.
command ou scriptsouistring ou Arrayplus de détails dans ce chapitre / plus de détails dans ce chapitre
dependenciesnonArrayplus de détails dans ce chapitre
whennonstringplus de détails dans ce chapitre
limitHostsnonArrayplus de détails dans ce chapitre
copyTononObject[]plus de détails dans ce chapitre
parameters.requirednonObjectplus de détails dans ce chapitre
parameters.optionalnonObjectplus de détails dans ce chapitre

Détails des attributs

command

L’attribut “command” n’accepte qu’une commande ou une série de commandes simples, pouvant être enchaînées avec ”&&” et/ou ”;”.

Exemple d’un manifeste “operation” de type “command” :

comment: "Une operation du type command"
command: 'echo "Hello World" && ls /'

scripts

L’attribut “scripts” est une liste de noms de fichiers, situés dans le répertoire de l’opération.

Exemple d’un manifeste “operation” de type “scripts” :

comment: "Une operation du type scripts"
scripts:
- "run.sh"
- "run1.sh"

Les scripts sont exécutés dans l’ordre indiqué. Bien qu’une opération utilise généralement qu’un seul script, j’ai ajouté cette fonctionnalité qui augmente de fait le niveau de complexité.

dependencies

Indiquez la liste des paquets dont dépend l’opération. Ces paquets seront installés avant l’exécution.

Exemple :

curl n’est pas installé par défaut sur la distribution Debian. Votre opération fait appel a cette commande, pour être sûr que la commande existe lors du run, indiquez la dépendance dans le manifeste :

dependencies:
- "curl"

when

String de la forme “$clé [condition] valeur”

L’attribut “when” permet de limiter l’exécution d’une opération à une condition. Mes besoins s’arrêtent pour l’instant à vérifier qu’une variable d’environnement corresponde à la valeur indiquée, ou bien une valeur d’inventaire.

Exemple : Je veux que l’opération soit exécutée uniquement si l’environnement contient “$REBOOT == 1”.

comment: "firstoperation"
script:
- "run.sh"
when: "$REBOOT==1"

Ex : Je veux que l’opération soit exécutée seulement si la condition “when” faisant référence à un inventaire soit bien remplie : “#inv.attribute == 1”.

comment: "firstoperation"
script:
- "run.sh"
when: "#inv.attribute == 1"

“when” supporte la substitution des variables d’environnement, y compris “$host” qui correspond au nom hôte du serveur sur lequel est exécuté l’opération. Exemple : “#inv.server.$host.ipaddress == 192.168.1.1”

Les seules conditions supportées sont pour l’instant ”==” (est égal) et ”!=” (est différent).

J’ai choisi d’implémenter les conditions comme bash. Une tolérance est appliquée lors d’utilisation d’espaces, en reprenant l’exemple précédent, l’outil accepte “$REBOOT == 1”.

limitHosts

Certaines opérations ne sont exécutables que sur certains hôtes (hostname/Addresse IP). Indiquez la liste des hôtes autorisés. Ex: limitHosts: [‘server1’, ‘server2’]. Cet attribut ne peut pas être surchargé dans un operationBook

Exemple : Je veux que l’opération soit exécutée exclusivement sur les hôtes “server1” et “server2”.

comment: "firstoperation"
script:
- "run.sh"
limitHosts: ['server1', 'server2']
# OR
limitHosts:
- 'server1'
- 'server2'

copyTo

Permet d’envoyer des fichiers vers l’hôte. Cette phase est réalisée sur l’hôte avant l’exécution du shell. Vous pouvez par conséquent envoyer des templates, qui seront préparés et installés par le ou les shells de cette opération.

Liste d’objets dotés de 3 attributs :

  • src: chemin absolu ou relatif du fichier local
  • dest: chemin complet absolu de la destination

Attributs optionnels :

  • chmod: (string) exécute chmod après transfert, notation unix : “755”, “600”, …

(Non implémenté pour l’instant) :

  • chown: (string:string) exécute chown après transfert : [unix user] ou [unix user]:[unix group]
  • chgrp: (string) exécute chgrp après transfert, nom du groupe unix

Exemple : Je veux envoyer le template “tpl.tpl” vers l’hôte et l’installer dans ‘/usr/local/bin’. Je l’envoie d’abord vers /tmp, le shell se chargera de la substitution du contenu par les valeurs souhaitées et d’installer le fichier obtenu dans “/usr/local/bin”

  • manifest.yaml :
comment: "firstoperation"
script:
- "run.sh"
copyTo:
- src: "./resources/tpl.tpl"
dest: "/tmp/tpl.tpl"
  • run.sh :
#!/usr/bin/env bash
myShell="/usr/local/bin/myshell.sh"
tpl="/tmp/tpl.tpl"
envsubst < "${tpl}" > "${myShell}"
chmod +x "${myShell}"
rm -f "${tpl}"

Autre exemple, envoi d’un fichier de type service “systemd” :

comment: "firstoperation"
script:
- "run.sh"
copyTo:
- src: "./resources/myservice.service"
dest: "/etc/systemd/system/myservice.service"
chmod: "644"

parameters.required

Objet composé des noms de variables requises. Ces variables seront des variables d’environnement globales pour bash, par convention, ces noms sont en majuscules. Chaque propriété de l’objet (variable d’environnement) est composé d’un objet doté de 2 attributs :

  • type (obligatoire) : type de la variable (valeurs possibles : “string” | “number”)
  • comment (non obligatoire-conseillé) : commentaire de ce paramètre
  • default (non obligatoire) : valeur par défaut (string), peut aussi être un raccourci vers l’inventaire : “#inv.attr.$host.attr” ($host = nom de l’hôte à l’exécution). Cette valeur est surchargé par l’opérationBook, puis par les commutateur -e [nom de variable].
comment: "firstoperation"
script:
- "run.sh"
parameters:
required:
VERSION:
type: string
comment: "parseable version to update"

parameters.optional

Objet composé des noms de variables optionnelles. Ces variables seront des variables d’environnement globales pour bash, par convention, ces noms sont en majuscules. Chaque propriété de l’objet (variable d’environnement) est composé d’un objet doté de 3 attributs :

  • type (obligatoire) : type de la variable (valeurs possibles : “string” | “number”)
  • comment (non obligatoire-conseillé) : commentaire de ce paramètre
  • default (non obligatoire) : valeur par défaut (string), peut aussi être un raccourci vers l’inventaire : “#inv.attr.$host.attr” ($host = nom de l’hôte à l’exécution).
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"

Plus de détails sur l’attribut “default” :

Du fait de l’utilisation de ‘set -u’ dans le shell construit, bash s’attend à ce que toutes les variables utilisées soient déclarées en amont. Si une variable n’est pas déclarée avant son exécution, le shell s’arrêtera avec l’erreur Unbound….

Pour éviter ce type d’erreur, affectez une valeur par défaut.

Si vous n’indiquez pas de valeur par défaut, vous pouvez gérer des variables non déclarées comme suit :

#!/usr/bin/env bash
set -u # included in all shells built by automation-cli
myVersion=${VERSION:-"v1.5.2"}
echo "${myVersion}"

Description du fichier run.sh

Le nom de ce fichier est arbitraire. Vous pouvez le nommer comme bon vous semble. Le manifeste devra être ajusté (scripts) en conséquence.

Ce fichier comporte le Shebang, pour permettre son exécution en dehors d’une intégration “automation-cli”.

Le shell final dispose déjà d’un entête spécifiant :

#!/usr/bin/env bash ==> shebang
# default
set -euo pipefail

Vous n’avez par conséquent pas à vous soucier de l’interception des erreurs. Vous pouvez contrôler la gestion d’erreur au sein de vos shells en désactivant l’interception d’erreur : “set +e”. N’oubliez pas de le réactiver : “set -e”. Si vos shells activent/désactivent fréquemment l’interception d’erreur, vous devriez réviser la conception de votre code.

Le shell s’arrêtera à la première erreur rencontrée, même dans les pipes, et bash vérifiera que les variables utilisées dans votre shell soient toutes déclarées en amont.

En plus des commandes nécessaires à la réalisation de vos tâches, vous pouvez aussi insérer toutes les méthodes internes fournies par “automation-cli”.