Necesitaba configurar el proceso de creación y entrega de paquetes de software desde un repositorio Git al sitio. Y cuando vi, no hace mucho, aquí en Habré un artículo sobre buildbot (enlace al final), decidí probarlo y aplicarlo para esto.
Dado que buildbot es un sistema distribuido, sería lógico crear un host de compilación independiente para cada arquitectura y sistema operativo. 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 buildbot master (master) y uno de los trabajadores (worker)
vm-srv-build2 - debian 10, para crear paquetes DEB
vm-srv-build3 - Windows 10, para el ensamblaje, usted mismo comprende qué
vamos a recoger GUI de Rac — una interfaz gráfica para 1C rac para administrar un grupo de servidores. Para Linux, se utilizarán herramientas estándar para cada sistema operativo; para crear un archivo exe para Windows a partir de un script tcl, use envoltura libre.
Instalación
GNU / Linux
Para la instalación existe suficiente documentación en la red. 1,2. Sí, y no causa ningún problema especial:
Para maestro:
Por supuesto, sería más correcto crear paquetes para cada sistema operativo, pero esto no está dentro del alcance del artículo. También omitiremos la descripción de cómo configurar contenedores para el trabajo, solo señalaré que uso ProxMox VE. Y también necesitarás instalar paquetes para cada eje requerido para la construcción (centos: rpmdevtools, etc.; debian: build-essential, dh-make, pbuilder, etc.)
Los proyectos y servicios de buildbot se ejecutarán como un usuario sin privilegios, por lo que deberá crearlos en todos los hosts que participan en el proceso:
adduser buildbot
A continuación, configuraremos el lanzamiento automático de servicios, respectivamente, en cada uno de los hosts (contenedores):
Después de eso, puede crear una infraestructura de directorio para "trabajadores" (en todos los hosts), para ello se registra con el usuario buildbot y ejecuta 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 los hosts trabajadores, se puede iniciar el servicio buildbot-worker
systemctl start buildbot-worker
MS Windows
Como "trabajador" para la construcción en Windows, se utilizará una máquina virtual con la última versión de Win10.
Para trabajar necesitas:
Una vez instalado todo lo anterior, puede instalar el buildbot:
pip install buildbot-worker
Crear un directorio de trabajo
md c:worker
Y lancemos
buildbot-worker start c:worker
Si todo funciona (consulte el registro c: trabajadortwistd.log), entonces puede registrar 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):
Con los "trabajadores" eso es todo, no puedes tocarlos más, todo el control viene del maestro.
Configuración del asistente
Para empezar, creemos la infraestructura para el maestro (en el host principal), para ello nos registramos con el usuario buildbot y ejecutamos los siguientes comandos:
su - buildbot
mkdir /home/buildbot/master
cd ~
buildbot create-master master
Para paquetes ya preparados, cree un directorio de compilaciones.
mkdir /home/buildbot/builds
Se ha creado un archivo master.cfg en el directorio /home/buildbot/master/. Este archivo es un código Python y contiene una descripción de todos los mecanismos del sistema y trabajaremos con él en el futuro.
Para automatizar el ensamblaje de paquetes de diferentes versiones, para no tener que subir al código del archivo master.cfg, en el script principal del programa rac_gui.tcl, en el encabezado, se han colocado líneas con la versión actual y el lanzamiento. agregado:
Y en base a estas líneas, buildbot numerará los paquetes. Para extraer los datos, se utiliza una llamada a la consola grep. En buildbot, simplemente no puedes definir variables para "trabajadores" (en cualquier caso, no encontré cómo). Para eso están las propiedades. Aquellos. al proceso de compilación, agregue los pasos para determinar la versión y la versión y, en consecuencia, establezca las propiedades de la versión y la versión. Las propiedades se pueden configurar de varias maneras, en este caso es una llamada al comando de la 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"
)
)
Puede sustituir los valores recibidos llamando a util.Interpolate().
Cabe señalar aquí que, dado que el host también se utiliza para el ensamblaje manual de paquetes, el ensamblaje se realizará siguiendo las rutas estándar.
Para establecer los números de versión y lanzamiento correctos, se utiliza una llamada sed estándar, es decir. el comando reemplaza los valores dentro del archivo de especificaciones con los necesarios
Copiamos el paquete ensamblado terminado y el archivo con los códigos fuente al maestro. Pero puede copiar inmediatamente archivos desde el que está en funcionamiento a su repositorio o al sitio.
# Скопируем файл на мастер
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")
)
)
Comencemos el proceso de copiar los paquetes recopilados al alojamiento a través de FTP en el maestro. Para ello se utiliza guión en tcl.
Este es el fin de RPM. Ahora comencemos a describir el algoritmo para crear un 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 un paquete RPM, algunos de los siguientes procedimientos los realiza el propio rpm durante el ensamblaje y se describen dentro de las especificaciones; 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")]
)
)
Guardamos el archivo y puedes intentar iniciar el servicio del asistente:
systemctl restart buildbot-master
En el registro comprobaremos que todo está en orden con la configuración y que todo funciona normalmente. Todos nuestros trabajadores ahora deberían conectarse, lo cual 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 web-morde. Donde también puede ver errores de compilación, iniciar un proceso congelado si algo salió mal, etc.
Inmediatamente después del lanzamiento de nuestros arduos trabajadores, puede verlo a través del menú "Construcciones" -> "Trabajadores"
Una vez completado 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.
Si hace clic en la línea deseada con el mouse, se abrirá una página con el estado actual de este proceso, donde podrá ver qué está sucediendo, qué errores, etc.
La configuración maestra completa se puede encontrar aquí