Як зупинити роботу, яка не зупиняється на зомбі на Jenkins, не перезавантажуючи сервер?


178

Наш сервер Дженкінса має роботу, яка триває три дні, але нічого не робить. Клацання маленьким X у кутку нічого не робить, і журнал виводу консолі також нічого не показує. Я перевірив наші сервери побудови, і робота насправді, здається, не працює взагалі.

Чи є спосіб сказати jenkins, що робота "виконана", відредагувавши якийсь файл або блокування чи щось таке? Оскільки у нас багато роботи, ми не хочемо перезапускати сервер.


1
Здається, що в останніх версіях Дженкінса рішення не таке, яке позначено як прийняте. (Але один з '16)
NicolasW

Відповіді:


213

Перейдіть у розділ "Керування Дженкінсом"> "Консоль скриптів", щоб запустити скрипт на вашому сервері, щоб перервати звичну нитку.

Ви можете отримати всі живі нитки Thread.getAllStackTraces()та перервати ту, що висить.

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

ОНОВЛЕННЯ:

Вищеописане рішення з використанням потоків може не працювати на більш пізніх версіях Дженкінса. Щоб перервати заморожені трубопроводи, зверніться до цього рішення ( alexandru-bantiuc ) і запустіть:

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

48
Працювали чудово! Для всіх, хто читає, ви можете переглянути імена ниток, спершу запустивши вище, за допомогою методу, який викликаєt -> println(t.getName());
Phil

2
І все-таки він не працює з вищезазначеним сценарієм, він отримує сценарії, але не вбиває те саме.
Рагхав S

2
чи можете ви надрукувати ім'я конкретного потоку після відповідності імені в t.getName()=="SOME NAME"?
Захра

3
І мені це не допомагає - потік не реагує на переривання ().
Zitrax

2
для мене переривання було недостатньо, мені потрібно було зателефонувати t.stopнатомість:Thread.getAllStackTraces().keySet().each() { t -> if (t.getName()=="YOUR THREAD NAME" ) { println(“Found, stopping now… “); t.stop(); } }
п’ятниця

258

У мене була та сама проблема, і виправити її через консоль Jenkins.

Перейдіть у розділ "Керування Дженкінсом"> "Консоль сценарію" та запустіть сценарій:

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

Вам просто потрібно вказати свої JobName та JobNumber.


У мене це було з трубопровідною роботою, яка розпочала інші роботи. Сервер вийшов з ладу, інших завдань більше не було, але робота в конвеєрі все ще була зомбі. Я спершу спробував прийняту відповідь, безрезультатно. Мені довелося кілька разів запускати команду @ Александру, кожного разу, коли я бачив, як смуга ходу роботи в трубопроводі трохи рухається. Нарешті трубопровід загинув, і для хороших заходів я його також видалив.
Амедей Ван Гассе

18
Це також чудово підходить для багатогалузевих проектів, але головне - вказати JobName як Jenkins.instance.getItemByFullName ("<ім'я_проекту> / <ім'я галузі")
evasilchenko

22
Ця відповідь допомогла мені вирішити свою проблему. Трубопровід був тотальним зомбі. Вищеописаний сценарій не працював, і конвеєр продовжував працювати навіть після декількох перезавантажень дженкінів. Я прочитав деяку документацію внутрішнього класу і знайшов метод delete (), щоб мій скрипт виглядав так: Jenkins.instance.getItemByFullName("JobName").getBuildByNumber(JobNumber).delete();Після виконання цього та одного іншого jenkins перезавантажте збірку зомбі, нарешті, не було.
Szymon Sadło

5
Немає методу finishв AbstractBuild, ні FreeSyleBuild, ні MavenModulesetBuild
Якуб

3
У мене виникла проблема при виконанні цього сценарію, будь-яка ідея? 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

Якщо ви отримали багатогалузеву трубопровідну роботу (а ви адміністратор Дженкінса), використовуйте на консолі сценарію Дженкінса цей сценарій:

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

З https://isissue.jenkins-ci.org/browse/JENKINS-43020

Якщо ви не впевнені, що таке повне ім’я (шлях) завдання, ви можете скористатися наступним фрагментом, щоб перерахувати повне ім’я всіх елементів:

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

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


бічна примітка до цього: якщо ви використовуєте SVN (і ви дотримуєтесь стандартних умов), ваш <BRANCH NAME> буде чимось на зразок гілок / my_branch
tvt173

25

Я використовую плагін для моніторингу для цього завдання. Після установки плагіна

  1. Перейдіть до Manage Jenkins> Monitoring of Hudson / Jenkins master
  2. Розгорніть подробиці ниток, маленьке синє посилання праворуч
  3. Шукайте підвішене ім’я роботи

    Ім'я теми розпочнеться так

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

  4. Клацніть червону, круглу кнопку праворуч у таблиці рядка, яку має ваше бажане завдання


3
У ній написано, як убито, але знову, коли ми оновлюємо сторінку, нитка, здається, жива
Raghav S

Цікаво. Я буду дивитись на це. Ймовірно, це залежить від збірки. Якщо ви запустили зовнішні процеси, можливо, за допомогою розширень ANT або Maven, це може вийти з ладу.
шеф-кухар

Це рішення, яке працювало на мене. Щойно потрапив у список потоку, здійснив пошук назви завдання та натиснув на червону кнопку. jenkinsServer / моніторинг # теми
Gilberto

24

Одного разу я зіткнувся з побудовою, яку "консоль сценарію" не могла зупинити. Нарешті я вирішив проблему цими кроками:

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

це фактично допомогло в моєму випадку: робота вже не існувала під час вбивства через консоль (динамічна робота в конвеєрі, функція гілки видалена)
mkko

24

Перше запропоноване рішення досить близько. Якщо ви використовуєте stop () замість interrupt (), це навіть вбиває утікаючі нитки, які нескінченно працюють у жорстокому системному сценарії. Це знищить будь-яку збірку, яка працює на роботу. Ось код:

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

4
ІМО, що має бути прийнятою відповіддю. Всі інші відповіді для мене не спрацювали, оскільки збірка вже перервана, але висіння на деякому кроці після створення. Тільки це рішення справді зупинило збірку
Кутци

1
Використання containsтут є некоректним та небезпечним - якщо назва вашої роботи - "Запустити тести", воно також знищить будь-які завдання з назвою "Запустити тести - інтеграція", "Запустити тести - блок" тощо. Кожен, хто використовує це, повинен бути обережним, щоб не припинити неспоріднені роботи несподівано
Брендон

13

Якщо у вас трубопровід, який не можна зупиняти, спробуйте наступне:

  1. Відмовтеся від роботи, натиснувши червоний X поруч із панеллю прогресу збирання
  2. Клацніть на "Призупинити / відновити" на збірці, щоб призупинити
  3. Натисніть кнопку "Призупинити / відновити" ще раз, щоб відновити збірку

Призупинити / відновити роботу з трубопроводом

Дженкінс зрозуміє, що роботу слід припинити і припинить роботу


8
У мене немає цього пункту меню.
papaiatis

13

Без того , щоб використовувати консоль сценарію або додаткові плагіни, ви можете просто перервати збірки , ввівши /stop, /termабо /killпісля URL збірки в вашому браузері.

Дослівне цитування з вищенаведеного посилання:

Завдання на трубопроводі можна зупинити, надіславши HTTP POST-запит до кінцевих точок URL-адреси збірки.

  • <BUILD ID URL> / stop - скасовує трубопровід.
  • <BUILD ID URL> / term - примусово припиняє збірку (слід використовувати лише тоді, коли зупинка не працює.
  • <BUILD ID URL> / kill - важко вбити трубопровід. Це найбільш руйнівний спосіб зупинки трубопроводу і його слід використовувати лише в крайньому випадку.

7

Для таких випадків плагін може стати корисним. Це автоматично знищить роботу, якщо це займе занадто довго.


1
На жаль, це не варіант для нас, тому що у нас є кілька завдань, які повинні працювати протягом днів (не питайте)
blokkie

7
Ви налаштовуєте тайм-аути побудови на основі роботи.
Драко Атер

1
Ні, у нас збірка застрягла понад 3 години із встановленим тайм-аутом 95 хвилин. Я не думаю, що плагін тайм-ауту може допомогти, оскільки він робить те саме, що натиснути "Скасувати" вручну
Якуб Боченський

7

Я здогадуюсь відповісти занадто пізно, але мені допомагають деякі люди.

  1. Встановіть плагін моніторингу. ( http://wiki.jenkins-ci.org/display/JENKINS/Monitoring )
  2. Перейдіть до jenkinsUrl / моніторинг / вузли
  3. Перейдіть до розділу "Нитки" внизу
  4. Клацніть на кнопці деталі зліва від майстра
  5. Сортувати за часом користувача (мс)
  6. Потім подивіться на ім’я потоку, у вас буде ім’я та номер збірки
  7. Вбий це

У мене недостатньо репутації, щоб розміщувати зображення, вибачте.

Сподіваюся, це може допомогти


1
Не допомагає, Каже, убив. але знову при перезавантаженні сторінки я можу побачити, що Нитка
Raghav S

Ви вбиваєте нитку збірки або підрядок складання? Як називається ця нитка? Я думаю, ти не вб'єш хорошого. Якщо ви вкажете нитку збірки, ви побачите, що збірка успішно закінчена.
Саймон

2
Я намагався вбити Нитку, яка пов'язана з номером виконавця раба, який також мав назву роботи. Також я знайшов кілька інших потоків, пов’язаних з Handling GET, і містилася інформація щодо Subversion. Вбивство обох теж не допомогло. Нарешті мені перезапуск допоміг. Ще одне спостереження було: Інші потоки без асоціації SVN можна було зламати.
Raghav S

Ця відповідь є копією відповіді @cheffe, яка була розміщена на місяць раніше.
t0r0X

6

Верхній відповідь майже працював для мене, але у мене була одна серйозна проблема: у мене була дуже велика кількість (~ 100) робочих місць зомбі з - за особливо погано ймеру Дженкінс, тому вручну знайти потрібне ім'я завдання номер збірки кожного і кожна робота із зомбі, а потім ручне їх вбивство було нездійсненним. Ось як я автоматично знайшов і вбив зомбі-роботи:

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

Цей скрипт перебирає всі складання всіх завдань і використовує getResult().equals(null)для визначення того, закінчила чи ні робота. Збірка, яка знаходиться в черзі, але ще не запущена, не буде повторена (оскільки цієї збірки не буде job.builds), і завершена вже складена конструкція поверне щось інше, ніж nullдля build.getResult(). Легально виконана робота також матиме результат нарощуванняnull , тому переконайтеся, що у вас немає запущених завдань, які ви не хочете вбивати, перш ніж виконувати цю .

Кілька вкладених циклів в основному необхідні для виявлення кожної гілки / PR для кожного сховища в проекті багатогалузевого трубопроводу; якщо ви не використовуєте багатогалузеві трубопроводи, ви можете просто переглядати всі ваші завдання безпосередньо чимось подібним Jenkins.instance.getItems().each.


3
Я трохи покращив ваш сценарій. runningBuilds = Jenkins.instance.getView('All').getBuilds().findAll() { it.getResult().equals(null) } runningBuilds.each { branch->branch.doKill() }
Тобі

5

Я подивився на джерело Дженкінса, і, здається, те, що я намагаюся зробити, неможливо, тому що зупинення роботи, як видається, робиться через переривання теми. Я поняття не маю, чому робота висить, хоча ..

Редагувати:

Можливі причини зупинки роботи:

  • якщо Дженкінс застряг у нескінченному циклі, він ніколи не може бути перерваний.
  • якщо Дженкінс здійснює мережевий або файловий введення / вивід у Java VM (наприклад, тривала копія файлу або оновлення SVN), це не може бути перервано.

Це насправді не неможливо. Ви можете використовувати консоль сценарію jenkins, щоб перервати потік, на якому працює ваша робота. Дивіться пояснення тут: stackoverflow.com/a/26306081/1434041
Zahra

3

Зазвичай я в таких випадках використовую джинкінс-клі. Ви можете завантажити банку зі сторінки http://your-jenkins-host:PORT/cli. Потім бігайте

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

Допоміжна інформація:

Ви також можете пройти ряд подібних конструкцій 350:400. Загальна допомога, доступна за допомогою запуску

java -jar jenkins-cli.jar help

Довідка команд контексту для delete-buildsкористувача

java -jar jenkins-cli.jar delete-builds

3

Відповідь Олександра Бантюка спрацював для мене, щоб зупинити будівництво, але мої виконавці все ще проявляли себе як зайняті. Я зміг очистити статус зайнятого виконавця за допомогою наступного

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()
      }
    }
  }
}

3

Був цей самий випуск, але не було нитки стека. Ми видалили завдання за допомогою цього фрагмента в консолі Дженкінса. Замініть ім'я роботи та збільшить номер на свій.

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

1
Це не працює! Це лише видалить збірку з виду, залишивши запущений процес і всі ресурси заблоковані
Якуб

3

Нещодавно я натрапив на вузол / агент, у якого один виконавець протягом днів займав збірку "X" завдання трубопроводу, хоча ця сторінка вакансій стверджувала, що збірка "X" більше не існує (відкидається після 10 наступних збірок (!), Як конфігурується в роботі конвеєра). Перевірено, що на диску: build "X" справді не було.

Рішення: саме агент / вузол помилково повідомив, що окупований виконавець зайнятий виконанням збірки "X". Перервавши нитку виконавця, негайно випустив її.

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

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

Інші розглянуті відповіді:

  • Відповідь від @cheffe: не вийшло (див. Наступний пункт та оновлення нижче).
  • Відповіді Thread.getAllStackTraces(): немає відповідної нитки.
  • Відповідь від @ levente-holló та всі відповіді з getBuildByNumber(): не застосовувались, оскільки збірки насправді вже не було!
  • Відповідь від @austinfromboston: це наблизилось до моїх потреб, але це також призвело б до ураження будь-яких інших складових, які працюють на даний момент.

Оновлення:
Я знову пережив подібну ситуацію, коли Виконавець протягом декількох днів був зайнятий (ще існує) готовим будівництвом трубопроводу. Цей фрагмент коду був єдиним робочим рішенням.


Це зробило трюк для мене, дякую! Інші рішення не працювали, оскільки номер збірки вже був викинутий (ми просто зберігаємо lat 5 збірок, тому job.getBuildByNumber (...) нічого не повернув).
Л. Тішлер

2

У мене був той самий випуск за останні півгодини ...

Не вдалося видалити зомбі-збірку, що працює в моєму багатогалузевому конвеєрі. Навіть сервер перезапускається користувальницьким інтерфейсом або навіть з командного рядка через sudo service jenkins restart блокує виконання ... Збірка не зупиняється ... Вона завжди з’являється.

Використовувана версія: Jenkins ver 2.150.2

Мене дуже роздратувало, але ... заглянувши в журнал збірки, я виявив щось проміжне в кінці журналу:

Вихід з журналу файлів зомбі та показ перезавантаження не зупинили його

Червоними позначеними частинами є "розчаровуючі частини" ... Як ви бачите, я завжди хотів відмовитись від збірки з інтерфейсу користувача, але це не вийшло ...

Але є гіперпосилання з текстом Click here to forcibly terminate running steps... (перший зелений) Тепер я натиснув посилання ...) Після виконання посилання з'явилося повідомлення про Still pausedінше ПосиланняClick here to forcibily kill entire build (друге зелене) Після натискання на це посилання також скласти нарешті було важко вбито ...

Отож, здається, це працює без будь-яких спеціальних плагінів (за винятком самого плагін збірки багатогалузевих трубопроводів).


Якщо ви дали посилання, що "Натисніть тут, щоб насильно вбити всю збірку", тоді я б голосував, тому що це буде працювати для мене. На жаль, це рішення не відбувається, тому що Дженкінс не демонструє останні журнали, оскільки файл журналу становить кілька ГБ.
mjaggard

На жаль, зараз я більше не маю доступу до цих журналів. Якщо у мене знову ця помилка, я додам коментар її / оновлення рішення. А як же робити вхід на вашій машині jenkins і просто використовувати tailабо переглядач журналів, щоб отримати посилання?
de-jcup

3
Це працювало для мене, дякую! @mjaggard: Посилання є:<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

У мене було багато завдань по зомбі, тому я використав такий сценарій:

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

Це працює для мене щоразу:

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

Завдяки funql.org


0

У мене вже двічі траплялася така ж проблема, єдиний виправити диван - перезапустити сервер tomcat і перезапустити збірку.


0

Утиліта, яку я написав під назвою jkillthread, може бути використана для зупинки будь-якого потоку в будь-якому процесі Java, якщо ви можете увійти до машини, що працює під тим самим обліковим записом.


0

ДУЖЕ ПРОСТЕ РІШЕННЯ

Причиною того, що я бачив цю проблему, було неправильне httpпосилання на сторінці, замість того https, щоб воно припинило роботу. Все, що вам потрібно зробити - це відредагувати onclickатрибут на html-сторінці, дотримуючись наступного

  1. Відкрийте консольний журнал роботи (трубопровід), який завис
  2. Клацніть все, що є в наявності, щоб знищити роботу (значок x, "Клацніть тут, щоб насильно припинити виконання кроків" тощо), щоб отримати "Клацніть тут, щоб насильно вбити всю збірку", видно посилання (це НЕ на даний момент буде натискати)
  3. Відкрийте консоль браузера ( використовуйте будь-яку з трьох для chrome: F12; ctrl + shift + i; меню-> більше інструментів-> інструменти для розробників )
  4. Знайдіть посилання "Натисніть тут, щоб насильно вбити всю збірку" вручну або за допомогою кнопки "вибрати елемент на сторінці" консолі
  5. Двічі клацніть на onclick атрибут, щоб змінити його значення
  6. Append , sщоб httpматиhttps
  7. Натисніть Enter, щоб надіслати зміни
  8. Натисніть посилання "Натисніть тут, щоб насильно вбити всю збірку"

Використовуйте скріншот для довідки введіть тут опис зображення


0

Використання консолі Script за адресою 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

Жодне з цих рішень не працювало на мене. Мені довелося перезавантажити машину, на якій був встановлений сервер. Незрозумілу роботу зараз немає.


-1

Ви можете просто скопіювати завдання та видалити старе. Якщо не важливо, що ви втратили старі журнали збірки.


-2

Ось як я вирішив цю проблему у версії 2.100з Blue Ocean

  • Єдині плагіни, які я встановив, - це бітбукет.
  • У мене є лише один вузол.

sshв мою коробку Дженкінса
cd ~/.jenkins(де я зберігаю джинкіни)
cd job/<job_name>/branches/<problem_branch_name>/builds
rm -rf <build_number>

Після цього ви можете необов’язково змінити номер у nextBuildNumber(я це зробив)

Нарешті, я перезапустив jenkins ( brew services restart jenkins) Цей крок, очевидно, буде відрізнятися залежно від способу управління та встановлення Jenkins.


-3

Введіть блакитно-океанський інтерфейс користувача. Спробуйте припинити роботу звідти.


Що це означає? У мого сервера Дженкінса немає такого інтерфейсу
Ніко Хааз

Блакитний океан - дуже поширений плагін Jenkins, про нього можна прочитати тут .
користувач3360767

Це насправді припиняє роботу іншим чином, ніж класичний інтерфейс? Це здається сумнівним.
StockB
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.