Переконфигурируйте и перезагрузите подчиненного Hudson / Jenkins как часть сборки - PullRequest
12 голосов
/ 04 апреля 2011

У меня есть настройка сервера Jenkins (Hudson), которая запускает тесты на множестве подчиненных компьютеров. Я хочу переконфигурировать подчиненное устройство (используя удаленные API), перезагрузить подчиненное устройство, чтобы изменения вступили в силу, а затем продолжить тестирование. До сих пор я сталкивался с двумя препятствиями:

  1. Как только задание Jenkins начинает выполняться на ведомом устройстве, ведомое устройство не может разорвать или разорвать сетевое соединение с сервером, в противном случае Jenkins немедленно не проходит тест. Обычно я бы сказал, что это совершенно желательное поведение. Но в этом случае я хотел бы, чтобы Дженкинс принял прерывание, пока раб не вернется в режим онлайн, и Дженкинс не сможет подключиться к нему - или раб снова подключится к Дженкинсу.
  2. В задании, которое было подключено к ведомому устройству, мне нужно выполнить некоторые задачи сборки на главном сервере Jenkins, а не на подчиненном устройстве.

Возможно ли это? До сих пор я не нашел способа сделать это с помощью Jenkins или любого из его плагинов.

РЕДАКТИРОВАТЬ - Дополнительные пояснения Мне очень, очень нравится архитектура Дженкинса. В сочетании с уже имеющимися плагинами, это позволяет очень легко переносить задания на подчиненное устройство, запускать и возвращать результаты. А возможность выбрать любое подходящее ведомое устройство позволяет автоматически распределять задания / тесты.

В нашей ситуации мы используем виртуальные (VMware) подчиненные машины. Было достаточно легко написать скрипт, который заставил бы Дженкинса использовать VMware PowerCLI для запуска виртуальной машины, когда она должна была работать на ведомом устройстве, а затем переслать ей задание и вернуть результаты обратно. Все хорошо.

ИСКЛЮЧИТЬ Частью настройки каждого теста является небольшая переконфигурация виртуальной машины некоторым способом. Отключите UAC, войдите в систему как другой пользователь, установите другой драйвер и т. Д. - для каждого из этих изменений необходимо перезагрузить тестовую ВМ / ведомую, прежде чем изменения вступят в силу. Хотя я могу написать подчиненные сценарии по требованию (Launch Method = Launch slave посредством выполнения команды на главном устройстве), которые обрабатывают эту перенастройку и перезапуск, это необходимо сделать ПЕРЕД выполнением задания. Вот где возникает проблема - я не могу настроить подчиненное устройство так рано, потому что тип изменений конфигурации зависит от запускаемого задания, которое происходит только после запуска ведомого устройства.

Возможные решения
1) Используйте несколько ведомых экземпляров на одной виртуальной машине. Это не сработает - некоторые конфигурации являются взаимоисключающими, но Дженкинс этого не знает. Таким образом, он попытается запустить одну ведомую конфигурацию для одной работы, другую ведомую для другой работы - и оба ведомых будут работать на одной и той же виртуальной машине. Блокировки на работах не предотвращают это, так как запуск подчиненного не является частью работы.

2) (Оптимально) Шаг сборки, позволяющий заданию узнать, что его подчиненное соединение МОЖЕТ быть прервано. На этапе сборки может потребоваться включить некоторые параметры, чтобы Jenkins знал, как повторно подключить подчиненное устройство (будет ли подчиненное устройство автоматически подключаться, придется ли Jenkins запускать сценарий, будет достаточно простого SSH). Этап сборки будет обрабатывать отключение подчиненного устройства, игнорировать обычно отключение при сбое задания, а затем выполнять повторное подключение. Как только ведомое устройство вернется и заработает, может произойти следующий шаг сборки. Возможно, тайм-аут для сбоя задания, если подчиненное устройство не подключается через определенное время.

** Текущее решение ** - меньше оптимального
Прямо сейчас я не могу использовать подчиненную функцию Дженкинса. Вместо этого я использую серию этапов сборки - запускаемых на главном - которые используют скрипты Windows и PowerShell для включения виртуальной машины, настройки и перезапуска. На виртуальной машине установлен SSH-сервер, и я использую его для загрузки тестовых файлов на тестовую виртуальную машину, а затем удаленно их выполняю. Затем загрузите результаты обратно в Jenkins для обработки заданием. Это решение функционально, но требует гораздо больше работы, чем типичный подход Jenkins-slave. Кроме того, сценарии предназначены для одной виртуальной машины; Я не могу легко использовать бассейн рабов.

Ответы [ 2 ]

9 голосов
/ 12 мая 2011

Не уверен, что это будет работать для вас, но вы можете попытаться заставить узел агента Jenkins программно сообщить главному узлу, что он отключен.

У меня была ситуация, когда мне нужно было выполнить задание Jenkins, которое выполняет эти шаги (все при работе на главном узле):

  • возврат виртуальной машины узла агента Jenkins к отключенному снимку
  • скажите мастеру, что узел агента отключен (поскольку, похоже, мастер не замечает, что агент автоматически отключается, всякий раз, когда я возвращаюсь или отключаю питание своих виртуальных машин)
  • снова включите виртуальную машину узла агента
  • как «Действие после сборки», запустить отдельное задание, ограниченное для запуска на узле агента VM

Я выполняю шаг отключения агента с помощью POST-запроса curl, но для этого может быть более чистый способ:

curl -d "offlineMessage=&json=%7B%22offlineMessage%22%3A+%22%22%7D&Submit=Yes" http://JENKINS_HOST/computer/THE_NODE_TO_DISCONNECT/doDisconnect

Затем, когда я загружаю узел агента, агент запускается и автоматически подключается, и мастер замечает, что агент снова подключен (и затем отправляет ему задания).

Я также мог включать и выключать доступность узла с помощью этой команды (используя 'toggleOffline' вместо 'doDisconnect'):

curl -d "offlineMessage=back_in_a_moment&json=%7B%22offlineMessage%22%3A+%22back_in_a_moment%22%7D&Submit=Mark+this+node+temporarily+offline" http://JENKINS_HOST/computer/NODE_TO_DISCONNECT/toggleOffline

(Повторное выполнение этой же команды возвращает статус узла в нормальное состояние.)

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

Тем не менее, вы можете немного покопаться в этом Документе по API удаленного доступа , чтобы узнать, что еще возможно при таком подходе.

3 голосов
/ 23 июня 2011

Очень просто.Вы создаете мастер-задание, которое выполняется на мастере, из мастер-задания вы называете клиентское задание этапом сборки (это новый тип этапа сборки, и мне это нравится).Вы должны проверить, что основное задание должно ждать завершения задания клиента.Затем вы можете запустить свой скрипт, чтобы перенастроить клиент и запустить второй тест на клиенте.

Еще лучшая стратегия состоит в том, чтобы на подчиненных компьютерах работали два узла.Вам нужно настроить два узла в Jenkins.Я успешно использовал эту стратегию с подчиненным Unix.Причина была в том, что мне нужно было установить различные переменные среды, и я не хотел вставлять это в работу.Я использовал клиенты ssh, поэтому я не знаю, возможно ли это с разными типами клиентов.Чем вы сможете запустить оба теста одновременно, или будете объединять задания в цепочку или использовать основную стратегию, упомянутую выше.

...