web-dev-qa-db-fra.com

Comment arrêter un job zombie imparable sur Jenkins sans redémarrer le serveur?

Notre serveur Jenkins a un travail qui dure depuis trois jours, mais ne fait rien. Cliquer sur le petit X dans le coin ne fait rien et le journal de sortie de la console ne montre rien non plus. J'ai vérifié sur nos serveurs de build et le travail ne semble pas fonctionner du tout.

Existe-t-il un moyen de dire à Jenkins que le travail est "terminé", en modifiant un fichier, un verrou ou quelque chose? Comme nous avons beaucoup de tâches, nous ne voulons pas vraiment redémarrer le serveur.

148
blokkie

Allez dans "Manage Jenkins"> "Script Console" pour exécuter un script sur votre serveur afin d'interrompre le thread suspendu.

Vous pouvez obtenir tous les fils en direct avec Thread.getAllStackTraces() et interrompre celui qui est en attente.

Thread.getAllStackTraces().keySet().each() {
  t -> if (t.getName()=="YOUR THREAD NAME" ) {   t.interrupt();  }
}

MISE À JOUR:

La solution ci-dessus utilisant des threads peut ne pas fonctionner avec les versions Jenkins les plus récentes. Pour interrompre des pipelines gelés, reportez-vous à this solution (by alexandru-bantiuc ) et exécutez la commande suivante:

Jenkins.instance.getItemByFullName("JobName")
                .getBuildByNumber(JobNumber)
                .finish(
                        hudson.model.Result.ABORTED,
                        new Java.io.IOException("Aborting build")
                );
159
Zahra

J'ai également eu le même problème et le réparer via la console Jenkins.

Allez dans "Manage Jenkins"> "Script Console" et lancez un script:

 Jenkins .instance.getItemByFullName("JobName")
        .getBuildByNumber(JobNumber)
        .finish(hudson.model.Result.ABORTED, new Java.io.IOException("Aborting build")); 

Vous aurez juste à spécifier votre JobName et JobNumber.

220
Alexandru Bantiuc

J'utilise le plugin de surveillance pour cette tâche. Après l'installation du plugin

  1. Allez dans Manage Jenkins> Surveillance du maître Hudson/Jenkins
  2. Développez les détails des fils, le petit lien bleu sur le côté droit
  3. Rechercher le nom du travail qui est bloqué

    Le nom du fil va commencer comme ça

    Executor #2 for master : executing <your-job-name> #<build-number>

  4. Cliquez sur le bouton rond et rouge à l'extrême droite du tableau de la ligne correspondant à votre travail souhaité.

23
cheffe

Une fois, j'ai rencontré une construction qui ne pouvait pas être stoppée par la "Console de script". Enfin, j'ai résolu le problème avec ces étapes:

ssh onto the jenkins server
cd to .jenkins/jobs/<job-name>/builds/
rm -rf <build-number>
restart jenkins
22
mugi

Si vous avez un travail Multibranch Pipelineet que vous êtes un administrateur Jenkins), utilisez-le dans --- (Jenkins Script Console ce script:

Jenkins.instance
.getItemByFullName("<JOB NAME>")
.getBranch("<BRANCH NAME>")
.getBuildByNumber(<BUILD NUMBER>)
.finish(hudson.model.Result.ABORTED, new Java.io.IOException("Aborting build"));

De https://issues.jenkins-ci.org/browse/JENKINS-4302

Si vous n'êtes pas sûr du nom complet (chemin) du travail, vous pouvez utiliser l'extrait de code suivant pour répertorier le nom complet de tous les éléments:

  Jenkins.instance.getAllItems(AbstractItem.class).each {
    println(it.fullName)
  };

De https://support.cloudbees.com/hc/en-us/articles/226941767-Groovy-to-list-all-jobs

20
Markus Schulte

La première solution proposée est assez proche. Si vous utilisez stop () au lieu de interruption (), il tue même les threads emballés, qui s'exécutent sans fin dans un script système groovy. Cela supprimera toute construction exécutée pour un travail. Voici le code:

Thread.getAllStackTraces().keySet().each() {
    if (it.name.contains('YOUR JOBNAME')) {  
      println "Stopping $it.name"
      it.stop()
    }
}
18
funql.org

Si vous avez un travail Pipeline imparable, essayez les solutions suivantes:

  1. Abandonnez le travail en cliquant sur le X rouge situé en regard de la barre de progression de la construction.
  2. Cliquez sur "Pause/resume" sur la construction pour faire une pause
  3. Cliquez à nouveau sur "Pause/resume" pour reprendre la construction.

Pause/Resume pipeline job

Jenkins réalisera que le travail doit être terminé et arrête la construction

12
Levente Holló

Plug-in de délai de construction peut être utile dans de tels cas. Si le travail prend trop de temps, le travail sera automatiquement supprimé.

7
Draco Ater

Le réponse maximale a presque fonctionné pour moi, mais j'ai eu un problème majeur: j'ai eu un très grand nombre (~ 100) de travaux de zombies en raison d'un redémarrage de Jenkins particulièrement médiocre, ce qui a permis de rechercher manuellement le travail. nom et numéro de construction de chaque travail de zombie et ensuite les tuer manuellement était infaisable. Voici comment j'ai automatiquement trouvé et tué les jobs zombie:

Jenkins.instance.getItemByFullName(multibranchPipelineProjectName).getItems().each { repository->
  repository.getItems().each { branch->
    branch.builds.each { build->
      if (build.getResult().equals(null)) {
        build.doKill()
      }
    }
  }
}

Ce script parcourt toutes les versions de tous les travaux et utilise getResult().equals(null) pour déterminer si le travail est terminé ou non. Une génération qui est dans la file d'attente mais qui n'a pas encore commencé ne sera pas itérée (car cette construction ne sera pas dans job.builds), et une version terminée retournera autre chose que null pour build.getResult(). Un travail en cours d'exécution légitime aura également un résultat de construction de null, alors assurez-vous que vous n'avez aucun travail en cours que vous ne voulez pas tuer avant de l'exécuter.

Les multiples boucles imbriquées sont principalement nécessaires pour découvrir chaque branche/PR pour chaque référentiel dans un projet de pipeline multibranches; Si vous n'utilisez pas de pipelines multibranches, vous pouvez simplement relier tous vos travaux directement avec quelque chose comme Jenkins.instance.getItems().each.

6
jayhendren

Je suppose qu'il est trop tard pour répondre mais aidez certaines personnes.

  1. Installez le plugin de surveillance. ( http://wiki.jenkins-ci.org/display/JENKINS/Monitoring )
  2. Allez à jenkinsUrl/monitoring/nodes
  3. Aller à la section des discussions en bas
  4. Cliquez sur le bouton de détails à gauche du maître
  5. Trier par temps utilisateur (ms)
  6. Ensuite, regardez le nom du fil, vous aurez le nom et le numéro de la construction
  7. Tue le

Je n'ai pas assez de réputation pour poster des images désolé.

J'espère que ça peut aider

6
Simon

J'ai consulté la source Jenkins et il semble que ce que j'essaie de faire soit impossible, car arrêter un travail semble s'effectuer via une interruption Thread. Je n'ai aucune idée pourquoi le travail est suspendu bien ..

Modifier:

Raisons possibles pour des tâches imparables:

  • si Jenkins est coincé dans une boucle infinie, il ne pourra jamais être abandonné.
  • si Jenkins effectue une entrée/sortie réseau ou un fichier dans la Java VM (telle qu'une copie de fichier longue ou une mise à jour SVN), elle ne peut pas être abandonnée.
5
blokkie

J'utilise habituellement jenkins-cli dans de tels cas. Vous pouvez télécharger le fichier depuis une page http://your-jenkins-Host:PORT/cli. Puis courir

Java -jar jenkins-cli.jar delete-builds name_of_job_to_delete hanging_job_number

Info auxiliaire:

Vous pouvez également transmettre une série de builds comme 350:400. Aide générale disponible en cours d'exécution

Java -jar jenkins-cli.jar help

Aide sur la commande contextuelle pour delete-builds par

Java -jar jenkins-cli.jar delete-builds
3

Récemment, je suis tombé sur un noeud/agent dont un exécuteur était occupé pendant plusieurs jours par la construction "X" d'un travail de pipeline, bien que la page "travaux" prétendait que la construction "X" n'existait plus (abandonnée après 10 générations ultérieures (!), configuré dans le travail de pipeline). Vérifié que sur le disque: construire "X" était vraiment parti.

La solution: c’est l’agent/le noeud qui a signalé à tort que l’exécuteur occupé était occupé à exécuter la version "X". Interrompre le fil de cet exécuteur l'a immédiatement publié.

def executor = Jenkins.instance.getNode('NODENAME').computer.executors.find {
    it.isBusy() && it.name.contains('JOBNAME')
}

println executor?.name
if (executor?.isBusy()) executor.interrupt()

Autres réponses envisagées:

  • La réponse de @cheffe: n'a pas fonctionné (voir le point suivant et mettre à jour ci-dessous).
  • Les réponses avec Thread.getAllStackTraces(): pas de thread correspondant.
  • La réponse de @ levente-holló et toutes les réponses avec getBuildByNumber(): ne s'appliquaient pas car la construction n'était plus vraiment là!
  • La réponse de @austinfromboston: cela répondait parfaitement à mes besoins, mais cela aurait également neutralisé toute autre version en cours d'exécution pour le moment.

Mise à jour:
J'ai de nouveau vécu une situation similaire, dans laquelle un exécuteur testamentaire a été occupé pendant plusieurs jours par la construction d'un pipeline fini (toujours existant). Cet extrait de code était la seule solution efficace.

2
t0r0X

J'ai eu le même problème à la dernière demi-heure ...

N'a pas été en mesure de supprimer une construction zombie en cours d'exécution dans mon pipeline multi-branches. Même le serveur redémarre par l'interface utilisateur ou même à partir de la ligne de commande via Sudo service jenkins restart bloquait l'exécution ... La construction n'était pas stoppable ... Elle était toujours réapparue.

Version utilisée: Jenkins ver 2.150.2

J'étais très ennuyé, mais ... en regardant dans le journal de la construction, j'ai trouvé quelque chose d'intéressant à la fin du journal:

Logfile output of an zombie build and showing restart did not stop it

Les parties marquées en rouge sont les "parties frustrantes" ... Comme vous pouvez le constater, j'ai toujours voulu abandonner la construction de l'interface utilisateur, mais cela n'a pas fonctionné ...

Mais il y a un lien hypertexte avec le texte Click here to forcibly terminate running steps... (premier vert) Maintenant, j'ai appuyé sur le lien ...) Après l'exécution du lien, un message concernant Still paused est apparu avec un autre lien Click here to forcibily kill entire build (deuxième vert) Après avoir appuyé sur ce lien, la construction a finalement été mise à mort….

Cela semble donc fonctionner sans plug-in spécial (à l'exception du plug-in multibranch-pipeline build lui-même).

2
hexadez

La réponse d'Alexandru Bantiuc a bien fonctionné pour moi, mais les exécuteurs testamentaires étaient toujours aussi occupés. J'ai pu effacer le statut de l'exécuteur occupé en utilisant ce qui suit

server_name_pattern = /your-servers-[1-5]/
jenkins.model.Jenkins.instance.getComputers().each { computer ->
  if (computer.getName().find(server_name_pattern)) {
    println computer.getName()
    execList = computer.getExecutors()      
    for( exec in execList ) {
      busyState = exec.isBusy() ? ' busy' : ' idle'
      println '--' + exec.getDisplayName() + busyState
      if (exec.isBusy()) {
        exec.interrupt()
      }
    }
  }
}
2
austinfromboston

J'avais beaucoup de zombi-jobs, alors j'ai utilisé le script suivant:

for(int x = 1000; x < 1813; x = x + 1) {
    Jenkins .instance.getItemByFullName("JOBNAME/BRANCH")
    .getBuildByNumber(x)
    .finish(hudson.model.Result.ABORTED, new Java.io.IOException("Aborting build"))
}
1
Stéphane

Avait ce même problème, mais il n'y avait pas de thread de pile. Nous avons supprimé le travail en utilisant cet extrait de code dans la console Jenkins. Remplacez le nom du travail et construisez-le avec le vôtre.

def jobname = "Main/FolderName/BuildDefinition"
def buildnum = 6
Jenkins.instance.getItemByFullName(jobname).getBuildByNumber(buildnum).delete(); 
1
Kenneth King

Utilisation de la console de script sous https: // my-jenkins/script

import hudson.model.Job
import org.jenkinsci.plugins.workflow.job.WorkflowRun

Collection<Job> jobs = Jenkins.instance.getItem('My-Folder').getAllJobs()
for (int i = 0; i < jobs.size(); i++) {
  def job = jobs[i]
  for (int j = 0; j < job.builds.size(); j++) {
    WorkflowRun build = job.builds[j]
    if (build.isBuilding()) {
      println("Stopping $job ${build.number}")
      build.setResult(Result.FAILURE)
    }
  }
}
0
Poulad

Si le même problème m’est arrivé deux fois maintenant, le seul problème est de redémarrer le serveur Tomcat et de relancer la construction.

0
Ernie

Si vous ne souhaitez pas utiliser la console de script ou des plug-ins supplémentaires, essayez ces solutions simples comme indiqué dans la section https://wiki.jenkins.io/plugins/servlet/mobile?contentId=36603009#content/view/36603009

Les travaux de pipeline peuvent être arrêtés en envoyant une demande HTTP POST aux points de terminaison d'URL d'une construction.

  • BUILD ID URL/stop - annule un pipeline.
  • BUILD ID URL/terme - met fin de force à une construction (ne doit être utilisé que si stop ne fonctionne pas.
  • BUILD ID URL/kill - tue durement un pipeline. C'est le moyen le plus destructeur d'arrêter un pipeline et ne doit être utilisé qu'en dernier recours.
0
Dibakar Aditya

Un utilitaire que j'ai écrit et qui s'appelle jkillthread peut être utilisé pour arrêter n'importe quel thread dans n'importe quel processus Java, tant que vous pouvez vous connecter à la machine qui exécute le service sous le même compte.

0
Jesse Glick

SOLUTION TRÈS SIMPLE

La raison pour laquelle je voyais ce problème était un lien incorrect http sur la page au lieu de https qui devrait arrêter le travail. Tout ce que vous avez à faire est de modifier l'attribut onclick de la page html, en suivant

  1. Ouvrez un journal de la console du travail (pipeline) bloqué
  2. Cliquez sur ce qui est disponible pour tuer le travail (icône x, "Cliquez ici pour mettre fin de force aux étapes en cours", etc.) pour obtenir le lien "Cliquez ici pour tuer de force toute la construction" visible (c'est PAS va être cliquable pour le moment)
  3. Ouvrez la console du navigateur (, utilisez l'une des trois options suivantes pour chrome: F12; ctrl + Maj + i; menu-> plus d'outils-> outils de développement ).
  4. Localisez le lien "Cliquez ici pour forcer la destruction de toute la construction" manuellement ou en utilisant le bouton "Sélectionner un élément de la page" de la console.
  5. Double-cliquez sur l'attribut onclick pour modifier sa valeur.
  6. Ajoutez s à http pour avoir https
  7. Appuyez sur Entrée pour soumettre les modifications.
  8. Cliquez sur le lien "Cliquez ici pour tuer par la force toute la construction"

Utilisez screenshot pour référence enter image description here

0
Sergey Pleshakov