Buildbot në shembuj.

Më nevojitej të konfiguroj procesin e ndërtimit dhe dorëzimit të paketave programi nga repo Git në faqe. Duke parë një artikull në Habr rreth 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ë krijohet një host ndërtimi të veçantë për çdo arkitekturë dhe sistem operativ. Në rastin tonë, këto do të jenë konteinerët LXC (në rastin e linux) dhe qemu (në rastin e windows):

  • vm-srv-build1 — centos 7, këtu do të jetë master i buildbot dhe një nga punëtorët.
  • vm-srv-build2 — debian 10, për ndërtimin e pakove DEB.
  • vm-srv-build3 — windows 10, për ndërtimin, e kuptoni për çfarë.

Do të ndërtojmë Rac GUI — një ndërfaqe grafike për 1C rac për menaxhimin e klasterëve të serverëve. Në linux do të përdoren mjetet e zakonshme për çdo SO, për ndërtimin e skedarëve exe nën windows nga skripti tcl do të përdoret freewrap.

Instalimi

GNU/Linux

Për instalimin, dokumentacioni në rrjet është mjaftueshëm. 1,2Dhe nuk shkakton probleme të mëdha:
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-dateutil

Për ‘punëtorët’, mjafton kjo:

pip3 install buildbot-worker

Sigurisht, do të ishte më e saktë të ndërtoheshin paketat për çdo SO, por kjo nuk është temë e artikullit. Gjithashtu do ta kalojmë përshkrimin e konfigurimit të konteinerëve për të punuar, vetëm do të theksoj se përdor ProxMox VE. Dhe gjithashtu do të kërkohet të instalohen paketat e nevojshme për ndërtim për çdo sistem (centos: rpmdevtools etj.; debian: build-essential, dh-make, pbuilder etj.)

Ndërtimi i projekteve dhe shërbimet buildbot do të ekzekutohen nën emrin e një përdoruesi jo privilegjuar, prandaj është e nevojshme të krijohet ai në të gjitha hostet që marrin pjesë në proces:


adduser buildbot

Pastaj do të konfigurojmë fillimin automatike të shërbimeve, përkatësisht në secilin nga hostet (konteinerët):

Njësia systemd për fillimin 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.target

dhe ‘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.service

Duke qenë se të gjithë skriptet (në rastin tonë) ndodhen në /usr/local/, është e nevojshme të shkruhet rruga në variablat e mjedisit:

nano /root/.bash_profile

PATH=$PATH:$HOME/.local/bin:$HOME/bin:/usr/local/bin

Pas kësaj, mund të krijojmë infrastrukturën e katalogëve për ‘punëtorët’ (në të gjitha hostet), për këtë regjistrohemi nën përdoruesin buildbot dhe ekzekutojmë 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 123456

Në 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 123456

Në hostet e punës, shërbimi buildbot-worker mund të startohet

systemctl start buildbot-worker

MS Windows

Si ‘punëtor’ për ndërtimin nën windows, do të përdoret një makinë virtuale me versionin e fundit të Win10.
Për punë do të nevojitet:

Pas instalimit të gjithçkaje të përmendur, mund të instalojmë edhe vetë buildbotin:

pip install buildbot-worker

Krijojmë katalogun e punës

md c:worker

Dhe e startojmë

buildbot-worker start c:worker

Nëse gjithçka funksionon (shih log c:workertwistd.log), atëherë mund ta regjistrojmë ‘punëtorin’ si një shërbim, duke e shtuar në regjistrin e sistemit me katalogun e punës (komandat ekzekutohen në powershell të hapur si administrator):

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ë startojmë shërbimin

Start-Service buildbot

Me ‘punëtorët’ për këtë është gjithçka, të tjerat mund t'i lëmë ashtu siç janë, e gjithë menaxhimi bëhet nga masteri.

Konfigurimi i masterit

Për fillimin, krijojmë infrastrukturën për masterin (në hostin kryesor), për këtë regjistrohemi nën përdoruesin buildbot dhe ekzekutojmë komandat e mëposhtme:

su - buildbot
mkdir /home/buildbot/master
cd ~
buildbot create-master master

Për paketat e gatshme krijojmë një katalog build

mkdir /home/buildbot/builds

Në katalogun /home/buildbot/master/ u krijua një skedar master.cfg. Ky skedar përbën kod në python dhe përmban përshkrimin e të gjitha mekanizmave të punës së sistemit, me të do të punojmë edhe më tej.

nano /home/buildbot/master/master.cfg

import os, re
from buildbot.plugins import steps, util, schedulers, worker, changes, reporters

c= BuildmasterConfig ={}

# Përshkrimi i punëtorëve tanë.
c['workers'] = [ worker.Worker('CentOS', '123456'), worker.Worker('Debian-10', '123456'), worker.Worker('Windows-10', '123456')]
c['protocols'] = {'pb': {'port': 4000}} 

# Tregimi i masterit se cilin repository të monitorojë
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 nisjen 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 në versionet e ndryshme, për të mos qenë e nevojshme që të shkohet në kodin e skedarit master.cfg, në skriptin kryesor të programit rac_gui.tcl janë shtuar rreshta me versionin dhe publikimin aktual:

######################################################
#        Rac GUI
...
# version: 1.0.3
# release: 1

Dhe mbi bazën e këtyre rreshtave, buildbot do të numërojë paketat. Për të nxjerrë të dhënat, përdoret thirrja e grep-it në konsolë. Në buildbot nuk mund të përcaktohen variablat për "punëtorët" (në çdo rast, unë nuk gjej si). Për këtë shërbejnë pronësitë (property). Pra, në procesin e ndërtimit, shtojmë hapa për përcaktimin e versionit dhe publikimit dhe përkatësisht, vendosim pronësitë version dhe release. Pronësitë mund të vendosen në mënyra të ndryshme, në këtë rast kjo ë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 marra mund të vendosen duke thirrur 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ë në rrugët 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 të vendosur numrat e duhur të publikimit dhe versionit përdoret thirrja e sed 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 kopjohen në master. Por mund të kopjohen edhe menjëherë nga skedarët punonjës në repository-n tuaj ose në uebfaqe.

# Скопируем файл на мастер
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")
       )
)

Do ta nisim në master procesin e kopjimit të paketave të ndërtuara në hosting përmes ftp. Për këtë përdoret skрипт 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")]
        )
)

Me këtë për RPM e mbyllëm. Tani kalojmë në përshkrimin e algoritmit për ndërtimin e 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 publikimit 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"
       )
)

# Risim emrin e skedarit të 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 realizohen nga rpm gjatë ndërtimit dhe janë përshkruar brenda spesifikimit, për debianin e kemi të bëjmë me këtë 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 e mbyllëm, tani 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 zakonisht nuk ka grep dhe sed (apo ka?), 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 për statusin e procesit të ndërtimit, do të përdorim email-in elektronik.


c['services'] = []

template=u'''
    <h4>Statusi i ndërtimit: {{ summary }}</h4>
    <p> Punëtori i 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 tani mund ta provojmë të nisim shërbimin e masterit:

systemctl restart buildbot-master

Në log do të kontrollojmë që konfigurimi është në rregull dhe gjithçka funksionon siç duhet. Të gjithë punëtorët tanë tani duhet të lidhen, për çka në log "»»'/home/buildbot/master/twistd.log'»»" do të bëhet e ditur me gëzim:

 2019-07-24 16:50:35+0300 [-] Duke ai 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 duke.
 2019-07-24 16:50:35+0300 [-] reactor class: twisted.internet.epollreactor.EPollReactor.
 2019-07-24 16:50:35+0300 [-] DukeBuildMaster -- buildbot.version: 2.3.1
 2019-07-24 16:50:35+0300 [-] Duke konfigurinë 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 ndihmon në bazën e instalimit.
        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ë softuerit të instalimit dhe përdorimit të plug-in-eve dërgohet.
        Ju mund të `zgjidhni jashtë` duke e vendosur këtë variabël në asgjë.
        Ose `zgjidhni brenda` për më shumë informacion duke e vendosur në "plotë".

 2019-07-24 16:50:36+0300 [-] Setting up database with URL 'sqlite:/state.sqlite'
 2019-07-24 16:50:36+0300 [-] vendosja e modit të ditarit të databazës në 'wal'
 2019-07-24 16:50:36+0300 [-] shtimi 1 shërbimeve të reja, heqja 0
 2019-07-24 16:50:36+0300 [-] shtimi 1 burimi të ri të ndryshimit, heqja 0
 2019-07-24 16:50:36+0300 [-] gitpoller: duke përdorur punëtorin '/home/buildbot/master/gitpoller-work'
 2019-07-24 16:50:36+0300 [-] shtimi 3 ndërtues të rinj, heqja 0
 2019-07-24 16:50:36+0300 [-] shtimi 1 programi të ri për planifikim, heqja 0
 2019-07-24 16:50:36+0300 [-] inicializimi i plagin www 'waterfall_view'
 2019-07-24 16:50:36+0300 [-] inicializimi i plagin www 'console_view'
 2019-07-24 16:50:36+0300 [-] inicializimi i plagin www 'grid_view'
 2019-07-24 16:50:36+0300 [-] NOTE: plagi i www 'sitenav' është instaluar por nuk është konfiguruar
 2019-07-24 16:50:36+0300 [-] inicializimi i plagin www 'waterfall_view'
 2019-07-24 16:50:36+0300 [-] inicializimi i plagin www 'console_view'
 2019-07-24 16:50:36+0300 [-] inicializimi i plagin www 'grid_view'
 2019-07-24 16:50:36+0300 [-] NOTE: plagi www 'sitenav' është instaluar por nuk është konfiguruar
 2019-07-24 16:50:36+0300 [-] BuildbotSite duke filluar në 80
 2019-07-24 16:50:36+0300 [-] Duke nisur fabrikën <buildbot.www.service.BuildbotSite object at 0x7fe31c2657b8>
 2019-07-24 16:50:36+0300 [-] shtimi 3 punëtorëve të rinj, heqja 0
 2019-07-24 16:50:36+0300 [-] PBServerFactory duke filluar në 4000
 2019-07-24 16:50:36+0300 [-] Duke nisur fabrikën <twisted.spread.pb.PBServerFactory object at 0x7fe31c147470>
 2019-07-24 16:50:37+0300 [-] BuildMaster është duke funksionuar
 2019-07-24 16:50:37+0300 [-] buildbotNetUsageData: dërgimi {'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' duke u bashkuar nga IPv4Address(type='TCP', host='127.0.0.1', port=37332)
 2019-07-24 16:50:37+0300 [Broker,0,127.0.0.1] Marrë informacionin e punëtorit nga 'CentOS'
 2019-07-24 16:50:37+0300 [-] bot i bashkuar
 2019-07-24 16:50:37+0300 [Broker,0,127.0.0.1] Punëtori CentOS i bashkuar 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' duke u bashkuar nga IPv4Address(type='TCP', host='192.168.5.145', port=49831)
 2019-07-24 16:50:39+0300 [Broker,1,192.168.55.15] Marrë informacionin e punëtorit nga 'Windows-10'
 2019-07-24 16:50:40+0300 [-] bot i bashkuar
 2019-07-24 16:50:40+0300 [Broker,1,192.168.55.15] Punëtori Windows-10 i bashkuar me Rac-GUI-WIN-builder
 2019-07-24 16:50:41+0300 [Broker,2,192.168.55.99] punëtori 'Debian-10' duke u bashkuar nga IPv4Address(type='TCP', host='192.168.5.9', port=44430)
 2019-07-24 16:50:41+0300 [Broker,2,192.168.55.99] Marrë informacionin e punëtorit nga 'Debian-10'
 2019-07-24 16:50:41+0300 [-] bot i bashkuar
 2019-07-24 16:50:41+0300 [Broker,2,192.168.55.99] Punëtori Debian-10 i bashkuar me Rac-GUI-DEB-builder

Procesi i konfigurimit ka përfunduar. Mund të shihni gjendjen aktuale përmes ndërfaqes web. Ku gjithashtu mund të shihni gabimet e ndërtimit, të rifilloni një proces të ngecur nëse diçka ka shkuar keq, etj.

Menjëherë pas fillimit të punëtorëve tanë mund të shihni përmes menusë «Builds» -> «Workers»

Buildbot në shembuj.

Pas procesit të parë të ndërtimit (dmth. ndryshimeve në depozitën Git), në faqen e parë do të shfaqen statuset e proceseve.

Buildbot në shembuj.

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

Buildbot në shembuj.

Konfigurimi i plotë i masterit 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
    ))

# служба запуска сборки
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>Statusi i ndërtimit: {{ summary }}</h4>
<p> Punëtori i 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 këtij artikulli është bërë me materialet e mëposhtme:

Burimi: habr.com

Bleni hostim të besueshëm për faqe me mbrojtje nga DDoS, serverë VPS VDS 🔥 Bleni hostim të besueshëm për faqe me mbrojtje nga DDoS, serverë VPS VDS | ProHoster