Разработка сценариев установки#
Содержание#
Экспресс описание Installer#
Сценарии и этапы#
Каждый из исполняемых сценариев состоит из этапов. Любой этап может включать в себя дочерние этапы или состоять из шагов. Главное отличие этапа от шага - наличие параметра steps (списка шагов) и отсутствие параметра step_params.
Параметры этапа#
Поле |
Описание |
Примечание |
|---|---|---|
name |
Уникальное имя этапа |
Должно быть уникальным в рамках 1 этапа. |
steps |
Список запускаемых дочерних этапов и/или шагов. |
|
service_data |
Блок служебных параметров, позволяющих управлять процессом установки. |
|
vars |
Параметры, используемые для параметризации/шаблонизации на данном этапе и дочерних. |
Параметры шага#
Поле |
Описание |
Примечание |
|---|---|---|
name |
Уникальное имя этапа |
Должно быть уникальным в рамках 1 этапа. |
step_params |
Параметры шага |
Раньше именовалось просто steps, такой вариант поддерживается до сих пор. |
service_data |
Блок служебных параметров, позволяющих управлять процессом установки. |
|
vars |
Параметры, используемые для параметризации/шаблонизации в данном шаге. |
|
reimport |
Параметр, используемый для передачи дополнительных файлов параметров. |
Параметры блока служебных параметров (service_data)#
Поле |
Значение по умолчанию |
Обязательность наличия |
Назначение |
В старом формате |
|---|---|---|---|---|
stage_type |
sequence |
Нет |
Последовательный ( |
Присутствует. |
type |
– |
Да |
Используемый шагом модуль (Cmd, JenkinsRemote, Stash, Git и т.п.), для этапа не применяется. |
Был на уровне шага. |
allowed_status |
success |
Нет |
Список допустимых статусов для продолжения. |
Был на уровне шага и применялся лишь для него. |
retry |
1 |
Нет |
Количество попыток в случае получения недопустимого статуса. |
Был на уровне шага и применялся лишь для него. |
timeout |
5000 |
Нет |
Время в ms, которое проходит между попытками неуспешных запусков из поля retry. |
Был на уровне шага и применялся лишь для него. |
enabled |
on |
Нет |
Выбор запуска данного шага/этапа: |
Был на уровне шага и применялся лишь для него. |
delay |
0 |
Нет |
Время задержки перед запуском (с помощью него можно избежать единовременного обращения к ресурсу при параллельном запуске. |
Не было, но можно указывать на уровне шага. |
transaction |
– |
Нет |
Связывает условия запуска шагов с одинаковым значением данного поля. |
Был на уровне шага и применялся лишь для него. |
pool |
– |
нет |
Число максимальных одновременных параллельных запусков для данного этапа (в случае с шагом, игнорируется). |
Не применимо. |
У шага, в отличие от этапа, есть блок step_params (также поддерживается старый вариант: params). Это уже параметры, относящиеся непосредственно к шагу установки, они описаны далее в этом документе.
Помимо этого, всегда можно указать параметр import, значением которого является путь до другого JSON-файла, по сути являющегося частью данного сценария, вынесенной в отдельный файл.
Параметры Cmd шага#
Параметр |
Обязательность наличия |
Назначение |
|---|---|---|
command |
Да |
Может быть как строкой, так и списком строк. |
ignorePlh |
Нет |
Включение флага позволяет игнорировать нешаблонизированные значения. |
action |
Нет |
Тип действий, сейчас по сути только jsch - запуск на удаленном сервере. |
url |
Да (если action=jsch) |
Адрес удаленного сервера, на котором выполняется команда. |
user |
Да (если action=jsch) |
Логин, под которым подключаемся к этому серверу. |
pass |
Да (если action=jsch) |
Пароль, под которым подключаемся к этому серверу. |
port |
Нет |
Порт подключения (по умолчанию = 22). |
Скрытые параметры, через которые можно управлять из файла параметров#
Параметр |
Значение по умолчанию |
Назначение |
|---|---|---|
masked |
false |
Принудительное маскирование результатов выполнения команды. |
hide |
false |
Принудительное сокрытие результатов выполнения команды. |
Параметры шага JenkinsRemote#
Параметр |
Обязательность наличия |
Назначение |
|---|---|---|
action |
Да |
Говорит о том, какой вид действия необходимо произвести. На текущий момент это только |
url |
Да |
Корневой адрес Jenkins-сервера, к которому идет обращение. |
subUrl |
Да |
Адрес запускаемой Jenkins job, например: |
user |
Да |
Пользователь, из под которого производится запуск. |
pass |
Да |
Может быть как паролем, так и токеном. |
params |
Нет |
Параметры запускаемой Jenkins job. |
checkLog |
Нет |
Паттерн, по которому проверяется лог, и если совпадение не найдено - шаг завершается с ошибкой. |
Параметры шага Groovy#
Параметр |
Обязательность наличия |
Назначение |
|---|---|---|
action |
Да |
Тип запуска. Пока поддерживается только значение |
path |
Нет |
Путь к запускаемому groovy-скрипту (файлу). |
command |
Нет |
Groovy-текст в виде строки. |
args |
Нет |
Аргументы запуска скрипта (применимо только в случае, если используется файл, т.е. |
Дополнительные параметры#
Задаются в основном через файл параметров, или параметры запуска.
Параметр |
Значение по умолчанию |
Назначение |
|---|---|---|
installer.properties.file |
./installer.properties |
Путь к файлу параметров. |
installer.secrets.file |
./secret.properties |
Путь до зашифрованного файла параметров. |
installer.secrets.password |
– |
Параметр для расшифровки зашифрованного файла параметров. |
installer.scenario.file |
./tasks.json |
Путь до файла сценария. |
installer.secrets.encType |
vault |
Тип шифрования файла параметров (vault, или openssl - aes-256-cbc). |
installer.outputs.file |
Путь к сценарию + |
Путь до служебного файла. |
installer.encoding |
utf-8 везде, и cp866 в cmd |
Кодировка сценария. |
installer.reversePropPriority |
false |
Вспомогательный параметр, включает приоритет |
installer.pool.limit |
10 |
Лимит на число параллельных запусков. |
installer.props.import |
– |
Дополнительные файлы параметров, указываются через запятую. |
installer.crumb |
Автоматически |
Принудительно указать, использовать ли |
installer.writeJenkinsParams |
false |
Флаг принудительного отключения записи параметров запуска Jenkins job в служебный файл (актуально лишь для режимов отличных от prom). |
installer.jenkinsCount |
5 |
Количество попыток обращения к серверу при запуске удаленной Jenkins job. |
installer.mode |
Не задокументировано |
Не задокументировано. |
installer.interrupt.prop.name |
installerInterrupt |
Путь к файлу, в котором хранится информация об интерактивном вводе данных. |
installer.read.period |
2 |
Время в секундах, через которое считывается файл для перерисовки таблицы и интерактивного взаимодействия. |
installer.git.cred.scenario |
credentials под которыми запущена Jenkins job |
ID Jenkins Credential для доступа к сценарию. |
installer.nexus.full.url |
– |
Адрес Nexus для выгрузки дистрибутива Installer до репозитория включительно. |
installer.nexus.base.url |
|
Базовый адрес Nexus для выгрузки дистрибутива Installer. |
installer.nexus.repo |
Nexus_PROD/ |
Репозиторий с дистрибутивом Installer (не используется в full.url). |
installer.nexus.group |
Nexus_PROD/ |
groupId для дистрибутива Installer. |
installer.nexus.artifactId |
AUTOINSTALLER |
artifactId для дистрибутива Installer. |
installer.jdk.tool |
null |
Имя Java Tooling. |
installer.clean.ws.enabled |
false |
Флаг очистки workspace после выполнения сценария. |
installer.push.service.enabled |
true |
Флаг commit/push служебного файла после выполнения. |
installer.hashiCorp.enable |
false |
Флаг включения работы с HashiCorp. |
installer.hashiCorp.url |
– |
Адрес HashiCorp. |
installer.hashiCorp.logon.url |
/v1/auth/approle/login |
Адрес в API для авторизации HashiCorp |
installer.hashiCorp.nexus.role |
– |
appRole, под которой получаются данные из HashiCorp. |
installer.hashiCorp.nexus.token |
installer.hashiCorp.nexus.role |
То же самое, что и role, оставлено для совместимости с арх. постановкой. |
installer.hashiCorp.nexus.path |
– |
Путь к запрашиваемым Installer данным о пароле Nexus в HashiCorp. |
installer.hashiCorp.secret.path |
– |
Путь к запрашиваемым Installer данным о пароле расшифровки secret-файла в HashiCorp. |
installer.hashiCorp.secret.role |
– |
|
installer.hashiCorp.secret.token |
installer.hashiCorp.secret.role |
То же самое, что и role, оставлено для совместимости с арх. постановкой. |
installer.hashiCorp.second.stage |
true |
Флаг включения второго этапа. |
installer.state |
- |
Список папок, которые, помимо служебного файла, будут загружены в репозиторий сценария (необходимо указывать через запятую). |
installer.extended.debug |
false |
Флаг включения расширенного лога - вывода списка параметров в основной карте. Если true, то выводит на старте сценария, если full, то на каждом шаге. |
installer.secrets.debug |
false |
Флаг включения расширенного лога - вывода списка параметра в карте шифрованны параметров. Если true, то выводит на старте сценария. |
installer.reimport.props |
on |
Флаг, который говорит о том, нужно ли перечитывать файлы параметров на каждом шаге. Для отключения нужно указать off. |
installer.profiling |
false |
Флаг для включения режима профилирования. |
installer.use.bashtemplator |
false |
Флаг использования bashtemplator для шаблонизации сценария, вместо Jinjava (помимо true/false может принимать значение mixed). |
installer.log.level |
DEBUG |
Флаг для изменения уровня логирования. |
installer.cmd.autoset.e |
false |
Флаг, при включении которого, в любые cmd-команды в начало добавляется |
Общая информация#
Назначение#
В основном инсталляционная система служит для запуска скриптов и методов. Однако, она также управляет запуском, обработкой статусов и ошибок, итерациями, параметрами, межмодульным взаимодействием и многим другим. Другими словами, это прежде всего инструмент, под который можно дописывать и модифицировать логику обработки почти любого артефакта. Для упрощения работы такой инструмент уже содержит в себе необходимые скрипты (которые в рамках Installer называются «рецептами»), используемые для решения типовых задач. Подробнее об этом написано в разделе Рецепты по использованию Installer.
Структура Installer#
В состав Installer входят следующие элементы:
Ядро Installer, которое содержит логику обработки пакета установки и некоторые служебные функции.
Модули, которые содержат логику работы с определенным типом артефактов/сервисами, зависимости и пр.
Файл параметров (опционален), который содержит данные о режимах, пути до пакета установки и различные параметры установки.
Общие скрипты – утилиты-рецепты для решения типовых задач установки.
Общие шаги – небольшие сценарии, оформленные в виде импортируемых в сценарий шагов, которые являются своего рода методами для решения типовых задач установки.
Пакет установки, который содержит сценарий, его импортируемые части, и потенциально может содержать дополнительные артефакты, например: используемые сценарием скрипты.
Сценарий, который описывает шаги установки, их последовательность и ссылки на параметры.
Документация, которая содержит данный документ актуальной для данного дистрибутива версии.
Журнал изменений по версиям (changelog).
Список запланированных изменений (tasklist).
Сценарий установки#
Сценарий - это JSON-файл определенной структуры, который описывает шаги установки. По умолчанию это файл tasks.json, располагающийся в корне инсталляционного пакета. Изменить путь к файлу сценария можно указав в настройках секции Properties Content переменную scenarioFile=./путь_к_файлу.json.
Базовая инструкция работы Installer#
Структура сценария#
В корне располагается главный этап. Любой этап содержит следующие поля:
Поле |
Обязательность наличия |
Назначение |
|---|---|---|
name |
Да |
Помогает легче ориентироваться в логах, и обеспечивает связь данных служебного файла и сценария. Должно быть уникальным на одном уровне вложенности, то есть обеспечен уникальный путь из имен. |
steps |
Да |
Содержит список запускаемых на данном этапе шагов, однако шагами могут быть и другие вложенные этапы, аналогичные данному по структуре. |
service_data |
Нет |
Содержит управляющие параметры, такие как последовательность запуска и пр., если их не указать, берутся значения по умолчанию (см. ниже). |
vars |
Нет |
Параметры, применимые к данному шагу/этапу и дочерним. |
Также любой этап может иметь поле import, его значение содержит путь до JSON-файла (относительно рабочей директории), содержимое которого будет встроено в данную локацию. Таким образом можно разделить сценарий на набор файлов: основной сценарий и множество импортируемых субсценариев любого уровня вложенности.
Внутри списка шагов могут располагаться как новые этапы (таким образом можно создать дерево любого уровня сложности), так и непосредственно шаги установки.
Каждый шаг и этап содержит в себе блок служебных параметров: service_data. В этом блоке содержатся параметры, необходимые для управления процессом установки, например указать на количество повторных запусков шага при неудаче.
Раньше эти параметры располагались в теле шага/этапа,
и такой формат все еще поддерживается, но новые сценарии рекомендуется писать следующим образом:
Пример сценария (с некоторыми необязательными элементами):
{
"name": "<имя этапа>",
"service_data": {
"stage_type": "<тип порядка запуска>",
"retry": <число_попыток>,
"timeout": <время_ожидания_между_попытками>,
"transaction": "<id_связанных_этапов>",
"enabled": "<режим_включения_этапа>",
"allowed_status": [
"<допустимый_статус>"
]
},
"steps": [
{
"name": "<имя шага>",
"service_data": {
"type": "<тип_шага>",
"delay": "<время_ожидание_перед_запуском>",
"retry": <число_попыток>,
"timeout": <время_ожидания_между_попытками>,
"transaction": "<id_связанных_этапов>",
"enabled": "<режим_включения_этапа>",
"allowed_status": [
"<допустимый_статус>"
]
},
"step_params": {
"<имя параметра>": "<значение>"
},
"vars" {
"<имя_параметра>": "<значение>"
}
}
],
"vars" {
"<имя_параметра>": "<значение>"
}
}
Или то же самое, но с примером заполнения:
{
"name": "Installer example",
"service_data": {
"stage_type": "parallel",
"retry": 3,
"timeout": 3000L,
"transaction": "editConfigsBind",
"enabled": "on",
"allowed_status": [
"unstable"
]
},
"steps": [
{
"name": "Just print value of 'thisval'"
"service_data": {
"type": "Cmd",
"retry": 1,
"timeout": 1000L,
"transaction": "editConfigsBind",
"enabled": "forced",
"allowed_status": [
"error",
"unstable"
]
},
"params": {
"command": "echo ${thisval}"
}
},
{
"name": "Print 4321",
"service_data": {
"type": "Cmd",
}
"params": {
"command": "echo 4321"
}
}
],
"vars" {
"thisval": "1234"
}
}
В данном примере будет выведено две строки: "1234" и "4321". Поскольку запуск был настроен параллельным, то строки могут выводиться в разном порядке. При том, что число попыток запуска было указано как 2, но по факту выполняться запуск будет лишь 1 раз, поскольку «ошибочный» статус внесен в список дозволенных, и даже при получении ошибки (хотя в данном примере она исключена), шаги отработают все действия.
ID в данном примере не прописаны, поэтому Installer сам дописывает их в файл, проверив перед этим уникальность.
Параметризация и шаблонизация сценария#
На текущий момент установщик поддерживает как шаблонизацию посредством Jinja-шаблонизатора, так и параметризацию.
Рекомендуется использовать Jinja-шаблонизатор.
В этом случае поддерживается весь синтаксис Jinja.
Параметризация же оформляется через placeholder-ы ${KEY}.
В обоих случаях значения берутся из двух источников: глобальной карты параметров (ее источники описаны ниже), и блока vars. Причем в случае с вложенными этапами, параметризация работает рекурсивно - сперва блок параметризуется посредством vars текущего этапа, затем его родителем и так далее, до корневого vars.
При шаблонизации же многоуровневая подмена на данный момент не работает и производится единоразово на самом старте обработки.
Хранение параметров сценария в блоке „vars“#
В корне любого этапа или шага, есть блок vars. В нем можно создавать любые параметры, на которые в дальнейшем можно ссылаться в остальных частях сценариях. В качестве имен параметров может служить любая строка. Формат же ссылки следующий: {{имя_переменной}} или ${имя_переменной}.
Таким образом, если в блоке vars прописано:
"vars": {
"myvar": "world!"
}
, то в любой части сценария (кроме данного блока vars), вы
сможете указать это значение, например так:
"type": "Cmd",
"params": {
"command": "echo Hello {{myvar}}"
}
В этом случае данный шаг выведет строку "Hello world!".
В случае использования вложенных vars (на уровне этапов), приоритет всегда у дочерних vars. Если же аналогичные параметры задаются из других источников (например, из файла
installer.properties), то приоритет имеют первые. Однако, этот режим можно реверсировать, задав параметр installer.reversePropPriority = true.
Хранение параметров сценария в отдельном файле параметров#
Параметры можно задавать через два файла: installer.properties (или yaml), или secrets.properties (или yaml) (имена и пути этих файлов можно переопределить, см. ниже).
Это файлы в форматах properties и yaml, т.е. описанные как:
some.key=value
или
some:
key: val
(комментарии поддерживаются в формате: #комментарий).
При этом secrets* - это файл такого же формата, но зашифрованный либо vault, либо в openssl aes-256-cbc. Пароль для его расшифровки нужно передать параметром, одним из доступных способов (рекомендуемый - аргументы запуска).
⚠️ Важно!
Во избежание проблем несовместимости версий openssl, настоятельно рекомендуется при шифровании файла дополнительно указывать опцию-md md5.
Передача параметров сценария через аргументы запуска Autoinstaller#
Параметры можно также передавать через аргументы запуска. Передача осуществляется в формате ключ=значения, разделяя каждую пару параметров пробелом.
Вы можете либо поправить run.sh/run.bat, добавив в конце строки запуска, после ru.sbrf.Main параметры, либо передавать их при запуске, например:
./run.sh user=zaytsev7-as branch=feature/BSIDO-1815
Дополнительно поддерживается использование vm-аргументов, т.е. внутри исполняемого файла можно прописать -Dkey=value.
Передача параметров сценария через переменные окружения#
Четвертый способ передать значение - это переменные окружения.
В этом случае опять же задается некое имя переменной и ее значение.
Независимо от того, каким способом параметры переданы в Installer, они передаются на уровень всех модулей, и доступ к ним осуществляется через шаблон: {{ имя_переменной }}, или placeholder: ${имя_переменной}.
Передача параметров в процессе выполнения#
Пока данный механизм реализован лишь для Jenkins-версии и позволяет задавать переменные прямо в процессе исполнения в ручном режиме. Для этого в блоке служебных параметров соответствующего шага необходимо задать переменную interrupt. Ее значение - это имя переменной, ссылаться на которую можно будет дальше по сценарию. На данном шаге выполнение сценария приостановится и от пользователя запрошен ввод значения.
Использование ответа скриптов в качестве параметров#
Если вы выполняете некий bash-скрипт, то результаты его выполнения возможно использовать в последующих шагах. Для этого достаточно вывести в качестве ответа строку
следующего формата:
<здесь может быть любой текст> pass_in_map <ключ>=<значение>, <ключ2>= <значение2>, ...
Выполнение команды в командной строке#
Некоторые задачи можно решить посредством командной оболочки (bash, cmd, powershell* и пр.). В Installer это выполняется модулем Cmd. Если вы хотите выполнить команду на той же машине, где располагается Installer (Windows, или Linux), то шаг установки выглядит весьма просто:
"step_params": {
"command": "выполняемая команда"
}
* Использование powershell не проверялось и вероятно потребует небольших доработок, поэтому в данной версии Installer его использование не рекомендовано.
Если вы хотите выполнить многострочную команду для более удобного отображения в файле сценария, а также оформить это с разбиением на строки, то в качестве значения можно передавать список строк, например:
"step_params": {
"command": [
"for i in ${!array[@]} do",
"if ! grep -R '^[#]*\\s*${i}: .*' $file > /dev/null",
"then echo -e '\n$i: ${array[$i]}' >> $file",
"else",
"sed -ir 's/^[#]*\\s*${i}: .*/$i=${array[$i]}/,' $file",
"fi",
"done"
]
}
При этом нужно иметь в виду, что символ
";"перестал добавляться Installer в конце каждой строки и в случае необходимости, должен добавляться вами самостоятельно.
В случае, если у вас получается большой скрипт, то лучше будет вынести его в отдельный файл и вызывать его простой командой: "chmod 755 файл; ./<файл агрументы>".
В случае же, если вам необходимо выполнить команду на удаленном linux сервере, то в качестве параметров необходимо также передать еще и следующие: ip, user, pass, port (если не указать, используется 22).
Например:
"step_params": {
"ip": "8.8.8.8",
"user": "${osUser}",
"pass": "${osPassword}",
"port": 22,
"command": [
"for i in ${!array[@]} do",
"if ! grep -R '^[#]*\\s*${i}: .*' $file > /dev/null",
"then echo -e '\n$i: ${array[$i]}' >> $file",
"else",
"sed -ir 's/^[#]*\\s*${i}: .*/$i=${array[$i]}/,' $file",
"fi",
"done"
]
}
Разумеется, вместо написания множества команд всегда можно написать скрипт и вызвать его с нужными параметрами в шаге Installer (этот вариант является рекомендованным).
Импорт дополнительного файла в сценарии#
В сценарии также поддерживается возможность разделять его на
несколько отдельных файлов, и объединять посредством переменной import.
Это позволяет выделить, например, сложную логику какого-то шага в отдельный файл,
и даже переиспользовать его в нескольких местах одного сценария.
Выглядеть это будет в итоге примерно так:
{
"main": {
"name": "Основной этап",
"steps": [
{
"import": "newsub1.json"
},
{
"import": "newsub2.json"
}
]
}
}
Настройка Installer на полигоне#
Для настройки Jenkins job запуска, необходимо настроить Pipeline на репозиторий в используемом домене.
Например:
https://<...>/projects/DEVOPSEFS/repos/autoinstaller-assembly/browsehttps://<...>/stash/projects/DEVOPSEFS/repos/autoinstaller-assembly/browse
На файл runner-pipeline.groovy в переменных окружения Jenkins можно указать node.
Список параметров, которые необходимо задать:
Параметр |
Назначение |
|---|---|
taskUrl |
Url репозитория, из которого планируется выбрать сценарий установки (и в который будет опубликованы результаты). |
taskBranch |
Ветка в этом репозитории, из которой будет взят сценарий установки. |
taskDir |
Директория, в которой располагается сценарий установки ( |
taskFile |
Имя файла сценария в указанной директории. |
installerUrl |
Полный адрес расположения используемого дистрибутива Installer (используйте значение по умолчанию, если не требуется использовать какую-либо иную версию). |
vmArgs |
Аргументы запуска, которые можно передавать сценарию (один из способов. Подробнее о способах передачи параметров, читайте в документации Installer.). В частности с их помощью можно передать пароль для расшифровки файла, |
nexusCred |
Credentials вида «пользователь/парoль», под которым происходит подключение к Nexus для выгрузки дистрибутива Installer. |
gitCred |
Credentials, под которым происходит подключение к git для выгрузки сценария (если не указать, берет тот же, под которым работает Jenkins job). |
innerCred |
Credentials, в котором можно указать пароль для расшифровки файла параметров (вместо указания его через |
Часто встречающиеся проблемы и пути их устранения#
Если при установке артефакта в Nexus выводится PKIX ошибка, то можно произвести запуск с флагом
-Dmaven.wagon.http.ssl.insecure=trueВо избежание проблем несовместимости версий openssl, настоятельно рекомендуется при шифровании файла дополнительно указывать опцию
-md md5В режиме prom, из-за того что параметризация секретных параметров ведется только перед выполнением шага, изменение таких параметров не будет восприниматься Installer, как изменение, что не приведет к перезапуску шага. Если вам требуется, чтобы на такое изменение происходил перезапуск, нужно связать его с каким-либо дополнительным изменением. (по идее, уже не актуально)
На некоторых инсталляциях Jenkins данный функционал не может работать корректно из-за ошибки кросс-доменных запросов.
Ссылки#
Подробную информацию о Jenkins job для запуска Installer можно узнать в статье – Installer job.
Продвинутая инструкция работы с Installer.
Рецепты по использованию Installer.