Jenkins: build, install: Рубим скорлупу

…или вооружаемся базовыми средствами и делаем наиболее объемную часть.

Сборка

Сборка пакета - это вообще отдельная тема, почти уникальная для каждой команды разработки. Зависит это не только от языка разработки, но и от конечного потребителя. Эту джобу предлагается настроить самостоятельно. Стоит заметить, что в нашем варианте цепочки каждый собираемый пакет будет устанавливаться на машинку и обстреливаться внешними интеграционными тестами. Этот момент нужно учесть, если сборка у вас покоммитная.

Добавим только на этом этапе Description Setter Plugin & Build Name Setter Plugin. Настройка каждого проста до безобразия, но имеет свои нюансы. Например, первый, для дескрипшена - разделяет описание для успешного и неуспешного билда. Эта настройка скрывается под кнопкой «Расширенные». Думаю с регулярными выражениями проблем возникнуть не должно - в помощи есть пример. Искать сами настройки стоит в пост-билд степах, под названием Set build description.

Обращу внимание, что ищется нужная строка во всем логе и используется первое найденное совпадение. Если нужно безусловно поставить какое то описание (например, для установки описанием одной из переменных окружения) - в регулярке нужно поставить «.» (точку) и указать переменную окружения в формате ${ENV_VAR}.

В описание мы решили вставлять версию собранного пакета.

Вопрос к зрителям: Я на самом деле не понял как работать с мультизначениями в регулярке - если у кого то получится реализовать, скиньте пример

Второй же, использует не просто переменные окружения, а так называемые токены. При этом переменные окружения в виде этих токенов выглядят примерно так: ${ENV,var="VARIABLENAME"} - подробнее, в справке к полю ввода.

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

Нам так же потребуется Publish Over SSH Plugin. С его помощью в конце выполнения джобы, полученный артифакт с собранным пакетом мы зальем в репозиторий, где по крону сканируется наличие новых пакетов, после чего пересобирается индекс. Настройка серверов - в общей конфигурации Jenkins. Настройка места заливки - в post-build шагах, в шаге с названием Send build artifacts over SSH.

В этом плагине можно настроить много-много всего. Мы установили 5 попыток в расширенных настройках выбранного сервера, с промежутком в 10 секунд.

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

img-ssh-plugin

Кстати: тут же можно указать команду, которая выполнится сразу после трансфера - например, принудительно запускать пересканирование репозитория, вместо отслеживания его по cron, если это слишком дорого.

Установка

Это с одной стороны самая легкая в настройке джоба, с другой - одна из самых сложных. Мы используем red hat и yum. Для дебиана процесс может несколько отличаться, но не слишком кардинально.

Это параметризованная задача, с входным параметром - именем пакета для установки и установленной галочкой (указав тестовую машинку)

Restrict where this project can be run

Первый шаг - ожидание появления пакета в репозитории.

FIXME: Решение костыльное, и будет скоро переделано. Может быть кто то знает как это сделать лучше?

WAIT_TIME=120
sudo yum list $METAPACKAGE_NAME 2>&1 | grep Error && (echo 'sleep'; sleep $WAIT_TIME; sudo yum clean metadata;) ||  echo 'Pack ok'

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

Следующий шаг - простое sudo yum install -y $METAPACKAGE_NAME

Хозяйке на заметку:

Тут мы наивно предположили, что все зависимости всегда будут иметь возрастающую версию, и будут четко указаны в пакете, потому как yum не умеет корректно решать конфликты и приходится выкручиваться. Вариантов выкрутиться - несколько. Наиболее простой - удалять все что может помешать. А потом заново ставить. Вариант более продвинутый - использовать виртуализацию и поднимать машинку из конкретного чистого снепшота. В процессе борьбы с зависимостями пакетов вполне может помочь Ansible.

Статьи из этой серии:

  • [Прежде чем готовить кастрюлю] - вводная
  • [Чистим змей] - быстрое прототипирование и python
  • [Варим кофе] - есть место и для java
  • [Смешиваем] - как все это превратить в цепочку