Bug de Salt 3007.4 et 3006.12

Salt est l’outil que j’utilise chez Framasoft pour gérer la configuration des serveurs, y pousser des commandes, etc.
Il est de plus une pierre angulaire de Framaspace car on passe par lui pour déployer de nouveaux espaces (ou en supprimer) sur les serveurs.

D’habitude, ça fonctionne très bien, mais les dernières versions des deux versions disponibles (3007 et 3006) ont bien fichu le bazar : les minions tombait en timeout régulièrement. Ils étaient encore connectés au master, mais ne répondaient plus.

Bonne nouvelle : le problème a déjà été rapporté sur Github.

Meilleure nouvelle : il semblerait que deux des patchs suggérés dans la discussion règlent le problème !

Maintenant, comment appliquer ces patchs à tous ses minions ? Personnellement, j’en ai 126 et j’avais tout sauf envie d’aller sur chaque serveur 😅
La réponse est relativement simple : en faisant comme d’habitude et en utilisant salt 😁

Premièrement, préparer un script pour appliquer les patchs, dans le dossier des recettes salt. Dans mon cas, je l’ai mis à /srv/salt/fix-salt.sh :

cat <<EOF > /srv/salt/fix-salt.sh
#!/bin/bash
sed -i -e 's/^                elif self._creds\["aes"\] != creds\["aes"\]:/                elif (self._creds["aes"] != creds["aes"]) or (self._creds["session"] != creds["session"]):/' \\
    '/opt/saltstack/salt/lib/python3.10/site-packages/salt/crypt.py'
# Avoid patching again if already patched
if ! grep -q 'if data and data == b"bad load"' '/opt/saltstack/salt/lib/python3.10/site-packages/salt/channel/client.py'; then
    sed -i -e 's/upload the results to the master/&\n            if data and data == b"bad load":\n                yield self.auth.authenticate()\n                data = yield self.transport.send(\n                    self._package_load(load, nonce),\n                    timeout=timeout,\n                )/' \\
    '/opt/saltstack/salt/lib/python3.10/site-packages/salt/channel/client.py'
fi
EOF
chmod +x /srv/salt/fix-salt.sh

Ensuite, on redémarre le master, pour forcer les minions à se reconnecter et donc à de nouveau répondre.

systemctl restart salt-master

Après quelques minutes, on vérifie que tout le monde répond :

salt \* test.ping

Puis on exécute le script partout :

salt \* cmd.script salt://fix-salt.sh

On s’assure que le logiciel at est bien installé partout, car on va en avoir besoin, petit à petit pour éviter que la commande soit lancée partout en même temps et que des machines virtuelles sur le même hôte ne fassent gratter les disques :

salt -b 5 \* pkg.install at

Enfin on programme un redémarrage des minions :

salt \* cmd.run 'echo "systemctl restart salt-minion" | at now + 1 minute'

Pourquoi passer par at pour redémarrer les minions et pas par la commande salt \* minion.restart ou salt \* cmd.run "systemctl restart salt-minion" ?
Et bien tout simplement parce que le minion n’aime pas être redémarré par une commande à laquelle il doit répondre. Chez moi, ce genre de commande finit toujours par me retourner une erreur, soit que le minion n’a pas répondu (puisqu’il redémarre), soit qu’il ne redémarre pas correctement. Avec at, au moins, je suis tranquille 🙂

2 réflexions au sujet de “Bug de Salt 3007.4 et 3006.12”

  1. @luc Tu n'as pas d'inquiétude sur le suivi et le soutien au projet suite au rachat par Broadcom ?
    Perso j'ai arrêté d'utiliser Salt (pas seulement pour cette raison, mais en partie), malgré le fait que je trouve que c'est une excellente techno.

  2. @luc j'ai plus tendance à tout faire par des .sls au lieu des commandes directes.

    J'avais beaucoup apprécié ce tips https://salt.tips/patching-salt-modules/

    Et pour redémarrer les minions en ligne de commande, j'utilise :

    salt '*' cmd.run "salt-call –out-file=/dev/null –local test.sleep $((RANDOM % 30)) && salt-call –out-file=/dev/null –local service.restart salt-miniom" bg=True

Laisser un commentaire