Files
jenkins-server/README.md
T
aagusfernandez02 748704317b feat: jenkins server
2026-07-01 08:13:57 -03:00

226 lines
6.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Jenkins SCO — Deploy Server
Jenkins centralizado para el despliegue de software en terminales SCO (Self-Checkout) en producción.
## Estructura del repositorio
```
.
├── docker-compose.yml
└── data/
└── jenkins/
├── Dockerfile # Imagen Jenkins con plugins
├── jenkins.yaml # Configuración JCasC (nodos, seguridad, jobs)
├── deploy/
│ └── install.sh # Script desplegado en cada SCO
└── pipelines/
└── Jenkinsfile.ralph # Pipeline del cliente Ralph
```
## Arquitectura
- **Jenkins master**: corre en Docker en el servidor Minio (`186.67.82.140`).
- **Agentes (SCOs)**: cada terminal SCO conecta al master vía JNLP (puerto 50000). El proceso del agente corre como `root`.
- **Storage**: Minio almacena el software de cada cliente en buckets separados (ej: bucket `ralph`).
### Labels de agentes
Formato: `sco <cliente> <tienda>`
| Cliente | Tienda | Agentes |
|---|---|---|
| ralph | yabucoa | sco02sco07 |
| ralph | san-lorenzo | sco03sco06 |
| ralph | rio-grande | sco01sco06 |
## Levantar el servidor
```sh
docker compose up -d --build
```
Jenkins queda disponible en `http://<server-ip>:8080` (admin / H0l4mund0!).
## Conectar un agente SCO
1. Descargar el agente desde Jenkins:
```sh
curl -sO http://<server-ip>:8080/jnlpJars/agent.jar
mv agent.jar /opt/jenkins-agent/agent.jar
```
2. Obtener el secret del nodo: en Jenkins → *Manage Jenkins → Nodes → (nombre del nodo)*.
3. Crear el servicio systemd en el SCO:
```ini
# /etc/systemd/system/jenkins-agent.service
[Unit]
Description=Jenkins Agent
After=network.target
[Service]
User=root
ExecStart=/usr/bin/java -jar /opt/jenkins-agent/agent.jar \
-url http://<server-ip>:8080/ \
-secret <SECRET> \
-name "<nombre-del-nodo>" \
-workDir "/opt/jenkins-agent"
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
```
4. Habilitar y arrancar:
```sh
systemctl daemon-reload
systemctl enable --now jenkins-agent
```
## Ejecutar un deploy
1. En Jenkins, abrir el job `deploy-ralph`.
2. Click en **Build with Parameters**.
3. Seleccionar la **tienda** destino en el dropdown (yabucoa / san-lorenzo / rio-grande).
4. El pipeline despliega `install.sh ralph` en paralelo en todos los SCOs online de esa tienda.
## Qué hace `install.sh`
Recibe el nombre del cliente como argumento (`$1`):
1. Genera config de rclone apuntando al Minio local.
2. Sincroniza el bucket `$CUSTOMER` desde Minio hacia `/opt/sco/` en el SCO (excluyendo datos persistentes del backend).
3. Ajusta permisos en `/opt/sco/`.
4. Instala servicios systemd desde `/opt/sco/resources/services/`.
5. Configura autostart del usuario `sco`.
6. Instala crontabs de `root` y `sco`.
7. Instala paquetes Python offline.
8. Carga imágenes Docker.
9. Inicializa carpetas y archivos de base de datos del cpi-server.
10. Genera `engine.properties` para SymmetricDS (solo en primera instalación).
## Operaciones de mantenimiento
### Agregar un nuevo cliente
El deploy es idéntico para todos los clientes: el `install.sh` recibe el nombre del cliente como `$1`.
Solo cambia el nombre del job, el Jenkinsfile, y los nodos registrados.
**1. Registrar los nodos en `data/jenkins/jenkins.yaml`**
Bajo la clave `nodes`, añadir un bloque por cada SCO del cliente:
```yaml
- permanent:
name: "nuevocliente-tienda1-sco01"
labelString: "sco nuevocliente tienda1"
remoteFS: "/opt/jenkins-agent"
numExecutors: 1
retentionStrategy: "always"
launcher:
inbound: {}
```
Repetir para cada combinación tienda/SCO. Convención de nombres:
- Nombre del nodo: `<cliente>-<tienda>-<sco>` (ej: `ralph-yabucoa-sco02`)
- Label: `sco <cliente> <tienda>` (ej: `sco ralph yabucoa`)
**2. Crear el Jenkinsfile en `data/jenkins/pipelines/Jenkinsfile.<cliente>`**
Copiar `Jenkinsfile.ralph` y ajustar dos cosas:
```groovy
// En parameters: listar las tiendas del nuevo cliente
choices: ['tienda1', 'tienda2', 'tienda3'],
// En el stage Deploy: cambiar el nombre del cliente (dos lugares)
def labelExpr = "nuevocliente && ${params.TIENDA}"
sh "bash install.sh 'nuevocliente'"
```
**3. Agregar el job en `data/jenkins/jenkins.yaml`**
Al final de la sección `jobs`:
```yaml
- script: |
pipelineJob('deploy-nuevocliente') {
description('Deploy de install.sh a los SCOs de NuevoCliente.')
definition {
cps {
script(new File('/opt/jenkins/Jenkinsfile.nuevocliente').text)
sandbox(true)
}
}
}
```
**4. Montar el Jenkinsfile en `docker-compose.yml`**
```yaml
volumes:
- ./data/jenkins/pipelines/Jenkinsfile.nuevocliente:/opt/jenkins/Jenkinsfile.nuevocliente:ro
```
**5. Recrear el contenedor**
```sh
docker compose up -d --build
```
En el servidor remoto:
```sh
# Copiar los archivos modificados al servidor primero, luego:
docker compose up -d --build
```
---
### Agregar una tienda a un cliente existente
**1. Añadir los nodos de la nueva tienda en `jenkins.yaml`** (un bloque por SCO, igual que arriba).
**2. Agregar la tienda al dropdown del Jenkinsfile del cliente:**
```groovy
choices: ['yabucoa', 'san-lorenzo', 'rio-grande', 'nueva-tienda'],
```
**3. Aplicar en el servidor:**
```sh
docker compose restart jenkins
```
No hace falta rebuild completo si solo cambia `jenkins.yaml` o el Jenkinsfile — el contenedor los monta como volúmenes y JCasC los recarga.
> Si agregaste nodos nuevos pero no reiniciaste Jenkins, también podés recargar desde la UI: *Manage Jenkins → Configuration as Code → Reload existing configuration*.
---
### Agregar un SCO a una tienda existente
Solo tocar `jenkins.yaml`: añadir el nodo nuevo bajo `nodes`.
```yaml
- permanent:
name: "ralph-yabucoa-sco08"
labelString: "sco ralph yabucoa"
remoteFS: "/opt/jenkins-agent"
numExecutors: 1
retentionStrategy: "always"
launcher:
inbound: {}
```
Luego recargar la configuración:
```sh
docker compose restart jenkins
# o desde la UI: Manage Jenkins → Configuration as Code → Reload existing configuration
```
Una vez que Jenkins lo reconoce, conectar el agente en el SCO físico (ver sección "Conectar un agente SCO").