Como parar um trabalho de zumbi imparável no Jenkins sem reiniciar o servidor?

177

Nosso servidor Jenkins tem um trabalho em execução há três dias, mas não está fazendo nada. Clicar no pequeno X no canto não faz nada, e o log de saída do console também não mostra nada. Eu verifiquei nossos servidores de compilação e o trabalho não parece estar em execução.

Existe uma maneira de dizer a Jenkins que o trabalho está "concluído", editando algum arquivo ou bloqueio ou algo assim? Como temos muitos trabalhos, não queremos realmente reiniciar o servidor.

blokkie
fonte
1
Parece que nas versões recentes do Jenkins a solução não é a marcada como aceita. (mas o de '16)
NicolasW

Respostas:

212

Vá para "Gerenciar Jenkins"> "Console de scripts" para executar um script no servidor para interromper o encadeamento.

Você pode obter todos os threads ativos Thread.getAllStackTraces()e interromper o que está pendurado.

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

ATUALIZAR:

A solução acima usando threads pode não funcionar nas versões mais recentes do Jenkins. Para interromper pipelines congelados, consulte esta solução (por alexandru-bantiuc ) e execute:

Jenkins.instance.getItemByFullName("JobName")
                .getBuildByNumber(JobNumber)
                .finish(
                        hudson.model.Result.ABORTED,
                        new java.io.IOException("Aborting build")
                );
Zahra
fonte
48
Trabalhou muito bem! Para a leitura ninguém, você pode visualizar os nomes de rosca pelo primeiro executar o acima, com o método chamandot -> println(t.getName());
Phil
2
Ainda não está trabalhando com o script Above também, está recebendo os scripts, mas não está matando o mesmo.
Raghav S
2
você consegue imprimir o nome do segmento específico depois de corresponder o nome t.getName()=="SOME NAME"?
Zahra
3
Isso também não me ajuda - o thread não reage à interrupção ().
Zitrax
2
para mim interromper não foi suficiente, eu precisava ligar t.stop:Thread.getAllStackTraces().keySet().each() { t -> if (t.getName()=="YOUR THREAD NAME" ) { println(“Found, stopping now… “); t.stop(); } }
sexta
258

Eu também tive o mesmo problema e o corrigi via Jenkins Console.

Vá para "Gerenciar Jenkins"> "Console de scripts" e execute um script:

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

Você terá que especificar seu JobName e JobNumber.

Alexandru Bantiuc
fonte
Eu tive isso com um trabalho no Pipeline que iniciou outros trabalhos. O servidor travou, os outros trabalhos se foram, mas o trabalho no pipeline ainda era um zumbi. Tentei pela primeira vez a resposta aceita, sem sucesso. Eu tive que executar o comando do @ Alexandru várias vezes, cada vez que via a barra de progresso do trabalho no pipeline se mover um pouco. Finalmente, o trabalho no oleoduto morreu e, por boas medidas, eu também o excluí.
Amedee Van Gasse
18
Isso funciona muito bem para projetos multi-filial tão bem, mas a chave é para especificar o JobName como Jenkins.instance.getItemByFullName ( "<project-name> / <branch-name>")
evasilchenko
22
Esta resposta me ajudou a resolver meu problema. O oleoduto era um zumbi total. O script acima não funcionou e o pipeline ainda estava em execução, mesmo após a reinicialização de alguns jenkins. Eu li alguma documentação da classe interna e encontrei um método delete () para que meu script tenha a seguinte aparência: Jenkins.instance.getItemByFullName("JobName").getBuildByNumber(JobNumber).delete();Depois de executar este e outro jenkins reiniciar, a compilação zombie finalmente desapareceu.
Szymon Sadło
5
Não há método finishno AbstractBuild nem no FreeSyleBuild nem no MavenModulesetBuild
Jakub Bochenski
3
Eu tenho problema ao executar este script, alguma idéia? groovy.lang.MissingMethodException: No signature of method: hudson.model.FreeStyleBuild.finish() is applicable for argument types: (hudson.model.Result, java.io.IOException) values: [ABORTED, java.io.IOException: Aborting build] Possible solutions: find(), findAll(), find(groovy.lang.Closure) at
Tien Dung Tran
31

Caso você tenha um emprego de Pipeline Multibranch (e você seja um administrador da Jenkins), use no Jenkins Script Console este 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-43020

Se você não tiver certeza de qual é o nome completo (caminho) do trabalho, use o seguinte snippet para listar o nome completo de todos os itens:

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

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

Markus Schulte
fonte
nota de lado a isto: se você estiver usando SVN (e você seguir as convenções padrão), o seu <RAMO NAME> será algo como ramos / my_branch
tvt173
25

Eu uso o plug - in de monitoramento para esta tarefa. Após a instalação do plugin

  1. Vá para Gerenciar Jenkins> Monitoramento do mestre Hudson / Jenkins
  2. Expanda os Detalhes dos Encadeamentos, o pequeno link azul no lado direito
  3. Procure o nome do trabalho suspenso

    O nome do segmento começará assim

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

  4. Clique no botão redondo e vermelho à direita na tabela da linha que o trabalho desejado possui

cheffe
fonte
3
Ele diz como morto, mas novamente quando atualizar a página o fio parece estar vivo
Raghav S
Interessante. Vou dar uma olhada nisso. Provavelmente depende da construção. Caso você tenha iniciado processos externos, provavelmente por extensões ANT ou Maven, isso poderá falhar.
Cheffe
Esta é a solução que funcionou para mim. Apenas entrei na lista de tópicos, fiz uma pesquisa pelo nome do trabalho e clicou no botão vermelho. jenkinsServer / Monitoring # threads
Gilberto Treviño
24

Uma vez encontrei uma compilação que não podia ser interrompida pelo "Script Console". Finalmente, resolvi o problema com estas etapas:

ssh onto the jenkins server
cd to .jenkins/jobs/<job-name>/builds/
rm -rf <build-number>
restart jenkins
mugi
fonte
que realmente ajudou no meu caso: o trabalho não existe mais no momento da matando-o através do console (trabalho gasoduto dinâmico, ramo de recurso excluído)
mkko
24

A primeira solução proposta está bem próxima. Se você usar stop () em vez de interrupção (), ele mata threads em fuga, que são executados infinitamente em um script de sistema groovy. Isso matará qualquer construção executada para um trabalho. Aqui está o código:

Thread.getAllStackTraces().keySet().each() {
    if (it.name.contains('YOUR JOBNAME')) {  
      println "Stopping $it.name"
      it.stop()
    }
}
funql.org
fonte
4
IMO que deve ser a resposta aceita. Todas as outras respostas não funcionaram para mim, pois a compilação já estava em um estado interrompido, mas isso estava suspenso em alguma etapa pós-compilação. Só esta solução realmente fez parar a construção
Kutzi
1
O uso containsaqui é incorreto e perigoso - se o nome do seu trabalho for "Executar Testes", ele também matará todos os trabalhos chamados "Executar Testes - Integração", "Executar Testes - Unidade", etc. Qualquer pessoa que use isso precisará ter cuidado para não terminar os trabalhos não relacionados inesperadamente
Brandon
13

Se você tiver um trabalho de pipeline imparável, tente o seguinte:

  1. Interrompa o trabalho clicando no X vermelho ao lado da barra de progresso da construção
  2. Clique em "Pausar / retomar" na compilação para pausar
  3. Clique em "Pausar / retomar" novamente para retomar a compilação

Pausar / retomar trabalho de pipeline

Jenkins perceberá que o trabalho deve ser encerrado e interrompe a construção

Levente Holló
fonte
8
Eu não tenho esse item de menu.
Papaiatis
13

Sem ter que usar o console de script ou plugins adicionais, você pode simplesmente abortar uma compilação digitando /stop, /termou /killapós o URL de construção no seu browser.

Citando literalmente a partir do link acima:

Os trabalhos de pipeline podem ser interrompidos enviando uma solicitação HTTP POST aos pontos de extremidade da URL de uma construção.

  • <BUILD ID URL> / stop - interrompe um pipeline.
  • <BUILD ID URL> / term - finaliza forçosamente uma compilação (só deve ser usada se stop não funcionar.
  • <BUILD ID URL> / kill - mata com força um pipeline. Essa é a maneira mais destrutiva de interromper um pipeline e deve ser usada apenas como último recurso.
Dibakar Aditya
fonte
7

O plug-in de tempo limite de compilação pode ser útil para esses casos. Ele matará o trabalho automaticamente se demorar demais.

Draco Ater
fonte
1
Infelizmente isso não é uma opção para nós, porque nós temos um par de postos de trabalho que são supostamente para ser executado por dias (não pergunte)
blokkie
7
Você configura os tempos limite de criação por trabalho.
Draco Ater
1
Não, nós temos uma compilação preso por mais de 3 horas, com um conjunto de tempo limite para 95 minutos eu não acho que o plugin tempo limite pode ajudar como ele está fazendo o mesmo que clicar em "Abort" manualmente
Jakub Bochenski
7

Eu acho que é tarde demais para responder, mas minha ajuda a algumas pessoas.

  1. Instale o plug-in de monitoramento. ( http://wiki.jenkins-ci.org/display/JENKINS/Monitoring )
  2. Acesse jenkinsUrl / Monitoring / Nodes
  3. Vá para a seção Threads na parte inferior
  4. Clique no botão de detalhes à esquerda do mestre
  5. Classificar por Tempo do usuário (ms)
  6. Então olhe para o nome do thread, você terá o nome e o número da compilação
  7. Mate isso

Não tenho reputação suficiente para postar imagens, desculpe.

Espero que possa ajudar

Simon
fonte
1
Não está ajudando, diz matado. mas, novamente, quando a página é recarregada, eu consigo ver esse tópico
Raghav S
Você mata o encadeamento da compilação ou um sub-rosca da compilação? Qual é o nome desse segmento? Eu acho que você não mata o bom. Se você matar o encadeamento da compilação, verá a compilação concluída com êxito.
Simon
2
Tentei matar o Thread, que está associado ao número de escravos do executor, que também tinha o nome do trabalho. Também encontrei vários outros tópicos associados ao Handling GET e as informações contidas diziam respeito ao Subversion. Matar os dois também não ajudou. Finalmente reiniciar me ajudou. Mais uma observação foi: Outros threads sem associação com SVN eram passíveis de matança.
Raghav S
Esta resposta é uma cópia da resposta @cheffe, publicada um mês antes.
T0r0X 10/10
6

A resposta principal quase funcionou para mim, mas eu tinha um grande problema: eu tinha um número muito grande (~ 100) de trabalhos de zumbi devido a um reinício Jenkins particularmente em um período de tempo insuficiente, encontrando manualmente o nome do trabalho e o número de compilação de cada um. todo trabalho de zumbi e depois matá-los manualmente era inviável. Veja como eu automaticamente encontrei e matei os trabalhos de zumbi:

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

Esse script faz um loop em todas as compilações de todos os trabalhos e usa getResult().equals(null)para determinar se o trabalho foi ou não concluído. Uma construção que está na fila, mas ainda não foi iniciada, não será repetida (uma vez que essa construção não estará job.builds), e uma construção concluída já retornará algo diferente de nullpara build.getResult(). Um trabalho legitimamente em execução também terá um resultado de compilação null, portanto, verifique se você não possui trabalhos em execução que não deseja eliminar antes de executá-lo.

Os vários loops aninhados são principalmente necessários para descobrir todas as ramificações / PR de todos os repositórios em um projeto Multibranch Pipeline; se você não estiver usando pipelines multibranch, poderá percorrer todos os seus trabalhos diretamente com algo parecido Jenkins.instance.getItems().each.

jayhendren
fonte
3
Eu melhorei um pouco o seu script. runningBuilds = Jenkins.instance.getView('All').getBuilds().findAll() { it.getResult().equals(null) } runningBuilds.each { branch->branch.doKill() }
Tobi
5

Eu olhei para a fonte Jenkins e parece que o que estou tentando fazer é impossível, porque a interrupção de um trabalho parece ser feita através de uma interrupção do Thread. Eu não tenho idéia do porquê o trabalho está pendurado ..

Editar:

Possíveis razões para trabalhos imparáveis:

  • se Jenkins estiver preso em um loop infinito, nunca poderá ser abortado.
  • se o Jenkins estiver executando uma E / S de rede ou de arquivo na Java VM (como cópia longa do arquivo ou atualização do SVN), ela não poderá ser abortada.
blokkie
fonte
Na verdade, isso não é impossível. Você pode usar o console de scripts jenkins para interromper o encadeamento que está executando seu trabalho. Veja a explicação aqui: stackoverflow.com/a/26306081/1434041
Zahra
3

Eu costumo usar Jenkins-cli nesses casos. Você pode baixar o jar de uma páginahttp://your-jenkins-host:PORT/cli . Então corra

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

Informações auxiliares:

Você também pode passar por várias versões, como 350:400 . Ajuda geral disponível executando

java -jar jenkins-cli.jar help

Ajuda de comando de contexto para delete-buildspor

java -jar jenkins-cli.jar delete-builds
Krzysztof Jabłoński
fonte
3

A resposta de Alexandru Bantiuc funcionou bem para eu interromper a compilação, mas meus executores ainda estavam aparecendo como ocupados. Consegui limpar o status de executor ocupado usando o seguinte

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()
      }
    }
  }
}
austinfromboston
fonte
3

Teve esse mesmo problema, mas não havia thread de pilha. Excluímos o trabalho usando esse snippet no Jenkins Console. Substitua jobname e construa dnumber pelo seu.

def jobname = "Main/FolderName/BuildDefinition"
def buildnum = 6
Jenkins.instance.getItemByFullName(jobname).getBuildByNumber(buildnum).delete(); 
Kenneth King
fonte
1
Isso não funciona! Ele vai eliminar apenas a construção de vista deixando o processo em execução e todos os recursos bloqueado
Jakub Bochenski
3

Recentemente, deparei com um nó / agente que tinha um executor ocupado por dias por uma compilação "X" de uma tarefa de pipeline, embora a página de tarefas reivindicasse a compilação "X" não existisse mais (descartada após 10 compilações subsequentes (!), Como configurado no trabalho de pipeline). Verificou que no disco: a compilação "X" se foi realmente.

A solução: foi o agente / nó que relatou erroneamente que o executor ocupado estava ocupado executando a compilação "X". A interrupção do encadeamento do executor a liberou imediatamente.

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

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

Outras respostas consideradas:

  • A resposta do @cheffe: não funcionou (veja o próximo ponto e atualize abaixo).
  • As respostas com Thread.getAllStackTraces(): nenhum tópico correspondente.
  • A resposta de @ levente-holló e todas as respostas com getBuildByNumber(): não se aplicaram, pois a compilação não estava mais lá!
  • A resposta de @austinfromboston: chegou perto das minhas necessidades, mas também teria destruído qualquer outra compilação em execução no momento.

Atualização:
Experimentei novamente uma situação semelhante, em que um Executor foi ocupado por dias por uma construção de pipeline concluída (ainda existente). Esse trecho de código foi a única solução funcional.

t0r0X
fonte
Isso fez o truque para mim, obrigado! As outras soluções não estavam funcionando, já que o número da compilação já estava sendo descartado (apenas mantemos as cinco compilações anteriores, portanto job.getBuildByNumber (...) não retornou nada).
L. Tischler
2

Eu tive o mesmo problema na última meia hora ...

Não foi possível excluir uma compilação de zumbis em execução no meu pipeline de várias ramificações. Mesmo o servidor reinicia pela interface do usuário ou mesmo pela linha de comando via sudo service jenkins restart bloqueou a execução ... A compilação não foi interrompida ... Sempre reapareceu.

Versão usada: Jenkins ver 2.150.2

Fiquei muito chateado, mas ... ao olhar para o log da compilação, encontrei algo interessante no final do log:

A saída do arquivo de log de uma compilação zumbi e mostrar a reinicialização não a interrompeu

As partes marcadas em vermelho são as "partes frustrantes" ... Como você pode ver, eu sempre quis abortar a construção da interface do usuário, mas não funcionou ...

Mas existe um hiperlink com texto Click here to forcibly terminate running steps... (primeiro verde) Agora eu pressionei o link ...) Após a execução do link, uma mensagem Still pausedapareceu com outro Link Click here to forcibily kill entire build(segundo verde) Depois de pressionar esse link, a construção finalmente ficou difícil morto ...

Portanto, isso parece funcionar sem nenhum plug-in especial (exceto o próprio plug-in de compilação multibranch-pipeline).

de-jcup
fonte
Se você forneceu o link "Clique aqui para matar forçosamente a compilação inteira", eu votaria novamente, porque isso funcionaria para mim. Infelizmente, essa solução não ocorre porque o Jenkins falha em mostrar os logs mais recentes porque o arquivo de log possui vários GB.
Mjaggard #
Desculpe, no momento não tenho mais acesso a esses logs. Se eu tiver essa falha novamente, adicionarei um comentário à solução dela / atualização. Mas que tal fazer um logon na sua máquina jenkins e apenas usar tailou um visualizador de log para obter o link?
precisa saber é o seguinte
3
Isso funcionou para mim, obrigado! @mjaggard: O link é:<a href="#" onclick="new Ajax.Request('[server]/jenkins/job/[pipeline_name]/[job_number]/kill'); return false">Click here to forcibly kill entire build</a>
kaveish
1

Eu tinha muitos empregos de zombi, então usei o seguinte script:

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"))
}
Stéphane
fonte
1

Isso funciona para mim sempre:

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

Obrigado ao funql.org

Aviel Yosef
fonte
0

Já tive o mesmo problema duas vezes agora, o único sofá de correção foi reiniciar o servidor tomcat e reiniciar a compilação.

Ernie
fonte
0

Um utilitário que escrevi chamado jkillthread pode ser usado para interromper qualquer encadeamento em qualquer processo Java, desde que você possa efetuar login na máquina que está executando o serviço na mesma conta.

Jesse Glick
fonte
0

SOLUÇÃO MUITO SIMPLES

O motivo pelo qual eu estava vendo esse problema era um httplink incorreto na página, em vez de httpsinterromper o trabalho. Tudo o que você precisa fazer é editar o onclickatributo na página html, seguindo

  1. Abra um log do console do trabalho (pipeline) que foi interrompido
  2. Clique no que estiver disponível para eliminar o trabalho (ícone x, "Clique aqui para terminar forçosamente as etapas em execução" etc.) para obter o link "Clique aqui para eliminar forçosamente a compilação inteira" visível ( NÃO é será possível clicar no momento)
  3. Abra o console do navegador ( use qualquer um dos três no chrome: F12; ctrl + shift + i; menu-> mais ferramentas-> ferramentas de desenvolvedor )
  4. Localize o link "Clique aqui para eliminar forçosamente toda a compilação" manualmente ou usando o botão "selecionar um elemento na página" do console
  5. Clique duas vezes em onclick atributo para editar seu valor
  6. Anexar sa httpterhttps
  7. Pressione Enter para enviar as alterações
  8. Clique no link "Clique aqui para matar à força a compilação inteira"

Usar captura de tela para referência insira a descrição da imagem aqui

Sergey Pleshakov
fonte
0

Usando o console Script em 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)
    }
  }
}
Poulad
fonte
0

Nenhuma dessas soluções funcionou para mim. Eu tive que reiniciar a máquina em que o servidor estava instalado. O trabalho inábil agora se foi.

Marc Laliberté
fonte
-1

Você pode simplesmente copiar o trabalho e excluir o antigo. Se não importa que você tenha perdido os logs de compilação antigos.

GUOHUI QIAN
fonte
-2

Aqui está como eu corrigi esse problema na versão 2.100com Blue Ocean

  • Os únicos plugins que eu instalei são para o bitbucket.
  • Eu só tenho um único nó.

sshna minha caixa Jenkins
cd ~/.jenkins(onde eu mantenho Jenkins)
cd job/<job_name>/branches/<problem_branch_name>/builds
rm -rf <build_number>

Depois disso, é possível alterar opcionalmente o número em nextBuildNumber(fiz isso).

Finalmente, reiniciei o jenkins ( brew services restart jenkins) Esta etapa obviamente será diferente dependendo de como você gerencia e instala o Jenkins.

Tom Bates
fonte
-3

Digite a interface do usuário do blue-ocean. Tente parar o trabalho a partir daí.

user3360767
fonte
O que isso significa? Meu servidor Jenkins não tem tal UI
Nico Haase
O oceano azul é um plugin Jenkins muito comum, você pode ler sobre isso aqui .
user3360767
Isso realmente anula o trabalho de uma maneira diferente da interface do usuário clássica? Parece duvidoso.
precisa saber é o seguinte