Buildbot en ejemplos

Necesitaba configurar el proceso de ensamblar y entregar paquetes de software desde el repositorio de Git al sitio. Y habiendo visto, no hace mucho tiempo, aquí en Habr, el artículo sobre buildbot (el enlace al final) decidió probarlo y solicitarlo.


Dado que buildbot es un sistema distribuido, será lógico que cada arquitectura y sistema operativo cree un host de ensamblaje separado. En nuestro caso, estos serán contenedores LXC (en el caso de Linux) y qemu (en el caso de Windows):


  • vm-srv-build1 - centos 7, habrá un maestro de buildbot y uno de los trabajadores
  • vm-srv-build2 - debian 10, para construir paquetes DEB
  • vm-srv-build3 - windows 10, para el ensamblaje, usted mismo comprende qué

Recopilaremos Rac GUI , una cara gráfica de 1C rac para administrar un clúster de servidores. En Linux, se usarán herramientas estándar para cada sistema operativo, freewrap se usa para construir un archivo exe para Windows desde un script tcl.


Instalación


GNU / Linux


Para la instalación, la documentación en la red es suficiente 1 , 2 . Y no causa ningún problema especial:
Para el maestro


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 

Para los "trabajadores", esto es suficiente:


 pip3 install buildbot-worker 

Por supuesto, sería más correcto recopilar paquetes para cada sistema operativo, pero esto no está incluido en el alcance del artículo. También omitimos la descripción de la configuración de contenedores para el trabajo, solo noto que uso ProxMox VE. Y también necesita instalar paquetes para cada eje requerido para el ensamblaje (centos: rpmdevtools, etc .; debian: build-essential, dh-make, pbuilder, etc.)


Los servicios de ensamblaje de proyectos y buildbot se lanzarán en nombre de un usuario sin privilegios, por lo que debe crearlo en todos los hosts involucrados en el proceso:


 adduser buildbot 

A continuación, configure el inicio automático de servicios, respectivamente, en cada uno de los hosts (contenedores):


Unidad de Systemd para ejecutar el asistente:


 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 

y "trabajador"


 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 

Como todos los scripts (en nuestro caso) están en / usr / local /, debe escribirles la ruta en variables de entorno:


 nano /root/.bash_profile PATH=$PATH:$HOME/.local/bin:$HOME/bin:/usr/local/bin 

Después de eso, puede crear una infraestructura de directorio para los "trabajadores" (en todos los hosts), para esto, regístrese bajo el usuario buildbot y ejecute los siguientes comandos:


En el primer 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 

En el segundo 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 

En hosts que funcionan, se puede iniciar el servicio buildbot-worker


 systemctl start buildbot-worker 

MS Windows


Como una compilación "funcional" para Windows, se utilizará una máquina virtual con la última versión Win10.
Para trabajar necesitas:



Después de instalar todo lo anterior, puede instalar buildbot en sí:


 pip install buildbot-worker 

Crea un directorio de trabajo


 md c:\worker 

Y correr


 buildbot-worker start c:\worker 

Si todo funciona (consulte el registro c: \ worker \ twistd.log), puede registrar a nuestro "trabajador" como un servicio agregando un elemento con el directorio de trabajo al registro (los comandos se ejecutan en PowerShell ejecutándose como administrador):


 buildbot_worker_windows_service.exe --user VM-SRV-BUILD3\buildbot --password 123456 --startup auto install New-ItemProperty -path Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\BuildBot\Parameters -Name directories -PropertyType String -Value c:\worker 

Y puedes dirigir un sirviente


 Start-Service buildbot 

Eso es todo con los "trabajadores", entonces ya no tienes que tocarlos, toda la gestión va del maestro.


Asistente de configuración


Para comenzar, crearemos la infraestructura para el asistente (en el host principal), para esto nos registraremos bajo el usuario buildbot y ejecutaremos los siguientes comandos:


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

Para paquetes terminados, cree el directorio de compilaciones


 mkdir /home/buildbot/builds 

El archivo master.cfg se creó en el directorio / home / buildbot / master /. Este archivo es un código de Python y contiene una descripción de todos los mecanismos del sistema, seguiremos trabajando con él.


 nano /home/buildbot/master/master.cfg 

 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 = 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) ) 

Para automatizar el ensamblaje de paquetes de diferentes versiones, de modo que no tenga que subir al código del archivo master.cfg, en el script principal del programa rac_gui.tcl en el encabezado, se han agregado líneas con la versión y el lanzamiento actuales:


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

Y en base a estas líneas, buildbot numerará los paquetes. Para extraer datos, use la llamada grep de la consola. En buildbot, simplemente no puede definir variables para "trabajadores" (en cualquier caso, no he encontrado cómo). Para hacer esto, use las propiedades. Es decir en el proceso de ensamblaje, agregue los pasos para determinar la versión y la versión y, en consecuencia, establezca la versión y las propiedades de la versión. Las propiedades se pueden configurar de varias maneras, en este caso una llamada a un comando de consola:


 #       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" ) ) 

Sustituya los valores obtenidos llamando a 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"] ) ) 

Cabe señalar que, dado que el host también se utiliza para el ensamblaje manual de paquetes, el ensamblaje se realizará a lo largo de rutas estándar.


 #  spec rac_gui_build_RPM.addStep(steps.ShellCommand( command=["cp", "../rac-gui/rac_gui.spec", "/home/buildbot/rpmbuild/SPECS/rac_gui.spec"])) 

Para establecer los números correctos de versión y versión, use la llamada estándar sed, es decir el comando reemplaza los valores dentro del archivo de especificaciones con los necesarios


 #   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' ) ) 

Copiamos el paquete ensamblado terminado y lo archivamos con los códigos fuente al maestro. Pero puede copiar inmediatamente archivos desde su escritorio a su repositorio o sitio 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") ) ) 

En el asistente, comenzamos el proceso de copiar los paquetes recopilados en el alojamiento FTP. Para hacer esto, use el script 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")] ) ) 

En él con RPM terminado. Ahora comencemos la descripción del algoritmo de ensamblaje para el paquete DEB. Dado que los procesos de creación de paquetes para diferentes sistemas son independientes entre sí, se repetirán muchos pasos.


 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"])) 

Para el paquete RPM, parte de los siguientes procedimientos es realizado por el propio rpm durante el ensamblaje y se describe dentro de la especificación, para debian debe hacerlo aquí:


 #     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")] ) ) 

Y DEB está listo, ¡ahora 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) ) 

Dado que Windows no tiene grep y sed (¿o hay?), Utilizaremos 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:\\bin\\freewrap.exe", "rac_gui.tcl"])) #  ,   rac_gui_build_WIN.addStep(steps.ShellCommand( command=["c:\\Program Files\\7-zip\\7z.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), ] 

Para notificar sobre el estado del proceso de montaje, utilizaremos el correo electrónico.


 c['services'] = [] template=u'''\ <h4>Build status: {{ summary }}</h4> <p> Worker used: {{ 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'] = "The process of bulding" 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" } 

Guardamos el archivo y puede intentar iniciar el servicio del asistente:


 systemctl restart buildbot-master 

En el registro, verificamos que todo esté en orden con la configuración y que todo funcione como de costumbre. Todos nuestros empleados ahora deben conectarse, como se informará felizmente en el registro '' '' '' /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 

Esto completa el proceso de configuración. Puede ver el estado actual a través de la cara web. Donde también puede ver errores de ensamblaje, inicie un proceso congelado si algo salió mal, etc.


Inmediatamente después del lanzamiento de nuestros trabajadores, puede ver a través del menú "Construye" -> "Trabajadores"


imagen


Después de completar el primer proceso de compilación (es decir, cambios en el repositorio de Git), el estado de los procesos aparecerá en la primera página.


imagen


Si toca el mouse en la línea deseada, se abre una página con el estado actual del proceso, donde puede ver qué está sucediendo, qué errores, etc.


imagen


Puedes tomar toda la configuración maestra aquí
 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:\\bin\\freewrap.exe", "rac_gui.tcl"])) #  ,   rac_gui_build_WIN.addStep(steps.ShellCommand( command=["c:\\Program Files\\7-zip\\7z.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>Build status: {{ summary }}</h4> <p> Worker used: {{ 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.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'] = "The process of bulding" 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" } 

Materiales


En la preparación del artículo, se utilizaron los siguientes materiales:


Source: https://habr.com/ru/post/464489/


All Articles