Предпосылки
Да, мы традиционной ориентации староверы. Работаем в Конфигураторе, пользуемся хранилищем. Но уже испорчены влиянием opensource. И уже давненько выгружаем наши конфигурации в местный git.
Зачем?...
- Ну удобно делать codereview. Правда, это пока получается почти постфактум, когда уже продуктив актуализирован до состояния хранилища.
- Удобно смотреть blame (вину?) - какой участок кода каким коммитом был изменен.
- Также видна история коммитов по определенному объекту.
Несколько лет назад ввели в инфраструктуру Jenkins. Он, в том числе, занимался выгрузкой хранилищ в местный наш git.
Реализованная на тот момент инфраструктура уже устарела - и структурно, и программно. Все работало на одном сервере Jenkins, без использования slave-узлов. Использовалась старая версия gitsync (которая еще без плагинов). Наконец, git-сервер (Bonobo) предоставлял самый базовый интерфейс и функционал. Настало время уже все поменять, обновить и улучшить. Все это в Windows-окружении.
Реализация
Ребята, полного и пошагового руководства здесь не будет. Ведь есть подробные статьи на эту тему: про Jenkins [1], про gitsync [2], и книга Mastering Jenkins. Расскажу лишь некоторые моменты, которые могут помочь в ваших реализациях.
Таки вот общая картинка прохождения процесса выгрузки хранилища в git.
- Jenkins-master дает команду своему подчиненному (Jenkins-slave) выполнить некое действие (1).
- А именно, выполнить команду библиотеки gitsync (2).
- gitsync читает изменения в хранилище (3), вычитывает необходимые и отправляет их в удаленный git-репозиторий (4).
Дальнейшее повествование будет несколько хаотичным - от менее объемных описательных частей к более крупным. И прошу прощения за не слишком техническое изложение - не являюсь штатным devops-инженером, а лишь энтузиастом.
Клиент git
Администраторы нам предоставили виртуальный Windows Server. Это не тот, на котором уже крутится действующий Jenkins, это новая единица.
Поскольку мы собираемся выполнять операции с git-репозиториями, то устанавливаем git-клиент.
Сервер git
Решено новый git-сервер развернуть на этой же предоставленной виртуальной машине. Для установки выбрали Gitea.
Процесс установки подробно расписан на домашней странице продукта, трудностей не возникло. Для работы Gitea требуется использование СУБД - также развернули Postgree, из поставки 1С. Не забываем для Gitea открыть порт в брандмауэре (3000 по умолчанию).
OScript
Этим интерпретатором мы будем выполнять команды, предоставляемые библиотеками автоматизации. Одна из библиотек - это gitsync, о ней напишу чуть позже.
Лучше устанавливать не в Program files. Так меньше проблем при обновлении библиотек или при их конфигурировании.
Библиотеки замечательно устанавливаются/обновляются пакетным менеджером opm. Также можно настроить работу менеджера через прокси - об этом написано на странице проекта. Кажется, когда-то раньше работа opm через прокси не поддерживалась. Приходилось идти на поклон администраторам для временного прямого доступа в интернет.
Jenkins
В нашей инфраструктуре уже есть работающий сервер Jenlins. Но мы хотим разгрузить его от трудоемких операций. Поэтому на предоставленной виртуальной машине будет работать Jenkins-агент, выполняющий задания мастера.
Как описано в документации Jenkins и в различных статьях, есть несколько режимов работы агентов. Поскольку мы работаем в Windows-окружении, то изначально я планировал запускать агентов в режиме Let Jenkins control this Windows agent as Windows service. Но что-то пошло не так, пара попыток сопряжения мастера и агента так и не увенчались успехом. Это, кстати, отодвинуло реорганизацию на полгода.
Во второй (успешной) попытке решили строить взаимодействие мастера и агента в режиме Launch agent by connecting it to the controller. В этом режиме на подчиненном узле должно быть постоянно запущено java-приложение, являющееся тем самым агентом.
Как описано в [1] , в настройках безопасности задаем порты, по которым будут общаться мастер и подчиненные. Выберем статическое значение, откроем порты на мастере и подчиненном в их брандмауэрах.
В статье [1] рассматривается динамическое создание инфраструктуры. При этом происходит запуск агента средствами автоматизации развертывания. Но в нашем случае вся инфраструктура "статична". И вот каким-то образом нужно автоматически запускать приложение агента - например, при перезапуске сервера с агентом.
На помощь приходит обертка WinSW. Удобно! Работает в виде службы, может обновлять файл агента перед запуском.
Работа обертки настраивается конфигурационным xml-файлом. И тут есть нюанс - имена узлов и атрибутов регистрочувствительны. Например, вот такой фрагмент конфигурационного файла не даст запустить службу:
<stoptimeout>5000</stoptimeout>
Приведем его к требуемому:
<stopTimeout>5000</stopTimeout>
В журнале событий системы при этом пишутся ошибки с какими-то ненайденными/неточными реквизитами. Можно в документации особо и не вычитывать, а править по месту возникновения.
В узле download пропишем адрес, откуда подгружать файл агента, под каким именем сохранять локально.
В настройках путей есть фрагмент %BASE% - несложно догадаться, что это каталог, где расположен исполняемый файл WinSW. В моей реализации начально скачанный файл агента я разместил именно в нем.
Над содержимым <arguments> особо думать не нужно - просто скопируйте строку запуска из предлагаемой Jenkins'ом при настройке slave-узла. Только запускающее приложение (java.exe) нужно перенести в <executable>. Где берется командная строка запуска агента - опять же, смотрим в [1].
Gitsync
Как писал выше, это одна из библиотек хаба OScript. Про установку библиотеки написано в [2]. Опять же, коснусь только специфических моментов. А именно плагинов gitsync.
По нашей задаче мы должны закинуть содержимое хранилища на удаленный git-репозиторий. Соответственно, мы должны подключить нужный плагин (sync-remote).
Инициализируем плагины:
gitsync p init
Разрешаем использование всех плагинов:
gitsync p e -a
Проверям, что у нас теперь с плагинами - выводим список активных:
gitsync p ls
Видим нечто подобное:
C:\Windows\System32>gitsync p ls
Каталог плагинов: <C:\OneScript\lib\gitsync-installed-plugins>
Список плагинов:
[on] [1.3.0] - increment - Плагин добавляет возможность инкрементальной выгрузки в конфигурации
[on] [1.3.0] - limit - Плагин добавляет возможность ограничения на минимальный, максимальный номер версии хранилища, а так же на лимит на количество выгружаемых версий за один запуск
[on] [1.3.0] - check-authors - Плагин добавляет функциональность проверки автора версии в хранилище и файла AUTHORS [on] [1.3.1] - check-comments - Плагин добавляет функциональность проверки комментариев в хранилище
[on] [1.4.1] - smart-tags - Плагин добавляет функциональность автоматической расстановки меток в git
[on] [1.3.0] - tool1CD - Плагин заменяет использование штатных механизмов 1С на tool1CD при синхронизации
[on] [1.3.0] - unpackForm - Плагин добавляет функциональность распаковки обычных форм на исходники
[on] [1.3.0] - disable-support - Плагин снимает конфигурацию с поддержки перед выгрузкой в исходники
[on] [1.3.0] - sync-remote - Плагин добавляет функциональность синхронизации с удаленным репозиторием git
[on] [1.3.0] - edtExport - Плагин добавляет возможность выгрузки в формате EDT. Важно: Для работы плагина необходимы установленные EDT и Ring
[on] [1.0.0] - replace-authors - Плагин добавляет функциональность замены автора коммита
Стоит обратить внимание на плагин edtExport. В его описании не зря написано, что:
Важно: Для работы плагина необходимы установленные EDT и Ring
Даже если вы не планируете использовать этот плагин (не будете указывать его специфические ключи), плагин все равно будет инициализироваться при выполнении команд gitsync. И это может привести к ошибке вида:
КРИТИЧНАЯОШИБКА - {Модуль C:\OneScript\lib\gitsync-installed-plugins\gitsync-plugins\src\Классы\edtExport.os / Ошибка в строке: 148 / Не заполнено имя проекта}
Поэтому плагин следует деактивировать.
А теперь про пути установленных плагинов...
Если посмотреть на лог вывода установленных плагинов, то видим, что в нем выводится путь (Каталог плагинов), где расположены установленные плагины. Если не предпринять специальных действий, то плагины будут установлены в профиле пользователя. Это может привести к тому, что отлаженный скрипт вдруг не станет работать под управлением Jenkins. Например, мы залогинились на настраиваемом сервере под своей доменной учеткой, отладили работу скрипта выгрузки хранилища. Но не приняли во внимание, что агент Jenkins у нас работает, скорее всего, под другой учеткой. Агент поищет плагины в своем профиле и, конечно, не найдет. И свалит задачу сборки с ошибкой...
Чтобы избежать этого, нужно явно в системе прописать путь, куда будут устанавливаться плагины. Для этого пропишем каталог плагинов в любую из переменных среды:
- GITSYNC_PLUGINS_PATH
- GITSYNC_PLUGINS_DIR
- GITSYNC_PL_DIR
Про эти переменные, кстати, не написано в документации - пришлось покопаться в исходниках.
Настройка сборочной линии
Самое первое - нужно определиться с учеткой, от имени которой будет работать агент. Например, у этой учетки должны быть доступы к сетевым файловым ресурсам (к хранилищу, то бишь). Соответственно, работу обертки WinSW тоже нужно настроить на запуск от имени этой учетки.
Про gitsync и его плагины написано выше. Устанавливаем по фиксированному пути, настраиваем состав плагинов.
Для задачи синхронизации хранилища с удаленным репозиторием git нужен и локальный репозиторий. Определяем (создаем) каталог с локальным репо. Инициализируем git-репозиторий - выполняем git init или пользуемся каким-либо интерактивным инструментом типа TortoiseGit.
Если инициализировать репозиторий не под специальной учеткой для агента, то в запусках сборки мы можем поиметь ошибку вида:
fatal: unsafe repository ('C:/Jenkins/1C_confs/Конфигурация' is owned by someone else)
To add an exception for this directory, call
git config --global --add safe.directory 'C:/Jenkins/1C_confs/Конфигурация'}
Предлагаемый (git'ом) в ошибке рецепт у меня так и не сработал. Расширение прав безопасности для учетки агента тоже не дало эффект. В итоге, воспользовался материалом статьи и применил команду TAKEOWN - сделал всех администраторов владельцами репозитория:
takeown /F c:\Jenkins /A /R
Затем инициализируем этот же репозиторий командой gitsync init.
Для сборочной линии используем обычный freestyle-проект (задача со свободной конфигурацией). В этой задаче добавляем шаг сборки - Выполнить команду Windows. Пишем скрипт для выполнения синхронизации.
Для скрипта удобно воспользоваться возможностью передавать параметры скрипта через переменные окружения. И тогда скрипт будет иметь понятный вид:
set GITSYNC_STORAGE_PATH=\\DEVEL\stg\УОР\Конфигурация\
set GITSYNC_WORKDIR=1C_confs\Конфигурация
set GITSYNC_REPO_URL=http://reposerver:3000/gitsync/uor.main.stg.git
set GITSYNC_STORAGE_USER=user
set GITSYNC_DOMAIN_EMAIL=domain.ru
set GITSYNC_EMAIL=domain.ru
set GITSYNC_TEMPDIR=1C_confs\gitsync.tmp
set GITSYNC_REMOTE_PUSH_N_COMMITS=2
set GITSYNC_LIMIT=0
set GITSYNC_REMOTE_PUSH_TAGS=true
set GITSYNC_REMOTE_PUSH=true
set GITSYNC_SKIP_EXISTS_TAGS=true
set GITSYNC_TASK_PREFIX=#
gitsync s --numerator
Не забываем про метки в линии сборки и в настройках slave-узла, чтобы собрать именно на нужном сервере.
Заключение
Ну вот, с удовлетворением прочитали в консоли задачи сборки:
ИНФОРМАЦИЯ - Завершено выполнение команды <sync>
Started calculate disk usage of build
Finished Calculation of disk usage of build in 0 seconds
Started calculate disk usage of workspace
Finished Calculation of disk usage of workspace in 7 second
Finished: SUCCESS
Теперь историю разработки можем смотреть без долгих вычитываний из хранилища. Возможно, захотим еще и натравить bsl-сервер на полученный репозиторий. А может еще и замутим авто-сборку подключаемых отчетов и обработок через git-репозиторий. Но это уже другие истории.
Надеюсь, что кому-то статья поможет обойти грабли. Всем удач в автоматизации!