2016-01-20 1 views
0

Dans Jenkins, nous pouvons bloquer un travail A si le travail B est en cours d'exécution à l'aide de Créer un plugin de blocage .Bloquer un travail en cours d'exécution si des nœuds donnés avec une ou plusieurs étiquettes sont en cours d'exécution

enter image description here

De même ou d'une certaine façon, je voudrais un emploi, par ex: another_dumb_job à PAS exécuter/(attendre et laisser reposer dans la file) s'il y a une les travaux en cours s'exécutant sur tout esclave (s) sélectionné (s) jusqu'à ce que ces esclaves soient à nouveau libres. Par exemple: Je ne veux pas exécuter un Job (qui va supprimer un tas d'esclaves soit hors ligne/en ligne - en utilisant un travail en aval ou en appelant un script groovy/scriptler) jusqu'à ce que l'un de ces esclave (s) les tâches actives/en cours s'exécutent-elles sur elles? L'objectif final est de supprimer les esclaves de nœuds Jenkins, c'est-à-dire que le nœud/l'esclave est d'abord HORS LIGNE, puis les tâches existantes (exécutées sur un esclave sont terminées), puis les esclaves sont supprimés.

+0

Peut-être que vous pouvez utiliser le https://wiki.jenkins-ci.org/display/JENKINS/Throttle+Concurrent+Builds+ Plugin pour créer une catégorie pour ces travaux et n'en autoriser qu'un seul à la fois. –

+0

@Tizkiko merci pour le partage. Je pense qu'il suffit de définir le nombre maximum de tâches à exécuter ou le nombre maximal de tâches à exécuter sur un nœud/esclave donné. Dans mon cas, je voulais que le travail bloque/attende que tous les esclaves de nœud commençant par un nom donné soient exécutés à partir de n'importe quel travail déjà en cours sur eux. Cela était nécessaire dans mon cas, car je créais ces esclaves sur une ou plusieurs machines et les approvisionnais/les arrachais automatiquement à la volée - mais je ne voulais pas que la partie déchirante se produise avant que le nœud/les esclaves soient inactifs. –

Répondre

1

Pour supprimer tous les noeuds hors ligne, modifiez le script ci-dessous et exécutez doDelete() uniquement sur les esclaves où isOffline() est true ou isOnline() est false. Si vous voulez supprimer tous les nœuds (attention) alors ne pas utiliser le compte si suivante:

if (aSlave.name.indexOf(slaveStartsWith) == 0) { 

Je suis aussi ignorant un esclave (si vous voulez ignorer toujours un esclave être supprimé). Il peut être amélioré pour utiliser une liste d'esclaves à ignorer.

Quoi qu'il en soit, le script suivant supprimer gracieusement tous les esclaves de nœud Jenkins qui commence par un nom donné (de sorte que vous avez plus de contrôle) et il va marquer hors-ligne (dès que possible), mais le supprimer seulement après tout travail en cours d'exécution (s) sur ce (s) esclave (s) donné (s) est/sont terminé (s). Je pensais que je devais partager ici.

utilisant Jenkins Scriptler Plugin, on peut importer/télécharger/exécuter ce script: https://github.com/gigaaks/jenkins-scripts/blob/7eaf41348e886db108bad9a72f876c3827085418/scriptler/disableSlaveNodeStartsWith.groovy

/*** BEGIN META { 
    "name" : "Disable Jenkins Hudson slaves nodes gracefully for all slaves starting with a given value", 
    "comment" : "Disables Jenkins Hudson slave nodes gracefully - waits until running jobs are complete.", 
    "parameters" : [ 'slaveStartsWith'], 
    "core": "1.350", 
    "authors" : [ 
    { name : "GigaAKS" }, { name : "Arun Sangal" } 
    ] 
} END META**/ 

// This scriptler script will mark Jenkins slave nodes offline for all slaves which starts with a given value. 
// It will wait for any slave nodes which are running any job(s) and then delete them. 
// It requires only one parameter named: slaveStartsWith and value can be passed as: "swarm-". 

import java.util.* 
import jenkins.model.* 
import hudson.model.* 
import hudson.slaves.* 

def atleastOneSlaveRunnning = true; 
def time = new Date().format("HH:mm MM/dd/yy z",TimeZone.getTimeZone("EST")) 

while (atleastOneSlaveRunnning) { 

//First thing - set the flag to false. 
atleastOneSlaveRunnning = false; 
time = new Date().format("HH:mm MM/dd/yy z",TimeZone.getTimeZone("EST")) 

for (aSlave in hudson.model.Hudson.instance.slaves) { 

    println "-- Time: " + time; 
    println "" 
    //Dont do anything if the slave name is "ansible01" 
    if (aSlave.name == "ansible01") { 
     continue; 
    } 
    if (aSlave.name.indexOf(slaveStartsWith) == 0) { 
     println "Active slave: " + aSlave.name; 

     println('\tcomputer.isOnline: ' + aSlave.getComputer().isOnline()); 
     println('\tcomputer.countBusy: ' + aSlave.getComputer().countBusy()); 
     println "" 
     if (aSlave.getComputer().isOnline()) { 
      aSlave.getComputer().setTemporarilyOffline(true,null); 
      println('\tcomputer.isOnline: ' + aSlave.getComputer().isOnline());  
      println "" 
     } 
     if (aSlave.getComputer().countBusy() == 0) { 
      time = new Date().format("HH:mm MM/dd/yy z",TimeZone.getTimeZone("EST")) 
      println("-- Shutting down node: " + aSlave.name + " at " + time); 
      aSlave.getComputer().doDoDelete(); 
     } else { 
      atleastOneSlaveRunnning = true; 
     } 
    } 
} 
//Sleep 60 seconds 
if(atleastOneSlaveRunnning) { 
    println "" 
    println "------------------ sleeping 60 seconds -----------------" 
    sleep(60*1000); 
    println "" 
} 
} 

Maintenant, je peux créer un travail de jenkins de style libre, utilisez Scriptler script en action Construire et utiliser le script ci-dessus pour supprimez gracieusement les esclaves en commençant par un nom donné (paramètre de travail transmis au script scriptler).

Si vous êtes assez rapide pour obtenir le message d'erreur suivant, cela signifie, vous avez exécuté ou appelé le script Scriptler (comme indiqué ci-dessus) dans un emploi et restreint ce travail à exécuter sur un non -master aka machine noeud/esclave. Scriptler Scripts sont Scripts Groovy SYSTÈME, c'est-à-dire qu'ils doivent s'exécuter sur JVM maître Jenkins pour accéder à toutes les ressources Jenkins/les modifier. Pour résoudre le problème suivant, vous pouvez créer un travail () pour qu'il s'exécute sur le serveur maître, c'est-à-direJVM maître Jenkins) qui vient d'accepter un paramètre pour le script scriptler et appeler ce travail du premier emploi (comme déclencheur d'un projet/travail et de bloquer jusqu'à ce que le travail est terminé):

21:42:43 Execution of script [disableSlaveNodesWithPattern.groovy] failed - java.lang.NullPointerException: Cannot get property 'slaves' on null objectorg.jenkinsci.plugins.scriptler.util.GroovyScript$ScriptlerExecutionException: java.lang.NullPointerException: Cannot get property 'slaves' on null object 
21:42:43 at org.jenkinsci.plugins.scriptler.util.GroovyScript.call(GroovyScript.java:131) 
21:42:43 at hudson.remoting.UserRequest.perform(UserRequest.java:118) 
21:42:43 at hudson.remoting.UserRequest.perform(UserRequest.java:48) 
21:42:43 at hudson.remoting.Request$2.run(Request.java:328) 
21:42:43 at hudson.remoting.InterceptingExecutorService$1.call(InterceptingExecutorService.java:72) 
21:42:43 at java.util.concurrent.FutureTask.run(FutureTask.java:266) 
21:42:43 at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
21:42:43 at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
21:42:43 at java.lang.Thread.run(Thread.java:745) 
21:42:43 Caused by: java.lang.NullPointerException: Cannot get property 'slaves' on null object 

-à-dire Si vous avez Scriptler script étape de construction en cours d'exécution dans un travail (qui ne fonctionne pas sur une machine/JVM MASTER Jenkins), alors l'erreur ci-dessus viendra et pour résoudre, créer un travail "désactiverSlaveNodesStartsWith" et le limiter pour exécuter sur master (plus sûr côté) et en appelant le script Scriptler et passez le paramètre au travail/script.

Maintenant, de l'autre emploi, appelez ce travail:

enter image description here