Потрібно було мені налаштувати процес складання та доставки на сайт пакетів програм з Git-репозитарію. І побачивши, не так давно, тут на Хабре статтю з buildbot (посилання в кінці) вирішив для цього спробувати його і застосувати.
Так як buildbot - це розподілена система, то буде логічним під кожну архітектуру та операційну систему зробити окремий складальний хост. У нашому випадку це будуть LXC-контейнери (у разі linux) та qemu (у разі windows):
vm-srv-build1 - centos 7, тут буде buildbot майстер (master) і один з робітників (worker)
vm-srv-build2 — debian 10, для збирання DEB пакетів
vm-srv-build3 - windows 10, для складання, самі розумієте, під що
Збирати будемо Rac GUI - Графічна морда до 1С rac для управління кластером серверів. Під лінукс будуть використовуватися штатні засоби під кожну ОС, для збирання exe-файлу під windows з tcl-скрипту використовується безкоштовна обгортка.
Встановлення
GNU / Linux
Щодо встановлення, документації в мережі достатньо 1,2. Та й особливих проблем вона не викликає:
Для майстра:
Звичайно, правильнішим буде зібрати пакети під кожну ОС, але це до рамок статті не входить. Також опустимо опис налаштування контейнерів для роботи, зазначу лише, що використовую ProxMox VE. І ще потрібно встановити пакети під кожну вісь, необхідні для складання (centos: rpmdevtools і т.д; debian: build-essential, dh-make, pbuilder і т.д.)
Складання проектів та сервіси buildbot запускатимуться від імені непривілейованого користувача, тому необхідно його створити на всіх хостах, що беруть участь у процесі:
adduser buildbot
Далі налаштуємо автоматичний запуск сервісів відповідно на кожному з хостів (контейнерів):
Після цього можна створити інфраструктуру каталогів для «робітників» (на всіх хостах), для цього реєструється під користувачем buildbot і виконуємо наступні команди:
На першому хості vm-srv-build1:
su - buildbot
mkdir /home/buildbot/worker
cd ~
buildbot-worker create-worker --umask=0o22 --keepalive=60 worker vm-srv-build1:4000 CentOS 123456
На другому хості vm-srv-build2:
su - buildbot
mkdir /home/buildbot/worker
cd ~
buildbot-worker create-worker --umask=0o22 --keepalive=60 worker vm-srv-build1:4000 Debian-10 123456
На хостах-робочих службу buildbot-worker можна запустити
systemctl start buildbot-worker
MS Windows
Як «робочий» для складання під windows, буде використано віртуальну машину з останнім релізом Win10.
Для роботи знадобиться:
Після того, як встановиться все перераховане вище, можна поставити і сам buildbot:
pip install buildbot-worker
Створимо робочий каталог
md c:worker
І запустимо
buildbot-worker start c:worker
Якщо все працює (див. лог c:workertwistd.log), то можна нашого «робітника», зареєструвати як службу, додавши до реєстру пункт з робочим каталогом (команди виконуються в powershell запущеному від імені адміністратора):
З «робітниками» на цьому все, далі їх можна не чіпати, все керування йде з майстра.
Налаштування майстра
Для початку створимо інфраструктуру для майстра (на головному хості), для цього реєструється під користувачем buildbot і виконуємо наступні команди:
su - buildbot
mkdir /home/buildbot/master
cd ~
buildbot create-master master
Для готових пакетів створимо каталог builds
mkdir /home/buildbot/builds
У каталозі /home/buildbot/master/ було створено файл master.cfg. Даний файл є кодом на python і містить опис всіх механізмів роботи системи, з ним і будемо працювати надалі.
Для автоматизації складання пакетів різних версій, щоб не доводилося лазити в код файлу master.cfg, в основному скрипті програми rac_gui.tcl у заголовку, додані рядки з поточними версією та релізом:
І на основі цих рядків buildbot нумеруватиме пакети. Для висмикування даних використовується виклик консольного grep. У buildbot просто так не можна випередити змінні для «робітників» (принаймні, я не знайшов як). І тому служать властивості (property). Тобто. у складальний процес, додаємо кроки з визначення версії та релізу та відповідно, встановлюємо властивості version та release. Властивості можна встановлювати у різний спосіб, в даному випадку це виклик консольної команди:
# Добавим определение версии из основного файла
rac_gui_build_RPM.addStep(
steps.SetPropertyFromCommand(
command="grep version ../rac-gui/rac_gui.tcl | grep -oE 'b[0-9]{1,2}.[0-9]{1,2}.[0-9]{1,2}b'", property="version"
)
)
# Добавим определение релиза из основного файла
rac_gui_build_RPM.addStep(
steps.SetPropertyFromCommand(
command="grep release ../rac-gui/rac_gui.tcl | grep -oE 'b[0-9]{1,3}b'", property="release"
)
)
Підставляти отримані значення можна шляхом виклику util.Interpolate().
Для встановлення коректних номерів релізу та версії використовується виклик стандартного sed, тобто. команда замінює значення всередині spec-файлу на необхідні
На цьому із RPM закінчили. Тепер почнемо опис алгоритму складання DEB-пакета. Так як процеси збирання пакетів під різні системи незалежні один від одного, то й багато кроків повторяться.
rac_gui_build_DEB = util.BuildFactory()
rac_gui_build_DEB.addStep(steps.Git(
repourl = 'https://bitbucket.org/svk28/rac-gui.git',
haltOnFailure = True,
submodules = True,
mode='full',
workdir='build',
progress = True)
)
# Добавим определение версии из основного файла
rac_gui_build_DEB.addStep(
steps.SetPropertyFromCommand(
command="grep version rac_gui.tcl | grep -oE 'b[0-9]{1,2}.[0-9]{1,2}.[0-9]{1,2}b'", property="version"
)
)
# Добавим определение релиза из основного файла
rac_gui_build_DEB.addStep(
steps.SetPropertyFromCommand(
command="grep release rac_gui.tcl | grep -oE 'b[0-9]{1,3}b'", property="release"
)
)
# Переименуем запускаемый файл
rac_gui_build_DEB.addStep(steps.ShellCommand(
command=["mv", "rac_gui.tcl", "racgui"]))
Для RPM-пакета частина нижченаведених процедур робиться самим rpm при складанні та описані всередині спеку, для дебіана доводиться це робити тут:
# Поменяем пути к библиотекам
rac_gui_build_DEB.addStep(steps.ShellCommand(
command=["sed", "-i", "s+^set dir(lib)+set dir(lib) /usr/share/rac-gui/lib ;#+g", "racgui"]))
# Поменяем пути к файлам
rac_gui_build_DEB.addStep(steps.ShellCommand(
command=["sed", "-i", "s+[pwd]+/usr/share/rac-gui+g", "racgui"]))
# заархивируем исходники
rac_gui_build_DEB.addStep(steps.ShellCommand(
command=["tar", "czf", util.Interpolate("../rac-gui_%(prop:version)s.orig.tar.gz"), "."]))
# Соберём пакет
rac_gui_build_DEB.addStep(steps.ShellCommand(
command=["dpkg-buildpackage"]))
# Скопируем файл на мастер
rac_gui_build_DEB.addStep(
steps.FileUpload(
workersrc=util.Interpolate("../rac-gui_%(prop:version)s-%(prop:release)s_amd64.deb"),
masterdest=util.Interpolate("/home/buildbot/builds/rac-gui_%(prop:version)s-%(prop:release)s_amd64.deb")
)
)
rac_gui_build_DEB.addStep(
steps.MasterShellCommand(
command=["/usr/local/bin/deploy-ftp.tcl",
util.Interpolate("--local-file=/home/buildbot/builds/rac-gui_%(prop:version)s-%(prop:release)s_amd64.deb"),
util.Interpolate("--remote-file=uploads/rac-gui/rac-gui_%(prop:version)s-%(prop:release)s_amd64.deb")]
)
)
Зберігаємо файл і можна спробувати запустити службу майстра:
systemctl restart buildbot-master
У лозі проконтролюємо, що з конфігом все гаразд і все працює в штатному режимі. Всі наші працівники повинні тепер підключитися, про що в лозі »»'/home/buildbot/master/twistd.log»»' буде радісно повідомлено:
2019-07-24 16:50:35+0300 [-] Loading buildbot.tac...
2019-07-24 16:50:35+0300 [-] Loaded.
2019-07-24 16:50:35+0300 [-] twistd 19.2.1 (/usr/bin/python3.6 3.6.8) starting up.
2019-07-24 16:50:35+0300 [-] reactor class: twisted.internet.epollreactor.EPollReactor.
2019-07-24 16:50:35+0300 [-] Starting BuildMaster -- buildbot.version: 2.3.1
2019-07-24 16:50:35+0300 [-] Loading configuration from '/home/buildbot/master/master.cfg'
2019-07-24 16:50:36+0300 [-] /usr/local/lib/python3.6/site-packages/buildbot/config.py:90: buildbot.config.ConfigWarning: [0.9.0 and later] `buildbotNetUsageData` is not configured and defaults to basic.
This parameter helps the buildbot development team to understand the installation base.
No personal information is collected.
Only installation software version info and plugin usage is sent.
You can `opt-out` by setting this variable to None.
Or `opt-in` for more information by setting it to "full".
2019-07-24 16:50:36+0300 [-] Setting up database with URL 'sqlite:/state.sqlite'
2019-07-24 16:50:36+0300 [-] setting database journal mode to 'wal'
2019-07-24 16:50:36+0300 [-] adding 1 new services, removing 0
2019-07-24 16:50:36+0300 [-] adding 1 new change_sources, removing 0
2019-07-24 16:50:36+0300 [-] gitpoller: using workdir '/home/buildbot/master/gitpoller-work'
2019-07-24 16:50:36+0300 [-] adding 3 new builders, removing 0
2019-07-24 16:50:36+0300 [-] adding 1 new schedulers, removing 0
2019-07-24 16:50:36+0300 [-] initializing www plugin 'waterfall_view'
2019-07-24 16:50:36+0300 [-] initializing www plugin 'console_view'
2019-07-24 16:50:36+0300 [-] initializing www plugin 'grid_view'
2019-07-24 16:50:36+0300 [-] NOTE: www plugin 'sitenav' is installed but not configured
2019-07-24 16:50:36+0300 [-] initializing www plugin 'waterfall_view'
2019-07-24 16:50:36+0300 [-] initializing www plugin 'console_view'
2019-07-24 16:50:36+0300 [-] initializing www plugin 'grid_view'
2019-07-24 16:50:36+0300 [-] NOTE: www plugin 'sitenav' is installed but not configured
2019-07-24 16:50:36+0300 [-] BuildbotSite starting on 80
2019-07-24 16:50:36+0300 [-] Starting factory <buildbot.www.service.BuildbotSite object at 0x7fe31c2657b8>
2019-07-24 16:50:36+0300 [-] adding 3 new workers, removing 0
2019-07-24 16:50:36+0300 [-] PBServerFactory starting on 4000
2019-07-24 16:50:36+0300 [-] Starting factory <twisted.spread.pb.PBServerFactory object at 0x7fe31c147470>
2019-07-24 16:50:37+0300 [-] BuildMaster is running
2019-07-24 16:50:37+0300 [-] buildbotNetUsageData: sending {'installid': 'b6193b126b96689351d2fe95787c5a03fc0879f9', 'versions': {'Python': '3.6.8', 'Buildbot': '2.3.1', 'Twisted': '19.2.1'}, 'platform': {'platform': 'Linux-4.15.18-10- pve-x86_64-with-centos-7.6.1810-Core', 'system': 'Linux', 'machine': 'x86_64', 'processor': 'x86_64', 'python_implementation': 'CPython', 'version': '#1 SMP PVE 4.15.18-32', 'distro': 'centos:7'}, 'plugins': {'buildbot/worker/base/Worker': 3, 'buildbot/config/BuilderConfig': 3, 'buildbot/schedulers/basic/SingleBranchScheduler': 1, 'buildbot/reporters/mail/MailNotifier': 1, 'buildbot/changes/gitpoller/GitPoller': 1, 'buildbot/steps/worker/MakeDirectory': 1, 'buildbot/steps/source/git/Git': 3, 'buildbot/steps/shell/ShellCommand': 9, 'buildbot/steps/package/rpm/rpmbuild/RpmBuild': 1}, 'db': 'sqlite', 'mq': 'simple', 'www_plugins': ['waterfall_view', 'console_view', 'grid_view']}
2019-07-24 16:50:37+0300 [Broker,0,127.0.0.1] worker 'CentOS' attaching from IPv4Address(type='TCP', host='127.0.0.1', port=37332)
2019-07-24 16:50:37+0300 [Broker,0,127.0.0.1] Got workerinfo from 'CentOS'
2019-07-24 16:50:37+0300 [-] bot attached
2019-07-24 16:50:37+0300 [Broker,0,127.0.0.1] Worker CentOS attached to Rac-GUI-RPM-builder
2019-07-24 16:50:37+0300 [-] buildbotNetUsageData: buildbot.net said: ok
2019-07-24 16:50:39+0300 [Broker,1,192.168.55.15] worker 'Windows-10' attaching from IPv4Address(type='TCP', host='192.168.5.145', port=49831)
2019-07-24 16:50:39+0300 [Broker,1,192.168.55.15] Got workerinfo from 'Windows-10'
2019-07-24 16:50:40+0300 [-] bot attached
2019-07-24 16:50:40+0300 [Broker,1,192.168.55.15] Worker Windows-10 attached to Rac-GUI-WIN-builder
2019-07-24 16:50:41+0300 [Broker,2,192.168.55.99] worker 'Debian-10' attaching from IPv4Address(type='TCP', host='192.168.5.9', port=44430)
2019-07-24 16:50:41+0300 [Broker,2,192.168.55.99] Got workerinfo from 'Debian-10'
2019-07-24 16:50:41+0300 [-] bot attached
2019-07-24 16:50:41+0300 [Broker,2,192.168.55.99] Worker Debian-10 attached to Rac-GUI-DEB-builder
На цьому процес налаштування завершено. Подивитися поточний стан можна через веб-морду. Де також можна подивитися помилки складання, штовхнути завислий процес, якщо щось пішло ні так і т.д.
Відразу після запуску наших роботяг можна подивитися через меню «Builds» -> «Workers»
Після того, як буде здійснено перший процес складання (тобто зміни в Git-репозитарії), на першій сторінці з'явиться стан процесів.
Якщо ткнути мишею в потрібний рядок, то відкриється сторінка з поточним станом даного процесу, де видно що відбувається, які помилки і т.д.