refactor(ansible): Estandariza nombres de roles y actualiza Koji
Se estandarizan los nombres de los directorios de roles, cambiando guiones por guiones bajos. Se añaden nuevos scripts para limpieza y callbacks en Koji Hub. Además, se actualizan las configuraciones de Kojid, Kojira y PostgreSQL, incluyendo la instalación de paquetes, ajustes de mock y la gestión de variables.
This commit is contained in:
parent
08c38d3d56
commit
39aeb2d6b6
91 changed files with 1037 additions and 957 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -5,3 +5,5 @@ certs/
|
|||
*.swp
|
||||
bin/koji-test.bash
|
||||
bin/koji-rpms-test.bash
|
||||
memory.rst
|
||||
docs/koji
|
||||
|
|
|
|||
|
|
@ -25,6 +25,10 @@ regenerate-certs: clean-certs
|
|||
deploy:
|
||||
ansible-playbook --vault-pass-file=.pass deploy.yaml
|
||||
|
||||
.PHONY: bootstrap
|
||||
bootstrap:
|
||||
ansible-playbook --vault-pass-file=.pass bootstrap.yaml
|
||||
|
||||
.PHONY: reset
|
||||
reset:
|
||||
ansible-playbook --vault-pass-file=.pass reset.yaml
|
||||
|
|
|
|||
276
README.rst
276
README.rst
|
|
@ -9,148 +9,196 @@ Entorno de Desarrollo
|
|||
Para empezar a desarrollar, necesitas configurar un entorno de virtualización local. Este proyecto usa OpenTofu para aprovisionar
|
||||
máquinas virtuales con libvirt.
|
||||
|
||||
Requisitos Previos
|
||||
------------------
|
||||
* Sistema Operativo: Todo el desarrollo y las pruebas se han realizado en Fedora 42 x86_64.
|
||||
* Virtualización: Necesitas tener `libvirt` y `qemu` instalado y funcionando.
|
||||
* Permisos de Usuario: Tu usuario debe ser miembro de los grupos `libvirt`, `kvm` y `qemu`.
|
||||
Requisitos
|
||||
==========
|
||||
|
||||
.. code-block:: bash
|
||||
Este proyecto tiene las siguientes dependencias:
|
||||
|
||||
usermod -aG libvirt,kvm,qemu renich
|
||||
Software:
|
||||
OpenTofu:
|
||||
Para aprovisionar la infraestructura virtual.
|
||||
|
||||
Ansible:
|
||||
Para la configuración y el despliegue de Koji.
|
||||
|
||||
libvirt, libvirt-nss y qemu:
|
||||
Para la virtualización de las máquinas.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# instalar
|
||||
dnf -y install @virtualization libvirt-nss
|
||||
|
||||
# activar
|
||||
systemctl enable --now libvirtd.socket
|
||||
|
||||
# configurar
|
||||
authselect enable-feature with-libvirt
|
||||
authselect check
|
||||
authselect apply-changes
|
||||
|
||||
.. note::
|
||||
El authselect configura nsswitch para que utilice la información provista por libvirt-nss. Te permite acceder a tus
|
||||
máquinas virtuales usando su nombre en lugar de una IP. Por ejemplo, para entrar a `cs10-koji-00.mx-os` solo haces: ``ssh
|
||||
root@cs10-koji-00.mx-os`` y listo.
|
||||
|
||||
Colecciones de Ansible:
|
||||
El playbook depende de varias colecciones de Ansible. Puedes instalarlas con el siguiente comando:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
ansible-galaxy collection install -r requirements.yaml
|
||||
|
||||
Sistema Operativo:
|
||||
Todo el desarrollo y las pruebas se han realizado en Fedora 43 x86_64.
|
||||
|
||||
Permisos de Usuario:
|
||||
Tu usuario debe ser miembro de los grupos `libvirt`, `kvm` y `qemu`.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
usermod -aG libvirt,kvm,qemu renich
|
||||
|
||||
.. note::
|
||||
Después de agregarte a los grupos, puede que necesites cerrar sesión y volver a iniciarla para que los cambios surtan efecto.
|
||||
|
||||
Primeros Pasos
|
||||
--------------
|
||||
#. Aprovisiona la Infraestructura: El `GNUmakefile` proporciona un objetivo para facilitar este proceso.
|
||||
Configuración Inicial
|
||||
=====================
|
||||
|
||||
Antes de desplegar el entorno, necesitas realizar dos pasos de configuración:
|
||||
|
||||
Credenciales de Ansible Vault:
|
||||
Antes de ejecutar el playbook, crea un archivo cifrado `vars/credentials.yaml`. Este archivo contiene datos sensibles necesarios
|
||||
para el despliegue.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
ansible-vault encrypt vars/credentials.yaml
|
||||
|
||||
El archivo `credentials.yaml` debe contener las siguientes variables:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
# Database
|
||||
koji_db_user: koji
|
||||
koji_db_password: "your-database-password"
|
||||
koji_db_name: koji
|
||||
koji_db_network: "192.168.122.0/24"
|
||||
|
||||
# Web
|
||||
web_secret: "your-web-secret"
|
||||
|
||||
# GPG
|
||||
gpg_key_passphrase: "your-gpg-key-passphrase"
|
||||
|
||||
# Mail
|
||||
kojid_smtp_pass: "your-smtp-password"
|
||||
|
||||
.. note::
|
||||
El playbook está configurado para usar un archivo de contraseña de vault llamado `.pass`. Asegúrate de que este archivo exista en
|
||||
la raíz del proyecto y contenga tu contraseña de vault.
|
||||
|
||||
Imagen Base de la VM:
|
||||
Es muy importante que tengas una imagen qcow2 de CentOS Stream 10 en `~/VirtualMachines/cs10.qcow2`. De ahí se tomará la imagen
|
||||
base para la construcción de tu cluster de desarrollo. Se puso ahí porque, al parecer, ahí se considera un espacio válido por las
|
||||
políticas de SELinux en Fedora. Puedes verlo con: ``semanage fcontext -l | grep VirtualMachines``.
|
||||
|
||||
Despliegue y Uso
|
||||
================
|
||||
|
||||
El proceso principal para levantar y usar el entorno de Koji es el siguiente:
|
||||
|
||||
#. Aprovisiona la Infraestructura:
|
||||
Este comando usará OpenTofu para crear las máquinas virtuales necesarias.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
make init
|
||||
|
||||
Este comando usará OpenTofu para crear las máquinas virtuales necesarias para el entorno de Koji.
|
||||
|
||||
#. Despliega Koji: Una vez que la infraestructura esté lista, puedes desplegar Koji.
|
||||
#. Despliega Koji:
|
||||
Una vez que la infraestructura esté lista, puedes desplegar la configuración de Koji en las VMs.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
make deploy
|
||||
|
||||
.. note::
|
||||
Yo espero ~30 segundos después de que acabó de desplegar `opentofu`.
|
||||
#. Arranca Koji:
|
||||
Después del despliegue inicial, arranca Koji para crear las etiquetas, destinos y otros objetos necesarios.
|
||||
|
||||
Uso
|
||||
===
|
||||
.. code-block:: bash
|
||||
|
||||
Credenciales de Ansible Vault
|
||||
-----------------------------
|
||||
Antes de ejecutar el playbook, crea un archivo cifrado `vars/credentials.yaml`. Este archivo contiene datos sensibles necesarios
|
||||
para el despliegue.
|
||||
make bootstrap
|
||||
|
||||
.. code-block:: bash
|
||||
.. note::
|
||||
Espera unos 30 segundos después de que `make init` termine antes de ejecutar `make deploy` para asegurar que las VMs estén completamente listas.
|
||||
|
||||
ansible-vault encrypt vars/credentials.yaml
|
||||
Acceso al Entorno:
|
||||
Una vez desplegado, puedes acceder a la interfaz web de Koji en: https://cs10-koji-00.mx-os/koji
|
||||
|
||||
El archivo `credentials.yaml` debe contener las siguientes variables:
|
||||
Uso del Cliente (CLI):
|
||||
El playbook configura al usuario `kojiadmin` para administrar la instancia. Para usar el CLI, conéctate al Koji Hub (`cs10-koji-00.mx-os`)
|
||||
y ejecuta los comandos de Koji.
|
||||
|
||||
.. code-block:: yaml
|
||||
.. code-block:: bash
|
||||
|
||||
# Database
|
||||
koji_db_user: koji
|
||||
koji_db_password: "your-database-password"
|
||||
koji_db_name: koji
|
||||
koji_db_network: "192.168.122.0/24"
|
||||
ssh root@cs10-koji-00.mx-os
|
||||
sudo -u kojiadmin koji moshimoshi
|
||||
|
||||
# Web
|
||||
web_secret: "your-web-secret"
|
||||
Ejemplos de Comandos `koji`:
|
||||
Interfaz Web:
|
||||
Visita https://cs10-koji-00.mx-os/koji en tu navegador para acceder a la interfaz web de Koji. Aquí puedes ver compilaciones, tareas, paquetes, etc.
|
||||
|
||||
# GPG
|
||||
gpg_key_passphrase: "your-gpg-key-passphrase"
|
||||
Monitorear una Compilación:
|
||||
Usa el comando `koji taskinfo <task_id>` para ver el estado de una tarea específica. También puedes usar la interfaz web.
|
||||
|
||||
# Mail
|
||||
kojid_smtp_pass: "your-smtp-password"
|
||||
Hacer una Compilación:
|
||||
Para compilar un paquete, usa `koji build <tag> <fuente>`. Por ejemplo:
|
||||
|
||||
.. note::
|
||||
El playbook está configurado para usar un archivo de contraseña de vault llamado `.pass`. Asegúrate de que este archivo exista en
|
||||
la raíz del proyecto y contenga tu contraseña de vault.
|
||||
.. code-block:: bash
|
||||
|
||||
koji build mxos0-build git+https://git.mx-os.mx/RPMs/bash
|
||||
|
||||
Desarrollo
|
||||
==========
|
||||
Este proyecto incluye un `GNUmakefile` para agilizar las tareas de desarrollo comunes:
|
||||
Listar Tareas:
|
||||
`koji list-tasks` para ver tareas activas.
|
||||
|
||||
* `make init`: Destruye la infraestructura existente con OpenTofu y luego la recrea.
|
||||
* `make deploy`: Ejecuta el playbook de despliegue principal.
|
||||
* `make reset`: Ejecuta el playbook de reseteo.
|
||||
* `make regenerate-certs`: Limpia el directorio `certs/` y luego ejecuta las tareas de Ansible necesarias para regenerar todos los
|
||||
certificados. Esto es útil cuando solo necesitas actualizar los certificados sin afectar la infraestructura.
|
||||
* `make clean-certs`: Elimina todos los archivos en el directorio `certs/` excepto el archivo `.gitignore`.
|
||||
* `make tofu-init`: Inicializa el directorio de trabajo de OpenTofu.
|
||||
* `make tofu-apply`: Crea o actualiza la infraestructura definida en los archivos de OpenTofu.
|
||||
* `make tofu-destroy`: Destruye la infraestructura gestionada por OpenTofu.
|
||||
Listar Etiquetas:
|
||||
`koji list-tags` para ver etiquetas disponibles.
|
||||
|
||||
Desarrollo (Tareas de Makefile)
|
||||
===============================
|
||||
Este proyecto incluye un `GNUmakefile` para agilizar las tareas de desarrollo y mantenimiento comunes:
|
||||
|
||||
Despliegue
|
||||
==========
|
||||
Para desplegar, solo es necesario hacer lo siguiente:
|
||||
`make init`:
|
||||
Destruye la infraestructura existente con OpenTofu y luego la recrea.
|
||||
|
||||
.. code-block:: bash
|
||||
`make deploy`:
|
||||
Ejecuta el playbook de despliegue principal.
|
||||
|
||||
make tofu-init tofu-destroy tofu-apply
|
||||
sleep 30s
|
||||
make deploy
|
||||
`make bootstrap`:
|
||||
Ejecuta el playbook de arranque para configurar los objetos de Koji.
|
||||
|
||||
.. important::
|
||||
Es importante tener instalado y configurado `libvirt-nss` para que esto funcione bien.
|
||||
`make reset`:
|
||||
Ejecuta el playbook de reseteo.
|
||||
|
||||
Una vez desplegado, solo tienes que abrir un navegador e ir a: https://cs10-koji-00.mx-os/koji
|
||||
`make regenerate-certs`:
|
||||
Limpia el directorio `certs/` y luego ejecuta las tareas de Ansible necesarias para regenerar todos los certificados.
|
||||
|
||||
Cliente (CLI)
|
||||
-------------
|
||||
El playbook configura al usuario `kojiadmin` para administrar la instancia de Koji. Su archivo de configuración de cliente se
|
||||
encuentra en `/home/kojiadmin/.koji/config` en el Koji Hub (`cs10-koji-00.mx-os`). El playbook genera este archivo automáticamente e
|
||||
incluye las rutas de los certificados SSL necesarios y la configuración `authtype = ssl`.
|
||||
`make clean-certs`:
|
||||
Elimina todos los archivos en el directorio `certs/` excepto el archivo `.gitignore`.
|
||||
|
||||
Para interactuar con Koji como el usuario `kojiadmin` desde el Koji Hub, normalmente usarás comandos como:
|
||||
`make tofu-init`:
|
||||
Inicializa el directorio de trabajo de OpenTofu.
|
||||
|
||||
.. code-block:: bash
|
||||
`make tofu-apply`:
|
||||
Crea o actualiza la infraestructura definida en los archivos de OpenTofu.
|
||||
|
||||
koji moshimoshi
|
||||
`make tofu-destroy`:
|
||||
Destruye la infraestructura gestionada por OpenTofu.
|
||||
|
||||
.. note::
|
||||
Koji Hub es `cs10-koji-00.mx-os`.
|
||||
|
||||
Uso del Entorno Desplegado
|
||||
--------------------------
|
||||
|
||||
Una vez desplegado el entorno de Koji, puedes interactuar con él de las siguientes maneras:
|
||||
|
||||
* **Interfaz Web**: Visita https://cs10-koji-00.mx-os/koji en tu navegador para acceder a la interfaz web de Koji. Aquí puedes ver compilaciones, tareas, paquetes, etc.
|
||||
|
||||
* **Monitorear una Compilación**: Usa el comando `koji taskinfo <task_id>` para ver el estado de una tarea específica. También puedes usar la interfaz web.
|
||||
|
||||
* **Hacer una Compilación**: Para compilar un paquete, usa `koji build <tag> <fuente>`. Por ejemplo:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
koji build mxos0-build git+https://git.mx-os.mx/RPMs/osci-internal-test-package#5test
|
||||
|
||||
O desde un SRPM local:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
koji build mxos0-build /path/to/package.src.rpm
|
||||
|
||||
* **Listar Tareas**: `koji list-tasks` para ver tareas activas.
|
||||
|
||||
* **Listar Etiquetas**: `koji list-tags` para ver etiquetas disponibles.
|
||||
|
||||
* **Ver Información de un Paquete**: `koji info <package>`.
|
||||
|
||||
Para más comandos, consulta la documentación de Koji en https://docs.pagure.org/koji/.
|
||||
|
||||
|
||||
Firma de paquetes
|
||||
=================
|
||||
Este playbook configura Koji Hub para la firma automatizada de RPM a través de un servidor Sigul externo. Para fines de prueba,
|
||||
|
|
@ -163,12 +211,34 @@ Cómo funciona la firma automatizada
|
|||
#. El complemento envía una solicitud al servidor Sigul configurado (actualmente el servidor simulado en
|
||||
`http://localhost:8080/sigul`).
|
||||
#. El servidor Sigul "firma" el RPM (en el caso del servidor simulado, devuelve una respuesta de éxito y datos de firma simulados).
|
||||
#. El complemento importa la firma de nuevo en Koji.
|
||||
El complemento importa la firma de nuevo en Koji.
|
||||
|
||||
|
||||
Características Adicionales
|
||||
===========================
|
||||
Este playbook configura varias características adicionales para mejorar la mantenibilidad y seguridad de Koji:
|
||||
|
||||
Recolección de Basura:
|
||||
Un servicio de systemd (`koji-cleanup.timer`) se ejecuta semanalmente para limpiar compilaciones antiguas y directorios de
|
||||
trabajo, ayudando a conservar el espacio en disco.
|
||||
|
||||
Notificaciones:
|
||||
Koji está configurado para registrar todos los eventos en `/var/log/koji_callbacks.log`. Este es un sistema de notificación
|
||||
básico que puede ser extendido para integrarse con otros sistemas.
|
||||
|
||||
Permisos Granulares:
|
||||
Se crea un usuario `builder` con permisos limitados. Este usuario solo puede realizar compilaciones, lo que mejora la seguridad
|
||||
al limitar el acceso a funciones administrativas.
|
||||
|
||||
Autoincremento de NVR:
|
||||
La etiqueta de compilación `mxos0-build` está configurada para incrementar automáticamente el número de release de los paquetes,
|
||||
simplificando el proceso de compilación.
|
||||
|
||||
|
||||
Referencias
|
||||
===========
|
||||
* https://docs.pagure.org/fork/mikem/koji/server_howto/
|
||||
* https://docs.pagure.org/fork/mikem/koji/database_howto/
|
||||
* https://docs.pagure.org/fork/mikem/koji/server_bootstrap/
|
||||
* https://docs.pagure.org/fork/mikem/koji/using_the_koji_build_system/
|
||||
* https://docs.pagure.org/koji/server_howto/
|
||||
* https://docs.pagure.org/koji/database_howto/
|
||||
* https://docs.pagure.org/koji/external_repo_server_bootstrap/
|
||||
* https://docs.pagure.org/koji/server_bootstrap/
|
||||
* https://docs.pagure.org/koji/using_the_koji_build_system/
|
||||
|
|
|
|||
|
|
@ -5,7 +5,8 @@ remote_user = root
|
|||
|
||||
# optimization
|
||||
use_persistent_connections = True
|
||||
forks = 20
|
||||
forks = 50
|
||||
strategy = free
|
||||
|
||||
# facts
|
||||
gathering = smart
|
||||
|
|
|
|||
|
|
@ -6,10 +6,14 @@
|
|||
# --- Configuration ---
|
||||
# Adjust these variables if your environment differs from the defaults.
|
||||
PKI_DIR="certs"
|
||||
KOJIHUB_FQDN="cs10-koji-00.mx-os"
|
||||
KOJID_FQDN="cs10-koji-03.mx-os"
|
||||
POSTGRESQL_FQDN="cs10-koji-01.mx-os"
|
||||
CA_NAME="koji_ca"
|
||||
VARS_FILE="vars/default.yaml"
|
||||
|
||||
# Source variables from Ansible vars file
|
||||
KOJIHUB_FQDN=$(grep 'koji_hub_fqdn:' "$VARS_FILE" | sed 's/.*: //')
|
||||
KOJID_FQDN=$(grep 'kojid_fqdn:' "$VARS_FILE" | sed 's/.*: //')
|
||||
POSTGRESQL_FQDN=$(grep 'koji_db_host:' "$VARS_FILE" | sed 's/.*: //')
|
||||
CA_NAME=$(grep 'koji_ca_name:' "$VARS_FILE" | sed 's/.*: "\(.*\)"/\1/')
|
||||
|
||||
COMPONENTS=("kojihub" "kojiweb" "kojira" "kojid" "kojiadmin" "postgresql")
|
||||
# --- End Configuration ---
|
||||
|
||||
|
|
|
|||
|
|
@ -5,14 +5,5 @@
|
|||
vars_files:
|
||||
- vars/default.yaml
|
||||
- vars/credentials.yaml
|
||||
tasks:
|
||||
- name: Template Koji bootstrap script
|
||||
ansible.builtin.template:
|
||||
src: roles/koji-hub/templates/koji_bootstrap.sh.j2
|
||||
dest: /tmp/koji_bootstrap.sh
|
||||
mode: "0755"
|
||||
|
||||
- name: Run Koji bootstrap script
|
||||
ansible.builtin.shell:
|
||||
cmd: /tmp/koji_bootstrap.sh
|
||||
changed_when: true
|
||||
roles:
|
||||
- koji_bootstrap
|
||||
|
|
|
|||
24
deploy.yaml
24
deploy.yaml
|
|
@ -14,13 +14,21 @@
|
|||
hosts: all
|
||||
gather_facts: true
|
||||
|
||||
- name: "Setup: Common on all hosts"
|
||||
hosts: all
|
||||
vars_files:
|
||||
- vars/default.yaml
|
||||
roles:
|
||||
- role: common
|
||||
tags: common
|
||||
|
||||
- name: "Setup: NFS Server"
|
||||
hosts: kojifs
|
||||
vars_files:
|
||||
- vars/default.yaml
|
||||
roles:
|
||||
- role: nfs-server
|
||||
tags: nfs-server
|
||||
- role: nfs_server
|
||||
tags: nfs_server
|
||||
|
||||
- name: "Setup: Database Server"
|
||||
hosts: kojidb
|
||||
|
|
@ -36,8 +44,8 @@
|
|||
vars_files:
|
||||
- vars/default.yaml
|
||||
roles:
|
||||
- role: nfs-client
|
||||
tags: nfs-client
|
||||
- role: nfs_client
|
||||
tags: nfs_client
|
||||
|
||||
- name: "Deploy: Koji Hub, Kojira, and Mock Sigul Server"
|
||||
hosts: kojihub
|
||||
|
|
@ -45,13 +53,11 @@
|
|||
- vars/default.yaml
|
||||
- vars/credentials.yaml
|
||||
roles:
|
||||
- role: koji-hub
|
||||
tags: koji-hub
|
||||
|
||||
- role: koji_hub
|
||||
tags: koji_hub
|
||||
- role: kojira
|
||||
tags: kojira
|
||||
|
||||
- role: mock-sigul-server
|
||||
- role: mock_sigul_server
|
||||
tags: mock-sigul-server
|
||||
|
||||
- name: "Deploy: Koji Builders"
|
||||
|
|
|
|||
|
|
@ -10,198 +10,180 @@ Fase 1: Autoridad de Certificación y Generación de Certificados SSL
|
|||
===================================================================
|
||||
Esta fase establece la base criptográfica para que los componentes de Koji se comuniquen de forma segura.
|
||||
|
||||
#. Crea la Autoridad de Certificación (CA):
|
||||
Crea la Autoridad de Certificación (CA):
|
||||
Crea un directorio dedicado para tu infraestructura PKI de Koji (p. ej., `/etc/pki/koji`).
|
||||
Genera un certificado de CA Raíz autofirmado y su clave privada correspondiente. Usarás esta CA para firmar todos los demás certificados de componentes de Koji.
|
||||
Genera Certificados de Componentes y Usuarios:
|
||||
Para cada componente de Koji que requiere autenticación (koji_hub, koji-web, kojid, kojira y usuarios administradores), genera
|
||||
una solicitud de firma de certificado (CSR) única y una clave privada.
|
||||
|
||||
* Crea un directorio dedicado para tu infraestructura PKI de Koji (p. ej., `/etc/pki/koji`).
|
||||
* Genera un certificado de CA Raíz autofirmado y su clave privada correspondiente. Usarás esta CA para firmar todos los demás certificados de componentes de Koji.
|
||||
Certificados del Lado del Servidor (koji_hub, koji-web):
|
||||
El Common Name (CN) en estos certificados *debe* coincidir con el
|
||||
Nombre de Dominio Completo (FQDN) del servidor donde los desplegarás. Estos certificados deben incluir `serverAuth` en su
|
||||
`extendedKeyUsage`.
|
||||
Certificados del Lado del Cliente (kojid, kojira, usuarios administradores):
|
||||
El CN para estos certificados debe coincidir con
|
||||
el nombre de usuario de Koji que usarás para la autenticación. Estos certificados deben incluir `clientAuth` en su
|
||||
`extendedKeyUsage`.
|
||||
|
||||
#. Genera Certificados de Componentes y Usuarios:
|
||||
|
||||
* Para cada componente de Koji que requiere autenticación (koji-hub, koji-web, kojid, kojira y usuarios administradores), genera
|
||||
una solicitud de firma de certificado (CSR) única y una clave privada.
|
||||
* Certificados del Lado del Servidor (koji-hub, koji-web): El Common Name (CN) en estos certificados *debe* coincidir con el
|
||||
Nombre de Dominio Completo (FQDN) del servidor donde los desplegarás. Estos certificados deben incluir `serverAuth` en su
|
||||
`extendedKeyUsage`.
|
||||
* Certificados del Lado del Cliente (kojid, kojira, usuarios administradores): El CN para estos certificados debe coincidir con
|
||||
el nombre de usuario de Koji que usarás para la autenticación. Estos certificados deben incluir `clientAuth` en su
|
||||
`extendedKeyUsage`.
|
||||
* Firma cada CSR con tu CA Raíz recién creada para generar los certificados de componente/usuario.
|
||||
* Combina la clave privada de cada componente y su certificado firmado en un único archivo `.pem`. Los clientes de Koji usan a
|
||||
menudo este archivo `.pem`.
|
||||
* Para que los usuarios administradores accedan a través del navegador web, genera un paquete PKCS12 (`.p12`) a partir del
|
||||
certificado y la clave del usuario, que incluya el certificado de la CA.
|
||||
Firma cada CSR con tu CA Raíz recién creada para generar los certificados de componente/usuario.
|
||||
Combina la clave privada de cada componente y su certificado firmado en un único archivo `.pem`. Los clientes de Koji usan a
|
||||
menudo este archivo `.pem`.
|
||||
Para que los usuarios administradores accedan a través del navegador web, genera un paquete PKCS12 (`.p12`) a partir del
|
||||
certificado y la clave del usuario, que incluya el certificado de la CA.
|
||||
|
||||
Fase 2: Configuración de la Base de Datos PostgreSQL
|
||||
====================================================
|
||||
Koji usa una base de datos PostgreSQL para almacenar todos los metadatos relacionados con la compilación, la información del usuario y la configuración.
|
||||
|
||||
#. Instala e Inicializa PostgreSQL:
|
||||
Instala e Inicializa PostgreSQL:
|
||||
Instala el paquete `postgresql-server` en tu host de base de datos.
|
||||
Inicializa el clúster de la base de datos PostgreSQL.
|
||||
Crea la Base de Datos y el Usuario de Koji:
|
||||
Como el usuario `postgres`, crea una base de datos dedicada para Koji (p. ej., `koji`).
|
||||
Crea un usuario de PostgreSQL dedicado (p. ej., `koji`) que Koji usará para conectarse a la base de datos. Asígnale una
|
||||
contraseña segura a este usuario.
|
||||
Carga el Esquema de Koji:
|
||||
Carga el esquema de la base de datos de Koji desde el archivo SQL proporcionado (normalmente `/usr/share/koji/schema.sql` del
|
||||
paquete `koji`) en la base de datos de Koji que acabas de crear. Asegúrate de hacerlo como el usuario de la base de datos de
|
||||
Koji para mantener la propiedad correcta.
|
||||
Configura el Acceso a la Base de Datos (`postgresql.conf` y `pg_hba.conf`):
|
||||
Edita `postgresql.conf` para:
|
||||
|
||||
* Instala el paquete `postgresql-server` en tu host de base de datos.
|
||||
* Inicializa el clúster de la base de datos PostgreSQL.
|
||||
* Habilitar SSL (`ssl = on`).
|
||||
* Especificar los archivos de certificado y clave del servidor (`ssl_cert_file`, `ssl_key_file`).
|
||||
* Especificar el archivo del certificado de la CA (`ssl_ca_file`).
|
||||
* Configurar `listen_addresses` para permitir conexiones desde Koji Hub (p. ej., `'*'`).
|
||||
* Aumentar `max_connections` para satisfacer las necesidades de Koji (p. ej., `200`).
|
||||
|
||||
#. Crea la Base de Datos y el Usuario de Koji:
|
||||
|
||||
* Como el usuario `postgres`, crea una base de datos dedicada para Koji (p. ej., `koji`).
|
||||
* Crea un usuario de PostgreSQL dedicado (p. ej., `koji`) que Koji usará para conectarse a la base de datos. Asígnale una
|
||||
contraseña segura a este usuario.
|
||||
|
||||
#. Carga el Esquema de Koji:
|
||||
|
||||
* Carga el esquema de la base de datos de Koji desde el archivo SQL proporcionado (normalmente `/usr/share/koji/schema.sql` del
|
||||
paquete `koji`) en la base de datos de Koji que acabas de crear. Asegúrate de hacerlo como el usuario de la base de datos de
|
||||
Koji para mantener la propiedad correcta.
|
||||
|
||||
#. Configura el Acceso a la Base de Datos (`postgresql.conf` y `pg_hba.conf`):
|
||||
|
||||
* Edita `postgresql.conf` para:
|
||||
* Habilitar SSL (`ssl = on`).
|
||||
* Especificar los archivos de certificado y clave del servidor (`ssl_cert_file`, `ssl_key_file`).
|
||||
* Especificar el archivo del certificado de la CA (`ssl_ca_file`).
|
||||
* Configurar `listen_addresses` para permitir conexiones desde Koji Hub (p. ej., `'*'`).
|
||||
* Aumentar `max_connections` para satisfacer las necesidades de Koji (p. ej., `200`).
|
||||
* Edita `pg_hba.conf` para permitir conexiones desde Koji Hub a la base de datos de Koji con SSL y un método de autenticación seguro (p. ej., `scram-sha-256`). Además, configura el acceso local para el usuario `postgres`.
|
||||
Edita `pg_hba.conf` para permitir conexiones desde Koji Hub a la base de datos de Koji con SSL y un método de autenticación seguro (p. ej., `scram-sha-256`). Además, configura el acceso local para el usuario `postgres`.
|
||||
|
||||
Fase 3: Configuración de Koji Hub
|
||||
=================================
|
||||
El Koji Hub es el plano de control central para el sistema de compilación Koji.
|
||||
|
||||
#. Instala Koji Hub y Dependencias:
|
||||
|
||||
* Instala `koji-hub`, `koji-web`, `httpd`, `mod_ssl`, `mod_wsgi`, `python3-cryptography`, `nmap-ncat`, `postgresql` (bibliotecas
|
||||
de cliente) y `policycoreutils-python-utils`.
|
||||
|
||||
#. Configura el Hub (`/etc/koji-hub/hub.conf` y el directorio `.d`):
|
||||
|
||||
* Configura los parámetros de conexión de la base de datos (`DBName`, `DBUser`, `DBHost`, `DBPass`).
|
||||
* Establece `KojiDir` en la ruta donde Koji almacenará los datos de compilación (p. ej., `/mnt/koji`).
|
||||
* Configura los ajustes de autenticación, incluyendo `DNUsernameComponent` y `ProxyDNs` para la autenticación de certificados de
|
||||
cliente SSL.
|
||||
* Coloca las configuraciones sensibles (como `DBPass`) in un archivo separado dentro de `/etc/koji-hub/hub.conf.d/` con permisos
|
||||
restringidos.
|
||||
|
||||
#. Configura Apache para el Hub:
|
||||
|
||||
* Asegúrate de que `mod_ssl` y `mod_wsgi` estén habilitados.
|
||||
* Edita `/etc/httpd/conf.d/ssl.conf` para que apunte al certificado del servidor, la clave y el certificado de la CA de Koji del
|
||||
Koji Hub.
|
||||
* Configura el bloque `<Location /kojihub/ssllogin>` en `/etc/httpd/conf.d/kojihub.conf` para que requiera certificados de
|
||||
cliente SSL (`SSLVerifyClient require`).
|
||||
|
||||
#. Crea la Estructura del Sistema de Archivos de Koji:
|
||||
|
||||
* Crea los subdirectorios necesarios en `KojiDir` (p. ej., `packages`, `repos`, `work`, `scratch`, `repos-dist`, `certs`,
|
||||
`clients`).
|
||||
* Asegúrate de que el usuario `apache` tenga la propiedad y los permisos de escritura adecuados en estos directorios.
|
||||
|
||||
#. Despliega Plugins de Koji Hub:
|
||||
|
||||
* Copia cualquier complemento personalizado de Koji Hub (p. ej., `sigul_sign.py`) a `/usr/lib/koji-hub/plugins`.
|
||||
Instala Koji Hub y Dependencias:
|
||||
Instala `koji_hub`, `koji-web`, `httpd`, `mod_ssl`, `mod_wsgi`, `python3-cryptography`, `nmap-ncat`, `postgresql` (bibliotecas
|
||||
de cliente) y `policycoreutils-python-utils`.
|
||||
Configura el Hub (`/etc/koji_hub/hub.conf` y el directorio `.d`):
|
||||
Configura los parámetros de conexión de la base de datos (`DBName`, `DBUser`, `DBHost`, `DBPass`).
|
||||
Establece `KojiDir` en la ruta donde Koji almacenará los datos de compilación (p. ej., `/mnt/koji`).
|
||||
Configura los ajustes de autenticación, incluyendo `DNUsernameComponent` y `ProxyDNs` para la autenticación de certificados de
|
||||
cliente SSL.
|
||||
Coloca las configuraciones sensibles (como `DBPass`) in un archivo separado dentro de `/etc/koji_hub/hub.conf.d/` con permisos
|
||||
restringidos.
|
||||
Configura Apache para el Hub:
|
||||
Asegúrate de que `mod_ssl` y `mod_wsgi` estén habilitados.
|
||||
Edita `/etc/httpd/conf.d/ssl.conf` para que apunte al certificado del servidor, la clave y el certificado de la CA de Koji del
|
||||
Koji Hub.
|
||||
Configura el bloque `<Location /kojihub/ssllogin>` en `/etc/httpd/conf.d/kojihub.conf` para que requiera certificados de
|
||||
cliente SSL (`SSLVerifyClient require`).
|
||||
Crea la Estructura del Sistema de Archivos de Koji:
|
||||
Crea los subdirectorios necesarios en `KojiDir` (p. ej., `packages`, `repos`, `work`, `scratch`, `repos-dist`, `certs`,
|
||||
`clients`).
|
||||
Asegúrate de que el usuario `apache` tenga la propiedad y los permisos de escritura adecuados en estos directorios.
|
||||
Despliega Plugins de Koji Hub:
|
||||
Copia cualquier complemento personalizado de Koji Hub (p. ej., `sigul_sign.py`) a `/usr/lib/koji_hub/plugins`.
|
||||
|
||||
Fase 4: Configuración de Koji Web
|
||||
=================================
|
||||
La interfaz Koji Web te proporciona una forma fácil de usar para interactuar con Koji.
|
||||
|
||||
#. Configura Koji Web (`/etc/kojiweb/web.conf` y el directorio `.d`):
|
||||
|
||||
* Establece `KojiHubURL` y `KojiFilesURL` en las URL apropiadas.
|
||||
|
||||
* Para la autenticación SSL, especifica `WebCert` (el archivo PEM del componente koji-web) y `KojiHubCA` (el certificado de la CA de Koji).
|
||||
|
||||
* Establece el valor de `Secret` en una contraseña segura y única.
|
||||
|
||||
#. Configura Apache para Koji Web:
|
||||
|
||||
* Configura el bloque `<Location /koji/login>` en `/etc/httpd/conf.d/kojiweb.conf` para que requiera certificados de cliente SSL si los usuarios se autenticarán a través de navegadores web.
|
||||
Configura Koji Web (`/etc/kojiweb/web.conf` y el directorio `.d`):
|
||||
Establece `KojiHubURL` y `KojiFilesURL` en las URL apropiadas.
|
||||
Para la autenticación SSL, especifica `WebCert` (el archivo PEM del componente koji-web) y `KojiHubCA` (el certificado de la CA de Koji).
|
||||
Establece el valor de `Secret` en una contraseña segura y única.
|
||||
Configura Apache para Koji Web:
|
||||
Configura el bloque `<Location /koji/login>` en `/etc/httpd/conf.d/kojiweb.conf` para que requiera certificados de cliente SSL si los usuarios se autenticarán a través de navegadores web.
|
||||
|
||||
Fase 5: Configuración de Kojid (Constructor) y Kojira (Administrador de Repos)
|
||||
==============================================================================
|
||||
|
||||
#. Configura Kojid (en cada host constructor):
|
||||
|
||||
* Instala `koji-builder`, `rpm-build`, `rpmdevtools` y `mock`.
|
||||
* Edita `/etc/kojid/kojid.conf` para que apunte a la URL del servidor XML-RPC de Koji Hub.
|
||||
* Especifica el certificado de cliente del componente `kojid` y el certificado de la CA de Koji.
|
||||
* Establece el parámetro `user` en el FQDN del host constructor.
|
||||
* Establece `topdir` en el directorio de Koji montado (p. ej., `/mnt/koji`).
|
||||
* Establece `workdir` en un directorio local (p. ej., `/var/lib/kojid-work`).
|
||||
* Asegúrate de que el servicio `kojid` se ejecute como `root` (predeterminado) y tenga los permisos adecuados en `workdir`.
|
||||
* Agrega los usuarios que necesitan compilar paquetes (p. ej., `kojiadmin`) al grupo `mock`.
|
||||
|
||||
#. Configura Kojira (en el hub o en un host dedicado):
|
||||
|
||||
* Instala `koji-utils`.
|
||||
* Edita `/etc/kojira/kojira.conf` para que apunte a la URL del servidor XML-RPC de Koji Hub.
|
||||
* Especifica el certificado de cliente del componente `kojira` y el certificado de la CA de Koji.
|
||||
Configura Kojid (en cada host constructor):
|
||||
Instala `koji-builder`, `rpm-build`, `rpmdevtools` y `mock`.
|
||||
Edita `/etc/kojid/kojid.conf` para que apunte a la URL del servidor XML-RPC de Koji Hub.
|
||||
Especifica el certificado de cliente del componente `kojid` y el certificado de la CA de Koji.
|
||||
Establece el parámetro `user` en el FQDN del host constructor.
|
||||
Establece `topdir` en el directorio de Koji montado (p. ej., `/mnt/koji`).
|
||||
Establece `workdir` en un directorio local (p. ej., `/var/lib/kojid-work`).
|
||||
Asegúrate de que el servicio `kojid` se ejecute como `root` (predeterminado) y tenga los permisos adecuados en `workdir`.
|
||||
Agrega los usuarios que necesitan compilar paquetes (p. ej., `kojiadmin`) al grupo `mock`.
|
||||
Configura Kojira (en el hub o en un host dedicado):
|
||||
Instala `koji-utils`.
|
||||
Edita `/etc/kojira/kojira.conf` para que apunte a la URL del servidor XML-RPC de Koji Hub.
|
||||
Especifica el certificado de cliente del componente `kojira` y el certificado de la CA de Koji.
|
||||
|
||||
Estos componentes manejan los procesos de compilación reales y la gestión de repositorios.
|
||||
|
||||
#. Configura Kojira (en el hub o en un host dedicado):
|
||||
|
||||
* Instala `koji-utils`.
|
||||
* Edita `/etc/kojira/kojira.conf` para que apunte a la URL del servidor XML-RPC de Koji Hub.
|
||||
* Especifica el certificado de cliente del componente `kojira` y el certificado de la CA de Koji.
|
||||
Configura Kojira (en el hub o en un host dedicado):
|
||||
Instala `koji-utils`.
|
||||
Edita `/etc/kojira/kojira.conf` para que apunte a la URL del servidor XML-RPC de Koji Hub.
|
||||
Especifica el certificado de cliente del componente `kojira` y el certificado de la CA de Koji.
|
||||
|
||||
Fase 6: Configuración de SELinux y Firewall
|
||||
===========================================
|
||||
Un contexto de seguridad y un acceso a la red adecuados son cruciales para que Koji funcione.
|
||||
|
||||
#. Configuración de SELinux:
|
||||
Configuración de SELinux:
|
||||
Establece los siguientes booleanos de SELinux para permitir el acceso a la red y a los archivos necesarios para `httpd`:
|
||||
|
||||
* Establece los siguientes booleanos de SELinux para permitir el acceso a la red y a los archivos necesarios para `httpd`:
|
||||
* `setsebool -P httpd_can_network_connect_db=1` (permite que httpd se conecte a PostgreSQL)
|
||||
* `setsebool -P httpd_can_network_connect=1` (permite que httpd realice conexiones de red generales)
|
||||
* `setsebool -P allow_httpd_anon_write=1` (permite que httpd escriba en áreas de contenido público)
|
||||
* `setsebool -P httpd_use_nfs=1` (si `/mnt/koji` está en un recurso compartido NFS)
|
||||
|
||||
* `setsebool -P httpd_can_network_connect_db=1` (permite que httpd se conecte a PostgreSQL)
|
||||
* `setsebool -P httpd_can_network_connect=1` (permite que httpd realice conexiones de red generales)
|
||||
* `setsebool -P allow_httpd_anon_write=1` (permite que httpd escriba en áreas de contenido público)
|
||||
* `setsebool -P httpd_use_nfs=1` (si `/mnt/koji` está en un recurso compartido NFS)
|
||||
Aplica los contextos de archivo de SELinux correctos:
|
||||
|
||||
* Aplica los contextos de archivo de SELinux correctos:
|
||||
* `semanage fcontext -a -t public_content_rw_t "/mnt/koji(/.*)?"` (para contexto persistente)
|
||||
* `restorecon -r -v /mnt/koji` (para aplicar el contexto inmediatamente)
|
||||
* Alternativamente, para recursos compartidos NFS donde `semanage fcontext` podría no aplicarse, usa `chcon -R -t
|
||||
public_content_rw_t /mnt/koji/*` (aunque esto no es persistente entre reinicios).
|
||||
Configuración del Firewall:
|
||||
Abre los puertos de firewall necesarios en los hosts respectivos:
|
||||
|
||||
* `semanage fcontext -a -t public_content_rw_t "/mnt/koji(/.*)?"` (para contexto persistente)
|
||||
* `restorecon -r -v /mnt/koji` (para aplicar el contexto inmediatamente)
|
||||
* Alternativamente, para recursos compartidos NFS donde `semanage fcontext` podría no aplicarse, usa `chcon -R -t
|
||||
public_content_rw_t /mnt/koji/*` (aunque esto no es persistente entre reinicios).
|
||||
|
||||
#. Configuración del Firewall:
|
||||
|
||||
* Abre los puertos de firewall necesarios en los hosts respectivos:
|
||||
* Koji Hub: HTTP (80/tcp), HTTPS (443/tcp), Servidor Mock Sigul (8080/tcp, si se despliega en el hub).
|
||||
* Servidor PostgreSQL: PostgreSQL (5432/tcp) desde el Koji Hub.
|
||||
* Servidor NFS: NFS (servicios nfs, rpc-bind, mountd).
|
||||
* Koji Hub: HTTP (80/tcp), HTTPS (443/tcp), Servidor Mock Sigul (8080/tcp, si se despliega en el hub).
|
||||
* Servidor PostgreSQL: PostgreSQL (5432/tcp) desde el Koji Hub.
|
||||
* Servidor NFS: NFS (servicios nfs, rpc-bind, mountd).
|
||||
|
||||
Fase 7: Arranque del Entorno de Compilación de Koji
|
||||
===================================================
|
||||
Esta fase final prepara a Koji para que realice compilaciones reales.
|
||||
|
||||
#. Otorga Privilegios de Administrador al Usuario Inicial:
|
||||
|
||||
* Inserta manualmente un registro en la tabla `user_perms` en la base de datos de Koji para otorgarle al usuario administrador
|
||||
inicial (p. ej., `kojiadmin`) el permiso de `admin`. Este es un paso único para el administrador inicial.
|
||||
|
||||
#. Crea Etiquetas y un Destino de Compilación:
|
||||
|
||||
* Crea una etiqueta de destino (p. ej., `cs10`) donde terminarán los RPM finales: `koji add-tag cs10`.
|
||||
* Crea una etiqueta de compilación (p. ej., `cs10-build`) que defina el contenido del buildroot y agrégale arquitecturas: `koji
|
||||
add-tag --parent
|
||||
cs10 --arches "x86_64" cs10-build`.
|
||||
* Crea un destino de compilación que vincule la etiqueta de compilación y la etiqueta de destino: `koji add-target cs10-build
|
||||
cs10-build cs10`.
|
||||
|
||||
#. Puebla el Grupo de Compilación:
|
||||
|
||||
* Agrega los paquetes esenciales que se requieren para compilar (p. ej., `rpm-build`, `gcc`, `make`) al grupo `build` de tu
|
||||
etiqueta de compilación: `koji add-group-pkg cs10-build build <package_name>`.
|
||||
|
||||
* Alternativamente, importa definiciones de grupo desde una instancia de Koji existente (p. ej., el `comps.xml` de Fedora).
|
||||
|
||||
#. Regenera el Repositorio:
|
||||
|
||||
* Después de agregar paquetes al grupo de compilación, regenera el repositorio para la etiqueta de compilación: `koji regen-repo
|
||||
cs10-build`. Esto pone los paquetes a disposición de `kojid` para crear los buildroots.
|
||||
|
||||
#. Importa Paquetes Iniciales:
|
||||
|
||||
* Importa cualquier SRPM base y RPMs binarios a Koji y etiquétalos en tu etiqueta de destino. Esto proporciona una base de
|
||||
paquetes para la resolución de dependencias durante las compilaciones.
|
||||
Otorga Privilegios de Administrador al Usuario Inicial:
|
||||
Inserta manualmente un registro en la tabla `user_perms` en la base de datos de Koji para otorgarle al usuario administrador
|
||||
inicial (p. ej., `kojiadmin`) el permiso de `admin`. Este es un paso único para el administrador inicial.
|
||||
Crea Etiquetas y un Destino de Compilación:
|
||||
Crea una etiqueta de destino (p. ej., `cs10`) donde terminarán los RPM finales: `koji add-tag cs10`.
|
||||
Crea una etiqueta de compilación (p. ej., `cs10-build`) que defina el contenido del buildroot y agrégale arquitecturas: `koji
|
||||
add-tag --parent
|
||||
cs10 --arches "x86_64" cs10-build`.
|
||||
Crea un destino de compilación que vincule la etiqueta de compilación y la etiqueta de destino: `koji add-target cs10-build
|
||||
cs10-build cs10`.
|
||||
Puebla el Grupo de Compilación:
|
||||
Agrega los paquetes esenciales que se requieren para compilar (p. ej., `rpm-build`, `gcc`, `make`) al grupo `build` de tu
|
||||
etiqueta de compilación: `koji add-group-pkg cs10-build build <package_name>`.
|
||||
Alternativamente, importa definiciones de grupo desde una instancia de Koji existente (p. ej., el `comps.xml` de Fedora).
|
||||
Regenera el Repositorio:
|
||||
Después de agregar paquetes al grupo de compilación, regenera el repositorio para la etiqueta de compilación: `koji regen-repo
|
||||
cs10-build`. Esto pone los paquetes a disposición de `kojid` para crear los buildroots.
|
||||
Importa Paquetes Iniciales:
|
||||
Importa cualquier SRPM base y RPMs binarios a Koji y etiquétalos en tu etiqueta de destino. Esto proporciona una base de
|
||||
paquetes para la resolución de dependencias durante las compilaciones.
|
||||
|
||||
Este procedimiento detallado debería servirte como una guía completa para que configures un entorno Koji.
|
||||
|
||||
Fase 8: Características Adicionales
|
||||
===================================
|
||||
|
||||
Recolección de Basura:
|
||||
Un servicio de systemd (`koji-cleanup.timer`) se ejecuta semanalmente para limpiar compilaciones antiguas
|
||||
y directorios de trabajo, ayudando a conservar el espacio en disco.
|
||||
Notificaciones:
|
||||
Koji está configurado para registrar todos los eventos en `/var/log/koji_callbacks.log`. Este es un sistema
|
||||
de notificación básico que puede ser extendido para integrarse con otros sistemas.
|
||||
Permisos Granulares:
|
||||
Se crea un usuario `builder` con permisos limitados. Este usuario solo puede realizar compilaciones,
|
||||
lo que mejora la seguridad al limitar el acceso a funciones administrativas.
|
||||
Autoincremento de NVR:
|
||||
La etiqueta de compilación `mxos0-build` está configurada para incrementar automáticamente el número
|
||||
de release de los paquetes, simplificando el proceso de compilación.
|
||||
|
|
@ -1 +0,0 @@
|
|||
Subproject commit 0db0d21d8ae52df10884af7b3ede5de052a92739000000000000000000000000
|
||||
|
|
@ -8,4 +8,12 @@ apply:
|
|||
|
||||
.PHONY: destroy
|
||||
destroy:
|
||||
virsh -c qemu:///system destroy cs10-koji-00.mx-os
|
||||
virsh -c qemu:///system destroy cs10-koji-01.mx-os
|
||||
virsh -c qemu:///system destroy cs10-koji-02.mx-os
|
||||
virsh -c qemu:///system destroy cs10-koji-03.mx-os
|
||||
virsh -c qemu:///system undefine --remove-all-storage --nvram --tpm cs10-koji-00.mx-os
|
||||
virsh -c qemu:///system undefine --remove-all-storage --nvram --tpm cs10-koji-01.mx-os
|
||||
virsh -c qemu:///system undefine --remove-all-storage --nvram --tpm cs10-koji-02.mx-os
|
||||
virsh -c qemu:///system undefine --remove-all-storage --nvram --tpm cs10-koji-03.mx-os
|
||||
tofu destroy -auto-approve
|
||||
|
|
|
|||
|
|
@ -1,30 +1,3 @@
|
|||
resource "libvirt_volume" "cs10-base" {
|
||||
count = var.guest_count
|
||||
name = "${var.guest_base_name}-${format("%02d", count.index)}.${var.domain}-system.qcow2"
|
||||
pool = var.pool_name
|
||||
format = "qcow2"
|
||||
create = {
|
||||
content = {
|
||||
url = "file://${var.base_image_path}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "libvirt_cloudinit_disk" "cs10-cloudinit" {
|
||||
count = var.guest_count
|
||||
name = "${var.guest_base_name}-${format("%02d", count.index)}-cloudinit.iso"
|
||||
|
||||
user_data = templatefile("templates/cloudinit.cfg.tftpl", {
|
||||
root_password = var.root_password
|
||||
hostname = "${var.guest_base_name}-${format("%02d", count.index)}.${var.domain}"
|
||||
})
|
||||
|
||||
meta_data = yamlencode({
|
||||
instance-id = "${var.guest_base_name}-${format("%02d", count.index)}.${var.domain}"
|
||||
local-hostname = "${var.guest_base_name}-${format("%02d", count.index)}.${var.domain}"
|
||||
})
|
||||
}
|
||||
|
||||
resource "libvirt_domain" "cs10-base" {
|
||||
count = var.guest_count
|
||||
name = "${var.guest_base_name}-${format("%02d", count.index)}.${var.domain}"
|
||||
|
|
@ -35,22 +8,22 @@ resource "libvirt_domain" "cs10-base" {
|
|||
autostart = true
|
||||
type = "kvm"
|
||||
|
||||
os = {
|
||||
type = "hvm"
|
||||
arch = "x86_64"
|
||||
machine = "q35"
|
||||
firmware = "efi"
|
||||
loader_path = "/usr/share/edk2/ovmf/OVMF_CODE_4M.secboot.qcow2"
|
||||
loader_readonly = true
|
||||
loader_secure = true
|
||||
loader_type = "pflash"
|
||||
nvram = {
|
||||
path = "/var/lib/libvirt/qemu/nvram/${var.guest_base_name}-${format("%02d", count.index)}.${var.domain}_VARS.qcow2"
|
||||
template = "/usr/share/edk2/ovmf/OVMF_VARS_4M.secboot.qcow2"
|
||||
format = "qcow2"
|
||||
}
|
||||
boot_devices = ["hd"]
|
||||
}
|
||||
os = {
|
||||
type = "hvm"
|
||||
arch = "x86_64"
|
||||
machine = "q35"
|
||||
firmware = "efi"
|
||||
loader_path = "/usr/share/edk2/ovmf/OVMF_CODE_4M.secboot.qcow2"
|
||||
loader_readonly = true
|
||||
loader_secure = true
|
||||
loader_type = "pflash"
|
||||
nvram = {
|
||||
path = "/var/lib/libvirt/qemu/nvram/${var.guest_base_name}-${format("%02d", count.index)}.${var.domain}_VARS.qcow2"
|
||||
template = "/usr/share/edk2/ovmf/OVMF_VARS_4M.secboot.qcow2"
|
||||
format = "qcow2"
|
||||
}
|
||||
boot_devices = ["hd"]
|
||||
}
|
||||
|
||||
cpu = {
|
||||
mode = "host-passthrough"
|
||||
|
|
@ -64,19 +37,34 @@ resource "libvirt_domain" "cs10-base" {
|
|||
devices = {
|
||||
disks = [
|
||||
{
|
||||
type = "volume"
|
||||
driver = "qcow2"
|
||||
|
||||
source = {
|
||||
file = libvirt_volume.cs10-base[count.index].path
|
||||
pool = var.pool_name
|
||||
volume = libvirt_volume.cs10-base[count.index].name
|
||||
}
|
||||
|
||||
target = {
|
||||
dev = "vda"
|
||||
bus = "virtio"
|
||||
}
|
||||
target = { dev = "vda" }
|
||||
bus = "virtio"
|
||||
},
|
||||
{
|
||||
source = {
|
||||
file = libvirt_cloudinit_disk.cs10-cloudinit[count.index].path
|
||||
}
|
||||
target = { dev = "sda" }
|
||||
bus = "sata"
|
||||
type = "volume"
|
||||
device = "cdrom"
|
||||
readonly = true
|
||||
driver = "raw"
|
||||
|
||||
source = {
|
||||
pool = var.pool_name
|
||||
volume = libvirt_cloudinit_disk.cs10-cloudinit[count.index].name
|
||||
}
|
||||
|
||||
target = {
|
||||
dev = "sda"
|
||||
bus = "sata"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
|
|
@ -105,7 +93,7 @@ resource "libvirt_domain" "cs10-base" {
|
|||
|
||||
rngs = [
|
||||
{
|
||||
model = "virtio"
|
||||
model = "virtio"
|
||||
device = "/dev/urandom"
|
||||
}
|
||||
]
|
||||
|
|
@ -120,7 +108,7 @@ resource "libvirt_domain" "cs10-base" {
|
|||
|
||||
tpms = [
|
||||
{
|
||||
model = "tpm-crb"
|
||||
model = "tpm-crb"
|
||||
backend_type = "emulator"
|
||||
backend_version = "2.0"
|
||||
}
|
||||
|
|
@ -137,4 +125,73 @@ resource "libvirt_domain" "cs10-base" {
|
|||
type = "virtio"
|
||||
}
|
||||
}
|
||||
|
||||
# configuración por scripts
|
||||
provisioner "file" {
|
||||
source = "scripts"
|
||||
destination = "/tmp"
|
||||
|
||||
connection {
|
||||
type = "ssh"
|
||||
host = self.name
|
||||
timeout = "1m"
|
||||
}
|
||||
}
|
||||
|
||||
provisioner "remote-exec" {
|
||||
inline = [
|
||||
"bash /tmp/scripts/set-hostname.bash ${self.name}",
|
||||
"bash /tmp/scripts/dnf-config.bash",
|
||||
"bash /tmp/scripts/install-tools.bash",
|
||||
"bash /tmp/scripts/upgrade.bash"
|
||||
]
|
||||
|
||||
connection {
|
||||
type = "ssh"
|
||||
user = "root"
|
||||
host = self.name
|
||||
timeout = "1m"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "libvirt_volume" "cs10-base" {
|
||||
count = var.guest_count
|
||||
name = "${var.guest_base_name}-${format("%02d", count.index)}.${var.domain}-system.qcow2"
|
||||
pool = var.pool_name
|
||||
format = "qcow2"
|
||||
|
||||
create = {
|
||||
content = {
|
||||
url = "file://${var.base_image_path}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "libvirt_cloudinit_disk" "cs10-cloudinit" {
|
||||
count = var.guest_count
|
||||
name = "${var.guest_base_name}-${format("%02d", count.index)}.${var.domain}-cloudinit.iso"
|
||||
|
||||
user_data = templatefile("templates/cloudinit.cfg.tftpl", {
|
||||
root_password = var.root_password
|
||||
hostname = "${var.guest_base_name}-${format("%02d", count.index)}.${var.domain}"
|
||||
})
|
||||
|
||||
meta_data = yamlencode({
|
||||
instance-id = "${var.guest_base_name}-${format("%02d", count.index)}.${var.domain}"
|
||||
local-hostname = "${var.guest_base_name}-${format("%02d", count.index)}.${var.domain}"
|
||||
})
|
||||
}
|
||||
|
||||
resource "libvirt_volume" "cloudinit" {
|
||||
count = var.guest_count
|
||||
name = "${var.guest_base_name}-${format("%02d", count.index)}.${var.domain}-cloudinit.iso"
|
||||
pool = var.pool_name
|
||||
format = "iso"
|
||||
|
||||
create = {
|
||||
content = {
|
||||
url = libvirt_cloudinit_disk.cs10-cloudinit[count.index].path
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,190 +0,0 @@
|
|||
<domain type='kvm'>
|
||||
<name>cs10</name>
|
||||
<uuid>dd0ce3f5-a2c0-4bc9-8b1f-e92edeaf196d</uuid>
|
||||
<metadata>
|
||||
<libosinfo:libosinfo xmlns:libosinfo="http://libosinfo.org/xmlns/libvirt/domain/1.0">
|
||||
<libosinfo:os id="http://centos.org/centos-stream/10"/>
|
||||
</libosinfo:libosinfo>
|
||||
</metadata>
|
||||
<memory unit='KiB'>8388608</memory>
|
||||
<currentMemory unit='KiB'>8388608</currentMemory>
|
||||
<vcpu placement='static'>4</vcpu>
|
||||
<os firmware='efi'>
|
||||
<type arch='x86_64' machine='pc-q35-10.1'>hvm</type>
|
||||
<firmware>
|
||||
<feature enabled='yes' name='enrolled-keys'/>
|
||||
<feature enabled='yes' name='secure-boot'/>
|
||||
</firmware>
|
||||
<loader readonly='yes' secure='yes' type='pflash' format='qcow2'>/usr/share/edk2/ovmf/OVMF_CODE_4M.secboot.qcow2</loader>
|
||||
<nvram template='/usr/share/edk2/ovmf/OVMF_VARS_4M.secboot.qcow2' templateFormat='qcow2' format='qcow2'>/var/lib/libvirt/qemu/nvram/cs10_VARS.qcow2</nvram>
|
||||
<boot dev='hd'/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
<vmport state='off'/>
|
||||
<smm state='on'/>
|
||||
</features>
|
||||
<cpu mode='host-passthrough' check='none' migratable='on'/>
|
||||
<clock offset='utc'>
|
||||
<timer name='rtc' tickpolicy='catchup'/>
|
||||
<timer name='pit' tickpolicy='delay'/>
|
||||
<timer name='hpet' present='no'/>
|
||||
</clock>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
<on_reboot>restart</on_reboot>
|
||||
<on_crash>destroy</on_crash>
|
||||
<pm>
|
||||
<suspend-to-mem enabled='no'/>
|
||||
<suspend-to-disk enabled='no'/>
|
||||
</pm>
|
||||
<devices>
|
||||
<emulator>/usr/bin/qemu-system-x86_64</emulator>
|
||||
<disk type='file' device='disk'>
|
||||
<driver name='qemu' type='qcow2'/>
|
||||
<source file='/home/renich/VirtualMachines/cs10.qcow2'/>
|
||||
<target dev='vda' bus='virtio'/>
|
||||
<address type='pci' domain='0x0000' bus='0x04' slot='0x00' function='0x0'/>
|
||||
</disk>
|
||||
<controller type='usb' index='0' model='qemu-xhci' ports='15'>
|
||||
<address type='pci' domain='0x0000' bus='0x02' slot='0x00' function='0x0'/>
|
||||
</controller>
|
||||
<controller type='pci' index='0' model='pcie-root'/>
|
||||
<controller type='pci' index='1' model='pcie-root-port'>
|
||||
<model name='pcie-root-port'/>
|
||||
<target chassis='1' port='0x10'/>
|
||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0' multifunction='on'/>
|
||||
</controller>
|
||||
<controller type='pci' index='2' model='pcie-root-port'>
|
||||
<model name='pcie-root-port'/>
|
||||
<target chassis='2' port='0x11'/>
|
||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x1'/>
|
||||
</controller>
|
||||
<controller type='pci' index='3' model='pcie-root-port'>
|
||||
<model name='pcie-root-port'/>
|
||||
<target chassis='3' port='0x12'/>
|
||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x2'/>
|
||||
</controller>
|
||||
<controller type='pci' index='4' model='pcie-root-port'>
|
||||
<model name='pcie-root-port'/>
|
||||
<target chassis='4' port='0x13'/>
|
||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x3'/>
|
||||
</controller>
|
||||
<controller type='pci' index='5' model='pcie-root-port'>
|
||||
<model name='pcie-root-port'/>
|
||||
<target chassis='5' port='0x14'/>
|
||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x4'/>
|
||||
</controller>
|
||||
<controller type='pci' index='6' model='pcie-root-port'>
|
||||
<model name='pcie-root-port'/>
|
||||
<target chassis='6' port='0x15'/>
|
||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x5'/>
|
||||
</controller>
|
||||
<controller type='pci' index='7' model='pcie-root-port'>
|
||||
<model name='pcie-root-port'/>
|
||||
<target chassis='7' port='0x16'/>
|
||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x6'/>
|
||||
</controller>
|
||||
<controller type='pci' index='8' model='pcie-root-port'>
|
||||
<model name='pcie-root-port'/>
|
||||
<target chassis='8' port='0x17'/>
|
||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x7'/>
|
||||
</controller>
|
||||
<controller type='pci' index='9' model='pcie-root-port'>
|
||||
<model name='pcie-root-port'/>
|
||||
<target chassis='9' port='0x18'/>
|
||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0' multifunction='on'/>
|
||||
</controller>
|
||||
<controller type='pci' index='10' model='pcie-root-port'>
|
||||
<model name='pcie-root-port'/>
|
||||
<target chassis='10' port='0x19'/>
|
||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x1'/>
|
||||
</controller>
|
||||
<controller type='pci' index='11' model='pcie-root-port'>
|
||||
<model name='pcie-root-port'/>
|
||||
<target chassis='11' port='0x1a'/>
|
||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x2'/>
|
||||
</controller>
|
||||
<controller type='pci' index='12' model='pcie-root-port'>
|
||||
<model name='pcie-root-port'/>
|
||||
<target chassis='12' port='0x1b'/>
|
||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x3'/>
|
||||
</controller>
|
||||
<controller type='pci' index='13' model='pcie-root-port'>
|
||||
<model name='pcie-root-port'/>
|
||||
<target chassis='13' port='0x1c'/>
|
||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x4'/>
|
||||
</controller>
|
||||
<controller type='pci' index='14' model='pcie-root-port'>
|
||||
<model name='pcie-root-port'/>
|
||||
<target chassis='14' port='0x1d'/>
|
||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x5'/>
|
||||
</controller>
|
||||
<controller type='sata' index='0'>
|
||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/>
|
||||
</controller>
|
||||
<controller type='virtio-serial' index='0'>
|
||||
<address type='pci' domain='0x0000' bus='0x03' slot='0x00' function='0x0'/>
|
||||
</controller>
|
||||
<controller type='scsi' index='0' model='virtio-scsi'>
|
||||
<address type='pci' domain='0x0000' bus='0x07' slot='0x00' function='0x0'/>
|
||||
</controller>
|
||||
<interface type='network'>
|
||||
<mac address='52:54:00:62:40:d9'/>
|
||||
<source network='default'/>
|
||||
<model type='virtio'/>
|
||||
<address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
|
||||
</interface>
|
||||
<serial type='pty'>
|
||||
<target type='isa-serial' port='0'>
|
||||
<model name='isa-serial'/>
|
||||
</target>
|
||||
</serial>
|
||||
<console type='pty'>
|
||||
<target type='serial' port='0'/>
|
||||
</console>
|
||||
<channel type='unix'>
|
||||
<target type='virtio' name='org.qemu.guest_agent.0'/>
|
||||
<address type='virtio-serial' controller='0' bus='0' port='1'/>
|
||||
</channel>
|
||||
<channel type='spicevmc'>
|
||||
<target type='virtio' name='com.redhat.spice.0'/>
|
||||
<address type='virtio-serial' controller='0' bus='0' port='2'/>
|
||||
</channel>
|
||||
<input type='tablet' bus='usb'>
|
||||
<address type='usb' bus='0' port='1'/>
|
||||
</input>
|
||||
<input type='mouse' bus='ps2'/>
|
||||
<input type='keyboard' bus='ps2'/>
|
||||
<tpm model='tpm-crb'>
|
||||
<backend type='emulator' version='2.0'/>
|
||||
</tpm>
|
||||
<graphics type='spice' autoport='yes'>
|
||||
<listen type='address'/>
|
||||
<image compression='off'/>
|
||||
</graphics>
|
||||
<sound model='ich9'>
|
||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x1b' function='0x0'/>
|
||||
</sound>
|
||||
<audio id='1' type='spice'/>
|
||||
<video>
|
||||
<model type='virtio' heads='1' primary='yes'/>
|
||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
|
||||
</video>
|
||||
<redirdev bus='usb' type='spicevmc'>
|
||||
<address type='usb' bus='0' port='2'/>
|
||||
</redirdev>
|
||||
<redirdev bus='usb' type='spicevmc'>
|
||||
<address type='usb' bus='0' port='3'/>
|
||||
</redirdev>
|
||||
<watchdog model='itco' action='reset'/>
|
||||
<memballoon model='virtio'>
|
||||
<address type='pci' domain='0x0000' bus='0x05' slot='0x00' function='0x0'/>
|
||||
</memballoon>
|
||||
<rng model='virtio'>
|
||||
<backend model='random'>/dev/urandom</backend>
|
||||
<address type='pci' domain='0x0000' bus='0x06' slot='0x00' function='0x0'/>
|
||||
</rng>
|
||||
</devices>
|
||||
</domain>
|
||||
|
||||
|
|
@ -9,6 +9,3 @@ terraform {
|
|||
provider "libvirt" {
|
||||
uri = "qemu:///system"
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +0,0 @@
|
|||
#!/usr/bin/bash
|
||||
|
||||
cat << EOF >> /etc/dnf/dnf.conf
|
||||
|
||||
# get me the fastest mirrors!
|
||||
max_parallel_downloads = 10
|
||||
minrate=1M
|
||||
timeout=10
|
||||
|
||||
EOF
|
||||
|
|
@ -5,6 +5,13 @@ variable "root_password" {
|
|||
default = "Un pinche pass."
|
||||
}
|
||||
|
||||
# hostname and domain name
|
||||
variable "guest_base_name" {
|
||||
description = "Nombre base para las máquinas virtuales invitadas."
|
||||
type = string
|
||||
default = "cs10-koji"
|
||||
}
|
||||
|
||||
variable "domain" {
|
||||
description = "Dominio de red para las máquinas virtuales."
|
||||
type = string
|
||||
|
|
@ -12,28 +19,18 @@ variable "domain" {
|
|||
default = "mx-os"
|
||||
}
|
||||
|
||||
variable "guest_count" {
|
||||
description = "Número de máquinas virtuales a crear"
|
||||
type = number
|
||||
default = 1
|
||||
}
|
||||
|
||||
variable "guest_base_name" {
|
||||
description = "Nombre base para las máquinas virtuales invitadas."
|
||||
type = string
|
||||
default = "cs10-koji"
|
||||
}
|
||||
|
||||
# base image
|
||||
variable "base_image_path" {
|
||||
description = "Path to the base qcow2 image"
|
||||
type = string
|
||||
default = "/home/renich/VirtualMachines/cs10.qcow2"
|
||||
}
|
||||
|
||||
variable "guest_memory" {
|
||||
description = "Cantidad de memoria RAM para cada invitado en MB."
|
||||
# resources
|
||||
variable "guest_count" {
|
||||
description = "Número de máquinas virtuales a crear"
|
||||
type = number
|
||||
default = 4096
|
||||
default = 4
|
||||
}
|
||||
|
||||
variable "guest_vcpu" {
|
||||
|
|
@ -42,10 +39,10 @@ variable "guest_vcpu" {
|
|||
default = 2
|
||||
}
|
||||
|
||||
variable "disk_size" {
|
||||
description = "Tamaño del disco del sistema para cada invitado en bytes."
|
||||
variable "guest_memory" {
|
||||
description = "Cantidad de memoria RAM para cada invitado en MB."
|
||||
type = number
|
||||
default = 107374182400 # 100 GB
|
||||
default = 4096
|
||||
}
|
||||
|
||||
variable "pool_name" {
|
||||
|
|
@ -53,4 +50,3 @@ variable "pool_name" {
|
|||
type = string
|
||||
default = "fast"
|
||||
}
|
||||
|
||||
|
|
|
|||
20
reset.yaml
20
reset.yaml
|
|
@ -1,11 +1,20 @@
|
|||
---
|
||||
- name: Reset Koji Environment
|
||||
hosts: kojidb,kojihub,kojid
|
||||
strategy: free
|
||||
vars_files:
|
||||
- vars/default.yaml
|
||||
- vars/credentials.yaml
|
||||
vars_prompt:
|
||||
- name: confirm_reset
|
||||
prompt: "Are you sure you want to reset the Koji environment? This will delete all data. Type 'YES' to confirm."
|
||||
private: false
|
||||
|
||||
tasks:
|
||||
- name: "Check confirmation"
|
||||
ansible.builtin.fail:
|
||||
msg: "Reset operation cancelled."
|
||||
when: confirm_reset != 'YES'
|
||||
|
||||
- name: Stop Koji Hub and Kojira services
|
||||
ansible.builtin.service:
|
||||
name: "{{ item }}"
|
||||
|
|
@ -13,8 +22,7 @@
|
|||
loop:
|
||||
- httpd
|
||||
- kojira
|
||||
when: "'kojihub' in group_names"
|
||||
ignore_errors: true
|
||||
failed_when: false
|
||||
|
||||
- name: Stop and disable kojid service
|
||||
ansible.builtin.service:
|
||||
|
|
@ -22,7 +30,7 @@
|
|||
state: stopped
|
||||
enabled: false
|
||||
when: "'kojid' in group_names"
|
||||
ignore_errors: true
|
||||
failed_when: false
|
||||
|
||||
- name: Terminate all active connections to Koji database
|
||||
community.postgresql.postgresql_query:
|
||||
|
|
@ -65,8 +73,8 @@
|
|||
when: "'kojidb' in group_names"
|
||||
|
||||
- name: Clean up old Koji build data
|
||||
ansible.builtin.shell:
|
||||
cmd: "find {{ koji_top_dir }} -mindepth 2 -delete"
|
||||
ansible.builtin.command: find {{ koji_top_dir }} -mindepth 2 -delete
|
||||
changed_when: true
|
||||
when: "'kojihub' in group_names"
|
||||
|
||||
- name: Remove kojid work directory
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
# List of certificates to generate.
|
||||
# is_user: true will generate a .p12 file for browser import.
|
||||
koji_certs_to_generate:
|
||||
common_koji_certs_to_generate:
|
||||
- name: kojihub
|
||||
cn: "{{ koji_hub_fqdn }}" # Server certs must use the FQDN for the CN
|
||||
is_user: false
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
- name: Create temporary OpenSSL config for signing
|
||||
ansible.builtin.copy:
|
||||
dest: "{{ koji_pki_dir }}/openssl-{{ cert.name }}.cnf"
|
||||
mode: "0644"
|
||||
content: |
|
||||
[v3_ca]
|
||||
basicConstraints = CA:FALSE
|
||||
|
|
@ -30,11 +31,11 @@
|
|||
subjectAltName = @alt_names
|
||||
[alt_names]
|
||||
DNS.1 = {{ cert.cn }}
|
||||
{% for san in cert.sans|default([]) %}
|
||||
{% for san in cert.sans | default([]) %}
|
||||
DNS.{{ loop.index + 1 }} = {{ san }}
|
||||
{% endfor %}
|
||||
|
||||
- name: "Sign certificate for {{ cert.name }} with our CA"
|
||||
- name: "Sign certificate with our CA"
|
||||
ansible.builtin.shell:
|
||||
cmd: >
|
||||
openssl x509 -req
|
||||
|
|
@ -55,8 +56,6 @@
|
|||
path: "{{ koji_pki_dir }}/openssl-{{ cert.name }}.cnf"
|
||||
state: absent
|
||||
|
||||
|
||||
|
||||
- name: "Generate PKCS12 bundle for user {{ cert.name }}"
|
||||
community.crypto.openssl_pkcs12:
|
||||
action: export
|
||||
|
|
@ -72,4 +71,4 @@
|
|||
- name: "Create PEM file for {{ cert.name }}"
|
||||
ansible.builtin.shell:
|
||||
cmd: "cat {{ koji_pki_dir }}/{{ cert.name }}.crt {{ koji_pki_dir }}/{{ cert.name }}.key > {{ koji_pki_dir }}/{{ cert.name }}.pem"
|
||||
creates: "{{ koji_pki_dir }}/{{ cert.name }}.pem"
|
||||
creates: "{{ koji_pki_dir }}/{{ cert.name }}.pem"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
# SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
- hosts: localhost
|
||||
- name: Test common role
|
||||
hosts: localhost
|
||||
remote_user: root
|
||||
roles:
|
||||
- roles/common
|
||||
- common
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
---
|
||||
common_ca_key_path: "{{ common_koji_pki_dir }}/{{ common_ca_name }}_cert.key"
|
||||
common_ca_cert_path: "{{ common_koji_pki_dir }}/{{ common_ca_name }}_cert.crt"
|
||||
common_ca_key_path: "{{ koji_pki_dir }}/{{ common_ca_name }}_cert.key"
|
||||
common_ca_cert_path: "{{ koji_pki_dir }}/{{ common_ca_name }}_cert.crt"
|
||||
|
|
|
|||
|
|
@ -1,9 +0,0 @@
|
|||
---
|
||||
koji_hub_plugin_dir: /usr/lib/koji-hub/plugins
|
||||
koji_hub_config_dir: /etc/koji-hub/hub.conf.d
|
||||
koji_web_config_dir: /etc/kojiweb/
|
||||
httpd_ssl_config_file: /etc/httpd/conf.d/ssl.conf
|
||||
koji_hub_httpd_config_file: /etc/httpd/conf.d/kojihub.conf
|
||||
koji_client_config_file: /etc/koji.conf.d/main.conf
|
||||
admin_user_home: "/home/{{ koji_admin_user }}"
|
||||
admin_user_koji_dir: "{{ admin_user_home }}/.koji"
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
---
|
||||
#SPDX-License-Identifier: MIT-0
|
||||
galaxy_info:
|
||||
author: your name
|
||||
description: your role description
|
||||
company: your company (optional)
|
||||
|
||||
# If the issue tracker for your role is not on github, uncomment the
|
||||
# next line and provide a value
|
||||
# issue_tracker_url: http://example.com/issue/tracker
|
||||
|
||||
# Choose a valid license ID from https://spdx.org - some suggested licenses:
|
||||
# - BSD-3-Clause (default)
|
||||
# - MIT
|
||||
# - GPL-2.0-or-later
|
||||
# - GPL-3.0-only
|
||||
# - Apache-2.0
|
||||
# - CC-BY-4.0
|
||||
license: license (GPL-2.0-or-later, MIT, etc)
|
||||
|
||||
min_ansible_version: 2.1
|
||||
|
||||
# If this a Container Enabled role, provide the minimum Ansible Container version.
|
||||
# min_ansible_container_version:
|
||||
|
||||
galaxy_tags: []
|
||||
# List tags for your role here, one per line. A tag is a keyword that describes
|
||||
# and categorizes the role. Users find roles by searching for tags. Be sure to
|
||||
# remove the '[]' above, if you add tags to this list.
|
||||
#
|
||||
# NOTE: A tag is limited to a single word comprised of alphanumeric characters.
|
||||
# Maximum 20 tags per role.
|
||||
|
||||
dependencies: []
|
||||
# List your role dependencies here, one per line. Be sure to remove the '[]' above,
|
||||
# if you add dependencies to this list.
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
[hub-policy:admin]
|
||||
user = {{ koji_admin_user }}
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
KOJI_CMD="sudo -u kojiadmin koji --config=/home/kojiadmin/.koji/config"
|
||||
|
||||
# Clean up previous attempts to ensure a clean slate
|
||||
$KOJI_CMD remove-target "{{ koji_build_tag }}-build" || echo "Target {{ koji_build_tag }}-build did not exist"
|
||||
$KOJI_CMD remove-tag "{{ koji_build_tag }}-build" || echo "Tag {{ koji_build_tag }}-build did not exist"
|
||||
$KOJI_CMD remove-tag "{{ koji_build_tag }}" || echo "Tag {{ koji_build_tag }} did not exist"
|
||||
|
||||
# Tags
|
||||
$KOJI_CMD add-tag "{{ koji_build_tag }}" || echo "Tag {{ koji_build_tag }} already exists"
|
||||
$KOJI_CMD add-tag --parent "{{ koji_build_tag }}" --arches "x86_64" "{{ koji_build_tag }}-build" || echo "Tag {{ koji_build_tag }}-build already exists"
|
||||
|
||||
# Target
|
||||
$KOJI_CMD add-target "{{ koji_build_tag }}-build" "{{ koji_build_tag }}-build" || echo "Target {{ koji_build_tag }}-build already exists"
|
||||
|
||||
# External Repos
|
||||
$KOJI_CMD remove-external-repo "centos-stream-10-baseos" || echo "External repo centos-stream-10-baseos not found"
|
||||
$KOJI_CMD remove-external-repo "centos-stream-10-appstream" || echo "External repo centos-stream-10-appstream not found"
|
||||
$KOJI_CMD add-external-repo -t "{{ koji_build_tag }}-build" "centos-stream-10-baseos" "http://mirror.stream.centos.org/10-stream/BaseOS/x86_64/os/" || echo "External repo centos-stream-10-baseos already exists"
|
||||
$KOJI_CMD add-external-repo -t "{{ koji_build_tag }}-build" "centos-stream-10-appstream" "http://mirror.stream.centos.org/10-stream/AppStream/x86_64/os/" || echo "External repo centos-stream-10-appstream already exists"
|
||||
|
||||
# Groups
|
||||
$KOJI_CMD add-group "{{ koji_build_tag }}-build" "build" || echo "Group build already exists"
|
||||
$KOJI_CMD add-group-pkg "{{ koji_build_tag }}-build" "build" "build-sys" || echo "Package build-sys already in group build"
|
||||
$KOJI_CMD add-group-pkg "{{ koji_build_tag }}-build" "build" "python3-dnf" || echo "Package python3-dnf already in group build"
|
||||
$KOJI_CMD add-group-pkg "{{ koji_build_tag }}-build" "build" "python3-dnf-plugins-core" || echo "Package python3-dnf-plugins-core already in group build"
|
||||
|
||||
# Hosts
|
||||
{% for host in groups['kojibuilders'] %}
|
||||
$KOJI_CMD add-host "{{ host }}" x86_64 || echo "Host {{ host }} already exists"
|
||||
$KOJI_CMD add-host-to-channel "{{ host }}" createrepo || echo "Host {{ host }} already in channel createrepo"
|
||||
$KOJI_CMD edit-host --capacity={{ kojid_max_jobs }} "{{ host }}" || echo "Could not edit host {{ host }}"
|
||||
{% endfor %}
|
||||
|
||||
# Repo
|
||||
$KOJI_CMD add-user kojira || echo "User kojira already exists"
|
||||
$KOJI_CMD grant-permission repo kojira || echo "Permission repo already granted to kojira"
|
||||
$KOJI_CMD regen-repo --nowait "{{ koji_build_tag }}-build"
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
#SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
- hosts: localhost
|
||||
remote_user: root
|
||||
roles:
|
||||
- roles/koji-hub
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
#SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
# vars file for roles/koji-hub
|
||||
125
roles/koji_bootstrap/tasks/main.yaml
Normal file
125
roles/koji_bootstrap/tasks/main.yaml
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
---
|
||||
- name: Add kojira user
|
||||
ansible.builtin.command: "sudo -u {{ koji_admin_user }} koji --config={{ koji_hub_admin_user_koji_dir }}/config add-user kojira"
|
||||
register: koji_bootstrap_add_user_result
|
||||
changed_when: "'User added' in koji_bootstrap_add_user_result.stdout"
|
||||
failed_when: "koji_bootstrap_add_user_result.rc != 0 and 'already exists' not in koji_bootstrap_add_user_result.stderr"
|
||||
|
||||
- name: Grant repo permission to kojira user
|
||||
ansible.builtin.command: >
|
||||
sudo -u {{ koji_admin_user }} koji
|
||||
--config={{ koji_hub_admin_user_koji_dir }}/config
|
||||
grant-permission repo kojira
|
||||
register: koji_bootstrap_grant_permission_result
|
||||
changed_when: "'Permission granted' in koji_bootstrap_grant_permission_result.stdout"
|
||||
failed_when: "koji_bootstrap_grant_permission_result.rc != 0 and 'already has permission' not in koji_bootstrap_grant_permission_result.stderr"
|
||||
|
||||
- name: Create main build tag
|
||||
ansible.builtin.command: >
|
||||
sudo -u {{ koji_admin_user }} koji
|
||||
--config={{ koji_hub_admin_user_koji_dir }}/config
|
||||
add-tag --arches x86_64 {{ koji_build_tag }}
|
||||
register: koji_bootstrap_add_tag_result
|
||||
changed_when: "'Tag created' in koji_bootstrap_add_tag_result.stdout"
|
||||
failed_when: "koji_bootstrap_add_tag_result.rc != 0 and 'already exists' not in koji_bootstrap_add_tag_result.stderr"
|
||||
|
||||
- name: Create x86_64 build tag
|
||||
ansible.builtin.command: >
|
||||
sudo -u {{ koji_admin_user }} koji
|
||||
--config={{ koji_hub_admin_user_koji_dir }}/config
|
||||
add-tag --parent {{ koji_build_tag }} --arches x86_64 {{ koji_build_tag }}-build
|
||||
register: koji_bootstrap_add_arch_tag_result
|
||||
changed_when: "'Tag created' in koji_bootstrap_add_arch_tag_result.stdout"
|
||||
failed_when: "koji_bootstrap_add_arch_tag_result.rc != 0 and 'already exists' not in koji_bootstrap_add_arch_tag_result.stderr"
|
||||
|
||||
- name: Enable automatic build NVR bumping
|
||||
ansible.builtin.command: >
|
||||
sudo -u {{ koji_admin_user }} koji
|
||||
--config={{ koji_hub_admin_user_koji_dir }}/config
|
||||
edit-tag --extra autorelease=1 {{ koji_build_tag }}-build
|
||||
register: koji_bootstrap_edit_tag_result
|
||||
changed_when: "'Tag updated' in koji_bootstrap_edit_tag_result.stdout"
|
||||
failed_when: "koji_bootstrap_edit_tag_result.rc != 0 and 'tag not found' not in koji_bootstrap_edit_tag_result.stderr"
|
||||
|
||||
- name: Create build target
|
||||
ansible.builtin.command: >
|
||||
sudo -u {{ koji_admin_user }} koji
|
||||
--config={{ koji_hub_admin_user_koji_dir }}/config
|
||||
add-target {{ koji_build_tag }} {{ koji_build_tag }}-build
|
||||
register: koji_bootstrap_add_target_result
|
||||
changed_when: "'Target created' in koji_bootstrap_add_target_result.stdout"
|
||||
failed_when: "koji_bootstrap_add_target_result.rc != 0 and 'already exists' not in koji_bootstrap_add_target_result.stderr"
|
||||
|
||||
- name: Add CentOS Stream 10 BaseOS external repository
|
||||
ansible.builtin.command: >
|
||||
sudo -u {{ koji_admin_user }} koji
|
||||
--config={{ koji_hub_admin_user_koji_dir }}/config
|
||||
add-external-repo -t {{ koji_build_tag }}-build centos-stream-10-baseos
|
||||
https://mirror.stream.centos.org/10-stream/BaseOS/x86_64/os/
|
||||
register: koji_bootstrap_add_baseos_repo_result
|
||||
changed_when: "'External repository created' in koji_bootstrap_add_baseos_repo_result.stdout"
|
||||
failed_when: "koji_bootstrap_add_baseos_repo_result.rc != 0 and 'already exists' not in koji_bootstrap_add_baseos_repo_result.stderr"
|
||||
|
||||
- name: Add CentOS Stream 10 AppStream external repository
|
||||
ansible.builtin.command: >
|
||||
sudo -u {{ koji_admin_user }} koji
|
||||
--config={{ koji_hub_admin_user_koji_dir }}/config
|
||||
add-external-repo -t {{ koji_build_tag }}-build centos-stream-10-appstream
|
||||
https://mirror.stream.centos.org/10-stream/AppStream/x86_64/os/
|
||||
register: koji_bootstrap_add_appstream_repo_result
|
||||
changed_when: "'External repository created' in koji_bootstrap_add_appstream_repo_result.stdout"
|
||||
failed_when: "koji_bootstrap_add_appstream_repo_result.rc != 0 and 'already exists' not in koji_bootstrap_add_appstream_repo_result.stderr"
|
||||
|
||||
- name: Add CentOS Stream 10 EPEL external repository
|
||||
ansible.builtin.command: >
|
||||
sudo -u {{ koji_admin_user }} koji
|
||||
--config={{ koji_hub_admin_user_koji_dir }}/config
|
||||
add-external-repo -t {{ koji_build_tag }}-build centos-stream-10-epel
|
||||
https://mirror.facebook.net/fedora/epel/10/Everything/x86_64/
|
||||
register: koji_bootstrap_add_appstream_repo_result
|
||||
changed_when: "'External repository created' in koji_bootstrap_add_appstream_repo_result.stdout"
|
||||
failed_when: "koji_bootstrap_add_appstream_repo_result.rc != 0 and 'already exists' not in koji_bootstrap_add_appstream_repo_result.stderr"
|
||||
|
||||
- name: Add Koji builder hosts
|
||||
ansible.builtin.command: >
|
||||
sudo -u {{ koji_admin_user }} koji
|
||||
--config={{ koji_hub_admin_user_koji_dir }}/config
|
||||
add-host {{ item }} x86_64
|
||||
loop: "{{ groups['kojibuilders'] }}"
|
||||
register: koji_bootstrap_add_host_result
|
||||
changed_when: "'Host added' in koji_bootstrap_add_host_result.stdout"
|
||||
failed_when: "koji_bootstrap_add_host_result.rc != 0 and 'is already in the database' not in koji_bootstrap_add_host_result.stderr"
|
||||
|
||||
- name: Add Koji builder hosts to createrepo channel
|
||||
ansible.builtin.command: >
|
||||
sudo -u {{ koji_admin_user }} koji
|
||||
--config={{ koji_hub_admin_user_koji_dir }}/config
|
||||
add-host-to-channel {{ item }} createrepo
|
||||
loop: "{{ groups['kojibuilders'] }}"
|
||||
register: koji_bootstrap_add_host_to_channel_result
|
||||
changed_when: "'Host added to channel' in koji_bootstrap_add_host_to_channel_result.stdout"
|
||||
failed_when: "koji_bootstrap_add_host_to_channel_result.rc != 0 and 'is already subscribed' not in koji_bootstrap_add_host_to_channel_result.stderr"
|
||||
|
||||
- name: Set Koji builder host capacity
|
||||
ansible.builtin.command: >
|
||||
sudo -u {{ koji_admin_user }} koji
|
||||
--config={{ koji_hub_admin_user_koji_dir }}/config
|
||||
edit-host --capacity={{ kojid_max_jobs }} {{ item }}
|
||||
loop: "{{ groups['kojibuilders'] }}"
|
||||
changed_when: true
|
||||
|
||||
- name: Regenerate repo
|
||||
ansible.builtin.command: >
|
||||
sudo -u {{ koji_admin_user }} koji
|
||||
--config={{ koji_hub_admin_user_koji_dir }}/config
|
||||
regen-repo {{ koji_build_tag }}
|
||||
changed_when: false
|
||||
|
||||
- name: Create builder user
|
||||
ansible.builtin.command: >
|
||||
sudo -u {{ koji_admin_user }} koji
|
||||
--config={{ koji_hub_admin_user_koji_dir }}/config
|
||||
add-user builder
|
||||
register: koji_bootstrap_add_builder_user_result
|
||||
changed_when: "'User added' in koji_bootstrap_add_builder_user_result.stdout"
|
||||
failed_when: "koji_bootstrap_add_builder_user_result.rc != 0 and 'already exists' not in koji_bootstrap_add_builder_user_result.stderr"
|
||||
7
roles/koji_hub/defaults/main.yaml
Normal file
7
roles/koji_hub/defaults/main.yaml
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
koji_hub_plugin_dir: /usr/lib/koji_hub/plugins
|
||||
koji_hub_config_dir: /etc/koji_hub/hub.conf.d
|
||||
koji_hub_koji_web_config_dir: /etc/kojiweb/
|
||||
koji_hub_httpd_ssl_config_file: /etc/httpd/conf.d/ssl.conf
|
||||
koji_hub_httpd_config_file: /etc/httpd/conf.d/kojihub.conf
|
||||
koji_hub_koji_client_config_file: /etc/koji.conf.d/main.conf
|
||||
7
roles/koji_hub/files/koji-cleanup.service
Normal file
7
roles/koji_hub/files/koji-cleanup.service
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
[Unit]
|
||||
Description=Koji Cleanup Service
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/local/bin/koji_cleanup.sh
|
||||
9
roles/koji_hub/files/koji-cleanup.timer
Normal file
9
roles/koji_hub/files/koji-cleanup.timer
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
[Unit]
|
||||
Description=Run Koji Cleanup Service weekly
|
||||
|
||||
[Timer]
|
||||
OnCalendar=weekly
|
||||
Persistent=true
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
#SPDX-License-Identifier: MIT-0
|
||||
# SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
- name: Restart httpd
|
||||
ansible.builtin.service:
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
---
|
||||
#SPDX-License-Identifier: MIT-0
|
||||
# SPDX-License-Identifier: MIT-0
|
||||
galaxy_info:
|
||||
author: your name
|
||||
description: your role description
|
||||
company: your company (optional)
|
||||
author: MxOS
|
||||
description: Koji Hub role
|
||||
company: MxOS
|
||||
|
||||
# If the issue tracker for your role is not on github, uncomment the
|
||||
# next line and provide a value
|
||||
|
|
@ -16,9 +16,9 @@ galaxy_info:
|
|||
# - GPL-3.0-only
|
||||
# - Apache-2.0
|
||||
# - CC-BY-4.0
|
||||
license: license (GPL-2.0-or-later, MIT, etc)
|
||||
license: MIT
|
||||
|
||||
min_ansible_version: 2.1
|
||||
min_ansible_version: "2.1"
|
||||
|
||||
# If this a Container Enabled role, provide the minimum Ansible Container version.
|
||||
# min_ansible_container_version:
|
||||
|
|
@ -32,9 +32,7 @@
|
|||
- "{{ koji_top_dir }}/scratch"
|
||||
- "{{ koji_top_dir }}/repos-dist"
|
||||
|
||||
|
||||
|
||||
- name: Ensure admin user '{{ koji_admin_user }}' exists
|
||||
- name: Ensure admin user exists
|
||||
ansible.builtin.user:
|
||||
name: "{{ koji_admin_user }}"
|
||||
state: present
|
||||
|
|
@ -47,6 +45,8 @@
|
|||
append: true
|
||||
state: present
|
||||
|
||||
# This is for demonstration purposes only. In a production environment,
|
||||
# it is recommended to configure sudo access with a more restrictive policy.
|
||||
- name: Ensure wheel group has NOPASSWD sudo access
|
||||
ansible.builtin.lineinfile:
|
||||
path: /etc/sudoers
|
||||
|
|
@ -57,20 +57,26 @@
|
|||
|
||||
- name: Ensure .koji directory exists for '{{ koji_admin_user }}'
|
||||
ansible.builtin.file:
|
||||
path: "{{ admin_user_koji_dir }}"
|
||||
path: "{{ koji_hub_admin_user_koji_dir }}"
|
||||
state: directory
|
||||
owner: "{{ koji_admin_user }}"
|
||||
group: "{{ koji_admin_user }}"
|
||||
mode: "{{ koji_client_dir_mode }}"
|
||||
|
||||
- name: Configure Koji client for admin user
|
||||
ansible.builtin.template:
|
||||
src: koji.conf.j2
|
||||
dest: "{{ admin_user_koji_dir }}/config"
|
||||
dest: "{{ koji_hub_admin_user_koji_dir }}/config"
|
||||
owner: "{{ koji_admin_user }}"
|
||||
group: "{{ koji_admin_user }}"
|
||||
mode: "{{ koji_client_file_mode }}"
|
||||
|
||||
- name: Copy client certificates for '{{ koji_admin_user }}'
|
||||
ansible.builtin.copy:
|
||||
src: "{{ item.src }}"
|
||||
dest: "{{ admin_user_koji_dir }}/{{ item.dest }}"
|
||||
dest: "{{ koji_hub_admin_user_koji_dir }}/{{ item.dest }}"
|
||||
owner: "{{ koji_admin_user }}"
|
||||
group: "{{ koji_admin_user }}"
|
||||
mode: "{{ koji_client_file_mode }}"
|
||||
loop:
|
||||
- src: "{{ koji_pki_dir }}/kojiadmin.pem"
|
||||
|
|
@ -105,12 +111,23 @@
|
|||
- { src: "kojiadmin.pem", dest: "{{ koji_admin_cert_path }}", mode: "0644" }
|
||||
|
||||
- name: Update CA trust store
|
||||
ansible.builtin.shell: update-ca-trust
|
||||
changed_when: true
|
||||
ansible.builtin.command: update-ca-trust
|
||||
changed_when: false
|
||||
|
||||
- name: Flush handlers
|
||||
ansible.builtin.meta: flush_handlers
|
||||
|
||||
- name: Create Koji Hub and Web config directories
|
||||
ansible.builtin.file:
|
||||
path: "{{ item }}"
|
||||
state: directory
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0755"
|
||||
loop:
|
||||
- "{{ koji_hub_config_dir }}"
|
||||
- "{{ koji_hub_koji_web_config_dir }}"
|
||||
|
||||
- name: Configure httpd for Koji
|
||||
ansible.builtin.lineinfile:
|
||||
path: "{{ item.path }}"
|
||||
|
|
@ -118,9 +135,9 @@
|
|||
line: "{{ item.line }}"
|
||||
backup: true
|
||||
loop:
|
||||
- { path: "{{ httpd_ssl_config_file }}", regexp: "^SSLCertificateFile", line: "SSLCertificateFile {{ koji_hub_cert_path }}" }
|
||||
- { path: "{{ httpd_ssl_config_file }}", regexp: "^SSLCertificateKeyFile", line: "SSLCertificateKeyFile {{ koji_hub_key_path }}" }
|
||||
- { path: "{{ httpd_ssl_config_file }}", regexp: "^#?SSLCACertificateFile", line: "SSLCACertificateFile {{ koji_remote_ca_trust_path }}" }
|
||||
- { path: "{{ koji_hub_httpd_ssl_config_file }}", regexp: "^SSLCertificateFile", line: "SSLCertificateFile {{ koji_hub_cert_path }}" }
|
||||
- { path: "{{ koji_hub_httpd_ssl_config_file }}", regexp: "^SSLCertificateKeyFile", line: "SSLCertificateKeyFile {{ koji_hub_key_path }}" }
|
||||
- { path: "{{ koji_hub_httpd_ssl_config_file }}", regexp: "^#?SSLCACertificateFile", line: "SSLCACertificateFile {{ koji_remote_ca_trust_path }}" }
|
||||
notify: Restart httpd
|
||||
|
||||
- name: Enable SSL for Koji Hub
|
||||
|
|
@ -145,11 +162,20 @@
|
|||
- { src: "00-main.conf.j2", dest: "{{ koji_hub_config_dir }}/00-main.conf" }
|
||||
- { src: "db.conf.j2", dest: "{{ koji_hub_config_dir }}/db.conf" }
|
||||
- { src: "admin.conf.j2", dest: "{{ koji_hub_config_dir }}/admin.conf" }
|
||||
- { src: "web.conf.j2", dest: "{{ koji_web_config_dir }}/web.conf" }
|
||||
- { src: "web.conf.j2", dest: "{{ koji_hub_koji_web_config_dir }}/web.conf" }
|
||||
- { src: "policies.conf.j2", dest: "{{ koji_hub_config_dir }}/policies.conf" }
|
||||
- { src: "99-local-policies.conf.j2", dest: "{{ koji_hub_config_dir }}/99-local-policies.conf" }
|
||||
notify: Restart httpd
|
||||
|
||||
- name: Configure Koji Hub database connection
|
||||
ansible.builtin.blockinfile:
|
||||
path: /etc/koji-hub/hub.conf
|
||||
block: |
|
||||
DBHost = {{ koji_db_host }}
|
||||
DBPass = {{ koji_db_password }}
|
||||
marker: "# {mark} ANSIBLE MANAGED BLOCK FOR DB CONNECTION"
|
||||
notify: Restart httpd
|
||||
|
||||
- name: Set SELinux booleans for Apache
|
||||
ansible.posix.seboolean:
|
||||
name: "{{ item }}"
|
||||
|
|
@ -160,6 +186,7 @@
|
|||
- httpd_can_network_connect
|
||||
- allow_httpd_anon_write
|
||||
- httpd_use_nfs
|
||||
notify: Restart httpd
|
||||
|
||||
- name: Start and enable httpd
|
||||
ansible.builtin.service:
|
||||
|
|
@ -177,9 +204,11 @@
|
|||
|
||||
- name: Set SELinux context for Koji topdir
|
||||
ansible.builtin.command: semanage fcontext -a -t httpd_sys_rw_content_t "/mnt/koji(/.*)?"
|
||||
changed_when: false
|
||||
|
||||
- name: Apply SELinux context
|
||||
ansible.builtin.command: restorecon -r -v /mnt/koji
|
||||
changed_when: false
|
||||
|
||||
- name: Add database host to /etc/hosts
|
||||
ansible.builtin.lineinfile:
|
||||
|
|
@ -201,30 +230,15 @@
|
|||
port: 5432
|
||||
timeout: 120
|
||||
|
||||
- name: Check if Koji DB schema is loaded
|
||||
ansible.builtin.shell:
|
||||
cmd: psql -h {{ koji_db_host }} -U {{ koji_db_user }} -d {{ koji_db_name }} -c "SELECT 'users'::regclass;"
|
||||
register: schema_check
|
||||
failed_when: false
|
||||
changed_when: false
|
||||
environment:
|
||||
PGPASSWORD: "{{ koji_db_password }}"
|
||||
|
||||
- name: Load Koji DB Schema
|
||||
ansible.builtin.shell:
|
||||
cmd: psql -h {{ koji_db_host }} -U {{ koji_db_user }} -d {{ koji_db_name }} -f /usr/share/koji/schema.sql
|
||||
when: schema_check.rc != 0
|
||||
environment:
|
||||
PGPASSWORD: "{{ koji_db_password }}"
|
||||
|
||||
- name: Check if Koji DB schema is loaded
|
||||
community.postgresql.postgresql_query:
|
||||
login_db: "{{ koji_db_name }}"
|
||||
query: "SELECT 'users'::regclass;"
|
||||
query: "SELECT EXISTS (SELECT FROM information_schema.tables WHERE table_schema = 'public' AND table_name = 'users');"
|
||||
login_host: "{{ koji_db_host }}"
|
||||
login_user: "{{ koji_db_user }}"
|
||||
login_password: "{{ koji_db_password }}"
|
||||
register: schema_check
|
||||
register: koji_hub_schema_check
|
||||
changed_when: false
|
||||
|
||||
- name: Load Koji DB Schema
|
||||
community.postgresql.postgresql_script:
|
||||
|
|
@ -233,7 +247,7 @@
|
|||
login_host: "{{ koji_db_host }}"
|
||||
login_user: "{{ koji_db_user }}"
|
||||
login_password: "{{ koji_db_password }}"
|
||||
when: schema_check.failed
|
||||
when: not koji_hub_schema_check.query_result[0].exists
|
||||
|
||||
- name: Create kojiadmin user in database
|
||||
community.postgresql.postgresql_query:
|
||||
|
|
@ -246,43 +260,64 @@
|
|||
- name: Configure Koji client via ansible-settings.conf
|
||||
ansible.builtin.template:
|
||||
src: koji.conf.j2
|
||||
dest: "{{ koji_client_config_file }}"
|
||||
dest: "{{ koji_hub_koji_client_config_file }}"
|
||||
group: apache
|
||||
mode: "0644"
|
||||
|
||||
- name: Grant admin privileges to kojiadmin user
|
||||
community.postgresql.postgresql_query:
|
||||
login_db: "{{ koji_db_name }}"
|
||||
query: "INSERT INTO user_perms (user_id, perm_id, creator_id) VALUES ((SELECT id FROM users WHERE name = '{{ koji_admin_user }}'), (SELECT id FROM permissions WHERE name = 'admin'), (SELECT id FROM users WHERE name = '{{ koji_admin_user }}')) ON CONFLICT DO NOTHING"
|
||||
query: >
|
||||
INSERT INTO user_perms (user_id, perm_id, creator_id)
|
||||
VALUES (
|
||||
(SELECT id FROM users WHERE name = '{{ koji_admin_user }}'),
|
||||
(SELECT id FROM permissions WHERE name = 'admin'),
|
||||
(SELECT id FROM users WHERE name = '{{ koji_admin_user }}')
|
||||
) ON CONFLICT DO NOTHING
|
||||
login_host: "{{ koji_db_host }}"
|
||||
login_user: "{{ koji_db_user }}"
|
||||
login_password: "{{ koji_db_password }}"
|
||||
|
||||
- name: Ensure correct ownership of kojiadmin config
|
||||
ansible.builtin.file:
|
||||
path: "{{ admin_user_koji_dir }}"
|
||||
owner: "{{ koji_admin_user }}"
|
||||
group: "{{ koji_admin_user }}"
|
||||
recurse: true
|
||||
- name: Template Koji callback script
|
||||
ansible.builtin.template:
|
||||
src: koji_callbacks.py.j2
|
||||
dest: "{{ koji_callbacks_script_path }}"
|
||||
mode: "0755"
|
||||
|
||||
- name: Add Koji builder hosts
|
||||
ansible.builtin.shell:
|
||||
cmd: "sudo -u kojiadmin koji --config={{ admin_user_koji_dir }}/config add-host {{ item }} x86_64"
|
||||
loop: "{{ groups['kojibuilders'] }}"
|
||||
register: add_host_result
|
||||
failed_when: "add_host_result.rc != 0 and 'already in the database' not in add_host_result.stderr"
|
||||
changed_when: "add_host_result.rc == 0"
|
||||
- name: Configure Koji callbacks
|
||||
ansible.builtin.template:
|
||||
src: callbacks.conf.j2
|
||||
dest: "{{ koji_callbacks_config_path }}"
|
||||
mode: "0640"
|
||||
notify: Restart httpd
|
||||
|
||||
- name: Add Koji builder hosts to createrepo channel
|
||||
ansible.builtin.shell:
|
||||
cmd: "sudo -u kojiadmin koji --config={{ admin_user_koji_dir }}/config add-host-to-channel {{ item }} createrepo"
|
||||
loop: "{{ groups['kojibuilders'] }}"
|
||||
register: add_channel_result
|
||||
failed_when: "add_channel_result.rc != 0 and 'already in the database' not in add_channel_result.stderr and 'already subscribed to the createrepo channel' not in add_channel_result.stderr"
|
||||
changed_when: "add_channel_result.rc == 0"
|
||||
- name: Template Koji cleanup script
|
||||
ansible.builtin.template:
|
||||
src: koji_cleanup.sh.j2
|
||||
dest: "{{ koji_cleanup_script_path }}"
|
||||
mode: "0755"
|
||||
|
||||
- name: Set Koji builder host capacity
|
||||
ansible.builtin.shell:
|
||||
cmd: "sudo -u kojiadmin koji --config={{ admin_user_koji_dir }}/config edit-host --capacity={{ kojid_max_jobs }} {{ item }}"
|
||||
loop: "{{ groups['kojibuilders'] }}"
|
||||
changed_when: true
|
||||
- name: Create systemd service for Koji cleanup
|
||||
ansible.builtin.copy:
|
||||
src: koji-cleanup.service
|
||||
dest: "{{ koji_cleanup_service_path }}"
|
||||
mode: "0644"
|
||||
|
||||
- name: Create systemd timer for Koji cleanup
|
||||
ansible.builtin.copy:
|
||||
src: koji-cleanup.timer
|
||||
dest: "{{ koji_cleanup_timer_path }}"
|
||||
mode: "0644"
|
||||
|
||||
- name: Enable and start Koji cleanup timer
|
||||
ansible.builtin.systemd:
|
||||
name: koji-cleanup.timer
|
||||
state: started
|
||||
enabled: true
|
||||
daemon_reload: true
|
||||
|
||||
- name: Enable and start Koji DB sweeper timer
|
||||
ansible.builtin.service:
|
||||
name: koji-sweep-db.timer
|
||||
state: started
|
||||
enabled: true
|
||||
8
roles/koji_hub/templates/99-local-policies.conf.j2
Normal file
8
roles/koji_hub/templates/99-local-policies.conf.j2
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
[hub-policy:admin]
|
||||
user = {{ koji_admin_user }}
|
||||
|
||||
[task:newRepo]
|
||||
channel = repo
|
||||
|
||||
[task:build_rpm]
|
||||
user = builder
|
||||
3
roles/koji_hub/templates/callbacks.conf.j2
Normal file
3
roles/koji_hub/templates/callbacks.conf.j2
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
[hub]
|
||||
CallbackFile = /usr/local/bin/koji_callbacks.py
|
||||
CallbackRegex = .*
|
||||
18
roles/koji_hub/templates/koji_callbacks.py.j2
Normal file
18
roles/koji_hub/templates/koji_callbacks.py.j2
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
#!/usr/bin/python3
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
|
||||
def main():
|
||||
log_file = "/var/log/koji_callbacks.log"
|
||||
with open(log_file, "a") as f:
|
||||
f.write("Callback triggered:\n")
|
||||
f.write(f" Type: {os.environ.get('KOJI_TYPE')}\n")
|
||||
f.write(f" Table: {os.environ.get('KOJI_TABLE')}\n")
|
||||
f.write(f" ID: {os.environ.get('KOJI_ID')}\n")
|
||||
f.write(f" Attrs: {os.environ.get('KOJI_ATTRS')}\n")
|
||||
f.write("\n")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
26
roles/koji_hub/templates/koji_cleanup.sh.j2
Normal file
26
roles/koji_hub/templates/koji_cleanup.sh.j2
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Koji cleanup script
|
||||
# This script cleans up old build roots and work directories on the Koji hub.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# --- Configuration ---
|
||||
KOJI_TOP_DIR="{{ koji_top_dir }}"
|
||||
KOJI_ADMIN_USER="{{ koji_admin_user }}"
|
||||
ADMIN_USER_KOJI_DIR="{{ koji_hub_admin_user_koji_dir }}"
|
||||
|
||||
# --- Main Script ---
|
||||
|
||||
echo "$(date): Starting Koji cleanup..."
|
||||
|
||||
# Clean up old build roots
|
||||
# koji-gc --cleanup-buildroots --debug
|
||||
|
||||
# Clean up old work directories
|
||||
# find "$KOJI_TOP_DIR/work" -maxdepth 1 -type d -mtime +7 -exec rm -rf {} \;
|
||||
|
||||
# Example: Remove old scratch builds (older than 30 days)
|
||||
# koji --config="$ADMIN_USER_KOJI_DIR/config" list-builds --state=FAILED --state=CANCELED --state=DELETED --mine --after-completion="$(date -d '30 days ago' +%Y-%m-%d)" | awk '{print $1}' | xargs -r -L 1 koji --config="$ADMIN_USER_KOJI_DIR/config" remove-build --nowait
|
||||
|
||||
echo "$(date): Koji cleanup finished."
|
||||
7
roles/koji_hub/tests/test.yaml
Normal file
7
roles/koji_hub/tests/test.yaml
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
- name: Test koji_hub role
|
||||
hosts: localhost
|
||||
remote_user: root
|
||||
roles:
|
||||
- koji_hub
|
||||
3
roles/koji_hub/vars/main.yaml
Normal file
3
roles/koji_hub/vars/main.yaml
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
# SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
# vars file for roles/koji_hub
|
||||
|
|
@ -1,2 +1,5 @@
|
|||
---
|
||||
kojid_work_dir: /var/lib/kojid
|
||||
kojid_work_dir: /var/lib/kojid
|
||||
kojid_allowed_scms: git.mx-os.mx:/RPMs/*
|
||||
kojid_use_host_resolv: true
|
||||
kojid_max_jobs: 50
|
||||
|
|
|
|||
|
|
@ -1,5 +1,10 @@
|
|||
config_opts['root'] = '{{ kojid_mock_root }}'
|
||||
config_opts['releasever'] = '10'
|
||||
config_opts['rpmbuild_networking'] = True
|
||||
config_opts['use_bootstrap'] = False
|
||||
config_opts['target_arch'] = 'x86_64'
|
||||
config_opts['legal_host_arches'] = ('x86_64',)
|
||||
config_opts['chroot_setup_cmd'] = 'install rpm-build rpmdevtools rpmlint'
|
||||
config_opts['yum.conf'] = """
|
||||
[main]
|
||||
gpgcheck=1
|
||||
|
|
@ -8,6 +13,7 @@ keepcache=1
|
|||
reposdir=/dev/null
|
||||
retries=20
|
||||
strict=1
|
||||
sslverify=0
|
||||
|
||||
[baseos]
|
||||
name=CentOS Stream 10 - BaseOS
|
||||
|
|
@ -24,5 +30,10 @@ name=CentOS Stream 10 - CRB
|
|||
baseurl=https://mirror.stream.centos.org/10-stream/CRB/x86_64/os/
|
||||
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial-SHA256
|
||||
enabled=1
|
||||
|
||||
[epel]
|
||||
name=Extra Packages for Enterprise Linux 10 - x86_64
|
||||
baseurl=https://dl.fedoraproject.org/pub/epel/10/Everything/x86_64/
|
||||
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-epel-10
|
||||
enabled=1
|
||||
"""
|
||||
config_opts['chroot_setup_cmd'] = 'install rpm-build rpmdevtools rpmlint'
|
||||
|
|
@ -1,4 +1,3 @@
|
|||
#SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
- name: Restart kojid
|
||||
ansible.builtin.service:
|
||||
|
|
|
|||
|
|
@ -1,36 +1,22 @@
|
|||
# SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
galaxy_info:
|
||||
author: your name
|
||||
description: your role description
|
||||
company: your company (optional)
|
||||
author: "Renich Bon Ciric"
|
||||
description: "Koji builder"
|
||||
company: "Mx-OS"
|
||||
|
||||
# If the issue tracker for your role is not on github, uncomment the
|
||||
# next line and provide a value
|
||||
# issue_tracker_url: http://example.com/issue/tracker
|
||||
license: "GPL-2.0-or-later"
|
||||
|
||||
# Choose a valid license ID from https://spdx.org - some suggested licenses:
|
||||
# - BSD-3-Clause (default)
|
||||
# - - MIT
|
||||
# - GPL-2.0-or-later
|
||||
# - GPL-3.0-only
|
||||
# - Apache-2.0
|
||||
# - CC-BY-4.0
|
||||
license: license (GPL-2.0-or-later, MIT, etc)
|
||||
min_ansible_version: "2.15"
|
||||
|
||||
min_ansible_version: 2.1
|
||||
|
||||
# If this a Container Enabled role, provide the minimum Ansible Container version.
|
||||
# min_ansible_container_version:
|
||||
platforms:
|
||||
- name: Fedora
|
||||
versions:
|
||||
- "40"
|
||||
- name: EL
|
||||
versions:
|
||||
- "10"
|
||||
|
||||
galaxy_tags: []
|
||||
# List tags for your role here, one per line. A tag is a keyword that describes
|
||||
# and categorizes the role. Users find roles by searching for tags. Be sure to
|
||||
# remove the '[]' above, if you add tags to this list.
|
||||
#
|
||||
# NOTE: A tag is limited to a single word comprised of alphanumeric characters.
|
||||
# Maximum 20 tags per role.
|
||||
|
||||
dependencies: []
|
||||
# List your role dependencies here, one per line. Be sure to remove the '[]' above,
|
||||
# if you add dependencies to this list.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,16 @@
|
|||
---
|
||||
|
||||
- name: Install Koji-Builder packages and rpm-build
|
||||
- name: Enable CodeReady Builder (CRB) repository
|
||||
ansible.builtin.command: dnf config-manager --set-enabled crb
|
||||
args:
|
||||
creates: /etc/yum.repos.d/centos-stream-crb.repo
|
||||
|
||||
- name: Install EPEL repository
|
||||
ansible.builtin.dnf:
|
||||
name: epel-release
|
||||
state: present
|
||||
|
||||
- name: Install Koji-Builder packages, rpm-build, and koji CLI
|
||||
ansible.builtin.dnf:
|
||||
name:
|
||||
- koji-builder
|
||||
|
|
@ -8,6 +18,8 @@
|
|||
- rpmdevtools
|
||||
- mock
|
||||
- policycoreutils-python-utils
|
||||
- git
|
||||
- koji
|
||||
state: present
|
||||
|
||||
- name: Create kojid work directory
|
||||
|
|
@ -32,11 +44,12 @@
|
|||
group: mock
|
||||
mode: "2775"
|
||||
|
||||
- name: Configure mock site defaults
|
||||
ansible.builtin.template:
|
||||
src: site-defaults.cfg.j2
|
||||
dest: /etc/mock/site-defaults.cfg
|
||||
- name: Copy mock configuration file
|
||||
ansible.builtin.copy:
|
||||
src: mxos0-build-x86_64.cfg
|
||||
dest: /etc/mock/mxos0-build-x86_64.cfg
|
||||
mode: "0644"
|
||||
notify: restart kojid
|
||||
|
||||
- name: Configure kojid
|
||||
ansible.builtin.template:
|
||||
|
|
@ -77,6 +90,13 @@
|
|||
group: root
|
||||
mode: "0600"
|
||||
|
||||
- name: Configure Koji client on builder
|
||||
ansible.builtin.template:
|
||||
src: roles/koji_hub/templates/koji.conf.j2
|
||||
dest: /etc/koji.conf.d/ansible-settings.conf
|
||||
mode: "0644"
|
||||
|
||||
|
||||
- name: Add hub host to /etc/hosts
|
||||
ansible.builtin.lineinfile:
|
||||
path: /etc/hosts
|
||||
|
|
@ -86,16 +106,11 @@
|
|||
|
||||
- name: Update CA trust
|
||||
ansible.builtin.command: update-ca-trust
|
||||
changed_when: false
|
||||
check_mode: false
|
||||
|
||||
- name: Start and enable kojid service
|
||||
ansible.builtin.service:
|
||||
name: kojid
|
||||
state: started
|
||||
enabled: true
|
||||
|
||||
- name: Add koji hub to /etc/hosts
|
||||
ansible.builtin.lineinfile:
|
||||
path: /etc/hosts
|
||||
line: "{{ hostvars[groups['kojihub'][0]].ansible_default_ipv4.address }} {{ koji_hub_fqdn }}"
|
||||
regexp: ".*{{ koji_hub_fqdn }}"
|
||||
state: present
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
# SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
- hosts: localhost
|
||||
- name: Test kojid role
|
||||
hosts: localhost
|
||||
remote_user: root
|
||||
roles:
|
||||
- roles/kojid
|
||||
- kojid
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#SPDX-License-Identifier: MIT-0
|
||||
# SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
- name: Restart kojira
|
||||
ansible.builtin.service:
|
||||
|
|
|
|||
|
|
@ -1,36 +1,22 @@
|
|||
# SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
galaxy_info:
|
||||
author: your name
|
||||
description: your role description
|
||||
company: your company (optional)
|
||||
author: "Renich Bon Ciric"
|
||||
description: "Koji scheduler"
|
||||
company: "Mx-OS"
|
||||
|
||||
# If the issue tracker for your role is not on github, uncomment the
|
||||
# next line and provide a value
|
||||
# issue_tracker_url: http://example.com/issue/tracker
|
||||
license: "GPL-2.0-or-later"
|
||||
|
||||
# Choose a valid license ID from https://spdx.org - some suggested licenses:
|
||||
# - BSD-3-Clause (default)
|
||||
# - MIT
|
||||
# - GPL-2.0-or-later
|
||||
# - GPL-3.0-only
|
||||
# - Apache-2.0
|
||||
# - CC-BY-4.0
|
||||
license: license (GPL-2.0-or-later, MIT, etc)
|
||||
min_ansible_version: "2.15"
|
||||
|
||||
min_ansible_version: 2.1
|
||||
|
||||
# If this a Container Enabled role, provide the minimum Ansible Container version.
|
||||
# min_ansible_container_version:
|
||||
platforms:
|
||||
- name: Fedora
|
||||
versions:
|
||||
- "40"
|
||||
- name: EL
|
||||
versions:
|
||||
- "10"
|
||||
|
||||
galaxy_tags: []
|
||||
# List tags for your role here, one per line. A tag is a keyword that describes
|
||||
# and categorizes the role. Users find roles by searching for tags. Be sure to
|
||||
# remove the '[]' above, if you add tags to this list.
|
||||
#
|
||||
# NOTE: A tag is limited to a single word comprised of alphanumeric characters.
|
||||
# Maximum 20 tags per role.
|
||||
|
||||
dependencies: []
|
||||
# List your role dependencies here, one per line. Be sure to remove the '[]' above,
|
||||
# if you add dependencies to this list.
|
||||
|
|
|
|||
|
|
@ -1,12 +1,10 @@
|
|||
#SPDX-License-Identifier: MIT-0
|
||||
# SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
- name: Install Koji Utils package (which includes kojira)
|
||||
ansible.builtin.dnf:
|
||||
name: ["koji-utils"]
|
||||
state: present
|
||||
|
||||
|
||||
|
||||
- name: Configure kojira
|
||||
ansible.builtin.template:
|
||||
src: kojira.conf.j2
|
||||
|
|
@ -26,13 +24,13 @@
|
|||
- { src: "kojira.key", dest: "/etc/pki/koji/kojira.key", mode: "0600" }
|
||||
|
||||
- name: "Concatenate certificate and key into a PEM file"
|
||||
ansible.builtin.shell: cat /etc/pki/koji/kojira.crt /etc/pki/koji/kojira.key > /etc/pki/koji/kojira.pem
|
||||
ansible.builtin.shell: cat /etc/pki/koji/kojira.crt /etc/pki/koji/kojira.key > {{ kojira_pem_path }}
|
||||
args:
|
||||
creates: /etc/pki/koji/kojira.pem
|
||||
creates: "{{ kojira_pem_path }}"
|
||||
|
||||
- name: Set permissions on kojira PEM file
|
||||
ansible.builtin.file:
|
||||
path: /etc/pki/koji/kojira.pem
|
||||
path: "{{ kojira_pem_path }}"
|
||||
mode: "0600"
|
||||
|
||||
- name: Start and enable kojira service
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
[kojira]
|
||||
server = https://{{ koji_hub_fqdn }}/kojihub
|
||||
cert = {{ kojira_cert_path }}
|
||||
cert = {{ kojira_pem_path }}
|
||||
serverca = {{ koji_remote_ca_trust_path }}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
# SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
- hosts: localhost
|
||||
- name: Test kojira role
|
||||
hosts: localhost
|
||||
remote_user: root
|
||||
roles:
|
||||
- roles/kojira
|
||||
- kojira
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
# SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
# vars file for roles/kojira
|
||||
|
||||
|
|
|
|||
|
|
@ -1,36 +0,0 @@
|
|||
#SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
galaxy_info:
|
||||
author: your name
|
||||
description: your role description
|
||||
company: your company (optional)
|
||||
|
||||
# If the issue tracker for your role is not on github, uncomment the
|
||||
# next line and provide a value
|
||||
# issue_tracker_url: http://example.com/issue/tracker
|
||||
|
||||
# Choose a valid license ID from https://spdx.org - some suggested licenses:
|
||||
# - BSD-3-Clause (default)
|
||||
# - MIT
|
||||
# - GPL-2.0-or-later
|
||||
# - GPL-3.0-only
|
||||
# - Apache-2.0
|
||||
# - CC-BY-4.0
|
||||
license: license (GPL-2.0-or-later, MIT, etc)
|
||||
|
||||
min_ansible_version: 2.1
|
||||
|
||||
# If this a Container Enabled role, provide the minimum Ansible Container version.
|
||||
# min_ansible_container_version:
|
||||
|
||||
galaxy_tags: []
|
||||
# List tags for your role here, one per line. A tag is a keyword that describes
|
||||
# and categorizes the role. Users find roles by searching for tags. Be sure to
|
||||
# remove the '[]' above, if you add tags to this list.
|
||||
#
|
||||
# NOTE: A tag is limited to a single word comprised of alphanumeric characters.
|
||||
# Maximum 20 tags per role.
|
||||
|
||||
dependencies: []
|
||||
# List your role dependencies here, one per line. Be sure to remove the '[]' above,
|
||||
# if you add dependencies to this list.
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
#SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
- hosts: localhost
|
||||
remote_user: root
|
||||
roles:
|
||||
- roles/nfs-client
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
#SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
- hosts: localhost
|
||||
remote_user: root
|
||||
roles:
|
||||
- roles/nfs-server
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
#SPDX-License-Identifier: MIT-0
|
||||
# SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
# defaults file for roles/nfs-client
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
#SPDX-License-Identifier: MIT-0
|
||||
# SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
# handlers file for roles/nfs-client
|
||||
22
roles/nfs_client/meta/main.yaml
Normal file
22
roles/nfs_client/meta/main.yaml
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
# SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
galaxy_info:
|
||||
author: "Renich Bon Ciric"
|
||||
description: "NFS client"
|
||||
company: "Mx-OS"
|
||||
|
||||
license: "GPL-2.0-or-later"
|
||||
|
||||
min_ansible_version: "2.15"
|
||||
|
||||
platforms:
|
||||
- name: Fedora
|
||||
versions:
|
||||
- "40"
|
||||
- name: EL
|
||||
versions:
|
||||
- "10"
|
||||
|
||||
galaxy_tags: []
|
||||
|
||||
dependencies: []
|
||||
|
|
@ -1,9 +1,13 @@
|
|||
#SPDX-License-Identifier: MIT-0
|
||||
# SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
- name: Install NFS client packages
|
||||
ansible.builtin.dnf:
|
||||
name: nfs-utils
|
||||
ansible.builtin.package:
|
||||
name: "{{ item }}"
|
||||
state: present
|
||||
loop:
|
||||
- nfs-utils
|
||||
- nfs4-acl-tools
|
||||
- policycoreutils-python-utils
|
||||
|
||||
- name: Create mount point directory
|
||||
ansible.builtin.file:
|
||||
|
|
@ -11,12 +15,12 @@
|
|||
state: directory
|
||||
mode: "0755"
|
||||
|
||||
- name: Add kojifs0 to /etc/hosts
|
||||
- name: Add NFS server to /etc/hosts
|
||||
ansible.builtin.lineinfile:
|
||||
path: /etc/hosts
|
||||
line: "{{ hostvars[groups['kojifs'][0]].ansible_default_ipv4.address }} {{ koji_nfs_host }}"
|
||||
create: true
|
||||
state: present
|
||||
mode: "0644"
|
||||
|
||||
- name: Mount the Koji NFS share
|
||||
ansible.posix.mount:
|
||||
|
|
@ -27,10 +31,16 @@
|
|||
state: mounted
|
||||
|
||||
- name: Set SELinux context for Koji NFS mount
|
||||
ansible.builtin.command: semanage fcontext -a -t httpd_sys_rw_content_t "{{ koji_top_dir }}(/.*)?"
|
||||
ansible.builtin.command: semanage fcontext -a -t nfs_t "{{ koji_top_dir }}(/.*)?"
|
||||
changed_when: false
|
||||
check_mode: false
|
||||
|
||||
- name: Apply SELinux context
|
||||
ansible.builtin.command: restorecon -r -v "{{ koji_top_dir }}"
|
||||
ansible.builtin.command: restorecon -R "{{ koji_top_dir }}"
|
||||
changed_when: false
|
||||
check_mode: false
|
||||
|
||||
- name: Flush systemd journal to disk
|
||||
ansible.builtin.command: journalctl --flush
|
||||
changed_when: false
|
||||
check_mode: false
|
||||
7
roles/nfs_client/tests/test.yaml
Normal file
7
roles/nfs_client/tests/test.yaml
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# tests file for nfs_client
|
||||
---
|
||||
- name: Test nfs_client role
|
||||
hosts: localhost
|
||||
remote_user: root
|
||||
roles:
|
||||
- nfs_client
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
#SPDX-License-Identifier: MIT-0
|
||||
# SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
# vars file for roles/nfs-client
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
#SPDX-License-Identifier: MIT-0
|
||||
# SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
# defaults file for roles/nfs-server
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
#SPDX-License-Identifier: MIT-0
|
||||
# SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
- name: Restart nfs-server
|
||||
ansible.builtin.service:
|
||||
22
roles/nfs_server/meta/main.yaml
Normal file
22
roles/nfs_server/meta/main.yaml
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
# SPDX-License-Identifier: MIT-0
|
||||
galaxy_info:
|
||||
author: "Renich Bon Ciric"
|
||||
description: "NFS server"
|
||||
company: "Mx-OS"
|
||||
|
||||
license: "GPL-2.0-or-later"
|
||||
|
||||
min_ansible_version: "2.15"
|
||||
|
||||
platforms:
|
||||
- name: Fedora
|
||||
versions:
|
||||
- "40"
|
||||
- name: EL
|
||||
versions:
|
||||
- "10"
|
||||
|
||||
galaxy_tags: []
|
||||
|
||||
dependencies: []
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
#SPDX-License-Identifier: MIT-0
|
||||
# SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
- name: Install NFS server packages
|
||||
ansible.builtin.dnf:
|
||||
|
|
@ -17,9 +17,9 @@
|
|||
ansible.builtin.lineinfile:
|
||||
path: /etc/hosts
|
||||
line: "{{ hostvars[item].ansible_default_ipv4.address }} {{ item }}"
|
||||
create: true
|
||||
state: present
|
||||
loop: "{{ groups['koji_nodes'] }}"
|
||||
mode: "0644"
|
||||
loop: "{{ groups['all'] }}"
|
||||
|
||||
- name: Configure the NFS export for all Koji nodes
|
||||
ansible.builtin.template:
|
||||
|
|
@ -29,9 +29,11 @@
|
|||
group: root
|
||||
mode: "0644"
|
||||
|
||||
# This command does not provide a reliable way to determine if the NFS exports were changed,
|
||||
# so we run it on every execution.
|
||||
- name: Export all NFS filesystems
|
||||
ansible.builtin.command: exportfs -ra
|
||||
changed_when: true
|
||||
changed_when: false
|
||||
|
||||
- name: Start and enable NFS services
|
||||
ansible.builtin.service:
|
||||
7
roles/nfs_server/tests/test.yaml
Normal file
7
roles/nfs_server/tests/test.yaml
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
- name: Test nfs_server role
|
||||
hosts: localhost
|
||||
remote_user: root
|
||||
roles:
|
||||
- nfs_server
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
#SPDX-License-Identifier: MIT-0
|
||||
# SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
# vars file for roles/nfs-server
|
||||
|
|
@ -1,2 +1,2 @@
|
|||
---
|
||||
koji_db_network: "192.168.122.0/24"
|
||||
postgresql_koji_db_network: 192.168.1.0/24
|
||||
|
|
|
|||
|
|
@ -1,36 +1,22 @@
|
|||
---
|
||||
#SPDX-License-Identifier: MIT-0
|
||||
# SPDX-License-Identifier: MIT-0
|
||||
galaxy_info:
|
||||
author: your name
|
||||
description: your role description
|
||||
company: your company (optional)
|
||||
author: "Renich Bon Ciric"
|
||||
description: "PostgreSQL server"
|
||||
company: "Mx-OS"
|
||||
|
||||
# If the issue tracker for your role is not on github, uncomment the
|
||||
# next line and provide a value
|
||||
# issue_tracker_url: http://example.com/issue/tracker
|
||||
license: "GPL-2.0-or-later"
|
||||
|
||||
# Choose a valid license ID from https://spdx.org - some suggested licenses:
|
||||
# - BSD-3-Clause (default)
|
||||
# - MIT
|
||||
# - GPL-2.0-or-later
|
||||
# - GPL-3.0-only
|
||||
# - Apache-2.0
|
||||
# - CC-BY-4.0
|
||||
license: license (GPL-2.0-or-later, MIT, etc)
|
||||
min_ansible_version: "2.15"
|
||||
|
||||
min_ansible_version: 2.1
|
||||
|
||||
# If this a Container Enabled role, provide the minimum Ansible Container version.
|
||||
# min_ansible_container_version:
|
||||
platforms:
|
||||
- name: Fedora
|
||||
versions:
|
||||
- "40"
|
||||
- name: EL
|
||||
versions:
|
||||
- "10"
|
||||
|
||||
galaxy_tags: []
|
||||
# List tags for your role here, one per line. A tag is a keyword that describes
|
||||
# and categorizes the role. Users find roles by searching for tags. Be sure to
|
||||
# remove the '[]' above, if you add tags to this list.
|
||||
#
|
||||
# NOTE: A tag is limited to a single word comprised of alphanumeric characters.
|
||||
# Maximum 20 tags per role.
|
||||
|
||||
dependencies: []
|
||||
# List your role dependencies here, one per line. Be sure to remove the '[]' above,
|
||||
# if you add dependencies to this list.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#SPDX-License-Identifier: MIT-0
|
||||
# SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
- name: Install PostgreSQL packages
|
||||
ansible.builtin.dnf:
|
||||
|
|
@ -43,34 +43,24 @@
|
|||
state: started
|
||||
enabled: true
|
||||
|
||||
- name: Configure PostgreSQL settings
|
||||
community.postgresql.postgresql_set:
|
||||
name: "{{ item.name }}"
|
||||
value: "{{ item.value }}"
|
||||
- name: Configure PostgreSQL settings for SSL and listening
|
||||
ansible.builtin.lineinfile:
|
||||
path: /var/lib/pgsql/data/postgresql.conf
|
||||
regexp: "^{{ item.regexp }}"
|
||||
line: "{{ item.line }}"
|
||||
state: present
|
||||
backup: true
|
||||
loop:
|
||||
- { name: 'ssl_ca_file', value: 'ca.crt' }
|
||||
- { name: 'ssl', value: 'on' }
|
||||
- { name: 'ssl_cert_file', value: 'server.crt' }
|
||||
- { name: 'ssl_key_file', value: 'server.key' }
|
||||
- { name: 'max_connections', value: '200' }
|
||||
- { name: 'listen_addresses', value: '*' }
|
||||
- { regexp: '#?ssl\\s*=\\s*.*', line: "ssl = on" }
|
||||
- { regexp: '#?ssl_cert_file\\s*=\\s*.*', line: "ssl_cert_file = 'server.crt'" }
|
||||
- { regexp: '#?ssl_key_file\\s*=\\s*.*', line: "ssl_key_file = 'server.key'" }
|
||||
- { regexp: '#?ssl_ca_file\\s*=\\s*.*', line: "ssl_ca_file = 'ca.crt'" }
|
||||
- { regexp: '#?listen_addresses\\s*=\\s*.*', line: "listen_addresses = '*'" }
|
||||
- { regexp: '#?max_connections\\s*=\\s*.*', line: "max_connections = 200" }
|
||||
become: true
|
||||
become_user: postgres
|
||||
notify: Restart postgresql
|
||||
|
||||
|
||||
|
||||
- name: Remove old pg_hba.conf entry for Koji hub (IPv4 network)
|
||||
community.postgresql.postgresql_pg_hba:
|
||||
dest: /var/lib/pgsql/data/pg_hba.conf
|
||||
contype: hostssl
|
||||
databases: "{{ koji_db_name }}"
|
||||
users: "{{ koji_db_user }}"
|
||||
address: "{{ koji_db_network }}"
|
||||
method: scram-sha-256
|
||||
state: absent
|
||||
notify: Restart postgresql
|
||||
|
||||
- name: Configure pg_hba.conf to allow connection from the Koji hub (IPv4 address)
|
||||
community.postgresql.postgresql_pg_hba:
|
||||
dest: /var/lib/pgsql/data/pg_hba.conf
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#SPDX-License-Identifier: MIT-0
|
||||
# SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
- hosts: localhost
|
||||
- name: Test postgresql role
|
||||
hosts: localhost
|
||||
remote_user: root
|
||||
roles:
|
||||
- roles/postgresql
|
||||
- postgresql
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
#SPDX-License-Identifier: MIT-0
|
||||
# SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
# vars file for roles/postgresql
|
||||
|
|
|
|||
|
|
@ -1,20 +1,18 @@
|
|||
$ANSIBLE_VAULT;1.1;AES256
|
||||
34666536376534346332353761373632616231633137393735323834323935373338353439316366
|
||||
3233633036366138356563323737646365313137386135620a643663623866613162303134663836
|
||||
61336336333334393362653436653636313230386364343065643133376436343765373366626139
|
||||
3436636136353136620a663363633637323064316566356133353836643338303433356661386334
|
||||
33383432396463373738343831316661376132336332313764643666353136623639306139373036
|
||||
34373661633365336163393436633931643661643930396361666561383639373639333361366434
|
||||
61326137323666663663386262373638613532333761393166396461616361326666353638316437
|
||||
31663737363966376333303333643563306139663339313239343263346231643261393739303238
|
||||
30373865393830643631656463373732613032326165366338613362366439326435343632343636
|
||||
36353962316565313330363763636466356238396164393436643537386464363439336230353838
|
||||
66383766316435373130313835336531383438636235383534633337653536626635626165376533
|
||||
33343935656635306336666263373136303530396161363164363365646531343830636264626666
|
||||
37633438623463306466353966343261383934366236396433343139386461336536656561366165
|
||||
37383963626162653138653866303731653434303266353138616162636232376134363533383763
|
||||
66393034636432383966633535386161646430653265623464653264633439666363313062363232
|
||||
35653263366461336439306537393533396333646166333263376233366332393865633839316537
|
||||
36656337356561313234346633626435396138353862393266356436376636653137356665623865
|
||||
35316337393464353364626138653966633932316561623763323037313530656435343465386264
|
||||
663835356535363635633730633236386431
|
||||
32363236643164663830326362396363616430386434303237613039313030616463636432376266
|
||||
6134646466626634366538323639346464393432633063350a666366326630316563363033336366
|
||||
61356438376265663161616164333138363132336630396432376530333535306361643239646461
|
||||
3635616265376363390a326131346132336366663836653639623361353236363430393965303333
|
||||
66613762306430653431396339366263356261393764623462376235653463343962323732623933
|
||||
38666366303238303364386363393133343361393565636562623235636535653932623263323133
|
||||
35383537323063613537616439643866373164353932343837643166323838666439373462633865
|
||||
30323861653334306430363765646361353231353030613661396435643738316263306233656231
|
||||
64306431383032366539396263356461633432373535633133666265373231643637343732626362
|
||||
30343833643666343131666632323737323465393662346238623231356532613461306630616630
|
||||
30336638656338323130393832316535613838373665656461363864646361313964333831356536
|
||||
37373661396463646432326138393537366233656664353134653933613239623364336661363939
|
||||
30656539623663653333383535383564643334383632306162393737626130346637656537333930
|
||||
62366464663539393835663438383162336130373862316565373365383531366264663934643466
|
||||
30336631656663633263643431363864613232393334376461303731393662316537636462383830
|
||||
31656536613534623230613362663664326533393464623336653363303335333962353332633733
|
||||
3161
|
||||
|
|
|
|||
|
|
@ -17,12 +17,14 @@ koji_top_dir: /mnt/koji
|
|||
koji_pki_dir: "{{ playbook_dir }}/certs"
|
||||
kojid_work_dir: /var/lib/kojid
|
||||
koji_remote_pki_dir: /etc/pki/koji
|
||||
koji_hub_config_dir: /etc/koji-hub/hub.conf.d
|
||||
koji_web_config_dir: /etc/kojiweb
|
||||
koji_client_config_file: /etc/koji.conf.d/ansible-settings.conf
|
||||
koji_hub_config_dir: /etc/koji_hub/hub.conf.d
|
||||
koji_hub_koji_web_config_dir: /etc/kojiweb
|
||||
koji_hub_koji_client_config_file: /etc/koji.conf.d/ansible-settings.conf
|
||||
koji_remote_kojira_conf_path: /etc/kojira/kojira.conf
|
||||
koji_remote_kojihub_httpd_conf_path: /etc/httpd/conf.d/kojihub.conf
|
||||
koji_remote_kojiweb_httpd_conf_path: /etc/httpd/conf.d/kojiweb.conf
|
||||
koji_hub_admin_user_home: "/home/{{ koji_admin_user }}"
|
||||
koji_hub_admin_user_koji_dir: "{{ koji_hub_admin_user_home }}/.koji"
|
||||
|
||||
# Certificate Paths (Remote)
|
||||
koji_hub_cert_path: /etc/pki/koji/kojihub.crt
|
||||
|
|
@ -32,7 +34,7 @@ koji_admin_key_path: /etc/pki/koji/kojiadmin.key
|
|||
kojid_crt_path: /etc/pki/koji/kojid.crt
|
||||
kojid_key_path: /etc/pki/koji/kojid.key
|
||||
kojid_pem_path: /etc/pki/koji/kojid.pem
|
||||
kojira_cert_path: /etc/pki/koji/kojira.pem
|
||||
kojira_pem_path: /etc/pki/koji/kojira.pem
|
||||
koji_remote_ca_trust_path: /etc/pki/ca-trust/source/anchors/koji_ca.crt
|
||||
|
||||
# Certificate Settings
|
||||
|
|
@ -46,7 +48,7 @@ koji_cert_organization: "MxOS"
|
|||
koji_cert_organizational_unit: "Infraestructura"
|
||||
|
||||
# Certificate Generation List
|
||||
koji_certs_to_generate:
|
||||
common_koji_certs_to_generate:
|
||||
- name: kojihub
|
||||
cn: "{{ koji_hub_fqdn }}"
|
||||
is_user: false
|
||||
|
|
@ -82,13 +84,18 @@ kojid_mock_user: kojid
|
|||
kojid_vendor: Fundación MxOS
|
||||
kojid_packager: Koji
|
||||
kojid_distribution: MxOS
|
||||
kojid_allowed_scms: git.mx-os.mx:/MxOS/rpms/*
|
||||
kojid_allowed_scms: git.mx-os.mx:/RPMs/*
|
||||
kojid_allowed_scms_use_config: true
|
||||
kojid_allowed_scms_use_policy: false
|
||||
kojid_smtp_host: mail.mx-os.mx
|
||||
kojid_smtp_user: kojid@cs10-koji-03.mx-os
|
||||
kojid_from_addr: Koji Build System <kojid@cs10-koji-03.mx-os>
|
||||
kojid_mock_root: /var/lib/mock/mxos0-build-x86_64
|
||||
|
||||
# HTTPD/Web Paths
|
||||
httpd_ssl_config_file: /etc/httpd/conf.d/ssl.conf
|
||||
koji_hub_httpd_config_file: /etc/httpd/conf.d/kojihub.conf
|
||||
koji_hub_httpd_ssl_config_file: /etc/httpd/conf.d/ssl.conf
|
||||
koji_cleanup_script_path: /usr/local/bin/koji_cleanup.sh
|
||||
koji_cleanup_service_path: /etc/systemd/system/koji-cleanup.service
|
||||
koji_cleanup_timer_path: /etc/systemd/system/koji-cleanup.timer
|
||||
koji_callbacks_script_path: /usr/local/bin/koji_callbacks.py
|
||||
koji_callbacks_config_path: /etc/koji_hub/hub.conf.d/callbacks.conf
|
||||
|
|
|
|||
Loading…
Reference in a new issue