Existe-t-il des modèles établis pour l'installation d'un commutateur d'arrêt ou d'activation / désactivation des tâches cron des utilisateurs?

8

Nous avons des versions assez longues pour lesquelles nous planifions généralement nos tâches cron, mais à l'occasion, nous devons réexécuter une génération pendant une période non standard et nous pouvons rencontrer des conflits avec des tâches cron qui sont généralement sûres à exécuter à ces moments.

Nous avons plusieurs comptes qui exécutent à la fois les builds et les tâches cron, nous ne pouvons donc pas suspendre le service crontab pour la machine entière, puis le redémarrer plus tard.

Je me demandais si quelqu'un avait un modèle ou une implémentation. J'imagine que ça marche comme

L'utilisateur crée un fichier: ~ / block-crontab l'
utilisateur exécute la construction Le travail cron recherche ce fichier dans le répertoire personnel de l'utilisateur et s'il y en a, il ignore simplement tous les travaux cron. Sinon, il exécute les travaux. Ensuite, lorsque la construction est terminée, l'utilisateur supprime ~ / block-crontab

Cela fonctionnerait-il? Je suppose que je devrais modifier le script cron d'une manière ou d'une autre. Je me demande surtout s'il existe une approche meilleure / standard à ce problème?

Merci.

Sean
la source
Qu'entendez-vous par [the build] can run into conflicts with from jobs that are tipically safe to run at those times? Y a-t-il des travaux non générés qui ne peuvent pas s'exécuter pendant la génération? Tous les emplois s'excluent-ils mutuellement? Ou tout simplement en ce qui concerne la construction?
GnP
1
Avez-vous regardé l'intro flockou run-one(Debian / Ubuntu)? serverfault.com/questions/82857/…
Stefan Lasiewski
Par exemple, nous exécutons une grosse mise à jour de base de données chaque matin. Ensuite, toutes les heures jusqu'à l'après-midi, nous rafraîchissons la première page avec des nouvelles ou des articles aléatoires. Si elle est exécutée pendant la mise à jour de la base de données, la première page peut contenir des éléments manquants.
Sean
Je n'ai pas regardé le troupeau ou le run-one. Merci.
Sean

Réponses:

10

Plutôt que de jouer avec crond, je suggère fortement d'implémenter une forme (même simple) de verrouillage à l'intérieur de vos scripts de construction. Par exemple, touchez et recherchez un fichier dans /var/run/: si votre script trouve quelque chose, un autre processus construit le projet. Vous devez évidemment supprimer le fichier de verrouillage lorsque vous avez terminé.

Comme @GnP l'a noté dans les commentaires, vous pouvez également utiliser l' flockutilitaire pour gérer semi-automatiquement vos fichiers de verrouillage.

Si vous ne comptez / ne pouvez pas compter sur un mécanisme de verrouillage, lancez simplement a service crond stoppour arrêter le crondsystème.

shodanshok
la source
2
La flockcommande serait un bon ajout à cette réponse. Il gère le fichier de verrouillage et tous les petits détails qu'il contient.
GnP
@GnP Excellente suggestion! J'ai mis à jour ma réponse en conséquence
shodanshok
1
Sachez simplement que flockle descripteur de fichier est hérité des processus enfants, sauf si vous effectuez un mouvement pour le fermer. Cela peut parfois provoquer des comportements inattendus, surtout si les gens démarrent des «tâches d'arrière-plan» qui sont exécutées dans cron.
Matthew Ife
1

J'ai tendance à envelopper toutes les commandes de longue durée dans un écran et cronà démarrer l'écran uniquement s'il n'y en a pas déjà une en cours d'exécution.

Donc, la ligne suivante crontab

*/2 * * * *  /bin/bash /path/to/LongRunningScript.bash

... se transforme en quelque chose comme ceci:

*/2 * * * *  /usr/bin/screen -S MyUniqueName -Q select . || /usr/bin/screen -dmS MyUniqueName /bin/bash /path/to/LongRunningScript.bash

J'aime cela, car il vous donne également la possibilité de vous attacher à un script en cours d'exécution et de vérifier sa sortie / son état.

Dans votre scénario, vous pouvez cronvérifier un autre écran avant d'exécuter une génération, par exemple

0 3 * * *  /usr/bin/screen -S ManualBuild -Q select . || /usr/bin/screen -dmS AutomatedBuild /bin/bash /path/to/BuildScripts.bash
10 3 * * *  /usr/bin/screen -S ManualBuild -Q select . || /usr/bin/screen -dmS OtherAutomatedBuild /bin/bash /path/to/OtherBuildScripts.bash

Lorsque vous exécutez une génération manuelle, lancez-vous dans une screenpremière avant d'exécuter le script (veuillez commenter si vous avez besoin d'indications sur la façon de vous connecter / vous déconnecter screen. C'est un utilitaire utile - essayez-le si vous n'avez pas encore commencé à l'utiliser)

Tapez screen -S ManualBuild, appuyez [enter]et exécutez les commandes que vous souhaitez exécuter.

Remarque: Si vous utilisez l'exemple tel que fourni, vous risquez de confondre cronsi vous avez plus d'une session d'écran avec un nom de "ManualBuild" en cours d'exécution.

très très
la source
Désolé, je viens de voir votre note "sur plusieurs utilisateurs" - cela ne fonctionnera pas sur tous les utilisateurs sans modification. Vous devez vérifier si l'écran prend en charge la connexion aux sessions d'autres utilisateurs.
très
c'est une bonne idée. Je devrais briser l'habitude des développeurs de laisser leurs fenêtres de mandat ouvertes pendant des mois à la fois. :)
Sean
S'ils laissent leur session ouverte, vous pouvez l'attacher à un écran attaché avec screen -x ScreenNameet selon votre distribution (paramètres suid pour screen), vous pouvez rendre une session d'écran partageable avec d'autres utilisateurs. La manière la plus propre serait d'exécuter ces commandes de build sous un nom d'utilisateur spécifique, je suppose, le même utilisateur qui possède le travail cron.
Très