Më nevojitej të konfigur një proces ndërtimi dhe dorëzimi të paketave të programeve në një faqe nga Git-repozitari. Dhe duke parë, nuk ka shumë kohë, këtu në Habr një artikull mbi buildbot (linku në fund), vendosa ta provoj dhe ta aplikoj atë.
Duke qenë se buildbot është një sistem i shpërndarë, do të ishte logjike të krijonim një host ndërtimi të veçantë për secilën arkitekturë dhe sistem operativ. Në rastin tonë, këto do të jenë konteinerë LXC (në rastin e linux) dhe qemu (në rastin e windows):
- vm-srv-build1 — centos 7, këtu do të jetë masteri (master) i buildbot dhe një nga punëtorët (worker)
- vm-srv-build2 — debian 10, për ndërtimin e paketave DEB
- vm-srv-build3 — windows 10, për ndërtimin, e kuptoni për çfarë
Do të ndërtosh — ndërfaqja grafike për 1C rac për menaxhimin e klasterit të serverëve. Për linux do të përdoren mjetet e zakonshme për çdo OS, për ndërtimin e skedarëve exe për windows nga skenari tcl përdoret .
Instalimi
GNU/Linux
Për instalimin, dokumentimi në internet është mjaft i mjaftueshëm ,. Po ashtu nuk shkakton ndonjë problem të veçantë:
Për masterin:
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-dateutilPër "punëtorët", e mjaftueshme është kjo:
pip3 install buildbot-workerSigurisht, do të ishte më e drejtë të ndërtosh paketat për secilën OS, por kjo nuk bie nën kuadri i artikullit. Po ashtu do të kaloj përshkrimin e konfigurimit të konteinerëve për punë, do të theksoj vetëm se përdor ProxMox VE. Po ashtu do të nevojitet të instalosh paketat për çdo sistem të nevojshëm për ndërtimin (centos: rpmdevtools etj; debian: build-essential, dh-make, pbuilder etj.)
Projektet dhe shërbimet e buildbot do të nisin nën emrin e një përdoruesi të pa privilegjuar, prandaj është e nevojshme ta krijosh në të gjitha hostet që marrin pjesë në proces:
adduser buildbotMë pas do të konfiguroni nisjen automatike të shërbimeve, përkatësisht në secilin nga hostet (konteinerët):
Uniti i Systemd për nisjen e masterit:
touch /etc/systemd/buildbot-master.service
[Unit]
Description=Shërbimi master i BuildBot
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.targetdhe "punëtorin"
touch /etc/systemd/buildbot-worker.service
[Unit]
Description=Shërbimi punëtor i BuildBot
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.serviceDuke qenë se të gjitha skenaret (në rastin tonë) ndodhen në /usr/local/, duhet të shkruani rrugën e tyre në variablat e mjedisit:
nano /root/.bash_profile
PATH=$PATH:$HOME/.local/bin:$HOME/bin:/usr/local/binPas kësaj, mund të krijoni infrastrukturën e katalogëve për "punëtorët" (në të gjitha hostet), për këtë regjistrohet përdoruesi buildbot dhe ekzekutohen komandat e mëposhtme:
Në hostin e parë vm-srv-build1:
su - buildbot
mkdir /home/buildbot/worker
cd ~
buildbot-worker create-worker --umask=0o22 --keepalive=60 worker vm-srv-build1:4000 CentOS 123456Në hostin e dytë 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 123456Në hostet-punëtor, shërbimi buildbot-worker mund të nisët
systemctl start buildbot-workerMS Windows
Si "punëtor" për ndërtimin nën Windows, do të përdoret një makinë virtuale me versionin më të fundit Win10.
Për punë do të nevojitet:
- Për instalimin e disa gjërave të ndryshme në Python nevojitej të shkarkohej
- 7Zip
Pas instalimit të gjithçkaje të përmendur më parë, mund të instalohet dhe vetë buildbot:
pip install buildbot-workerTë krijojmë katalogun e punës
md c:workerDhe do ta nisim
buildbot-worker start c:workerNëse gjithçka funksionon (shihni logun c:workertwistd.log), atëherë mund ta regjistroni "punëtorin" tonë si shërbim, duke shtuar një hije në regjistrin me katalogun e punës (komandat ekzekutohen në PowerShell të hapur nga administratorët):
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
Dhe mund të nisim shërbimin
Start-Service buildbotMe "punëtorët" për këtë është e gjitha, më pas mund të mos i prekim, e gjithë menaxhimi bëhet nga masteri.
Konfigurimi i masterit
Për fillim, le të krijojmë infrastrukturën për masterin (në hostin kryesor), për këtë regjistrohet përdoruesi buildbot dhe ekzekutohen komandat e mëposhtme:
su - buildbot
mkdir /home/buildbot/master
cd ~
buildbot create-master masterPër paketat e gatshme le të krijojmë katalogun builds
mkdir /home/buildbot/buildsNë katalogun /home/buildbot/master/ është krijuar skedari master.cfg. Ky skedar përfaqëson kodin në Python dhe përmban përshkrimin e të gjitha mekanizmave të punës së sistemit, me të do të punojmë më tej.
nano /home/buildbot/master/master.cfgimport os, re
from buildbot.plugins import steps, util, schedulers, worker, changes, reporters
c= BuildmasterConfig ={}
# Përshkrimi i punonjësve tanë.
c['workers'] = [ worker.Worker('CentOS', '123456'), worker.Worker('Debian-10', '123456'), worker.Worker('Windows-10', '123456')]
c['protocols'] = {'pb': {'port': 4000}}
# Caktimi i burimit të ndryshimeve që masteri duhet të ndjekë
c['change_source'] = []
c['change_source'].append(changes.GitPoller(
repourl = 'https://bitbucket.org/svk28/rac-gui.git',
project = 'Rac-GUI',
branches = True,
pollInterval = 60
)
)
# Shërbimi për nxitjen e ndërtimit
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
# Ndërtimi i paketës 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)
)Për automatizimin e ndërtimit të paketave të versioneve të ndryshme, për të shmangur hyrjen në kodin e skedarit master.cfg, në skriptin kryesor të programit rac_gui.tcl, janë shtuar rreshtat me versionin dhe lëshimin aktual:
######################################################
# Rac GUI
...
# version: 1.0.3
# release: 1Dhe mbi bazën e këtyre rreshtave, buildbot do të numërojë paketat. Për nxjerrjen e të dhënave, përdoret thirrja e grep-it në konsolë. Në buildbot nuk është e mundur të përcaktohen variablat për "punonjësit" (së paku, unë nuk gjetë ashtu). Për këtë shërbejnë pronat (property). Pra, në procesin e ndërtimit, shtojmë hapa për përcaktimin e versionit dhe lëshimit dhe kështu vendosim pronat version dhe release. Pronat mund të vendosen në mënyra të ndryshme, në këtë rast është thirrja e komandës në konsolë:
# Добавим определение версии из основного файла
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"
)
)Vlerat e marrë mund të vendosen përmes thirrjes 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"]
)
)Duhet të theksohet se, pasi hosti përdoret gjithashtu për ndërtimin manual të paketave, ndërtimi do të kalojë përmes rrugëve standarde.
# Копируем spec
rac_gui_build_RPM.addStep(steps.ShellCommand(
command=["cp", "../rac-gui/rac_gui.spec", "/home/buildbot/rpmbuild/SPECS/rac_gui.spec"]))Për caktimin e numrave të saktë të lëshimit dhe versionit përdoret thirrja e sed-it standard, dmth, komanda zëvendëson vlerat brenda skedarit spec me ato të nevojshme.
# меняем версию
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'
)
)Paketa e ndërtuar dhe arkivi me burimet do të kopjohen në master. Por është e mundur edhe të kopjoni direkt nga skedari punues në depozitat tuaja ose në sitin tuaj.
# Скопируем файл на мастер
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")
)
)Le t'i fillojmë procesin në master për kopjimin e paketave të ndërtuara në hosting përmes ftp. Për këtë përdoret në 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")]
)
)Këtu mbyllet për RPM. Tani do të fillojmë me përshkrimin e algoritmit të ndërtimit të paketës DEB. Duke qenë se proceset e ndërtimit të paketave për sisteme të ndryshme janë të pavarura nga njëra-tjetra, shumë hapa do të përsëriten.
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)
)
# Shtojmë përcaktimin e versionit nga skedari kryesor
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"
)
)
# Shtojmë përcaktimin e lëshimit nga skedari kryesor
rac_gui_build_DEB.addStep(
steps.SetPropertyFromCommand(
command="grep release rac_gui.tcl | grep -oE 'b[0-9]{1,3}b'", property="release"
)
)
# Ruenim skedarin e ekzekutueshëm
rac_gui_build_DEB.addStep(steps.ShellCommand(
command=["mv", "rac_gui.tcl", "racgui"]))Për paketën RPM, disa nga procedurat e mëposhtme bëhen nga vetë rpm gjatë ndërtimit dhe janë të përshkruara brenda spekës, për Debian duhet t'i bëjmë këtu:
# Поменяем пути к библиотекам
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")]
)
)Dhe me DEB përfundojmë, tani te 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)
)Duke qenë se në Windows nuk ka grep dhe sed (ose ka?), ne do të përdorim 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),
]Për të njoftuar mbi gjendjen e procesit të ndërtimit, do të përdorim emailin elektrik.
c['services'] = []
template=u'''
<h4>Statusi i ndërtimit: {{ summary }}</h4>
<p> Puna e përdorur: {{ workername }}</p>
{% for step in build['steps'] %}
<p> {{ step['name'] }}: {{ step['result'] }}</p>
{% endfor %}
<p><b> -- Buildbot-i</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)
# Cilësimet kryesore të mjeshtrit
c['title'] = "Procesi i ndërtimit"
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"
}Ruajmë skedarin dhe mund të provoni të nisni shërbimin e masterit:
systemctl restart buildbot-masterNë log do të kontrollojmë që konfigurimi të jetë në rregull dhe gjithçka të funksionojë siç duhet. Të gjithë punonjësit tanë duhet tani të lidhen, gjë për të cilën do të njoftohemi me gëzim në logun '”/'home/buildbot/master/twistd.log'”.
2019-07-24 16:50:35+0300 [-] Po ngarkon buildbot.tac...
2019-07-24 16:50:35+0300 [-] E ngarkuar.
2019-07-24 16:50:35+0300 [-] twistd 19.2.1 (\/usr\/bin\/python3.6 3.6.8) duke fillimin.
2019-07-24 16:50:35+0300 [-] klasa reactor: twisted.internet.epollreactor.EPollReactor.
2019-07-24 16:50:35+0300 [-] Po fillon BuildMaster -- buildbot.version: 2.3.1
2019-07-24 16:50:35+0300 [-] Po ngarko konfigurimin nga '\/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 dhe më vonë] `buildbotNetUsageData` nuk është konfiguruar dhe parazgjedhja është bazike.
Ky parametr ndihmon ekipin e zhvillimit të buildbot për të kuptuar bazën e instalimit.
Nuk mblidhen informacione personale.
Vetëm informacioni rreth versionit të programit të instaluar dhe përdorimit të pluginëve dërgohet.
Mund të `zhvendosni` duke vendosur këtë variabël në None.
Ose `opt-in` për më shumë informacion duke e vendosur në "full".
2019-07-24 16:50:36+0300 [-] Duke vendosur bazën e të dhënave me URL 'sqlite:\/state.sqlite'
2019-07-24 16:50:36+0300 [-] duke vendosur modin e ditarit të bazës së të dhënave në 'wal'
2019-07-24 16:50:36+0300 [-] duke shtuar 1 shërbim të ri, duke hequr 0
2019-07-24 16:50:36+0300 [-] duke shtuar 1 burim ndryshimi të ri, duke hequr 0
2019-07-24 16:50:36+0300 [-] gitpoller: po përdor workdir '\/home\/buildbot\/master\/gitpoller-work'
2019-07-24 16:50:36+0300 [-] duke shtuar 3 ndërtues të rinj, duke hequr 0
2019-07-24 16:50:36+0300 [-] duke shtuar 1 orar të ri, duke hequr 0
2019-07-24 16:50:36+0300 [-] duke inicializuar plugin-in www 'waterfall_view'
2019-07-24 16:50:36+0300 [-] duke inicializuar plugin-in www 'console_view'
2019-07-24 16:50:36+0300 [-] duke inicializuar plugin-in www 'grid_view'
2019-07-24 16:50:36+0300 [-] SHENIM: plugin-i www 'sitenav' është instaluar por nuk është konfiguruar
2019-07-24 16:50:36+0300 [-] duke inicializuar plugin-in www 'waterfall_view'
2019-07-24 16:50:36+0300 [-] duke inicializuar plugin-in www 'console_view'
2019-07-24 16:50:36+0300 [-] duke inicializuar plugin-in www 'grid_view'
2019-07-24 16:50:36+0300 [-] SHENIM: plugin-i www 'sitenav' është instaluar por nuk është konfiguruar
2019-07-24 16:50:36+0300 [-] BuildbotSite po fillon në 80
2019-07-24 16:50:36+0300 [-] Po fillon fabrika <buildbot.www.service.BuildbotSite object at 0x7fe31c2657b8>
2019-07-24 16:50:36+0300 [-] duke shtuar 3 punëtorë të rinj, duke hequr 0
2019-07-24 16:50:36+0300 [-] PBServerFactory po fillon në 4000
2019-07-24 16:50:36+0300 [-] Po fillon fabrika <twisted.spread.pb.PBServerFactory object at 0x7fe31c147470>
2019-07-24 16:50:37+0300 [-] BuildMaster është duke punuar
2019-07-24 16:50:37+0300 [-] buildbotNetUsageData: po dërgon {'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] punëtori 'CentOS' po shtohet nga IPv4Address(type='TCP', host='127.0.0.1', port=37332)
2019-07-24 16:50:37+0300 [Broker,0,127.0.0.1] Morëm informacionin e punëtorit nga 'CentOS'
2019-07-24 16:50:37+0300 [-] bot i lidhur
2019-07-24 16:50:37+0300 [Broker,0,127.0.0.1] Punëtori CentOS i lidhur me Rac-GUI-RPM-builder
2019-07-24 16:50:37+0300 [-] buildbotNetUsageData: buildbot.net tha: ok
2019-07-24 16:50:39+0300 [Broker,1,192.168.55.15] punëtori 'Windows-10' po shtohet nga IPv4Address(type='TCP', host='192.168.5.145', port=49831)
2019-07-24 16:50:39+0300 [Broker,1,192.168.55.15] Morëm informacionin e punëtorit nga 'Windows-10'
2019-07-24 16:50:40+0300 [-] bot i lidhur
2019-07-24 16:50:40+0300 [Broker,1,192.168.55.15] Punëtori Windows-10 i lidhur me Rac-GUI-WIN-builder
2019-07-24 16:50:41+0300 [Broker,2,192.168.55.99] punëtori 'Debian-10' po shtohet nga IPv4Address(type='TCP', host='192.168.5.9', port=44430)
2019-07-24 16:50:41+0300 [Broker,2,192.168.55.99] Morëm informacionin e punëtorit nga 'Debian-10'
2019-07-24 16:50:41+0300 [-] bot i lidhur
2019-07-24 16:50:41+0300 [Broker,2,192.168.55.99] Punëtori Debian-10 i lidhur me Rac-GUI-DEB-builderProcesi i konfigurimit përfundoi. Mund të shikoni gjendjen aktuale përmes ndërfaqes në web, ku gjithashtu mund të shihni gabimet e ndërtimit, të rinisni një proces të ngjitur nëse diçka shkoi keq, etj.
Menjëherë pas nisjes së punëtorëve tanë, mund të shihni përmes menusë «Builds» -> «Workers»

Pas përfundimit të procesit të parë të ndërtimit (dmth. ndryshimet në depo Git), gjendja e proceseve do të shfaqet në faqen e parë.

Nëse klikoni në rreshtin e duhur, do të hapet një faqe me gjendjen aktuale të këtij procesi, ku mund të shihni çfarë po ndodh, cilat janë gabimet, etj.

Konfigurimi i plotë i mësuesit mund të merret këtu
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
))
# Shërbimi i nisjes së ndërtimit
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)
)
# Do ta shtojmë përcaktimin e versionit nga skedari kryesor
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"
)
)
# Do ta shtojmë përcaktimin e lëshimit nga skedari kryesor
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'
))
# Do ta kopjojmë skedarin në master
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)
)
# Do ta shtojmë përcaktimin e versionit nga skedari kryesor
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"
)
)
# Do ta shtojmë përcaktimin e lëshimit nga skedari kryesor
rac_gui_build_DEB.addStep(
steps.SetPropertyFromCommand(
command="grep release rac_gui.tcl | grep -oE 'b[0-9]{1,3}b'", property="release"
)
)
# Do ta riemërojmë skedarin e ekzekutuar
rac_gui_build_DEB.addStep(steps.ShellCommand(
command=["mv", "rac_gui.tcl", "racgui"]))
# Do t'i ndërojmë rrugët për bibliotekat
rac_gui_build_DEB.addStep(steps.ShellCommand(
command=["sed", "-i", "s+^set dir(lib)+set dir(lib) \/usr\/share\/rac-gui\/lib ;#+g", "racgui"]))
# Do t'i ndërojmë rrugët për skedarët
rac_gui_build_DEB.addStep(steps.ShellCommand(
command=["sed", "-i", "s+[pwd]+\/usr\/share\/rac-gui+g", "racgui"]))
# Do të kompresojmë kodin burim
rac_gui_build_DEB.addStep(steps.ShellCommand(
command=["tar", "czf", util.Interpolate("..\/rac-gui_%(prop:version)s.orig.tar.gz"), "."]))
# Do të ndërtrojmë paketin
rac_gui_build_DEB.addStep(steps.ShellCommand(
command=["dpkg-buildpackage"]))
# Do ta kopjojmë skedarin në master
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)
)
# Do ta shtojmë përcaktimin e versionit nga skedari kryesor
rac_gui_build_WIN.addStep(
steps.SetPropertyFromCommand(
command="powershell -command "((Get-Content .rac_gui.tcl | Select-String -Pattern 'version:') -split 's')[2]",
property="version"
)
)
# Do ta shtojmë përcaktimin e lëshimit nga skedari kryesor
rac_gui_build_WIN.addStep(
steps.SetPropertyFromCommand(
command="powershell -command "((Get-Content .rac_gui.tcl | Select-String -Pattern 'release:') -split 's')[2]",
property="release"
)
)
# Do ta krijojmë skedarin ekzekutues
rac_gui_build_WIN.addStep(steps.ShellCommand(
command=["c:binfreewrap.exe", "rac_gui.tcl"]))
# Do ta paketojmë atë që kemi arrit
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"]))
# Do ta kopjojmë në master
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")
)
)
# Do ta kopjojmë skedarin në hostimin
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>Statusi i ndërtimit: {{ summary }}</h4>
<p> Puna e përdorur: {{ workername }}</p>
{% for step in build['steps'] %}
<p> {{ step['name'] }}: {{ step['result'] }}</p>
{% endfor %}
<p><b> -- Buildbot-i</b></p>
'''
mailNotifier = reporters.MailNotifier(fromaddr="112@icvibor.ru",
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'] = "Procesi i ndërtimit"
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"
}Materialet
Përgatitja e artikullit është bazuar në materialet e mëposhtme:
- Dhe dokumentacioni për produktin
Burimi: habr.com
