Наложи ми настройка на процеса на изграждане и доставка на сайта на пакети програми от 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, за изграждане, сами разбирате, под какво
Ще изграждаме — графичен интерфейс за 1С rac за управление на клъстера от сървъри. Под линукс ще бъдат използвани стандартни инструменти за всяка ОС, а за изграждане на exe файл под windows от tcl скрипт ще използваме .
Инсталиране
GNU/Linux
По отношение на инсталацията, документацията в мрежата е достатъчна ,. И не предизвиква особени проблеми:
За майстора:
pip3 install buildbot
pip3 install twisted
pip3 install autobahn
pip3 install pysqlite3
pip3 install sqlalchemy sqlalchemy-migrate
pip3 install buildbot-www buildbot-grid-view buildbot-console-view buildbot-waterfall-view
pip3 install python-dateutilЗа "работниците", това е достатъчно:
pip3 install buildbot-workerРазбира се, по-правилно би било да изградим пакети за всяка ОС, но това не влиза в рамките на статията. Също така ще пропуснем описанието на настройка на контейнерите за работа, ще отбележа само, че използвам ProxMox VE. И ще е необходимо да инсталираме пакети за всяка система, необходими за изграждане (centos: rpmdevtools и т.н.; debian: build-essential, dh-make, pbuilder и т.н.)
Проектите и услугите на buildbot ще се стартират от името на непривилегирован потребител, затова е необходимо да го създадем на всички хостове, участващи в процеса:
adduser buildbotСлед това ще настроим автоматичното стартиране на услугите, съответно на всеки от хостовете (контейнерите):
Systemd юнит за стартиране на майстора:
touch /etc/systemd/buildbot-master.service
[Unit]
Description=BuildBot master service
After=network.target
[Service]
User=buildbot
Group=buildbot
WorkingDirectory=/home/buildbot/master
ExecStart=/usr/local/bin/buildbot start --nodaemon
ExecReload=/bin/kill -HUP $MAINPID
[Install]
WantedBy=multi-user.targetи "работника"
touch /etc/systemd/buildbot-worker.service
[Unit]
Description=BuildBot worker service
After=network.target
[Service]master
User=buildbot
Group=buildbot
WorkingDirectory=/home/buildbot/worker
ExecStart=/usr/local/bin/buildbot-worker start --nodaemon
[Install]
WantedBy=buildbot-master.serviceТъй като всички скриптове (в нашия случай) се намират в /usr/local/, е необходимо да уточним пътя до тях в променливите на средата:
nano /root/.bash_profile
PATH=$PATH:$HOME/.local/bin:$HOME/bin:/usr/local/binСлед това можете да създадете инфраструктура от каталози за „работещите“ (на всички хостове), за което се регистрирате под потребителя 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-workerMS Windows
Като „работник“ за изграждане под Windows ще се използва виртуална машина с последната версия на Win10.
За работа ще са необходими:
- За инсталиране на различни пакети в Python трябваше да сваля
- 7Zip
След като всичко изброено по-горе бъде инсталирано, можете да инсталирате и самия buildbot:
pip install buildbot-workerСъздаване на работен каталог
md c:workerИ стартирайте
buildbot-worker start c:workerАко всичко работи (вижте лог c:workertwistd.log), можете да регистрирате „работника“ като услуга, добавяйки в регистъра записа с работния каталог (командите се изпълняват в PowerShell, стартирано от администратора):
buildbot_worker_windows_service.exe --user VM-SRV-BUILD3buildbot --password 123456 --startup auto install
New-ItemProperty -path Registry::HKEY_LOCAL_MACHINESYSTEMCurrentControlSetservicesBuildBotParameters -Name directories -PropertyType String -Value c:worker
И можете да стартирате услугата
Start-Service buildbotС „работниците“ това е всичко, не е нужно да се занимавате повече с тях, цялото управление става от майстора.
Настройка на майстора
Първо, да създадем инфраструктура за майстора (на основния хост), за което се регистрирате под потребителя buildbot и изпълнявате следните команди:
su - buildbot
mkdir /home/buildbot/master
cd ~
buildbot create-master masterЗа готовите пакети създайте каталог builds
mkdir /home/buildbot/buildsВ каталога /home/buildbot/master/ е създаден файл master.cfg. Този файл представлява код на Python и съдържа описание на всички механизми на системата, с него ще работим по-нататък.
nano /home/buildbot/master/master.cfgimport os, re
from buildbot.plugins import steps, util, schedulers, worker, changes, reporters
c = BuildmasterConfig = {}
# Описание наших рабочих.
c['workers'] = [ worker.Worker('CentOS', '123456'), worker.Worker('Debian-10', '123456'), worker.Worker('Windows-10', '123456')]
c['protocols'] = {'pb': {'port': 4000}}
# Указание мастеру какой репозиторий отслеживать
c['change_source'] = []
c['change_source'].append(changes.GitPoller(
repourl = 'https://bitbucket.org/svk28/rac-gui.git',
project = 'Rac-GUI',
branches = True,
pollInterval = 60
)
)
# служба запуска сборки
c['schedulers'] = []
c['schedulers'].append(schedulers.SingleBranchScheduler(
name="Rac-GUI-schedulers",
change_filter=util.ChangeFilter(branch='master'),
builderNames=["Rac-GUI-RPM-builder", "Rac-GUI-DEB-builder", "Rac-GUI-WIN-builder"],
properties = {'owner': 'admin'}
)
)
@util.renderer
######################################3
# Сборка RPM-пакета
rac_gui_build_RPM = util.BuildFactory()
rac_gui_build_RPM.addStep(steps.Git(
repourl = 'https://bitbucket.org/svk28/rac-gui.git',
workdir = 'rac-gui',
haltOnFailure = True,
submodules = True,
mode='full',
progress = True)
)За автоматизация на изграждането на пакети от различни версии, за да не е необходимо да се влиза в кода на файла master.cfg, в основния скрипт на програмата rac_gui.tcl са добавени редове с текущата версия и релиз:
######################################################
# Rac GUI
...
# version: 1.0.3
# release: 1И на базата на тези редове 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().
# Запакуем исходники
rac_gui_build_RPM.addStep(
steps.ShellCommand(
command=["tar", "czf", util.Interpolate("/home/buildbot/rpmbuild/SOURCES/rac-gui-%(prop:version)s-%(prop:release)s.tar.gz"), "../rac-gui"]
)
)Тук трябва да се отбележи, че тъй като хостът се използва и за ръчно изграждане на пакети, изграждането ще преминава по стандартните пътища.
# Копируем spec
rac_gui_build_RPM.addStep(steps.ShellCommand(
command=["cp", "../rac-gui/rac_gui.spec", "/home/buildbot/rpmbuild/SPECS/rac_gui.spec"]))За задаване на коректни номера на релиза и версията се използва стандартното извикване на sed, т.е. команда, която заменя стойностите в spec-файла с необходимите.
# меняем версию
rac_gui_build_RPM.addStep(steps.ShellCommand(
command=["sed", "-i", util.Interpolate("s/.*Version:.*/Version:t%(prop:version)s/"), "/home/buildbot/rpmbuild/SPECS/rac_gui.spec"]))
# меняем релиз
rac_gui_build_RPM.addStep(steps.ShellCommand(
command=["sed", "-i", util.Interpolate("s/.*Release:.*/Release:t%(prop:release)s/"), "/home/buildbot/rpmbuild/SPECS/rac_gui.spec"]))
# запускаем процесс сборки
rac_gui_build_RPM.addStep(steps.RpmBuild(
specfile="/home/buildbot/rpmbuild/SPECS/rac_gui.spec",
dist='.el5',
topdir='/home/buildbot/rpmbuild',
builddir='/home/buildbot/rpmbuild/build',
rpmdir='/home/buildbot/rpmbuild/RPMS',
sourcedir='/home/buildbot/rpmbuild/SOURCES'
)
)Готовият сглобен пакет и архивът с изходния код копираме на мастера. Но е възможно и веднага от работния файл да копирате в своя репозиторий или на сайта.
# Скопируем файл на мастер
rac_gui_build_RPM.addStep(
steps.FileUpload(
workersrc=util.Interpolate("/home/buildbot/rpmbuild/RPMS/noarch/rac-gui-%(prop:version)s-%(prop:release)s.noarch.rpm"),
masterdest=util.Interpolate("/home/buildbot/builds/rac-gui-%(prop:version)s-%(prop:release)s.noarch.rpm")
)
)
rac_gui_build_RPM.addStep(
steps.FileUpload(
workersrc=util.Interpolate("/home/buildbot/rpmbuild/SOURCES/rac-gui-%(prop:version)s-%(prop:release)s.tar.gz"),
masterdest=util.Interpolate("/home/buildbot/builds/rac-gui-%(prop:version)s-%(prop:release)s.tar.gz")
)
)Ще запуснем на мастера процеса по копиране на сглобените пакети на хостинга по FTP. За това се използва на tcl.
rac_gui_build_RPM.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.noarch.rpm"),
util.Interpolate("--remote-file=uploads/rac-gui/rac-gui-%(prop:version)s-%(prop:release)s.noarch.rpm")]
)
)
rac_gui_build_RPM.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.tar.gz"),
util.Interpolate("--remote-file=uploads/rac-gui/rac-gui-%(prop:version)s-%(prop:release)s.tar.gz")]
)
)С 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 при сборке и описана внутри спека, для Debian это нужно делать здесь.
# Поменяем пути к библиотекам
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")]
)
)И с DEB покончено, теперь переходим к Windows!
rac_gui_build_WIN = util.BuildFactory()
rac_gui_build_WIN.addStep(steps.Git(
repourl = 'https://bitbucket.org/svk28/rac-gui.git',
haltOnFailure = True,
submodules = True,
mode='full',
workdir='build',
progress = True)
)Так как в Windows по умолчанию нет grep и sed (или все-таки есть?), будем использовать PowerShell.
# Добавим определение версии из основного файла
rac_gui_build_WIN.addStep(
steps.SetPropertyFromCommand(
command="powershell -command "((Get-Content .rac_gui.tcl | Select-String -Pattern 'version:') -split 's')[2]",
property="version"
)
)
# Добавим определение релиза из основного файла
rac_gui_build_WIN.addStep(
steps.SetPropertyFromCommand(
command="powershell -command "((Get-Content .rac_gui.tcl | Select-String -Pattern 'release:') -split 's')[2]",
property="release"
)
)
# Создадим запускаемый файл
rac_gui_build_WIN.addStep(steps.ShellCommand(
command=["c:binfreewrap.exe", "rac_gui.tcl"]))
# запакуем то, что получилось
rac_gui_build_WIN.addStep(steps.ShellCommand(
command=["c:Program Files7-zip7z.exe", "a", "-r", util.Interpolate("..rac-gui_%(prop:version)s-%(prop:release)s.win.zip"), "..build"]))
# скопируем на мастер
rac_gui_build_WIN.addStep(
steps.FileUpload(
workersrc=util.Interpolate("..rac-gui_%(prop:version)s-%(prop:release)s.win.zip"),
masterdest=util.Interpolate("/home/buildbot/builds/rac-gui_%(prop:version)s-%(prop:release)s.win.zip")
)
)
# Скопируем файл на хостинг
rac_gui_build_WIN.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.win.zip"),
util.Interpolate("--remote-file=uploads/rac-gui/rac-gui_%(prop:version)s-%(prop:release)s.win.zip")]
)
)
# Тут определяем какие сборщики у нас есть
c['builders'] = [
util.BuilderConfig(name="Rac-GUI-RPM-builder", workername='CentOS', factory=rac_gui_build_RPM),
util.BuilderConfig(name="Rac-GUI-DEB-builder", workername='Debian-10', factory=rac_gui_build_DEB),
util.BuilderConfig(name="Rac-GUI-WIN-builder", workername='Windows-10', factory=rac_gui_build_WIN),
]Для уведомления о состоянии процесса сборки будем использовать электрическую почту.
c['services'] = []
template=u'''
<h4>Състояние на изграждане: {{ summary }}</h4>
<p> Използван работник: {{ workername }}</p>
{% for step in build['steps'] %}
<p> {{ step['name'] }}: {{ step['result'] }}</p>
{% endfor %}
<p><b> -- The Buildbot</b></p>
'''
mailNotifier = reporters.MailNotifier(fromaddr="builder@domain.ru",
sendToInterestedUsers=False,
mode=('all'),
extraRecipients=["admin@domain.ru"],
relayhost="mail.domain.ru",
smtpPort=587,
smtpUser="builder@domain.ru",
smtpPassword="******",
messageFormatter=reporters.MessageFormatter(
template=template, template_type='html',
wantProperties=True, wantSteps=True))
c['services'].append(mailNotifier)
# Основни настройки на мастера
c['title'] = "Процес на изграждане"
c['titleURL'] = "http://vm-srv-build1:80/"
c['buildbotURL'] = "http://vm-srv-build1/"
c['www'] = dict(port=80,
plugins=dict(waterfall_view={}, console_view={}, grid_view={}))
c['db'] = {
'db_url' : "sqlite:///state.sqlite"
}Сохраняем файл и можно попробовать запустить службу мастера:
systemctl restart buildbot-masterВ логе контролируем, что с конфигурацией все в порядке и все работает в штатном режиме. Все наши работники теперь должны подключиться, и в логе »»'/home/buildbot/master/twistd.log'»» будет радостно сообщено об этом:
2019-07-24 16:50:35+0300 [-] Зареждане на buildbot.tac...
2019-07-24 16:50:35+0300 [-] Заредено.
2019-07-24 16:50:35+0300 [-] twistd 19.2.1 (\/usr\/bin\/python3.6 3.6.8) стартира.
2019-07-24 16:50:35+0300 [-] клас на реактора: twisted.internet.epollreactor.EPollReactor.
2019-07-24 16:50:35+0300 [-] Стартиране на BuildMaster -- buildbot.version: 2.3.1
2019-07-24 16:50:35+0300 [-] Зареждане на конфигурация от '\/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 и по-късно] `buildbotNetUsageData` не е конфигурирано и по подразбиране е настроено на основно.
Тази променлива помага на екипа за разработка на buildbot да разбере базата на инсталацията.
Лични данни не се събират.
Изпраща се само информация за софтуерната версия на инсталацията и използването на плъгини.
Можете да `откажете` абонамента, задавайки тази променлива на None.
Или да `потвърдите`, че искате повече информация, задавайки я на "full".
2019-07-24 16:50:36+0300 [-] Настройване на база данни с URL 'sqlite:\/state.sqlite'
2019-07-24 16:50:36+0300 [-] настройване на режима на журнал на базата данни на 'wal'
2019-07-24 16:50:36+0300 [-] добавяне на 1 нови услуги, премахване на 0
2019-07-24 16:50:36+0300 [-] добавяне на 1 нови източника на промени, премахване на 0
2019-07-24 16:50:36+0300 [-] gitpoller: използване на работна директория '\/home\/buildbot\/master\/gitpoller-work'
2019-07-24 16:50:36+0300 [-] добавяне на 3 нови строители, премахване на 0
2019-07-24 16:50:36+0300 [-] добавяне на 1 нови планировчици, премахване на 0
2019-07-24 16:50:36+0300 [-] инициализиране на www плъгин 'waterfall_view'
2019-07-24 16:50:36+0300 [-] инициализиране на www плъгин 'console_view'
2019-07-24 16:50:36+0300 [-] инициализиране на www плъгин 'grid_view'
2019-07-24 16:50:36+0300 [-] ЗАБЕЛЕЖКА: www плъгин 'sitenav' е инсталиран, но не е конфигуриран
2019-07-24 16:50:36+0300 [-] инициализиране на www плъгин 'waterfall_view'
2019-07-24 16:50:36+0300 [-] инициализиране на www плъгин 'console_view'
2019-07-24 16:50:36+0300 [-] инициализиране на www плъгин 'grid_view'
2019-07-24 16:50:36+0300 [-] ЗАБЕЛЕЖКА: www плъгин 'sitenav' е инсталиран, но не е конфигуриран
2019-07-24 16:50:36+0300 [-] BuildbotSite стартира на 80
2019-07-24 16:50:36+0300 [-] Стартиране на фабрика <buildbot.www.service.BuildbotSite обект на 0x7fe31c2657b8>
2019-07-24 16:50:36+0300 [-] добавяне на 3 нови работници, премахване на 0
2019-07-24 16:50:36+0300 [-] PBServerFactory стартира на 4000
2019-07-24 16:50:36+0300 [-] Стартиране на фабрика <twisted.spread.pb.PBServerFactory обект на 0x7fe31c147470>
2019-07-24 16:50:37+0300 [-] BuildMaster работи
2019-07-24 16:50:37+0300 [-] buildbotNetUsageData: изпраща {'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] работник 'CentOS' се свързва от IPv4Address(type='TCP', host='127.0.0.1', port=37332)
2019-07-24 16:50:37+0300 [Broker,0,127.0.0.1] Получено workerinfo от 'CentOS'
2019-07-24 16:50:37+0300 [-] бот свързан
2019-07-24 16:50:37+0300 [Broker,0,127.0.0.1] Работник CentOS свързан с Rac-GUI-RPM-builder
2019-07-24 16:50:37+0300 [-] buildbotNetUsageData: buildbot.net каза: ok
2019-07-24 16:50:39+0300 [Broker,1,192.168.55.15] работник 'Windows-10' се свързва от IPv4Address(type='TCP', host='192.168.5.145', port=49831)
2019-07-24 16:50:39+0300 [Broker,1,192.168.55.15] Получено workerinfo от 'Windows-10'
2019-07-24 16:50:40+0300 [-] бот свързан
2019-07-24 16:50:40+0300 [Broker,1,192.168.55.15] Работник Windows-10 свързан с Rac-GUI-WIN-builder
2019-07-24 16:50:41+0300 [Broker,2,192.168.55.99] работник 'Debian-10' се свързва от IPv4Address(type='TCP', host='192.168.5.9', port=44430)
2019-07-24 16:50:41+0300 [Broker,2,192.168.55.99] Получено workerinfo от 'Debian-10'
2019-07-24 16:50:41+0300 [-] бот свързан
2019-07-24 16:50:41+0300 [Broker,2,192.168.55.99] Работник Debian-10 свързан с Rac-GUI-DEB-builderПроцесът на настройка е завършен. Можете да проверите текущото състояние чрез уеб интерфейса. Там също можете да видите грешките от компилацията, да рестартирате зависналия процес, ако нещо е сбъркано и т.н.
Веднага след старта на нашите работници можете да ги видите в менюто „Builds” -> „Workers”

След като се извърши първият процес на компилация (т.е. промени в Git репозитория), на първата страница ще се появи състоянието на процесите.

Ако кликнете с мишката върху нужния ред, ще се отвори страница с текущото състояние на този процес, където можете да видите какво се случва, какви грешки и т.н.

Цялата конфигурация на майстора може да бъде намерена тук
import os, re
from buildbot.plugins import steps, util, schedulers, worker, changes, reporters
c= BuildmasterConfig ={}
c['workers'] = [ worker.Worker('CentOS', '123456'), worker.Worker('Debian-10', '123456'), worker.Worker('Windows-10', '123456')]
c['protocols'] = {'pb': {'port': 4000}}
c['change_source'] = []
c['change_source'].append(changes.GitPoller(
repourl = 'https://bitbucket.org/svk28/rac-gui.git',
project = 'Rac-GUI',
branches = True,
pollInterval = 600
))
# Служба по стартиране на сборката
c['schedulers'] = []
c['schedulers'].append(schedulers.SingleBranchScheduler(
name="Rac-GUI-schedulers",
change_filter=util.ChangeFilter(branch='master'),
builderNames=["Rac-GUI-RPM-builder", "Rac-GUI-DEB-builder", "Rac-GUI-WIN-builder"],
properties = {'owner': 'admin'}
))
@util.renderer
def get_name_version_release(props):
prog_name = "rac-gui"
prog_version = "1.0.3"
prog_release = "3"
return {
"prog_name": prog_name
#"prog_version": prog_version,
#"prog_release": prog_release
}
rac_gui_build_RPM = util.BuildFactory()
rac_gui_build_RPM.addStep(steps.Git(
repourl = 'https://bitbucket.org/svk28/rac-gui.git',
workdir = 'rac-gui',
haltOnFailure = True,
submodules = True,
mode='full',
progress = True)
)
# Добавяме определение на версията от основния файл
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"
)
)
rac_gui_build_RPM.addStep(steps.ShellCommand(
command=["tar", "czf", util.Interpolate("\/home\/buildbot\/rpmbuild\/SOURCES\/rac-gui-%(prop:version)s-%(prop:release)s.tar.gz"), "..\/rac-gui"]))
rac_gui_build_RPM.addStep(steps.ShellCommand(
command=["cp", "..\/rac-gui\/rac_gui.spec", "\/home\/buildbot\/rpmbuild\/SPECS\/rac_gui.spec"]))
rac_gui_build_RPM.addStep(steps.ShellCommand(
command=["sed", "-i", util.Interpolate("s\/.*Version:.*\/Version:t%(prop:version)s\/"), "\/home\/buildbot\/rpmbuild\/SPECS\/rac_gui.spec"]))
rac_gui_build_RPM.addStep(steps.ShellCommand(
command=["sed", "-i", util.Interpolate("s\/.*Release:.*\/Release:t%(prop:release)s\/"), "\/home\/buildbot\/rpmbuild\/SPECS\/rac_gui.spec"]))
rac_gui_build_RPM.addStep(steps.RpmBuild(
specfile="\/home\/buildbot\/rpmbuild\/SPECS\/rac_gui.spec",
dist='.el5',
topdir='\/home\/buildbot\/rpmbuild',
builddir='\/home\/buildbot\/rpmbuild\/build',
rpmdir='\/home\/buildbot\/rpmbuild\/RPMS',
sourcedir='\/home\/buildbot\/rpmbuild\/SOURCES'
))
# Копираме файла на сървъра
rac_gui_build_RPM.addStep(
steps.FileUpload(
workersrc=util.Interpolate("\/home\/buildbot\/rpmbuild\/RPMS\/noarch\/rac-gui-%(prop:version)s-%(prop:release)s.noarch.rpm"),
masterdest=util.Interpolate("\/home\/buildbot\/builds\/rac-gui-%(prop:version)s-%(prop:release)s.noarch.rpm")
)
)
rac_gui_build_RPM.addStep(
steps.FileUpload(
workersrc=util.Interpolate("\/home\/buildbot\/rpmbuild\/SOURCES\/rac-gui-%(prop:version)s-%(prop:release)s.tar.gz"),
masterdest=util.Interpolate("\/home\/buildbot\/builds\/rac-gui-%(prop:version)s-%(prop:release)s.tar.gz")
)
)
rac_gui_build_RPM.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.noarch.rpm"),
util.Interpolate("--remote-file=uploads\/rac-gui\/rac-gui-%(prop:version)s-%(prop:release)s.noarch.rpm")]
)
)
rac_gui_build_RPM.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.tar.gz"),
util.Interpolate("--remote-file=uploads\/rac-gui\/rac-gui-%(prop:version)s-%(prop:release)s.tar.gz")]
)
)
####################################
## 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"]))
# Променяме пътищата към библиотеките
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")]
)
)
############################################
# WIN
############################################
rac_gui_build_WIN = util.BuildFactory()
rac_gui_build_WIN.addStep(steps.Git(
repourl = 'https://bitbucket.org/svk28/rac-gui.git',
haltOnFailure = True,
submodules = True,
mode='full',
workdir='build',
progress = True)
)
# Добавяме определение на версията от основния файл
rac_gui_build_WIN.addStep(
steps.SetPropertyFromCommand(
command="powershell -command "((Get-Content .rac_gui.tcl | Select-String -Pattern 'version:') -split 's')[2]",
property="version"
)
)
# Добавяме определение на релиза от основния файл
rac_gui_build_WIN.addStep(
steps.SetPropertyFromCommand(
command="powershell -command "((Get-Content .rac_gui.tcl | Select-String -Pattern 'release:') -split 's')[2]",
property="release"
)
)
# Създаваме изпълняем файл
rac_gui_build_WIN.addStep(steps.ShellCommand(
command=["c:binfreewrap.exe", "rac_gui.tcl"]))
# Запаковаме полученото
rac_gui_build_WIN.addStep(steps.ShellCommand(
command=["c:Program Files7-zip7z.exe", "a", "-r", util.Interpolate("..rac-gui_%(prop:version)s-%(prop:release)s.win.zip"), "..build"]))
# Копираме на сървъра
rac_gui_build_WIN.addStep(
steps.FileUpload(
workersrc=util.Interpolate("..rac-gui_%(prop:version)s-%(prop:release)s.win.zip"),
masterdest=util.Interpolate("\/home\/buildbot\/builds\/rac-gui_%(prop:version)s-%(prop:release)s.win.zip")
)
)
# Копираме файла на хостинга
rac_gui_build_WIN.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.win.zip"),
util.Interpolate("--remote-file=uploads\/rac-gui\/rac-gui_%(prop:version)s-%(prop:release)s.win.zip")]
)
)
c['builders'] = [
util.BuilderConfig(name="Rac-GUI-RPM-builder", workername='CentOS', factory=rac_gui_build_RPM),
util.BuilderConfig(name="Rac-GUI-DEB-builder", workername='Debian-10', factory=rac_gui_build_DEB),
util.BuilderConfig(name="Rac-GUI-WIN-builder", workername='Windows-10', factory=rac_gui_build_WIN),
]
c['services'] = []
template=u'''
<h4>Състояние на изграждане: {{ summary }}</h4>
<p> Използван работник: {{ workername }}</p>
{% for step in build['steps'] %}
<p> {{ step['name'] }}: {{ step['result'] }}</p>
{% endfor %}
<p><b> -- The Buildbot</b></p>
'''
mailNotifier = reporters.MailNotifier(fromaddr="112@icvibor.bg",
sendToInterestedUsers=False,
mode=('all'),
extraRecipients=["my@domain.local"],
relayhost="mail.domain.local",
smtpPort=587,
smtpUser="buildbot@domain.local",
smtpPassword="**********",
messageFormatter=reporters.MessageFormatter(
template=template, template_type='html',
wantProperties=True, wantSteps=True))
c['services'].append(mailNotifier)
c['title'] = "Процес на изграждане"
c['titleURL'] = "http://vm-srv-build1:80/"
c['buildbotURL'] = "http://vm-srv-build1/"
c['www'] = dict(port=80,
plugins=dict(waterfall_view={}, console_view={}, grid_view={}))
c['db'] = {
'db_url' : "sqlite:///state.sqlite"
}Материали
При подготовката на статията бяха използвани следните материали:
- И документацията по продукта
Източник: habr.com
