Un peu plus d'assaisonnement

Magazine
Marque
GNU/Linux Magazine
Numéro
166
Mois de parution
décembre 2013
Spécialité(s)


Résumé
Nous avons précédemment vu comment le système de gestion de configuration Salt nous permettait de contrôler différents aspects d'un parc de machines, par exemple en s'assurant que des fichiers de configuration communs étaient tous synchronisés et que les paquets nécessaires aux services souhaités sur ces serveurs étaient bien installés et à jour. Bien que le nombre de modules fournis par défaut par Salt permette l'orchestration d'un parc relativement standard, pour une infrastructure de grande envergure ou pour des besoins spécifiques, il peut s'avérer indispensable de créer son propre module de contrôle, c'est cet aspect du logiciel que nous allons explorer ici.

Body

1. Vogue, petit module, vogue

Un master Salt sait évidemment communiquer avec ses minions pour les interroger ou leur faire exécuter des actions et dans ce dernier cas, une panoplie de possibilités permet de façonner les minions avec grande souplesse.

Salt est livré muni d'une quantité remarquable de modules, présents dans ${PREFIX}/lib/pythonX.Y/{site,dist}-packages/salt/modules. Mais d'emblée, nous sommes en mesure d'étendre cette liste sans polluer le contenu du répertoire placé sous le contrôle du paquet fourni par votre système. Pour ce faire, il suffit, dans le répertoire défini comme file_roots dans le fichier de configuration de salt-master d'ajouter un répertoire _modules (notez l'underscore devant le nom du répertoire). Une fois le répertoire _modules peuplé de modules maison, ces derniers seront synchronisés sur les minions grâce à la commande :

# salt ‘*’ saltutil.sync_modules

Où, comme vu dans l'article de présentation de la suite Salt, '*' représente l'environnement de base (tous les minions); on aurait pu spécifier un minion en particulier ou une condition relative à une catégorie de minions. Par exemple, pour cibler les minions dont le système d'exploitation est Debian GNU/Linux, on aurait fait :

# salt -G ‘os:Debian’ saltutil.sync_modules

Utilisant ainsi les grains, valeurs statiques chargées au démarrage des minions.

Deux intérêts majeurs à la possibilité de synchroniser ainsi dynamiquement des modules :

- Utiliser des modules spécifiques à votre environnement.

- Tester des modules que vous souhaiteriez publier plus largement et pourquoi pas les soumettre au projet Salt pour inclusion dans le logiciel lui même.

Munis de cette facilité, nous allons pouvoir démarrer l'apprentissage de l'écriture d'un module simple et nous familiariser ainsi avec les multiples possibilités offertes par l'environnement Salt.

2. Hello, Salt

Nous en avons parlé dans l'article d'introduction, Salt est écrit en python, et tout naturellement, les modules sont également proposés dans ce langage, simplifiant grandement leur écriture. Nous allons donc écrire un simple module qui renvoie une chaîne de caractères et constater son fonctionnement sur un sous-ensemble de minions. Exécution :

$ cat ~/salt/_modules/hello.py
def hello():
return ‘Hello, Salt!

On synchronise ce module comme vu précédemment, je choisis ici mes machines NetBSD :

# salt -G ‘os:NetBSD’ saltutil.sync_modules
watto:
- modules.hello
korriban:
- modules.hello
coruscant:
- modules.hello
exar:
- modules.hello
ragnos:
- modules.hello

Le maître nous informe que le module hello a été synchronisé sur nos minions dont le grain “os” vaut NetBSD. Il nous est maintenant possible de faire appel à notre nouveau module de la façon la plus simple qui soit :

$ sudo salt -G ‘os:NetBSD’ hello.hello
exar:
Hello, Salt!
watto:
Hello, Salt!
coruscant:
Hello, Salt!
korriban:
Hello, Salt!
ragnos:
Hello, Salt!

Simple non ?

Le développement de modules, comme tout développement, pouvant s'avérer semé d'embûches, il n'est pas obligatoire de passer systématiquement par la machinerie master - minion. L'utilitaire salt-call permet de réaliser un appel direct :

# salt-call hello.hello
[INFO ] Configuration file path: /usr/pkg/etc/salt/minion
local:
Hello, Salt!

Ce petit exemple ouvre d'ores et déjà un nombre de possibilités assez vaste mais sa portée reste limitée. Héritant des capacités objet de Python, Salt permet, au sein d'un module, de faire appel à toute sa machinerie interne.

Faisons-donc appel, dans notre module trivial, à la notion de grains :

$ cat hello.py
def hello():
if __grains__[‘kernelrelease’] < ‘6.1’:
return ‘VIEUX!’
return ‘JEUNE! {0}’.format(__grains__[‘kernelrelease’])

Après avoir synchronisé cette nouvelle version, nous pouvons constater son bon fonctionnement :

# salt -G ‘os:NetBSD’ hello.hello
watto:
JEUNE! 6.1_RC4
coruscant:
VIEUX!
exar:
VIEUX!
korriban:
VIEUX!
ragnos:
VIEUX!

Pour rappel, on consultera la liste des grains disponibles via la commande :

# salt ‘watto’ grains.items
watto:
cpu_flags: FPU DE PSE TSC MSR PAE MCE CX8 APIC SEP MTRR PGE MCA
CMOV PAT PSE36 CFLUSH MMX FXSR SSE SSE2 SSE3 CX16 POPCNT RAZ XD LAHF
cpu_model: Intel 686-class
cpuarch: i386
defaultencoding: ISO8859-15
defaultlanguage: fr_FR
domain: home.imil.net
fqdn: watto.home.imil.net
gpus:
{‘model’: ‘CL-GD5446’, ‘vendor’: ‘Cirrus Logic’}
host: watto
id: watto
ipv4:
127.0.0.1
192.168.1.151
kernel: NetBSD
kernelrelease: 6.1_RC4
localhost: watto.home.imil.net
master: coruscant
mem_total: 511
nodename: watto.home.imil.net
num_cpus: 2
num_gpus: 1
os: NetBSD
os_family: NetBSD
osrelease: 6.1_RC4
path: /usr/bin:/bin:/usr/pkg/bin:/usr/local/bin:/sbin:/usr/sbin:/
usr/pkg/sbin:/usr/X11R7/bin:/home/imil/bin
ps: ps auxwww
pythonpath:
/usr/pkg/bin
/usr/pkg/lib/python27.zip
/usr/pkg/lib/python2.7
/usr/pkg/lib/python2.7/plat-netbsd6
/usr/pkg/lib/python2.7/lib-tk
/usr/pkg/lib/python2.7/lib-old
/usr/pkg/lib/python2.7/lib-dynload
/usr/pkg/lib/python2.7/site-packages
pythonversion: 2.7.3.final.0
saltpath: /usr/pkg/lib/python2.7/site-packages/salt
saltversion: 0.15.1
server_id: 1276300030
shell: /usr/pkg/bin/bash
virtual: kvm

Toutes les clés et valeurs sont disponibles, soit à partir de la ligne de commande à la suite du flag -G, soit directement dans le module à l'aide du dict __grains__.

3. Pass'pass'l'module

Au delà des grains, c'est à l'intégralité des fonctionnalités de Salt auxquelles nous avons accès dans notre module, ceci à travers le dict __salt__. Accédons par exemple aux fonctions d'exécution :

$ cat hello.py
def hello(directory):
return __salt__[‘cmd.run’](‘ls {0}’.format(directory))
$ sudo salt ‘coruscant’ saltutil.sync_modules
$ sudo salt-call hello.hello ‘/usr’
[INFO ] Configuration file path: /usr/pkg/etc/salt/minion
[INFO ] Executing command ‘ls /usr’ in directory ‘/root’
local:
X11R6
X11R7
bin
games
include
lib
libdata
libexec
local
mdec
obj
obj-i386
pkg
pkgsrc
sbin
share
src
tests
tools
tools-i386

Ici, nous exécutons la commande ls suivie d'un paramètre variable (directory) en faisant appel au module cmdmod.py, présent dans l'installation de base de Salt. Ce dernier expose des fonctions d'interfaçage avec l'exécution de commandes sur le minion ciblé. Bien évidemment, notre module hello est également immédiatement disponible pour tous les autres modules chargés. Par exemple, lors de l'écriture de hello2, dans un fichier distinct hello2.py, nous sommes parfaitement autorisés à utiliser les fonctionnalités de hello.py :

$ cat hello2.py
def hello2():
return __salt__[‘hello.hello’](‘/stand’)
$ sudo salt ‘coruscant’ saltutil.sync_modules
coruscant:
- modules.hello2
$ sudo salt-call hello2.hello2
[INFO ] Configuration file path: /usr/pkg/etc/salt/minion
[INFO ] Executing command ‘ls /stand’ in directory ‘/root’
local:
amd64

La fonction hello2 fait appel à la fonction hello précédemment écrite dans hello.py en lui passant en paramètre le répertoire /stand. hello2 retourne à Salt la valeur de retour de la fonction hello que nous avons appelé via le dict __salt__ qui donne un accès direct à cette dernière.

4. Transformation

Dans l'exemple précédent, vous aurez probablement remarqué qu'alors qu'on accède aux fonctions d’exécution via l'appel à cmd.<fonction>, le module se nomme en réalité cmdmod.py. Bien plus qu'un simple renommage, le module utilise ici une puissante fonctionnalité: les modules virtuels.

L'un des intérêts de l'orchestration réside dans la généricité des fonctions appelées, par exemple, il serait fastidieux d'appeler séparément apt.install, pkgin.install ou encore yum.install pour écrire nos recettes d'installation de paquets sur notre parc hétérogène. Au lieu de cela, nous appelons Salt de façon générique :

# salt ‘*’ pkg.install vim

Pourtant, les fonctionnalités d'installation de logiciels tiers sont belles et bien présentes dans plusieurs modules, aux noms distincts. Quelle est cette sorcellerie ? C'est ici la notion de module virtuel qui se charge d'appeler le bon backend pour installer le paquet. Par exemple, dans pkgin.py, j'ai ajouté :

def _check_pkgin():
‘’’
Looks to see if pkgin is present on the system, return full path
‘’’
return salt.utils.which(‘pkgin’)
def __virtual__():
‘’’
Set the virtual pkg module if the os is supported by pkgin
‘’’
supported = [‘NetBSD’, ‘SunOS’, ‘DragonFly’, ‘Minix’, ‘Darwin’]
if __grains__[‘os’] in supported and _check_pkgin():
return ‘pkg’
else:
return False

Ainsi, si le système d'exploitation est supporté par pkgin et que pkgin est accessible dans l'un des $PATH (salt.utils.which), nous informons Salt que ce module sera appelé via son nom virtuel pkg. Autre avantage de cette fonctionnalité, on évitera élégamment les conflits de nommage en créant son module Python avec un nom différent que celui par lequel il est invoqué, exactement comme cela est réalisé pour les fonctions cmd inscrites dans cmdmod.py.

5. Une dernière pincée

Quelques astuces supplémentaires permettront à vos futurs modules de passer la barrière du pull-up request, participation au projet rendue extrêmement simple grâce au site GitHub[1].

5.1 Les fonctions internes

Il n'est pas rare, dans tout type de projet, d'écrire des fonctions qui n'ont qu'une portée interne, dans notre cas, des fonctions qui ne seront pas exposées aux minions. Cela se réalise très simplement en préfixant le nom de la fonction par un underscore, par exemple :

Fonction chargée par le minion :

def foo():
return ‘bar’

Fonction non-chargée par le minion :

def _foo():
return ‘bar’

5.2 Do-cu-men-tez !

La méthode de documentation d'un module Salt n'est pas différente de celle employée pour un code Python classique. En renseignant proprement un docstring dans vos fonctions, ces dernières seront consultables par la commande Salt sys.doc :

def foo():
‘’’
This function returns the number of fooes.
CLI Example::
salt ‘*’ test.foo
‘’’

6. Quoi, vous êtes encore là ?

Accordez-moi que le développement de modules Salt brille par sa simplicité, mais également par sa souplesse et ses concepts inhérents. De plus, l'excellente lisibilité des modules présents dans l'installation de base vous permettra de vous mettre au travail rapidement. Le projet étant développé collaborativement sur GitHub, il est aisé de se faire une idée assez précise des structures et modèles utilisés. Enfin, le canal #salt sur le réseau IRC freenode est peuplé de nombreux développeurs du projet dont la sympathie et l'entrain ne gâchent rien au plaisir de participer à un tel projet.

7. Références

[1] https://github.com/saltstack/salt




Article rédigé par

Par le(s) même(s) auteur(s)

smolBSD : UNIX façon « Ikea »

Magazine
Marque
Linux Pratique
Numéro
141
Mois de parution
janvier 2024
Spécialité(s)
Résumé

Dans les séries américaines, on appelle ce genre d’histoire un crossover, les premières occurrences ont démarré dans Linux Pratique, puis une partie plus profonde sur l’amincissement d’un noyau NetBSD, pas nécessairement utile pour la finalité de notre produit, a fait son apparition dans GNU/Linux Magazine. Aujourd’hui, nous allons apprendre à construire un système BSD UNIX, NetBSD, From Scratch.

SmolBSD : un système UNIX de 7 mégaoctets qui démarre en moins d’une seconde

Magazine
Marque
GNU/Linux Magazine
Numéro
265
Mois de parution
septembre 2023
Spécialité(s)
Résumé

Que de racolage en si peu de mots. Et pourtant si, c’est bien la promesse de cet article, comment parvenir à construire un système d’exploitation fonctionnel en moins de… 10 mégabits. Quelle est cette sorcellerie ? En utilisant une fonctionnalité prévue, mais pas utilisée à cet escient par le noyau NetBSD, nous allons lui faire subir un régime drastique !

La grande migration, Épisode II

Magazine
Marque
Linux Pratique
Numéro
138
Mois de parution
juillet 2023
Spécialité(s)
Résumé

Dans l’épisode précédent [1], nous avons posé les premières briques d’une infrastructure d’auto-hébergement : vm-bhyve comme solution de virtualisation, sous FreeBSD donc, Wireguard comme gestionnaire de tunnel, une petite instance t4g.nano, 2 cœurs ARM64 et 512M de RAM chez AWS et un premier succès de déplacement de machine virtuelle hébergeant un simple serveur web d’un serveur dédié vers notre infrastructure personnelle. Nous allons voir maintenant comment migrer en douceur une machine virtuelle concentrant les services de base d’une architecture à l’autre.

Les derniers articles Premiums

Les derniers articles Premium

Le combo gagnant de la virtualisation : QEMU et KVM

Magazine
Marque
Contenu Premium
Spécialité(s)
Résumé

C’est un fait : la virtualisation est partout ! Que ce soit pour la flexibilité des systèmes ou bien leur sécurité, l’adoption de la virtualisation augmente dans toutes les organisations depuis des années. Dans cet article, nous allons nous focaliser sur deux technologies : QEMU et KVM. En combinant les deux, il est possible de créer des environnements de virtualisation très robustes.

Brève introduction pratique à ZFS

Magazine
Marque
Contenu Premium
Spécialité(s)
Résumé

Il est grand temps de passer à un système de fichiers plus robuste et performant : ZFS. Avec ses fonctionnalités avancées, il assure une intégrité des données inégalée et simplifie la gestion des volumes de stockage. Il permet aussi de faire des snapshots, des clones, et de la déduplication, il est donc la solution idéale pour les environnements de stockage critiques. Découvrons ensemble pourquoi ZFS est LE choix incontournable pour l'avenir du stockage de données.

Générez votre serveur JEE sur-mesure avec Wildfly Glow

Magazine
Marque
Contenu Premium
Spécialité(s)
Résumé

Et, si, en une ligne de commandes, on pouvait reconstruire son serveur JEE pour qu’il soit configuré, sur mesure, pour les besoins des applications qu’il embarque ? Et si on pouvait aller encore plus loin, en distribuant l’ensemble, assemblé sous la forme d’un jar exécutable ? Et si on pouvait même déployer le tout, automatiquement, sur OpenShift ? Grâce à Wildfly Glow [1], c’est possible ! Tout du moins, pour le serveur JEE open source Wildfly [2]. Démonstration dans cet article.

Les listes de lecture

9 article(s) - ajoutée le 01/07/2020
Vous désirez apprendre le langage Python, mais ne savez pas trop par où commencer ? Cette liste de lecture vous permettra de faire vos premiers pas en découvrant l'écosystème de Python et en écrivant de petits scripts.
11 article(s) - ajoutée le 01/07/2020
La base de tout programme effectuant une tâche un tant soit peu complexe est un algorithme, une méthode permettant de manipuler des données pour obtenir un résultat attendu. Dans cette liste, vous pourrez découvrir quelques spécimens d'algorithmes.
10 article(s) - ajoutée le 01/07/2020
À quoi bon se targuer de posséder des pétaoctets de données si l'on est incapable d'analyser ces dernières ? Cette liste vous aidera à "faire parler" vos données.
Voir les 124 listes de lecture

Abonnez-vous maintenant

et profitez de tous les contenus en illimité

Je découvre les offres

Déjà abonné ? Connectez-vous