patchcenter/migrate_patching_notes_20260507.sql
Admin MPCZ 90444c0c56 feat(patching): particularites par serveur (notes wiki SANEF) + skip_first_reboot + reboot_delay cluster
Migration migrate_patching_notes_20260507.sql:
- servers.skip_first_reboot boolean (TPV1: vptraatpf1/2 a true)
- servers.patching_notes text (markdown — meme operateur)
- server_clusters.reboot_delay_min_minutes int default 0
- Backfill patching_notes pour 22 cas particuliers du wiki SANEF:
  ASM Oracle (~50 hosts kernel*), TPV1, HAproxy FL, Covoiturage,
  SI Patrimoine (vrpatbsip1 avant vrpataels1, kibana, certs),
  Talend, Scoop (Debian apt-mark hold + CentOS containers Docker),
  DATI (pm2/tomcat post-reboot), COMMVAULT (mode maintenance),
  Masterparc (kmeihm pm2), Splunk (RPM special),
  Site institutionnel (HAproxy backend rotation, no *node*),
  Centreon (1 par 1 + check centengine), Sextan (10min reboot delay),
  OCTAN, PAIPOR (site maintenance), Gaspar, Postgres, Oracle OEM, SMTP relay
- Cluster Sextan cree (10 min entre reboots) + 10 serveurs Sextan rattaches

UI iexec:
- Banner cumule en haut: '⚠ Particularites pour N serveur(s)' si au moins 1 note
- Badges sur la cellule asset_name: ⚠ note (modal markdown au clic),
  ⏭ skip 1st reboot, ⏱ Xmin (cluster reboot delay)
- Modal patching_notes avec rendu pre/markdown, fermeture Escape

UI fiche serveur (server_detail.html):
- Ligne 'Skip 1er reboot' dans bloc Patching
- Bandeau orange particularites avec contenu patching_notes si renseigne

Pas encore implemente cote logique d'execution (Phase 2):
- skip_first_reboot logic dans le step reboot
- enforcement reboot_delay_min_minutes entre membres cluster
- Pour l'instant: notes affichees en mode 'memo operateur' uniquement
2026-05-07 11:41:05 +02:00

318 lines
13 KiB
SQL

-- Migration : particularités patching extraites du wiki SANEF "Procédures cas spécifiques"
-- - servers.skip_first_reboot : boolean (default false) — saute le 1er reboot post-patch
-- - servers.patching_notes : text — mémo opérateur (markdown), affiché dans iexec
-- - server_clusters.reboot_delay_min_minutes : int default 0 — délai minimum entre reboots de membres
-- Idempotent.
-- Source : DokuWiki SANEF "Procédures de mises à jour Linux cas spécifiques"
-- ─── 1) Nouvelles colonnes ────────────────────────────────────
ALTER TABLE public.servers
ADD COLUMN IF NOT EXISTS skip_first_reboot boolean NOT NULL DEFAULT false,
ADD COLUMN IF NOT EXISTS patching_notes text;
ALTER TABLE public.server_clusters
ADD COLUMN IF NOT EXISTS reboot_delay_min_minutes integer NOT NULL DEFAULT 0;
-- ─── 2) skip_first_reboot — TPV1 (info JFCRABS) ──────────────
UPDATE public.servers SET skip_first_reboot = true
WHERE LOWER(hostname::text) IN ('vptraatpf1', 'vptraatpf2');
-- ─── 3) Backfill patching_notes par groupe applicatif ────────
-- ASM stockage : exclude kernel* déjà fait, on ajoute un mémo sur la procédure grubby
UPDATE public.servers SET patching_notes =
$mn$**ASM Oracle stockage** kernel* exclu (kmod-redhat-oracleasm doit suivre la version d'ASM).
Post-MAJ : vérifier le kernel par défaut avec `sudo grubby --info=ALL`.
Si le nouveau kernel a été installé, remettre l'ancien comme kernel de boot par défaut :
`sudo grubby --set-default /boot/vmlinuz-<ancien_kernel>`
Si apparition de `kmod-redhat-oracleasm-kernel_<version>` : exclure le kernel à la prochaine MAJ.$mn$
WHERE LOWER(hostname::text) IN (
'lamarrac1','lamarrac2','lamarrac3','lamarrac4',
'srdsibora1','srdsibora2','lptrabgas1',
'lragtbpla1','lpaiigrid1',
'lamaprac1','lamaprac2','lamaprac3','lamaprac4',
'lampadp1','lampadp2','lampadv1','lampasu1','lampasu2',
'lampcrm1','lampdec1','lampfin1','lampfin3','lampoct1','lamppea1',
'lamppla1','lamppla2','lamrsip1','lamrsip2','lamtinf1','lamtpfe1',
'lpagtbpla1','lpemvbaemv1','lpemvbpemv1','lpemvbpemv2',
'lpsimbpfe1','lraiibora1','lremvbremv1','lremvbremv2',
'rmila150','rmilgmo3','rmilsas1',
'rsmiged1','rsmigmo1','rsmipat1','rsmisar2',
'srtrabgas1','vpemvgrid1','vpnapamed1'
);
-- TPV1 — pas de 1er reboot
UPDATE public.servers SET patching_notes =
$mn$**TPV1 pas de premier reboot pour les pf** (info JFCRABS).
`skip_first_reboot=true` est positionné, le workflow iexec saute automatiquement le 1er reboot.$mn$
WHERE LOWER(hostname::text) IN ('vptraatpf1', 'vptraatpf2');
-- HAproxy FL
UPDATE public.servers SET patching_notes =
$mn$**HAproxy Flux Libre** exclusions du domaine Flux Libre s'appliquent
(`*podman* run* *container* *sdcss-kmod*` uniquement).$mn$
WHERE LOWER(hostname::text) IN ('vrpeahbst1','vppeahbst1','vipeahbst1');
-- Covoiturage
UPDATE public.servers SET patching_notes =
$mn$**Covoiturage** — services métier ne se relancent pas automatiquement.
Post-reboot :
```bash
systemctl restart covoit*
systemctl start covoit-load # si non démarré
```$mn$
WHERE LOWER(hostname::text) = 'vppeaaphov1';
-- SI Patrimoine 1.0 - sipat (vrpatbsip1)
UPDATE public.servers SET patching_notes =
$mn$**SI Patrimoine** — patcher CE SERVEUR AVANT vrpataels1 (sipat doit être arrêté).
Pre-patch :
```bash
sudo su - sipat -c "/applis/sipat/stop.bash"
# Commenter dans crontab user sipat :
# * * * * * /applis/sipat/start.bash sipat &>/dev/null
```
Post-patch : redémarrer, vérifier que sipat n'est PAS lancé, puis patcher vrpataels1.
Après vrpataels1 OK : décommenter crontab + redémarrer.$mn$
WHERE LOWER(hostname::text) = 'vrpatbsip1';
UPDATE public.servers SET patching_notes =
$mn$**SI Patrimoine Elasticsearch** patcher APRÈS vrpatbsip1 (sipat arrêté).
Post-patch : vérifier que Elasticsearch est toujours fonctionnel.
Vérifier présence des certificats CA recette dans `/usr/lib/jvm/java/lib/security/cacerts` :
```bash
keytool -list -keystore /usr/lib/jvm/java/lib/security/cacerts | grep -i recette
```
Doit afficher `acdistributionrecette` et `acracinerecette`. Sinon importer via `/etc/pki/ca-trust/source/anchors/recette-ac.pem` puis `sudo update-ca-trust`.$mn$
WHERE LOWER(hostname::text) = 'vrpataels1';
UPDATE public.servers SET patching_notes =
$mn$**SI Patrimoine Kibana** *kibana* déjà dans la base d'exclusions globale, rien à faire.$mn$
WHERE LOWER(hostname::text) = 'vppatakib1';
-- Talend
UPDATE public.servers SET patching_notes =
$mn$**Talend** — relancer Talend depuis l'utilisateur Talend en passant par le compte root.$mn$
WHERE LOWER(hostname::text) = 'vdechatal1';
-- Scoop (Debian — hors yum)
UPDATE public.servers SET patching_notes =
$mn$**Scoop Debian** HORS workflow yum standard. Utilise `apt-mark hold` :
```bash
sudo apt-mark hold *mongodb* *sql* *postgres* *mariadb* *oracle* *centreon* *pgdg* *php* *java* *containers* *docker* *qwserver* *ansible* *node* *tomcat* *jupyter*
sudo apt-get update && sudo apt-get upgrade
sudo apt-mark unhold *mongodb* *sql* *postgres* *mariadb* *oracle* *centreon* *pgdg* *php* *java* *containers* *docker* *qwserver* *ansible* *node* *tomcat* *jupyter*
```
vrscobpf1 : post-reboot, java/scoop-ptf nécessite connexion compte `scoop` :
```bash
sudo su -l scoop
sudo systemctl status scoop-ptf
```$mn$
WHERE LOWER(hostname::text) IN ('vrscobpf1','vrscouevs1');
-- Scoop CentOS (vpscoav2x1)
UPDATE public.servers SET patching_notes =
$mn$**Scoop CentOS** arrêter les containers Docker AVANT le patch :
```bash
sudo docker container ls # lister
sudo docker container stop <ID1> <ID2> ... # arrêter
# patch yum normal (avec exclude *containers*)
sudo docker container start <ID1> <ID2> ... # redémarrer
```
Pour vrscoav2x1 : laisser IP forwarding activé (`net.ipv4.ip_forward = 1`) sinon métier KO.$mn$
WHERE LOWER(hostname::text) = 'vpscoav2x1';
-- DATI - composants pm2/tomcat
UPDATE public.servers SET patching_notes =
$mn$**DATI composant FrontalIP (node/pm2)** métier non auto post-reboot :
```bash
sudo su - node -c "pm2 start /applis/frontal-ip/frontal.js -i 2"
```$mn$
WHERE LOWER(hostname::text) IN ('vrexpadat3','vpexpadat3');
UPDATE public.servers SET patching_notes =
$mn$**DATI Tomcat** métier non auto post-reboot :
```bash
sudo su - tomcat -c "/applis/tomcat/bin/catalina.sh start"
```$mn$
WHERE LOWER(hostname::text) IN ('vpexpadat1','vpexpadat2');
-- COMMVAULT
UPDATE public.servers SET patching_notes =
$mn$**COMMVAULT** pré-patch obligatoire :
1. Mettre le serveur en mode maintenance dans la console Commvault.
2. Suspendre les jobs qui utilisent le media agent à patcher.
Vérifier post-patch que les jobs reprennent correctement avant de désactiver le mode maintenance.$mn$
WHERE LOWER(hostname::text) IN (
'spbckamag1','spbckamag2','spbckamag3','spbckamag4',
'spbckamag5','spbckamag6','spbckamag7','spbckamag8',
'spbckmmag1','spbckmmag2'
);
-- Masterparc
UPDATE public.servers SET patching_notes =
$mn$**Masterparc kmeihm via pm2** relance manuelle si non auto :
```bash
sudo su - root -c "/usr/local/bin/pm2 list"
sudo su - root -c "/usr/local/bin/pm2 start 'cd /applis/kme/kmeihm ; node ./app.js' --name kmeihm"
sudo su - root -c "/usr/local/bin/pm2 show kmeihm"
```$mn$
WHERE LOWER(hostname::text) = 'vrtrabkme1';
-- SPLUNK
UPDATE public.servers SET patching_notes =
$mn$**Splunk Enterprise** procédure RPM spéciale, NE PAS patcher avec workflow yum standard.
Cf wiki SANEF section "SPLUNK" :
1. `sudo /applis/splunk/bin/splunk stop`
2. `sudo cp -r /applis/splunk/ /applis/splunk-avant-maj` (rollback)
3. `sudo rpm -U --prefix=/applis /root/splunk-X.Y.Z.x86_64.rpm`
4. `sudo /applis/splunk/bin/splunk start` + accepter licence + migration config$mn$
WHERE LOWER(hostname::text) IN ('spsecalog1','spemvalog1');
-- Site institutionnel HAproxy + backends
UPDATE public.servers SET patching_notes =
$mn$**Site institutionnel HAproxy + backends www.sanef.com**
Pré-patch obligatoire : rotation des backends dans `/etc/haproxy/haproxy.cfg` sur vpintaprx2.
Avant de patcher vpintaweb2 : commenter `app1 192.168.20.36:80` (vpintaweb2)
Avant de patcher vpintaweb3 : commenter `app2 192.168.20.37:80` (vpintaweb3)
Test config + reload après chaque modif :
```bash
sudo haproxy -f /etc/haproxy/haproxy.cfg -c
sudo systemctl restart haproxy.service
```
Post-patch : faire valider le métier par RA Arnaud Meillon / Bertrand Letendard avant de réactiver les 2 backends.
Ne pas MAJ les paquets `*node*` (déjà dans la base d'exclusions).$mn$
WHERE LOWER(hostname::text) IN ('vpintaprx2','vpintaweb2','vpintaweb3');
-- Centreon polleurs
UPDATE public.servers SET patching_notes =
$mn$**Centreon — patcher 1 serveur à la fois et valider avant le suivant.**
Post-reboot : vérifier services :
```bash
sudo systemctl status centengine
sudo systemctl status centreontrapd # seulement s'il existe
```
Démarrer manuellement si non actifs.$mn$
WHERE LOWER(hostname::text) IN (
'vpaiiapol1','vpaiiapol2','vpaiiapol3','vpaiiapol4','vpaiiapol5',
'vpaiiapol6','vpaiiapol7','vpaiiapol9','vpaiiapol10'
);
-- Sextan
UPDATE public.servers SET patching_notes =
$mn$**Sextan** vérifier IP forwarding (`sysctl net.ipv4.ip_forward` doit être 1).
Si à 0 : éditer `/etc/sysctl.conf`, mettre `net.ipv4.ip_forward=1` puis `sudo sysctl -p /etc/sysctl.conf`.
ATTENTION : espacer les reboots de minimum 10 min entre chaque serveur Sextan (sinon perte de données). Le cluster Sextan a `reboot_delay_min_minutes=10`.$mn$
WHERE LOWER(hostname::text) IN (
'vdameasxt1','vdameasxt2','vdameasxt3','vdameasxt4',
'vrameahtp1','vrameahtp2',
'vrameasxt1','vrameasxt2','vrameasxt3','vrameasxt4'
);
-- OCTAN - vrameaoct1
UPDATE public.servers SET patching_notes =
$mn$**OCTAN applis ne se relancent pas auto post-reboot** :
```bash
sudo su - tomcat -c 'pm2 start /applis/decisionnelpeage/backend/index.js --name backend'
sudo /bin/bash /applis/base-recette/octan-edition-4.8/bin/catalina.sh start &
sudo /bin/bash /applis/base-recette/octan-services/bin/control.sh start &
sudo /bin/bash /applis/base-recette/octan-services-a150/bin/run.sh start &
sudo /bin/bash /applis/base-qualif/octan-edition-4.8/bin/catalina.sh start &
sudo /bin/bash /applis/base-qualif/octan-services/bin/control.sh start &
```$mn$
WHERE LOWER(hostname::text) = 'vrameaoct1';
-- PAIPOR
UPDATE public.servers SET patching_notes =
$mn$**PAIPOR** pré-patch : mettre site en maintenance.
Sur vpcliabosp1, éditer `/applis/sanef/forsAccess.override.json` :
```json
"sanef": { "maintenanceEspaceClient": true, ... }
```
Post-patch : remettre `false`.
Ne pas MAJ `python2-certbot` ni `*certbot*` (déjà dans base exclusions).$mn$
WHERE LOWER(hostname::text) = 'vpsimapai1';
-- Gaspar
UPDATE public.servers SET patching_notes =
$mn$**Gaspar** applis Java non auto post-reboot. Relance manuelle Tomcat (cf wiki).$mn$
WHERE LOWER(hostname::text) = 'vrtraagas1';
-- Postgres BDD
UPDATE public.servers SET patching_notes =
$mn$**Postgres** service ne se lance pas automatiquement post-reboot :
```bash
sudo systemctl start postgres*
```
Pour vraiibpgs3 (réplication de vraiibpgs2) : si problème, demander à Nadine BENARD de redémarrer le métier.$mn$
WHERE LOWER(hostname::text) IN ('vraiibpgs1','vraiibpgs2','vraiibpgs3');
-- Oracle OEM
UPDATE public.servers SET patching_notes =
$mn$**Oracle OEM** relancer la couche OMS manuellement post-reboot, en utilisateur `oracle` :
```bash
/applis/oracle/oem/middleware134/bin/emctl start oms
```$mn$
WHERE LOWER(hostname::text) = 'lpaiigrid1';
-- SMTP Relay
UPDATE public.servers SET patching_notes =
$mn$**SMTP Relay** post-reboot, vérifier services :
```bash
systemctl status postfix
systemctl status keepalived
```
Lancer le check_smtp et confirmer la réception du mail à Joel CAVE :
```bash
cd /usr/local/bin && ./check_smtp.sh
```$mn$
WHERE LOWER(hostname::text) IN ('vpdsismtp1','vpdsismtp2');
-- ─── 4) reboot_delay_min_minutes sur cluster Sextan ──────────
-- Création du cluster Sextan s'il n'existe pas (idempotent via ON CONFLICT)
INSERT INTO public.server_clusters (name, description, reboot_strategy, reboot_delay_min_minutes)
VALUES ('Sextan', 'Cluster Sextan — espacer les reboots de 10 min minimum (perte données sinon)',
'sequential', 10)
ON CONFLICT (name) DO UPDATE
SET reboot_delay_min_minutes = 10,
description = EXCLUDED.description;
-- Rattache les serveurs Sextan au cluster
UPDATE public.servers s
SET cluster_id = (SELECT id FROM server_clusters WHERE name='Sextan')
WHERE LOWER(s.hostname::text) IN (
'vdameasxt1','vdameasxt2','vdameasxt3','vdameasxt4',
'vrameahtp1','vrameahtp2',
'vrameasxt1','vrameasxt2','vrameasxt3','vrameasxt4'
);