Сказ про то, как я DevOps-ом занимался (OneScript, Deployka, Jenkins)

Решаем задачу: автоматизировать обновление тестовых баз 1С из хранилища конфигурации при появлении в нём новых изменений. Данная статья родилась в муках хождения по граблям и поиска безопасного форватора среди подводных камней. Изложение постарался представить в виде инструкции для новичка, в которой собрал всё, с чем пришлось столкнуться.
Сам я не DevOps-ер, ни на что не претендую, просто делюсь опытом 🙂

Вводная

Обзаводимся софтом

Составление сценария запуска

   Запуск RAS как сервис

Установка Jenkins

   Решение проблемы занятого порта 8080

      Вариант 1. Как открыть порт в брендмауэре Windows

      Вариант 2. Как переопределить рабочий порт Jenkins

   Первоначальная настройка и установка плагинов

Настройка проекта в Jenkins

Вместо заключения. Запуск сценария и мониторинг результата

Перед началом хочу поблагодарить коллег из коллективов SilverBulleters и xDD за бесценную консультационную поддержку.

Итак, поехали!

Вводная

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

Обзаводимся софтом

Для решения задачи нам понадобится:

С установкой OneScript затруднений никаких не возникает. После установки самого 1Script, ставим Деплойку из командной строки:

opm install deployka

Консоль командной строки должна быть запущена под администратором. И нужно самому быть администратором на машине, где происходит сие представление. Понимаю, совет банальный, но у меня были затруднения из-за корпоративных политик безопасности нашей компании, поэтому предупреждаю.

На установке 1С-ки вообще не вижу смысла останавливаться 🙂 Переходим к сути.

Составление сценария запуска

Сам сценарий работы с deployka взят из примера и адаптирован "под себя". Собственно, самих изменений немного, вот результат сценария команд, который у меня получился в результате:

deployka session lock -ras dev-td:2845 -rac "C:Program Files1cv88.3.10.2466in
ac.exe" -db "zup cb fin test" -db-user "Admin" -lockmessage "Плановое обновление" -lockuccode update

deployka session kill -ras dev-td:2845 -rac "C:Program Files1cv88.3.10.2466in
ac.exe" -db "zup cb fin test" -db-user "Admin" -lockmessage "Плановое обновление, 5 мин" -lockuccode update

deployka loadrepo "/IBConnectionString""Srvr=dev-td:2841;Ref='zup cb fin test'""" \dit-dev11C-Storage8.3hrm_test_fin -db-user "Admin" -storage-user admin -storage-pwd 777 -uccode update

deployka dbupdate "/IBConnectionString""Srvr=dev-td:2841;Ref='zup cb fin test'""" -db-user "Admin" -allow-warnings -uccode update

deployka session unlock -ras dev-td:2845 -rac "C:Program Files1cv88.3.10.2466in
ac.exe" -db "zup cb fin test" -db-user "Admin"

То есть, порядок такой:

  1. Блокируем сессии для входа в базу, оставляем себе лазейку в параметре -lockuccode;
  2. Убиваем все текущие сессии;
  3. Загружаем изменения конфигурации из хранилища. Тут столкнулся с проблемой правильного написания строки соединения с базой, которую требует первый параметр команды loadrepo. Решения было найдено здесь (есть пример строки подключения для файловой и клиент-серверной базы);
  4. Обновляем конфигурацию базы данных. Здесь ключевой момент — наличие ключа -allow-warnings. Он необходим на случай, если в конфигурации были изменения структуры, то их необходимо принять безоговорочно. В интерактивном режиме мы привыкли видеть дополнительное окно с перечислением изменений структуры, в котором нажимаем на кнопку "Принять", после чего обновление успешно завершается. Так вот, ключ -allow-warnings как раз "нажимает" на эту кнопку;
  5. Снимаем блокировку сессий, чтобы с базой могли работать пользователи.

Какие здесь есть нюансы:

  • Сервер RAC используем той версии платформы, на которой крутится целевая база;
  • Имя пользователя прописываю латиницей (завёл отдельного пользователя для этого). Когда используешь командную консоль, Jenkin и еще какой-нибудь редактор текста, то договориться между ними о кодировках кириллицы — это отдельный тур вальса с бубном, на нём останавливаться не буду.
  • Предварительно должен быть запущен сервер RAS.

Запуск RAS как сервис

Сервер RAS можно разово запустить отдельным bat-файлом, а можно запустить его как сервисную службу. Я пошёл вторым путём, команда для запуска следующая:

sc create "1C:Enterprise RAS" binpath=""C:Program Files1cv88.3.10.2466in
as.exe" cluster --service --port=2845 localhost:2840"

Номера портов следует прописывать, исходя из того, на каких портах "сидит" соответствующий сервер 1С: Предприятия.

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

На данном этапе сценарием уже можно пользоваться из командной строки или в виде bat-файла. Но наша задача — обернуть ещё это всё в CI и автоматизировать процесс.

Установка Jenkins

Скачиваем установочный пакет под нужную ОС по ссылке в начале статьи.

Запускаем, устанавливаем всё по умолчанию. После установки, Jenkins будет доступен из браузера по адресу: localhost:8080. Должен появиться приветственный экран Jenkins:

Рисунок 1. Приветственная страничка Jenkins

Рисунок 1

Если экран появился, можно переходить к первоначальным настройкам системы. В противном случает придётся еще побороться с закрытым портом 8080.

Здесь описан порядок подключения на локальной машине. В общем случае, в адресной строке браузера следует писать IP сервера, на котором установлен Jenkins: http://[IP-адрес сервера]:8080

Про более сложную распределенную установку Jenkins на сервере/клиентах написано здесь.

Другие способы установки Jenkins:

 

Решение проблемы занятого порта 8080

Если после установки Jenkins в браузере появляется что угодно, но только не то, что изображено на рисунке 1, значит порт 8080 на вашем компьютере закрыт или занят другим приложением (PS а заодно проверьте статус работы сервиса Jenkins и наличие оперативной памяти, Jenkins потребляем от 256Мб до 1Гб оперативы). Решения проблемы два: либо открыть порт средствами Windows, либо переопределить номер порта для Jenkins.

Вариант 1. Как открыть порт в брандмауэре Windows

Открываем брандмауэр: нажимаем [Win+R], даём команду firewall.cpl. В открывшемся окне переходим в «Дополнительные параметры», затем открываем раздел «Правила для входящих подключений». Должно появиться окно:

Рисунок 2

В правой колонке нажимаем «Создать правило…».

Шаг 1. Выбираем тип правила «Для порта» и нажимаем «Далее».

Рисунок 3

Шаг 2. В поле «Определённые локальные порты» вводим номер нашего порта 8080, и нажимаем «Далее»

Рисунок 4

Шаг 3. Выбираем вариант «Разрешить подключение» и жмём «Далее»

Рисунок 5

Шаг 4. Оставляем всё по умолчанию и нажимаем «Далее»

Рисунок 6

Шаг 5. На заключительном шаге указываем имя для нового правила файервола и нажимаем «Готово».

Рисунок 7

Если и после этого Jenkins не запустится, добавьте еще одно такое же правило, только на шаге 2 укажите правило UDP.

Вариант 2. Как переопределить рабочий порт Jenkins

Чтобы Jenkins подключался к другому порту, в файле Program FilesJenkinsjenkins.xml нужно найти ключ:

--httpPort=8080

и поменять номер на желаемый, после чего перезапустить сервис Jenkins.

Первоначальная настройка и установка плагинов

После того, как установка выполнена, в браузере мы попадаем в окно приветствия (см. Рисунок 1). Здесь нужно вставить пароль из файла Program FilesJenkinssecretsinitialAdminPassword и нажат «Продолжить». На следующем шаге выбираем режим установки плагинов: Install suggested plugins.

Рисунок 8

Для решения нашей задачи нам понадобится плагин Filesystem Trigger Plug-in, его и устанавливаем.

После установки создаём профиль администратора, имя пользователя и пароль запоминаем для использования в дальнейшей работе. Нажимаем «Продолжить», на экране появится сообщение, свидетельствующее о готовности Jenkins к работе.

Рисунок 9

Нажимаем «Start using Jenkins» и переходим в рабочую панель системы.

Дополнительно:

 

Настройка проекта в Jenkins

Теперь, когда Jenkins настроен и готов к работе, создадим наш сценарий. Выбираем на главной странице Jenkins команду «Создать Item» («New Job»). Задаём название нашему проекту, выбираем тип «Создать задачу со свободной конфигурацией» («Free-style project») и нажимаем OK.

Рисунок 10

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

Рисунок 11

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

Устанавливаем флажок [FSTrigger] — Monitor files, далее ставим флажки Inspect fila contents (собственно проверка, а не поменялся ли файл?) и Ignore modification data (дабы избежать ложных срабатываний сценария). В поле File Path прописываем полный путь к файлу *.1cd хранилища конфигурации.

В поле «Расписание» («Schedule») прописываем строку: */15 * * * *. Это означает, что проверка изменений файла (а значит и необходимости дальнейшего запуска сборки) будет выполняться каждые 15 минут. Подробнее о формате написания этой строки можно почитать в справке, которая открывается по «знаку вопроса» справа от поля ввода.

Рисунок 12

В разделе «Сборка» выбираем команду «Добавить шаг сборки – Выполнить команду Windows», и в появившемся поле ввода прописываем команду соответствующего шага. Затем повторяем то же самое для остальных шагов. В результате должно получиться то, что показано на рисунке 13.

Рисунок 13

Еще один вариант:

 

Нажимаем «Сохранить».

Поздравляю! Вы автоматизировали одну из рутинных операций в своей работе. Добро пожаловать в мир DevOps-а! :))

Вместо заключения. Запуск сценария и мониторинг результата

После сохранения сценария открывается страница управления этим сценарием. Если выбрать команду «Собрать сейчас», то сценарий будет запущен, а результат появится в разделе «История сборок».

Рисунок 14

Из контекстного меню конкретного запуска сценария можно через команду «Console Output» посмотреть детали выполнения.

Рисунок 15

Также запустить сценарий можно из контекстного меню конкретного проекта в списке главного окна системы.

Рисунок 16

 

32 Comments

  1. necropunk

    Плюс за первопроходчество. Вечно нет времени нормально полазить по граблям.

    Reply
  2. sytkosa

    Однозначно плюс за информацию. Автор можешь добавить код для файловых баз в статью для полноты картины ?

    Reply
  3. olegtymko

    (1) Так Серебрянная пуля давно это делает и методичку выпустила.

    Reply
  4. Gureev

    Можете обосновать выбор дженкинса взамен обычного шедулера?

    И почему не PoSh?

    Reply
  5. awk

    С кодировкой проблем нет. Просто надо прописать в реестре: HKCUConsoleCodePage = 65001

    Reply
  6. awk

    (4) А обычный шедулер умеет консолидировано запускать задачи на разных серверах?

    Reply
  7. ImHunter

    (6) Это уж слишком «продвинутый» пример)

    (4) На примере публикации — если внимательно прочитать, то можно увидеть, что используется не просто шедулинг. Этот шедулинг зажигает триггер в зависимости от модифицированности отслеживаемого файла. Аналогично такое сделать на ПоШ — уже думать надо.

    Можно немного развить тему публикации и повысить безопасность — Дженкинс позволяет хранить пароли в специальном хранилище. И их (пароли) можно потом не хардкодить в скрипты. Как аналогичное сделать в ПоШ — сходу и не знаю.

    Вообще, публикация охватывает совсем маленький кусочек функционала Дженкинс’а. И кажется, что зачем он (Джен) вообще нужен. Но аппетит приходит во время еды.

    Захотим мы, к примеру, выгружать cf обновленной конфы в artifactory. В Джен мы добавим 2-3 шага. И это заработает.

    В ПоШ, да, мы тоже это сможем сделать. Только сначала почитаем кучку доков, (напишем-отладим) * N раз. И потратим на это в 10 раз больше времени и нервов.

    Reply
  8. necropunk

    (3) При всем уважении к их безусловно полезному труду — пару раз пробовал осилить, еще до методички, но времени катастрофически не хватало. А сейчас читаю — и узнаю проблемы, на которые натыкался. Думаю, я не один такой, может кому поможет и хорошо. Все-таки лично мне по этому пути пока тяжеловато следовать.

    Reply
  9. Gureev

    (6) обычный шедулер умеет запускать задание по расписанию ) легко, быстро, не жрет ресурсы, и не требует установки)

    Задания пишутся в скрипте на питоне или ПоШе, которые умеют намного больше чем дженкинс)

    Reply
  10. Evil Beaver

    Супер, спасибо за статью

    Reply
  11. t.v.s.

    (10)А по событию из системы контроля версий умеет? А отслеживать изменения, и запускать билд, только когда что-то поменялось?

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

    Reply
  12. t.v.s.

    (3) А где почитать эту самую методичку?

    Reply
  13. ImHunter

    (13) Ну видишь ли, мы привыкли к простому/хорошему. А ты, вероятно, си-шник в душе?

    Reply
  14. Gureev

    (14) Не люблю когда пиццу доставляют камазом)

    Reply
  15. t.v.s.

    (13) Не хочу спорить. Любую задачу можно решить сотней разных способов, каждый выбирает для себя.

    Reply
  16. olegtymko

    (12) Я покупал у Серебряной пули. Можно посмотреть на их сайте.

    Reply
  17. herfis

    Плюс не глядя (почти).

    Reply
  18. awk

    (10) Когда напишите подобие TeamCity, TFS или Jenkins — дай знать, я заценю… :)))

    Reply
  19. pumbaE

    sleep не хватает пред тем как делать kill, если же это не быстрый bugfix.

    Теоретически алгоритм должен быть таким:

    lock
    loadrepo
    sleep (до времени, которое поставили в lock)
    kill
    dbupdate
    unlock
    
    Reply
  20. grumagargler

    (7) еще один вариант 🙂 всё в тестере написать, на 1с, и работу по блокировке пользователей, и пакетный запуск конфигуратора и мониторинг изменения файла по расписанию или событию (правда компонента только под виндовс).

    Reply
  21. Gureev

    (19) Зачем?

    Reply
  22. herfis

    (13) Не куда пихается, а по прямому назначению — для сборки и диплоя.

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

    Reply
  23. awk

    (22) Так Jenkins то же со скриптов начинался… Хочешь изобретать велосипед — изобретай. Получиться лучше — буду использовать.

    Reply
  24. awk

    (20) Мое почтение. И конвеера должно быть два (если по феншую):

    1. сборка (copydb, loadrepo, test, publish) — запускать по изменению хранилища

    2. обновление (loadcf,backup, updatedb, userupdate) — запускать по расписанию и наличию обновления

    Reply
  25. nicxxx

    фарватер 🙂

    Reply
  26. lustin

    (17) https://isthisdesign.org/bookoneorder

    Это печатный вариант — настройка gitLab, Jenkins + OScript

    Reply
  27. kuzyara

    (26) ?

    Reply
  28. boggonzikov
    кодировках кириллицы — это отдельный тур вальса с бубном, на нём останавливаться не буду.

    Мне помогло:

    1. jenkins.xml

    <arguments>-Xrs -Xmx256m -Dfile.encoding=UTF-8 -Dhudson.lifecycle=hudson.lifecycle.WindowsServiceLifecycle -jar «%BASE%jenkins.war» —httpPort=8181 —webroot=»%BASE%war»</arguments>

    2. Изменить кодировку в консоли

    chcp 65001

    Reply
  29. Pavel_Dv

    Никто не сталкивался?

    Подозреваю что косяк в настройка сервера, на тестовом все ОК. Пока не пойму, куда копать

    Службы запущены, пользователь админ как базы, так и кластера, так и сервера…

    C:Windowssystem32>deployka scheduledjobs lock -ras localhost:1545 -rac «C:Pro

    gram Files (x86)1cv88.3.12.1469in
    ac.exe» -db «BASENAME» -cluster-admin «USR1CV8_

    RAS» -cluster-pwd «PASSWORD» -db-user «USR1CV8_RAS» -db-pwd «PASSWORD»

    ИНФОРМАЦИЯ — Получаю список кластеров

    ИНФОРМАЦИЯ — Получаю список баз кластера

    ИНФОРМАЦИЯ — Получен УИД базы

    КРИТИЧНАЯОШИБКА — {Модуль C:Program Files (x86)OneScriptlibdeploykasrcКлас

    сыКомандаУправлениеСеансами.os / Ошибка в строке: 482 / Сообщение от RAS/RAC

    server_addr=tcp://S01-1C01_01:0 descr=10.2.0.128:10049(0x00002741): Требуемый ад

    рес для своего контекста неверен. ;

    line=1056 file=srcDataExchangeTcpClientImpl.cpp

    Reply
  30. Pavel_Dv

    Разобрался. Проблема Deployka в том, что она позволяет управлять только одним кластером на сервере.

    На нашем 3 кластера.

    О данной проблеме известно давно, но до реализации не дошло. Может кто знает обходные пути?

    https://github.com/oscript-library/deployka/issues/33

    Reply
  31. AntonSm

    (31) деплойка не развивается.

    Попробуйте vannesa-runner из того же сообщества.

    Весь функционал переехал в него.

    Reply
  32. Pavel_Dv

    Уже осознал и переписал скрипты под runner

    Проблема в конечном итоге была такая:

    На кластере было 2 рабочих сервера. И ни в runner, ни в deployka не нашлось аргумента для выбора нужного сервера.

    Решение:

    Удалили второй рабочий сервер с кластера (к счастью был создан очень давно и не использовался).

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *