Статьи

Подключение к API Дженкинса (Хадсон), часть 2

Этот пост продолжается с первой части урока. Прошел почти год, но у меня наконец-то появилось время пересмотреть код, который я написал для взаимодействия с API Jenkins . Я использовал части этой работы, чтобы помочь в управлении несколькими сборочными серверами Jenkins , в основном с точки зрения синхронизации плагинов и перемещения заданий с одного компьютера на другой. В этой статье я собираюсь сосредоточиться в первую очередь на функциональности jar CLI и некоторых вещах, которые вы можете с ней сделать. В основном это было разработано против Дженкинса, но я провел небольшое тестирование с Hudson, и оно работало там для всего, что я пробовал, поэтому код остается в основном независимым от вашего выбора сервера сборки.

Структура проекта

Код размещен на Github и предоставляет сборку Gradle, которая загружает и запускает сервер Jenkins (или Hudson) локально для выполнения тестов. Сервер настроен на использование каталога сборки Gradle в качестве рабочего каталога, поэтому его можно удалить, просто выполнив очистку gradle . Я попробовал это с использованием версий необходимых библиотек Jenkins и Hudson, и, за исключением некоторых причуд между двумя реализациями CLI, они продолжают работать практически одинаково. Если вы хотите попробовать это с Хадсоном, а не с Дженкинсом, передайте флаг команды -Pswitch, и будут использованы соответствующие войны и библиотеки. Проект предназначен для запуска с Gradle 1.0-milestone-8 и поставляется с оболочкой Gradle для этой версии. Большая часть кода остается той же самой, что и в оригинальной статье, но есть некоторые улучшения и изменения, касающиеся новых версий Jenkins и Hudson.
Библиотека, созданная этим проектом, публикуется как артефакт Maven, и позже я опишу, как именно к нему добраться. Также включены некоторые примеры, демонстрирующие использование этой библиотеки в проектах Gradle или Maven, а также в скриптах Groovy с Grapes. Мы используем Groovy 1.8.6, Gradle 1.0-milestone-8 и Maven 3.0.3 для сборки всего.

Получение большего от CLI

В качестве альтернативы API-интерфейсу JAR-файл CLI — очень эффективный способ взаимодействия с сервером сборки. В дополнение к множеству встроенных команд скрипты Groovy могут выполняться удаленно, и с небольшим усилием мы можем легко сериализовать ответы, чтобы работать с данными, извлеченными на сервере. В качестве среды выполнения сервер предоставляет оболочку Groovysh и снабжает ее импортом для пакета hudson.model . Также в Binding передается экземпляр одноэлементного объекта Jenkins / Hudson в этом пакете. В этих примерах я использую обратно-совместимую версию Hudson, так как код предназначен для запуска на любом сервере.

Доступные команды

Существует множество встроенных команд, которые реализованы в пакете hudson.cli . Вот те, которые перечислены на странице CLI запущенного приложения:

  • build: строит задание и при желании ожидает его завершения.
  • cancel-quiet-down: отменить действие команды «quiet-down».
  • clear-queue: очищает очередь сборки
  • connect-node: переподключиться к узлу
  • copy-job: копирует работу.
  • create-job: создает новую работу, читая stdin как файл конфигурации XML.
  • delete-builds: удаляет записи сборки.
  • delete-job: удаляет работу
  • delete-node: удаляет узел
  • disable-job: отключает работу
  • Disnect-узел: отключается от узла
  • enable-job: включает работу
  • get-job: выдает XML-файл определения задания на стандартный вывод
  • groovy: выполняет указанный скрипт Groovy.
  • groovysh: запускает интерактивную заводную оболочку.
  • help: список всех доступных команд.
  • install-plugin: Устанавливает плагин из файла, URL или из центра обновлений.
  • install-tool: выполняет автоматическую установку инструмента и распечатывает его местоположение в стандартный вывод. Можно звонить только из
    внутри сборки.
  • keep-build: пометить сборку, чтобы сохранить сборку навсегда.
  • list-changes: создает дамп журнала изменений для указанных сборок.
  • login: сохраняет текущие учетные данные, чтобы будущие команды могли выполняться без явной информации об учетных данных.
  • logout: удаляет учетные данные, сохраненные с помощью команды входа в систему.
  • mail: читает стандартный ввод и отправляет его по электронной почте.
  • offline-узел: прекратить использование узла для временного построения до следующей команды «online-узел».
  • online-node: возобновить использование узла для выполнения сборок, чтобы отменить более раннюю команду «offline-node».
  • успокоение: успокойся Дженкинс, готовясь к перезапуску. Не начинайте никаких сборок.
  • reload-configuration: сбросить все загруженные данные в памяти и перезагрузить все из файловой системы. Полезно когда
    Вы изменили конфигурационные файлы прямо на диске.
  • рестарт: перезапустить Дженкинс
  • безопасный перезапуск: безопасный перезапуск Jenkins
  • безопасное отключение: переводит Jenkins в тихий режим, ожидает завершения существующих сборок и затем завершает работу.
    Дженкинс.
  • set-build-description: Устанавливает описание сборки.
  • set-build-display-name: устанавливает displayName сборки
  • set-build-result: Устанавливает результат текущей сборки. Работает только если вызывается из сборки.
  • выключение: немедленно выключает сервер Jenkins
  • update-job: обновляет XML определения задания из stdin. Противоположность команды get-job
  • версия: выводит текущую версию.
  • wait-node-offline: ожидание перехода узла в автономный режим
  • wait-node-online: дождитесь, когда узел станет онлайн
  • who-am-i: сообщает ваши учетные данные и разрешения

Не сразу понятно, какие аргументы требуются для каждого, но они почти всегда следуют шаблону CLI печати сведений об использовании при вызове без аргументов. Например, когда вы вызываете команду build без аргументов, вот что вы получаете в потоке ошибок:

Аргумент «РАБОТА» обязателен
java -jar jenkins-cli.jar сборка аргументов…
Начинает сборку и при необходимости ожидает завершения.
Помимо общего использования сценариев, эта команда может быть
используется для вызова другой работы из сборки одной работы.
С опцией -s эта команда изменяет код выхода на основе
результат сборки (код выхода 0 указывает на успех.)
При использовании опции -c сборка будет выполняться только в том случае, если
изменение СКМ
РАБОТА: Название работы, чтобы построить
-c: проверять изменения SCM перед началом сборки, и если нет
изменить, выйти без сборки
-p: указать параметры сборки в формате ключ = значение.
-s: дождаться завершения / прерывания команды

Получение данных из системы

Все взаимодействие с удаленной системой обрабатывается потоками, и довольно легко создать сценарии, которые будут возвращать данные в легко разбираемом формате String с использованием встроенных средств Groovy. Теоретически, вы должны быть в состоянии маршалировать и более сложные объекты, но давайте пока будем проще. Вот скрипт Groovy, который просто извлекает все имена заданий в список, вызывая метод проверки Groovy для цитирования всех значений.

01
02
03
04
05
06
07
08
09
10
11
12
@GrabResolver(name = 'glassfish', root = 'http://maven.glassfish.org/content/groups/public/')
@GrabResolver(name = "github", root = "http://kellyrob99.github.com/Jenkins-api-tour/repository")
@Grab('org.kar:hudson-api:0.2-SNAPSHOT')
@GrabExclude('org.codehaus.groovy:groovy')
import org.kar.hudson.api.cli.HudsonCliApi
 
String rootUrl = 'http://localhost:8080'
HudsonCliApi cliApi = new HudsonCliApi()
OutputStream out = new ByteArrayOutputStream()
cliApi.runCliCommand(rootUrl, ['groovysh', 'hudson.jobNames.inspect()'], System.in, out, System.err)
List allJobs = Eval.me(cliApi.parseResponse(out.toString()))
println allJobs          

Как только мы получим ответ, мы сделаем небольшую уборку, чтобы удалить некоторые посторонние символы в начале строки, и используем Eval.me для преобразования строки в список. Groovy предоставляет множество способов превращения текста в код, поэтому, если ваш сценарий использования усложняется, чем этот простой случай, вы можете использовать GroovyShell с Binding или другой альтернативой для анализа результатов во что-то полезное. Этот простой метод распространяется на Карты и другие типы, что упрощает работу с данными, отправленными с сервера.

Несколько полезных примеров

Поиск плагинов с обновлениями и их обновление

Вот пример использования скрипта Groovy для поиска всех плагинов, у которых есть доступные обновления, возвращая этот результат вызывающей стороне, а затем вызывая команду CLI ‘install-plugin’ для всех из них. Удобно, что эта команда либо установит плагин, если его еще нет, либо обновит его до последней версии, если он уже установлен.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
def findPluginsWithUpdates = '''
Hudson.instance.pluginManager.plugins.inject([]) { List toUpdate, plugin ->
    if(plugin.hasUpdate())
    {
        toUpdate << plugin.shortName
    }
    toUpdate
}.inspect()
'''
OutputStream updateablePlugins = new ByteArrayOutputStream()
cliApi.runCliCommand(rootUrl, ['groovysh', findPluginsWithUpdates], System.in, updateablePlugins, System.err)
 
def listOfPlugins = Eval.me(parseOutput(updateablePlugins.toString()))
listOfPlugins.each{ plugin ->
    cliApi.runCliCommand(rootUrl, ['install-plugin', plugin])
}

Установить или обновить набор плагинов все сразу

Это определенно лучше, чем при использовании пользовательского интерфейса «Управление плагинами», и является идемпотентным, поэтому запуск его более одного раза может привести только к обновлению уже установленных плагинов. Этот набор плагинов может быть излишним, но это некоторые плагины, которые я недавно исследовал для возможного использования.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
@GrabResolver(name='glassfish', root='http://maven.glassfish.org/content/groups/public/')
@Grab('org.kar:hudson-api:0.2-SNAPSHOT')
@GrabExclude('org.codehaus.groovy:groovy')
import static java.net.HttpURLConnection.*
import org.kar.hudson.api.*
import org.kar.hudson.api.cli.HudsonCliApi
 
String rootUrl = 'http://localhost:8080'
HudsonCliApi cliApi = new HudsonCliApi()
 
['groovy', 'gradle', 'chucknorris', 'greenballs', 'github', 'analysis-core', 'analysis-collector', 'cobertura',
        'project-stats-plugin','audit-trail', 'view-job-filters', 'disk-usage', 'global-build-stats',
        'radiatorviewplugin', 'violations', 'build-pipeline-plugin', 'monitoring', 'dashboard-view',
        'iphoneview', 'jenkinswalldisplay'].each{ plugin ->
    cliApi.runCliCommand(rootUrl, ['install-plugin', plugin])
}
 
//  Restart a node, required for newly installed plugins to be made available.
cliApi.runCliCommand(rootUrl, 'safe-restart')

Поиск всех неудачных сборок и запуск их

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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
@GrabResolver(name = 'glassfish', root = 'http://maven.glassfish.org/content/groups/public/')
@GrabResolver(name = "github", root = "http://kellyrob99.github.com/Jenkins-api-tour/repository")
@Grab('org.kar:hudson-api:0.2-SNAPSHOT')
@GrabExclude('org.codehaus.groovy:groovy')
import org.kar.hudson.api.cli.HudsonCliApi
 
String rootUrl = 'http://localhost:8080'
HudsonCliApi cliApi = new HudsonCliApi()
OutputStream out = new ByteArrayOutputStream()
def script = '''hudson.items.findAll{ job ->
    job.isBuildable() && job.lastBuild && job.lastBuild.result == Result.FAILURE
}.collect{it.name}.inspect()
'''
cliApi.runCliCommand(rootUrl, ['groovysh', script], System.in, out, System.err)
List failedJobs = Eval.me(cliApi.parseResponse(out.toString()))
failedJobs.each{ job ->
    cliApi.runCliCommand(rootUrl, ['build', job])
}

Откройте интерактивную оболочку Groovy

Если вы действительно хотите тыкать в сервер, вы можете запустить интерактивную оболочку для проверки состояния и выполнения команд. Поток System.in связан, и ответы от сервера немедленно возвращаются.

01
02
03
04
05
06
07
08
09
10
11
12
@GrabResolver(name = 'glassfish', root = 'http://maven.glassfish.org/content/groups/public/')
@GrabResolver(name = "github", root = "http://kellyrob99.github.com/Jenkins-api-tour/repository")
@Grab('org.kar:hudson-api:0.2-SNAPSHOT')
@GrabExclude('org.codehaus.groovy:groovy')
import org.kar.hudson.api.cli.HudsonCliApi
/**
 * Open an interactive Groovy shell that imports the hudson.model.* classes and exposes
 * a 'hudson' and/or 'jenkins' object in the Binding which is an instance of hudson.model.Hudson
 */
HudsonCliApi cliApi = new HudsonCliApi()
String rootUrl = args ? args[0] :'http://localhost:8080'
cliApi.runCliCommand(rootUrl, 'groovysh')

Обновления к проекту

Многое произошло за последний год, и все зависимости проекта нуждались в обновлении. В частности, были улучшены Groovy, Gradle и Spock. В частности, Gradle прошла ОЧЕНЬ длинный путь с версии 0.9.2. Поддержка JSON, добавленная в Groovy 1.8, также пригодится. Споку потребовалась небольшая настройка для рендеринга динамического содержимого в отчетах о тестах при использовании @Unroll , но это небольшая цена за такие функции, как «старый» метод и цепная заглушка . По сути, в ответ на изменения в Groovy 1.8+ аннотация Spock @Unroll должна измениться на:

1
@Unroll('querying of #rootUrl should match #xmlResponse')

в закрытое выражение GString:

1
@Unroll({'querying of $rootUrl should match $xmlResponse'})

Похоже, что синтаксис все еще в движении, и я рад, что нашел это обсуждение проблемы в Интернете .

Размещение репозитория Maven на Github

Возможно, вы заметили из предыдущих примеров сценариев, что мы ссылаемся на опубликованную библиотеку, чтобы перейти к классу HudsonCliApi. На прошлой неделе я прочитал интересную статью, в которой описано, как использовать встроенные страницы Github для публикации репозитория Maven. Хотя это не так эффективно, как в репозитории, таком как Nexus или Artifactory, этого вполне достаточно для того, чтобы сделать стандартные двоичные файлы доступными для большинства распространенных инструментов сборки стандартным способом. Просто опубликуйте двоичные файлы вместе со связанными помпами в стандартном макете репозитория Maven, и вы отправитесь в гонку! У каждой системы управления зависимостями есть свои особенности (я смотрю на вас, Айви!), Но с ними довольно легко обойтись, поэтому вот примеры для Gradle, Maven и Groovy Grapes для использования библиотеки, созданной этим кодом проекта. Обратите внимание, что некоторые из необходимых зависимостей для Jenkins / Hudson недоступны в центральном репозитории Maven, поэтому мы получаем их из репозитория Glassfish.

Gradle

Довольно просто, это работает с последней версией Gradle и предполагает, что вы используете плагин Groovy.

01
02
03
04
05
06
07
08
09
10
11
12
13
repositories {
    mavenCentral()
    maven {
    }
    maven {
    }
}
dependencies {
    groovy 'org.codehaus.groovy:groovy-all:${versions.groovy}'
    compile 'org.kar:hudson-api:0.2-SNAPSHOT'
}

специалист

По сути тот же контент в xml, и в этом случае предполагается, что вы используете плагин GMaven

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<repositories>
    <repository>
        <id>glassfish</id>
        <name>glassfish</name>
    </repository>
    <repository>
        <id>github</id>
        <name>Jenkins-api-tour maven repo on github</name>
    </repository>
</repositories>
 
<dependencies>
    <dependency>
        <groupId>org.codehaus.groovy</groupId>
        <artifactId>groovy-all</artifactId>
        <version>${groovy.version}</version>
    </dependency>
    <dependency>
        <groupId>org.kar</groupId>
        <artifactId>hudson-api</artifactId>
        <version>0.2-SNAPSHOT</version>
    </dependency>
</dependencies>

виноград

В этом случае, похоже, существует проблема разрешения транзитивной зависимости для более старой версии Groovy, поэтому существует явное исключение для нее.

1
2
3
4
@GrabResolver(name='glassfish', root='http://maven.glassfish.org/content/groups/public/')
@Grab('org.kar:hudson-api:0.2-SNAPSHOT')
@GrabExclude('org.codehaus.groovy:groovy')

связи

  1. Страница проекта Github Jenkins-api-tour
  2. Maven репозитории на Github
  3. Пример скрипта Groovy скрипты
  4. Документация по Jenkins CLI

Похожие сообщения:

  1. Присоединение к API Дженкинса (Хадсон)
  2. Пять классных вещей, которые вы можете сделать с помощью скриптов Groovy
  3. Приложение Grails, демонстрирующее API-интерфейс StackExchange

Ссылка: Присоединение к API Jenkins (Hudson), часть 2 от нашего партнера по JCG Келли Робинсон в блоге The Kaptain on… stuff .