Puppet: exécution de la commande shell lorsque le fichier (ou le package) est mis à jour

8

Je veux exécuter mysql_tzinfo_to_sqlchaque fois que le paquet tzinfo (sur Ubuntu Server) change. J'ai pensé que Puppet pouvait s'en occuper.

Je pensais que Puppet réagirait à un changement dans la version du package, ou sinon, à un changement d'horodatage d'un fichier contenu dans le package.

La seule façon pour moi de le faire est d'avoir une ressource sans action directe et d'avoir un exécutable en fonction.

Mes questions sont les suivantes:

  1. Est-il possible de définir un fichier qui n'est utilisé que pour notifier une autre ressource (telle que exec )?
  2. Est-il possible de définir une ressource de package de sorte qu'une autre ressource (telle que exec ) soit activée lorsque le package change ou se met à jour?
  3. Est-il possible de définir une ressource exec qui exécute une ligne de commande shell (avec des pipes et redirection par exemple) au lieu d'une commande du système de fichiers?

Dans l'ensemble, cela semble écrasant.

SUIVI : réponses fantastiques! Dans un souci d'exhaustivité (et pour mémoire), je dois noter ce qui suit:

  1. La commande shell complète d'intérêt est mysql_tzinfo_to_sql | mysql -u root -p password (elle charge tzinfo dans une base de données MySQL pour MySQL).
  2. L'audit de /etc/tzinfoserait inutile car il s'agit simplement de la configuration du fuseau horaire local; l'objectif est de surveiller les changements dans les données tzinfo elles-mêmes (donc l'observation de /usr/share/zoneinfo).
  3. De même, le contenu ne serait pas la bonne chose à regarder - car il est probable qu'il ne changera pas; le mieux serait de regarder le mtime ou tout car les filetimes devraient changer après chaque mise à jour de tzinfo.

En outre, James Turnbull a tout écrit sur l'audit lors de son introduction. La référence du métaparamètre contient une brève description du fonctionnement du auditparamètre.

Mei
la source
L'une ou l'autre des réponses a-t-elle réellement résolu le problème? Si oui, pourriez-vous accepter celui qui l'a le mieux résolu? Je m'intéresse également à ce problème, et ce serait un pointeur utile pour le suivi.
Tom Anderson
Je n'ai jamais réussi à faire fonctionner cela entièrement - j'ai abandonné et je le fais de temps en temps (ou pendant l'installation) à la main.
Mei

Réponses:

7

Utilisez l'attribut d'audit pour suivre le contenu du fichier ou le numéro de version du package et déclencher la modification en vous abonnant à la ressource de package. Quelques problèmes avec cela, cela ne fonctionne pas avec --noop car le fichier state.yaml mettra à jour la version du fichier md5 checksum / package en mode --noop. Je ne sais pas s'il s'agit d'un bogue en attente, car je ne peux pas le retrouver pour le moment.

file { '/etc/tzinfo':
  audit => content,
}

exec { '/usr/bin/mysql_tzinfo_to_sql':
  subscribe => File['/etc/tzinfo'],
}

Une méthode plus fiable consiste simplement à dupliquer le fichier ailleurs et à l'utiliser pour déclencher des mises à jour (l'emplacement n'est pas important, nous suivons simplement le tzinfo d'origine comme source).

file { '/etc/puppet/stage/tzinfo':
  source => '/etc/tzinfo',
}

exec { '/usr/bin/mysql_tzinfo_to_sql':
  subscribe => File['/etc/tzinfo'],
}

Bien entendu, la deuxième méthode ne fonctionne pas avec les packages, mais vous éviteriez les problèmes --noop et state.yaml.

En ce qui concerne la troisième question, oui, vous pouvez utiliser des tuyaux et des redirections (utilisez un titre et mettez la commande dans l'attribut de commande):

exec { 
  '/bin/echo foo | grep foo > /tmp/foo':
}
Nan Liu
la source
C'est une réponse fantastique - même si je ne suis pas intéressé à regarder le fuseau horaire actuel, mais à modifier les données de fuseau horaire dans / usr / share / tzinfo. Utiliser 'audit => all' contre / usr / share / tzinfo devrait suffire, non?
Mei
Si vous essayez de récurser le répertoire, eh bien cela ne fonctionne pas tout à fait car l'audit ne fonctionne que sur le chemin spécifié et il ne récursif pas. audit => all signifie auditer tous les attributs, pas tous les fichiers. J'utiliserais la deuxième méthode avec recurse si vous choisissez cette méthode.
Nan Liu
Bon point - même si je n'avais pas l'intention de rechuter. Le répertoire / usr / share / tzinfo devrait changer de temps chaque fois que le paquet tzdata est mis à jour - du moins, c'était ma pensée.
Mei
J'avais besoin de quelque chose de similaire et j'ai essayé la première méthode - un audit sur un fichier. Dans mon cas, le fichier est le hachage de validation d'une extraction git d'un Exec précédent. La méthode fonctionne, sauf que la modification du fichier n'est remarquée que lors de l'exécution de la marionnette après celle qui modifie le fichier.
Thomas Vander Stichele
5

Oui, vous devriez pouvoir le faire.

* exemple de code théorique

package{'tzinfo':
  audit  => all,
  notify => Exec['mysql_tzinfo_to_sql'],
}

exec{'mysql_tzinfo_to_sql':
  refreshonly  => true,
  command      => "bash -c '/usr/local/bin/mysql_tzinfo_to_sql >> /var/log/stuff.log'",
}
  1. Oui, via le méta-paramètre notifier. Cependant, je ne suis pas sûr à 100% que la nouvelle fonctionnalité d'audit de puppet 2.6 déclenchera une notification si la version du package change en dehors du contrôle de puppet.

  2. Oui, avec refreshonly => true

  3. Oui, voyez mon exemple. Puppet exécute des commandes exec en dehors d'un shell interactif pour plus de simplicité et de sécurité. Vous pouvez demander à marionnette d'utiliser bash en mode sous-shell avec le commutateur -c, mais faites attention aux guillemets.

robbyt
la source
1
rafraîchir est important ici, je pense. La commande bash semble incongrue: si cette commande fonctionne, alors une commande shell normale devrait aussi fonctionner, non? En tout cas, cela ressemble à ça.
Mei
Est-ce que vous devez utiliser bash -cpour faire une redirection?
Tom Anderson
oui, bash -cest requis pour la redirection du shell dans cet exemple. Puppet n'utilise pas de shell interactif pour exec.
robbyt
2

je crois que j'ai pu faire fonctionner cela. voici les morceaux pertinents de mon manifeste de marionnettes:

file { '/usr/share/zoneinfo':
  audit => mtime,
  recurse => true,
  notify => Exec['mysql_tzinfo']
}

exec { 'mysql_tzinfo':
  refreshonly => true,
  command => 'mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root mysql',
}

après la première mise à jour, l'exec mysql_tzinfo est ignoré. testé en touchant / usr / share / zoneinfo / Etc / UTC, ce qui a incité mysql_tzinfo exec à s'exécuter lors de la prochaine étape.

Daniel Vena
la source
2

Cette question est ancienne, mais je l'ai parcourue à la recherche de quelque chose d'autre et j'ai voulu ajouter une autre réponse pour examen.

Il n'utilise pas de marionnette: Puisque nous voulons déclencher sur une installation / mise à jour RPM, pourquoi ne pas utiliser un déclencheur RPM? Il tire parti du système même utilisé pour l'installation, en l'étendant correctement de la manière pour laquelle il a été conçu.

Construire le RPM de déclenchement est très simple, et bien que ce ne soit pas amusant d'apprendre, une fois que le premier est fait, il peut être répété très facilement pour d'autres applications et conditions - ainsi, les coûts ne sont pas nuls mais les avantages l'emportent rapidement et largement sur ceux frais.

Pendant que nous sommes ici pour Puppet, et que le problème est résolu avec puppet, je crains qu'il ne tire parti d'une partie faible d'un outil pour répondre mal à une condition qui est beaucoup plus facile à déclencher avec un outil qui est déjà sur l'hôte et un outil dans lequel la plupart des admins sur la boîte auraient dû tremper leur orteil. Désolé de suggérer une solution en dehors des lignes, mais si vous vous promenez dans ce message à l'avenir comme je l'ai fait, et que le déclencheur RPM est une option pour vous, veuillez en tenir compte.

user2066657
la source