Настройка комплексных pipeline в Jenkins для одновременного запуска

Столкнулся с трудностью настроить Jenkins для прогона нескольких пайплайнов с частично пересекающимися джобами.

Задача: имеем 2 пайплайна, в одном в автоматическом режиме (по коммитам) гоняются тесты на релизной ветке, во втором - при необходимости запускаются вручную на конкретной ветке. Первый состоит из нескольких предустановочных джоб (compile-1, deploy-1, configure-1) и набора общих тестовых джоб (testA, testB, testC). Второй - из своих предустановочных (compile-2, deploy-2, configure-2) и тех же тестовых джоб (testA, testB, testC). Для первого есть выделенная ВМ, для второго обычно используется какая-либо ВМ из доступных.

Проблема: необходимо иметь возможность запускать оба пайплайна одновременно (на разных ВМ, естественно), но в то же время необходимо приостанавливать запуск первого пайплайна, если другой его экземпляр еще исполняется (любая из джоб), так как он запускается автоматически.

Идеальным решением была бы возможность блокировать джобу на основании совпадения параметров (например, IP машины), но таких плагинов я не нашел. Создавать по 2 экземпляра тестовых джоб, чтобы безусловно блокировать конкретных пайплайн (с помощью Build Blocker Plugin) выглядит слишком уж грубо.

Кто-то сталкивался c такой проблемой?

2 лайка

Почему бы в 1м пайплайне не использовать блок waitUntil { } с ожиданием окончания 2го пайплайна перез запуском каждой тестовой джобы? Либо я не до конца понял в чем именно проблема.

Необходимо блокировать повторный запуск именно первого пайплайна, так как он исполняется на одной и той же ВМ. Второй пайплайн должен работать без ограничений, независимо от того, запущен первый или нет.

Не работал с Pipeline, только с Job DSL - в waitUntil можно использовать Groovy скрипт с доступом к Jenkins классам? Таким образом наверное можно написать логику в первой джобе (compile-1), которая будет смотреть общие тестовые джобы (testA, testB, testC) и проверять, исполняются ли они с таким же параметром IP. И на основании этого откладывать старт следующей (deploy-1). Но в таком случае первая джоба будет исполняться произвольное время, правильно? Не очень хорошо как с визуальной стороны (“ой, тут какая-то джоба зависла”), так и со стороны получения метрик (продолжительность билда).

Необходимо блокировать повторный запуск именно первого пайплайна

Можно в настройках джобы выставить disable queue checking, чтобы билды не становились в очередь.

Не работал с Pipeline, только с Job DSL - в waitUntil можно использовать Groovy скрипт с доступом к Jenkins классам?

Да, по идее доступ к дженкинсу можно использовать и в Pipeline и в Build Flow job, только в последней нужно сделать импорты нужных hudson классов, и потом использовать что-то вроде этого (выведет имена всех доступных нод в порядке занятости - поиграться можно в дженкинс скрипт консоли):

def nodes = Jenkins.instance.nodes
    .collect { it.computer }
    .findAll { it.online }
    .sort { it.executors.findAll { it.isBusy() }}
    .collect { it.name }

Мне не очень понятна логика с переиспользованием одних и тех же джоб в разных пайплайнах (флоу), выглядит сложновато. Уж тогда проще для каждого пайплайна сделать свой набор джоб и сделать блок билда нужным джобам, если другая (такая же) джоба уже бежит.

Но джобы ведь будут идентичными, разница только в передаваемых параметрах - не копипаста ли?

Ок, попробую поиграться с waitUntil. Эх, правда, выглядит все это как выбор между копипастой и велосипедом :grin:

Может, попробовать поиграться с executors?
Попробовать выделить отдельного слейва для выполнения пресабмита, на котором установить 1 экзекутор? Соответственно, пока он занят - 2-я джоба станет в пул.
А 2-й слейв с необходимым кол-вом экзекуторов будет смотреть на 2-й пайплайн.

Я бы использовал Pipeline вместе с Job DSL, если так смущает копипаста. И можно генерить под каждый pipeline нужные джобы, хоть разные, хоть одинаковые.