Avevo bisogno di impostare il processo di assemblaggio e distribuzione di pacchetti software da un repository Git al sito. E quando ho visto, non molto tempo fa, qui su Habré un articolo su buildbot (link in fondo), ho deciso di provarlo e applicarlo.
Poiché buildbot è un sistema distribuito, sarebbe logico creare un host di build separato per ogni architettura e sistema operativo. Nel nostro caso si tratterà dei contenitori LXC (nel caso di Linux) e qemu (nel caso di Windows):
vm-srv-build1 - centos 7, ci sarà un master buildbot e uno dei lavoratori
vm-srv-build2 - debian 10, per creare pacchetti DEB
vm-srv-build3 - Windows 10, per l'assemblaggio, sai a cosa serve
Raccoglieremo GUI di Rac — un'interfaccia grafica per 1C rac per la gestione di un cluster di server. Per Linux verranno utilizzati strumenti standard per ciascun sistema operativo; per creare un file exe per Windows da uno script tcl, utilizzare avvolgere liberamente.
Installazione
GNU / Linux
Su Internet è disponibile documentazione sufficiente per l'installazione 1,2. Sì, e non causa particolari problemi:
Per il maestro:
Naturalmente sarebbe più corretto raccogliere pacchetti per ciascun sistema operativo, ma questo va oltre lo scopo dell'articolo. Tralasceremo anche la descrizione della configurazione dei contenitori per il lavoro, noterò solo che utilizzo ProxMox VE. E dovrai anche installare i pacchetti per ciascun asse richiesto per l'assemblaggio (centos: rpmdevtools, ecc.; debian: build-essential, dh-make, pbuilder, ecc.)
I progetti di build e i servizi buildbot verranno avviati come utente non privilegiato, quindi è necessario crearne uno su tutti gli host che partecipano al processo:
adduser buildbot
Successivamente configureremo l'avvio automatico dei servizi, rispettivamente, su ciascuno degli host (contenitori):
Successivamente, puoi creare un'infrastruttura di directory per i "lavoratori" (su tutti gli host), per fare ciò, registrati con l'utente buildbot ed esegui i seguenti comandi:
Sul primo host 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
Sul secondo host 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
Sugli host lavoratore è possibile avviare il servizio buildbot-worker
systemctl start buildbot-worker
MS Windows
Come “worker” per l'assemblaggio sotto Windows verrà utilizzata una macchina virtuale con l'ultima versione di Win10.
Per lavoro hai bisogno di:
Dopo aver installato tutto quanto sopra, è possibile installare il buildbot stesso:
pip install buildbot-worker
Creiamo una directory di lavoro
md c:worker
E lanciamoci
buildbot-worker start c:worker
Se tutto funziona (vedi log c:workertwistd.log), puoi registrare il nostro "worker" come servizio aggiungendo un elemento con la directory di lavoro al registro (i comandi vengono eseguiti in PowerShell in esecuzione come amministratore):
Con gli “operai” questo è tutto, non devi toccarli ulteriormente, tutto il controllo viene dal padrone.
Configurazione guidata
Per cominciare, creiamo l'infrastruttura per il master (sull'host principale), per fare ciò registriamoci con l'utente buildbot ed eseguiamo i seguenti comandi:
su - buildbot
mkdir /home/buildbot/master
cd ~
buildbot create-master master
Per i pacchetti già pronti, crea una directory builds
mkdir /home/buildbot/builds
È stato creato un file master.cfg nella directory /home/buildbot/master/. Questo file è un codice Python e contiene una descrizione di tutti i meccanismi del sistema; lavoreremo con esso in futuro.
Per automatizzare l'assemblaggio di pacchetti di versioni diverse, in modo da non dover approfondire il codice del file master.cfg, nello script principale del programma rac_gui.tcl sono state aggiunte nell'intestazione le righe con la versione e la release corrente :
E in base a queste righe buildbot numererà i pacchetti. Per estrarre i dati, utilizzare la chiamata grep della console. In buildbot semplicemente non puoi definire variabili per i "lavoratori" (almeno, non ho trovato come). Ecco a cosa servono le proprietà. Quelli. Nel processo di assemblaggio, aggiungiamo passaggi per determinare la versione e il rilascio e, di conseguenza, impostare le proprietà della versione e del rilascio. Le proprietà possono essere impostate in vari modi, in questo caso richiamando il comando da console:
# Добавим определение версии из основного файла
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"
)
)
Puoi sostituire i valori risultanti chiamando util.Interpolate().
Per impostare il rilascio corretto e i numeri di versione, utilizzare una chiamata sed standard, ad es. il comando sostituisce i valori all'interno del file spec con quelli richiesti
Copiamo il pacchetto assemblato finito e l'archivio con i sorgenti nel master. Ma puoi copiare immediatamente i file dal tuo file di lavoro al tuo repository o sito web.
# Скопируем файл на мастер
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")
)
)
Iniziamo il processo di copia dei pacchetti raccolti sull'hosting tramite FTP sul master. A questo scopo viene utilizzato copione su tcl.
Questo è tutto con RPM. Ora iniziamo a descrivere l'algoritmo per creare un pacchetto DEB. Poiché i processi per la creazione di pacchetti per sistemi diversi sono indipendenti l'uno dall'altro, verranno ripetuti molti passaggi.
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"]))
Per un pacchetto RPM, alcune delle seguenti procedure vengono eseguite dall'rpm stesso durante l'assemblaggio e sono descritte nelle specifiche; per Debian, devi farlo qui:
# Поменяем пути к библиотекам
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")]
)
)
Salva il file e puoi provare ad avviare il servizio di procedura guidata:
systemctl restart buildbot-master
Nel registro controlleremo che tutto sia in ordine con la configurazione e che tutto funzioni normalmente. Tutti i nostri lavoratori dovrebbero ora connettersi, il che sarà felicemente riportato nel log »»'/home/buildbot/master/twistd.log»»':
2019-07-24 16:50:35+0300 [-] Loading buildbot.tac...
2019-07-24 16:50:35+0300 [-] Loaded.
2019-07-24 16:50:35+0300 [-] twistd 19.2.1 (/usr/bin/python3.6 3.6.8) starting up.
2019-07-24 16:50:35+0300 [-] reactor class: twisted.internet.epollreactor.EPollReactor.
2019-07-24 16:50:35+0300 [-] Starting BuildMaster -- buildbot.version: 2.3.1
2019-07-24 16:50:35+0300 [-] Loading configuration from '/home/buildbot/master/master.cfg'
2019-07-24 16:50:36+0300 [-] /usr/local/lib/python3.6/site-packages/buildbot/config.py:90: buildbot.config.ConfigWarning: [0.9.0 and later] `buildbotNetUsageData` is not configured and defaults to basic.
This parameter helps the buildbot development team to understand the installation base.
No personal information is collected.
Only installation software version info and plugin usage is sent.
You can `opt-out` by setting this variable to None.
Or `opt-in` for more information by setting it to "full".
2019-07-24 16:50:36+0300 [-] Setting up database with URL 'sqlite:/state.sqlite'
2019-07-24 16:50:36+0300 [-] setting database journal mode to 'wal'
2019-07-24 16:50:36+0300 [-] adding 1 new services, removing 0
2019-07-24 16:50:36+0300 [-] adding 1 new change_sources, removing 0
2019-07-24 16:50:36+0300 [-] gitpoller: using workdir '/home/buildbot/master/gitpoller-work'
2019-07-24 16:50:36+0300 [-] adding 3 new builders, removing 0
2019-07-24 16:50:36+0300 [-] adding 1 new schedulers, removing 0
2019-07-24 16:50:36+0300 [-] initializing www plugin 'waterfall_view'
2019-07-24 16:50:36+0300 [-] initializing www plugin 'console_view'
2019-07-24 16:50:36+0300 [-] initializing www plugin 'grid_view'
2019-07-24 16:50:36+0300 [-] NOTE: www plugin 'sitenav' is installed but not configured
2019-07-24 16:50:36+0300 [-] initializing www plugin 'waterfall_view'
2019-07-24 16:50:36+0300 [-] initializing www plugin 'console_view'
2019-07-24 16:50:36+0300 [-] initializing www plugin 'grid_view'
2019-07-24 16:50:36+0300 [-] NOTE: www plugin 'sitenav' is installed but not configured
2019-07-24 16:50:36+0300 [-] BuildbotSite starting on 80
2019-07-24 16:50:36+0300 [-] Starting factory <buildbot.www.service.BuildbotSite object at 0x7fe31c2657b8>
2019-07-24 16:50:36+0300 [-] adding 3 new workers, removing 0
2019-07-24 16:50:36+0300 [-] PBServerFactory starting on 4000
2019-07-24 16:50:36+0300 [-] Starting factory <twisted.spread.pb.PBServerFactory object at 0x7fe31c147470>
2019-07-24 16:50:37+0300 [-] BuildMaster is running
2019-07-24 16:50:37+0300 [-] buildbotNetUsageData: sending {'installid': 'b6193b126b96689351d2fe95787c5a03fc0879f9', 'versions': {'Python': '3.6.8', 'Buildbot': '2.3.1', 'Twisted': '19.2.1'}, 'platform': {'platform': 'Linux-4.15.18-10- pve-x86_64-with-centos-7.6.1810-Core', 'system': 'Linux', 'machine': 'x86_64', 'processor': 'x86_64', 'python_implementation': 'CPython', 'version': '#1 SMP PVE 4.15.18-32', 'distro': 'centos:7'}, 'plugins': {'buildbot/worker/base/Worker': 3, 'buildbot/config/BuilderConfig': 3, 'buildbot/schedulers/basic/SingleBranchScheduler': 1, 'buildbot/reporters/mail/MailNotifier': 1, 'buildbot/changes/gitpoller/GitPoller': 1, 'buildbot/steps/worker/MakeDirectory': 1, 'buildbot/steps/source/git/Git': 3, 'buildbot/steps/shell/ShellCommand': 9, 'buildbot/steps/package/rpm/rpmbuild/RpmBuild': 1}, 'db': 'sqlite', 'mq': 'simple', 'www_plugins': ['waterfall_view', 'console_view', 'grid_view']}
2019-07-24 16:50:37+0300 [Broker,0,127.0.0.1] worker 'CentOS' attaching from IPv4Address(type='TCP', host='127.0.0.1', port=37332)
2019-07-24 16:50:37+0300 [Broker,0,127.0.0.1] Got workerinfo from 'CentOS'
2019-07-24 16:50:37+0300 [-] bot attached
2019-07-24 16:50:37+0300 [Broker,0,127.0.0.1] Worker CentOS attached to Rac-GUI-RPM-builder
2019-07-24 16:50:37+0300 [-] buildbotNetUsageData: buildbot.net said: ok
2019-07-24 16:50:39+0300 [Broker,1,192.168.55.15] worker 'Windows-10' attaching from IPv4Address(type='TCP', host='192.168.5.145', port=49831)
2019-07-24 16:50:39+0300 [Broker,1,192.168.55.15] Got workerinfo from 'Windows-10'
2019-07-24 16:50:40+0300 [-] bot attached
2019-07-24 16:50:40+0300 [Broker,1,192.168.55.15] Worker Windows-10 attached to Rac-GUI-WIN-builder
2019-07-24 16:50:41+0300 [Broker,2,192.168.55.99] worker 'Debian-10' attaching from IPv4Address(type='TCP', host='192.168.5.9', port=44430)
2019-07-24 16:50:41+0300 [Broker,2,192.168.55.99] Got workerinfo from 'Debian-10'
2019-07-24 16:50:41+0300 [-] bot attached
2019-07-24 16:50:41+0300 [Broker,2,192.168.55.99] Worker Debian-10 attached to Rac-GUI-DEB-builder
Questo completa il processo di configurazione. È possibile visualizzare lo stato corrente tramite l'interfaccia web. Dove puoi anche vedere errori di compilazione, avviare un processo bloccato se qualcosa è andato storto, ecc.
Subito dopo il lancio, i nostri lavoratori possono essere visualizzati attraverso il menu “Costruzioni” -> “Lavoratori”
Una volta completato il primo processo di compilazione (ovvero le modifiche al repository Git), lo stato dei processi verrà visualizzato nella prima pagina.
Se si fa clic con il mouse sulla riga desiderata, si aprirà una pagina con lo stato attuale di questo processo, in cui è possibile vedere cosa sta succedendo, quali errori, ecc.
L'intera configurazione della procedura guidata può essere trovata qui