feat(deploy): install silencieuse (dashboard) + MAJ GPO clients Léa + procédure Julien — 2026-07-06
Deux canaux de déploiement des clients Léa, en s'appuyant sur l'installeur EXE
v1.0.2 existant (per-user, upgrade-safe, mode /VERYSILENT /CONFIG=).
- Route dashboard `GET /api/fleet/installer` (web_dashboard/app.py, insertion pure,
125 lignes, 0 suppression) : sert un ZIP {EXE + install_silencieux.bat + enroll.txt
(SERVER_URL/token injectés via _resolve_public_server_url) + LISEZMOI} pour un poste
NEUF. L'EXE génère lui-même le machine_id → pas de pré-enregistrement (distinct de
la voie ZIP download_agent_package). Tri EXE en semver (1.0.10 > 1.0.2). Testée e2e.
- deploy/installer/silent/ : lanceur d'install silencieuse + gabarit enroll + notice.
- deploy/gpo/Deploy-LeaUpdate.ps1 : MAJ upgrade-safe via GPO **logon script user-context**
(install per-user invisible au contexte SYSTEM). Détection version = **DisplayVersion
du registre HKCU** (primaire pour install EXE ; le config.txt EXE ne porte PAS la
version — vérifié sur poste réel), fallback RPA_AGENT_VERSION (installs ZIP).
Comparaison semver, idempotent, journalisation best-effort silencieuse, non bloquant
à l'ouverture de session. Options -DryRun / -TargetVersionOverride / -LogShareOverride.
**Validé sur poste réel .11 (Windows PowerShell 5.1)** : branche « déjà à jour » et
branche « MAJ requise » (DryRun, 0 install), détection = 1.0.2.
- docs/PROCEDURE_DEPLOIEMENT_LEA_JULIEN.md : procédure (poste neuf / MAJ manuelle / GPO / rollback).
- EXE binaire jamais versionné (deploy/installer/releases/.gitignore).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
181
deploy/gpo/Deploy-LeaUpdate.ps1
Normal file
181
deploy/gpo/Deploy-LeaUpdate.ps1
Normal file
@@ -0,0 +1,181 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Met a jour l'agent Lea (installe per-user) via un script d'OUVERTURE DE SESSION GPO.
|
||||
|
||||
.DESCRIPTION
|
||||
============================================================================
|
||||
A DEPLOYER EN : User Configuration > Policies > Windows Settings >
|
||||
Scripts (Logon/Logoff) > Logon.
|
||||
ET PAS EN "Computer > Startup".
|
||||
============================================================================
|
||||
RAISON (non negociable) : l'installeur Lea est PER-USER
|
||||
(%LOCALAPPDATA%\Programs\Lea, cle de desinstallation sous HKCU). Un script de
|
||||
DEMARRAGE MACHINE tourne en contexte SYSTEM : il ne verrait NI l'installation
|
||||
NI HKCU du collaborateur -> il ne mettrait jamais rien a jour. Le contexte
|
||||
UTILISATEUR est donc obligatoire.
|
||||
|
||||
Le script, a chaque ouverture de session :
|
||||
1. Detecte la version installee (DisplayVersion de la cle de desinstallation
|
||||
Inno dans HKCU — primaire pour un install EXE ; fallback RPA_AGENT_VERSION
|
||||
du config.txt, present uniquement sur les installs via ZIP).
|
||||
2. La compare a la version cible (comparaison semver correcte :
|
||||
1.0.2 < 1.0.10, contrairement a une comparaison de chaines).
|
||||
3. Si plus ancienne : lance l'installeur en mode SILENCIEUX + UPGRADE-SAFE
|
||||
(SANS /CONFIG -> machine_id, serveur et token du poste PRESERVES).
|
||||
4. Journalise le resultat. IDEMPOTENT : ne refait rien si deja a jour.
|
||||
|
||||
Ne leve JAMAIS d'exception bloquant l'ouverture de session (tout en try/catch,
|
||||
sortie 0 sur erreur non geree).
|
||||
|
||||
.NOTES
|
||||
Execution : configurer la GPO pour lancer
|
||||
powershell.exe -NoProfile -ExecutionPolicy Bypass -File Deploy-LeaUpdate.ps1
|
||||
|
||||
Test sur un poste (lecture seule, ne telecharge/installe RIEN) :
|
||||
powershell.exe -NoProfile -ExecutionPolicy Bypass -File Deploy-LeaUpdate.ps1 -DryRun
|
||||
#>
|
||||
|
||||
param(
|
||||
# -DryRun : teste la DECISION (version installee vs cible) et journalise ce
|
||||
# qui SERAIT fait, sans rien telecharger ni installer. Pour valider un poste.
|
||||
[switch]$DryRun,
|
||||
# Overrides optionnels (sinon = valeurs du bloc PARAMETRES ci-dessous).
|
||||
# Utiles pour tester un poste (cible bumpee, journal local) sans editer le script.
|
||||
[string]$TargetVersionOverride,
|
||||
[string]$LogShareOverride
|
||||
)
|
||||
|
||||
# ============================================================================
|
||||
# PARAMETRES A ADAPTER PAR LE DSI / Julien (les 3 seules lignes a toucher)
|
||||
# ============================================================================
|
||||
|
||||
# Source de l'installeur : chemin UNC du domaine (recommande) OU URL http(s).
|
||||
# UNC : \\SRV-FICHIERS\Deploiement$\Lea\Lea-Setup-v1.0.2.exe
|
||||
# HTTPS : https://lea.labs.laurinebazin.design/api/fleet/installer/exe
|
||||
$ExeSource = '\\SRV-FICHIERS\Deploiement$\Lea\Lea-Setup-v1.0.2.exe'
|
||||
|
||||
# Version cible : DOIT correspondre a l'EXE ci-dessus.
|
||||
$TargetVersion = '1.0.2'
|
||||
|
||||
# Dossier de journalisation partage (audit Julien). Vide => journal local %TEMP%.
|
||||
$LogShare = '\\SRV-FICHIERS\Deploiement$\Lea\logs'
|
||||
|
||||
# ============================================================================
|
||||
# Ne rien modifier en dessous de cette ligne.
|
||||
# ============================================================================
|
||||
|
||||
# Overrides de ligne de commande (prioritaires sur le bloc PARAMETRES).
|
||||
if ($TargetVersionOverride) { $TargetVersion = $TargetVersionOverride }
|
||||
if ($PSBoundParameters.ContainsKey('LogShareOverride')) { $LogShare = $LogShareOverride }
|
||||
|
||||
$InstallDir = Join-Path $env:LOCALAPPDATA 'Programs\Lea'
|
||||
$ConfigTxt = Join-Path $InstallDir 'config.txt'
|
||||
$AppUninst = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall\{B3F9A1E2-5C4D-4E7F-9A1B-2C3D4E5F6789}_is1'
|
||||
|
||||
function Write-Log([string]$msg) {
|
||||
$line = '{0} {1}\{2} {3}' -f (Get-Date -Format 'yyyy-MM-dd HH:mm:ss'), $env:COMPUTERNAME, $env:USERNAME, $msg
|
||||
Write-Output $line
|
||||
# Journalisation best-effort : ne DOIT jamais perturber l'ouverture de session.
|
||||
# -ErrorAction SilentlyContinue car un partage injoignable produit une erreur
|
||||
# NON-terminante (non capturee par try/catch) — verifie sur poste reel .11.
|
||||
try {
|
||||
$dir = if ($LogShare) { $LogShare } else { Join-Path $env:TEMP 'Lea-update-logs' }
|
||||
if (-not (Test-Path $dir -ErrorAction SilentlyContinue)) {
|
||||
New-Item -ItemType Directory -Path $dir -Force -ErrorAction SilentlyContinue | Out-Null
|
||||
}
|
||||
$file = Join-Path $dir ('{0}_{1}.log' -f $env:COMPUTERNAME, $env:USERNAME)
|
||||
Add-Content -Path $file -Value $line -Encoding UTF8 -ErrorAction SilentlyContinue
|
||||
} catch { }
|
||||
}
|
||||
|
||||
function Get-InstalledVersion {
|
||||
# 1. Source de verite pour un install EXE (Inno) : DisplayVersion dans HKCU
|
||||
# (install per-user). Toujours ecrite par l'installeur -> methode primaire.
|
||||
# Verifie sur poste reel .11 : le config.txt genere par l'EXE ne contient
|
||||
# PAS de ligne de version, seul le registre fait foi.
|
||||
if (Test-Path $AppUninst) {
|
||||
$dv = (Get-ItemProperty -Path $AppUninst -Name DisplayVersion -ErrorAction SilentlyContinue).DisplayVersion
|
||||
if ($dv) { return $dv }
|
||||
}
|
||||
# 2. Fallback : RPA_AGENT_VERSION dans config.txt (present sur les installs
|
||||
# via ZIP/Python ; absent des installs via EXE).
|
||||
if (Test-Path $ConfigTxt) {
|
||||
$m = Select-String -Path $ConfigTxt -Pattern '^\s*RPA_AGENT_VERSION\s*=\s*(.+?)\s*$' -ErrorAction SilentlyContinue
|
||||
if ($m) { return $m.Matches[0].Groups[1].Value.Trim() }
|
||||
}
|
||||
return $null
|
||||
}
|
||||
|
||||
function ConvertTo-VersionParts([string]$v) {
|
||||
$clean = ($v -replace '^[vV]', '').Trim()
|
||||
$parts = New-Object System.Collections.Generic.List[int]
|
||||
foreach ($p in ($clean -split '\.')) {
|
||||
$n = 0
|
||||
if ([int]::TryParse($p, [ref]$n)) { $parts.Add($n) } else { $parts.Add(0) }
|
||||
}
|
||||
while ($parts.Count -lt 3) { $parts.Add(0) }
|
||||
return $parts
|
||||
}
|
||||
|
||||
function Compare-Semver([string]$a, [string]$b) {
|
||||
# -1 si a<b, 0 si egal, 1 si a>b. Tolerant (piege 1.0.2 < 1.0.10).
|
||||
$pa = ConvertTo-VersionParts $a
|
||||
$pb = ConvertTo-VersionParts $b
|
||||
$max = [Math]::Max($pa.Count, $pb.Count)
|
||||
for ($i = 0; $i -lt $max; $i++) {
|
||||
$va = if ($i -lt $pa.Count) { $pa[$i] } else { 0 }
|
||||
$vb = if ($i -lt $pb.Count) { $pb[$i] } else { 0 }
|
||||
if ($va -lt $vb) { return -1 }
|
||||
if ($va -gt $vb) { return 1 }
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
try {
|
||||
$installed = Get-InstalledVersion
|
||||
if (-not $installed) {
|
||||
Write-Log 'Lea non installe sur ce profil -> ignore (les nouveaux postes passent par le dashboard).'
|
||||
exit 0
|
||||
}
|
||||
if ((Compare-Semver $installed $TargetVersion) -ge 0) {
|
||||
Write-Log ('Deja a jour (installe={0}, cible={1}) -> rien a faire.' -f $installed, $TargetVersion)
|
||||
exit 0
|
||||
}
|
||||
|
||||
if ($DryRun) {
|
||||
Write-Log ('[DryRun] MAJ qui SERAIT appliquee : {0} -> {1}. Aucune action (ni telechargement ni installation).' -f $installed, $TargetVersion)
|
||||
exit 0
|
||||
}
|
||||
|
||||
Write-Log ('MAJ requise : installe={0} < cible={1}. Recuperation de l''installeur...' -f $installed, $TargetVersion)
|
||||
|
||||
# Recuperer l'EXE (UNC ou URL) vers un fichier temporaire local.
|
||||
$localExe = Join-Path $env:TEMP ('Lea-Setup-{0}.exe' -f $TargetVersion)
|
||||
if ($ExeSource -match '^(?i)https?://') {
|
||||
Invoke-WebRequest -Uri $ExeSource -OutFile $localExe -UseBasicParsing
|
||||
} else {
|
||||
Copy-Item -Path $ExeSource -Destination $localExe -Force
|
||||
}
|
||||
if (-not (Test-Path $localExe)) {
|
||||
Write-Log ('ECHEC : installeur introuvable apres recuperation ({0}).' -f $ExeSource)
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Installation SILENCIEUSE + UPGRADE-SAFE (sans /CONFIG : identite du poste preservee).
|
||||
# L'installeur arrete Lea (via lock), sauvegarde <app>_backup, puis met a jour.
|
||||
$logInstall = Join-Path $env:TEMP ('Lea-upgrade-{0}.log' -f (Get-Date -Format 'yyyyMMdd_HHmmss'))
|
||||
$installArgs = @('/VERYSILENT', '/SUPPRESSMSGBOXES', '/NORESTART', ('/LOG={0}' -f $logInstall))
|
||||
$proc = Start-Process -FilePath $localExe -ArgumentList $installArgs -Wait -PassThru
|
||||
$rc = $proc.ExitCode
|
||||
|
||||
if ($rc -eq 0) {
|
||||
$now = Get-InstalledVersion
|
||||
Write-Log ('MAJ OK : {0} -> {1} (code 0).' -f $installed, $now)
|
||||
} else {
|
||||
Write-Log ('ECHEC MAJ : code {0}. Journal installeur : {1}.' -f $rc, $logInstall)
|
||||
}
|
||||
exit $rc
|
||||
} catch {
|
||||
Write-Log ('ERREUR non geree : ' + $_.Exception.Message)
|
||||
exit 0 # ne JAMAIS bloquer l'ouverture de session
|
||||
}
|
||||
5
deploy/installer/releases/.gitignore
vendored
Normal file
5
deploy/installer/releases/.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
# L'installeur EXE (~33 Mo binaire) est déposé ici mais JAMAIS versionné.
|
||||
# On garde le dossier + son LISEZMOI, on ignore tout le reste.
|
||||
*
|
||||
!.gitignore
|
||||
!LISEZMOI.txt
|
||||
17
deploy/installer/releases/LISEZMOI.txt
Normal file
17
deploy/installer/releases/LISEZMOI.txt
Normal file
@@ -0,0 +1,17 @@
|
||||
============================================================
|
||||
deploy/installer/releases/ — Depot des installeurs EXE
|
||||
============================================================
|
||||
|
||||
DEPOSER ICI l'installeur "Lea-Setup-vX.Y.Z.exe" (buildé sur .11).
|
||||
|
||||
Le dashboard sert le plus RECENT via la route :
|
||||
GET /api/fleet/installer
|
||||
-> paquet ZIP "Lea-Install-Silencieux-vX.Y.Z.zip"
|
||||
(EXE + install_silencieux.bat + enroll.txt pré-rempli + LISEZMOI)
|
||||
|
||||
L'EXE (~33 Mo binaire) n'est VOLONTAIREMENT pas versionné dans git.
|
||||
Pour pointer ailleurs : variable d'environnement RPA_LEA_RELEASES_DIR.
|
||||
|
||||
Ce fichier LISEZMOI.txt sert uniquement à garder le dossier présent
|
||||
dans le dépôt (l'EXE, lui, est déposé à la main / par script de release).
|
||||
============================================================
|
||||
40
deploy/installer/silent/LISEZMOI_SILENCIEUX.txt
Normal file
40
deploy/installer/silent/LISEZMOI_SILENCIEUX.txt
Normal file
@@ -0,0 +1,40 @@
|
||||
============================================================
|
||||
Lea - Installation silencieuse (nouveau poste)
|
||||
============================================================
|
||||
|
||||
CE DOSSIER CONTIENT :
|
||||
- Lea-Setup-vX.Y.Z.exe : l'installeur Lea
|
||||
- install_silencieux.bat : le lanceur d'installation
|
||||
- enroll.txt : les parametres d'enrolement a remplir
|
||||
- LISEZMOI_SILENCIEUX.txt : ce fichier
|
||||
|
||||
------------------------------------------------------------
|
||||
QUAND UTILISER CETTE VOIE ?
|
||||
------------------------------------------------------------
|
||||
Pour installer Lea sur un poste qui NE l'a PAS encore.
|
||||
(Pour METTRE A JOUR un poste deja installe : voir la voie GPO,
|
||||
ou relancer simplement l'installeur qui detecte l'existant.)
|
||||
|
||||
------------------------------------------------------------
|
||||
PROCEDURE (3 etapes, ~2 min, sans droits administrateur)
|
||||
------------------------------------------------------------
|
||||
1. Ouvrir "enroll.txt" avec le Bloc-notes.
|
||||
Renseigner : USER_NAME, USER_EMAIL, SERVER_URL, API_TOKEN.
|
||||
(Remplacer les valeurs "CONFIGURE_ME".) Enregistrer.
|
||||
|
||||
2. Double-cliquer sur "install_silencieux.bat".
|
||||
L'installation se deroule sans fenetre d'installation.
|
||||
Ne pas fermer la fenetre noire avant le message "OK".
|
||||
|
||||
3. Verifier que Lea demarre (icone dans la barre des taches,
|
||||
pres de l'horloge). C'est termine.
|
||||
|
||||
------------------------------------------------------------
|
||||
EN CAS DE PROBLEME
|
||||
------------------------------------------------------------
|
||||
- Message "valeurs CONFIGURE_ME" : enroll.txt n'est pas rempli.
|
||||
- Message "aucun Lea-Setup trouve" : l'EXE n'est pas dans ce dossier.
|
||||
- Autre erreur : le journal detaille est indique a l'ecran
|
||||
(dossier %TEMP%, fichier Lea-install-silencieux.log).
|
||||
Le transmettre a l'administrateur AIVANOV.
|
||||
============================================================
|
||||
31
deploy/installer/silent/enroll.txt
Normal file
31
deploy/installer/silent/enroll.txt
Normal file
@@ -0,0 +1,31 @@
|
||||
# ============================================================
|
||||
# enroll.txt — Enrolement pour installation SILENCIEUSE
|
||||
# ------------------------------------------------------------
|
||||
# Utilise par install_silencieux.bat :
|
||||
# Lea-Setup-vX.Y.Z.exe /VERYSILENT /CONFIG=enroll.txt
|
||||
#
|
||||
# L'installeur lit ce fichier au demarrage et remplit les
|
||||
# informations d'enrolement SANS interface graphique.
|
||||
#
|
||||
# A FAIRE : renseigner les valeurs ci-dessous (remplacer les
|
||||
# CONFIGURE_ME), enregistrer, puis lancer install_silencieux.bat.
|
||||
#
|
||||
# Format : CLE=valeur, une ligne par parametre, # = commentaire.
|
||||
# NOTE : ce fichier sert l'INSTALL NEUVE. Sur une mise a jour,
|
||||
# l'installeur preserve tout seul l'identite du poste et
|
||||
# IGNORE ce fichier (voir la voie GPO).
|
||||
# ============================================================
|
||||
|
||||
# --- Identite du collaborateur ---
|
||||
USER_NAME=Prenom Nom
|
||||
USER_EMAIL=prenom.nom@clinique-wallerstein.fr
|
||||
USER_ID=
|
||||
|
||||
# --- Connexion au serveur Lea ---
|
||||
# Exemples de SERVER_URL :
|
||||
# LAN clinique (DGX) : http://192.168.1.178:5005/api/v1
|
||||
# Internet : https://lea.labs.laurinebazin.design/api/v1
|
||||
SERVER_URL=CONFIGURE_ME
|
||||
|
||||
# Token d'authentification (fourni par l'administrateur AIVANOV)
|
||||
API_TOKEN=CONFIGURE_ME
|
||||
73
deploy/installer/silent/install_silencieux.bat
Normal file
73
deploy/installer/silent/install_silencieux.bat
Normal file
@@ -0,0 +1,73 @@
|
||||
@echo off
|
||||
chcp 65001 >nul 2>&1
|
||||
setlocal enabledelayedexpansion
|
||||
title Lea - Installation silencieuse (nouveau poste)
|
||||
|
||||
:: ============================================================
|
||||
:: install_silencieux.bat
|
||||
:: Installe Lea sur un NOUVEAU poste, sans interface graphique.
|
||||
::
|
||||
:: Pre-requis : ce script, l'installeur "Lea-Setup-v*.exe" et
|
||||
:: "enroll.txt" (rempli) doivent etre dans le MEME dossier.
|
||||
::
|
||||
:: Installation PER-USER : aucun droit administrateur requis.
|
||||
:: ============================================================
|
||||
|
||||
set "HERE=%~dp0"
|
||||
set "ENROLL=%HERE%enroll.txt"
|
||||
set "LOG=%TEMP%\Lea-install-silencieux.log"
|
||||
|
||||
echo.
|
||||
echo ============================================================
|
||||
echo Lea - Installation silencieuse (nouveau poste)
|
||||
echo ============================================================
|
||||
echo.
|
||||
|
||||
:: --- 1. Localiser l'installeur (Lea-Setup-v*.exe, version la plus recente) ---
|
||||
set "EXE="
|
||||
for /f "delims=" %%f in ('dir /b /o-n "%HERE%Lea-Setup-v*.exe" 2^>nul') do (
|
||||
if not defined EXE set "EXE=%HERE%%%f"
|
||||
)
|
||||
if not defined EXE (
|
||||
echo ERREUR : aucun "Lea-Setup-v*.exe" trouve dans ce dossier.
|
||||
echo Placez ce script a cote de l'installeur Lea.
|
||||
echo.
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
echo Installeur detecte : !EXE!
|
||||
|
||||
:: --- 2. Verifier enroll.txt ---
|
||||
if not exist "%ENROLL%" (
|
||||
echo ERREUR : "enroll.txt" introuvable a cote de ce script.
|
||||
echo.
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
findstr /C:"CONFIGURE_ME" "%ENROLL%" >nul 2>&1
|
||||
if not errorlevel 1 (
|
||||
echo.
|
||||
echo ATTENTION : "enroll.txt" contient encore des valeurs CONFIGURE_ME.
|
||||
echo Ouvrez enroll.txt, renseignez SERVER_URL / API_TOKEN / USER_*,
|
||||
echo enregistrez, puis relancez ce script.
|
||||
echo.
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
:: --- 3. Installation silencieuse (per-user, pas d'admin) ---
|
||||
echo Installation en cours (silencieuse, ~1-2 min)... ne fermez pas cette fenetre.
|
||||
"!EXE!" /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /CONFIG="%ENROLL%" /LOG="%LOG%"
|
||||
set "RC=!errorlevel!"
|
||||
|
||||
echo.
|
||||
if "!RC!"=="0" (
|
||||
echo Installation terminee - OK.
|
||||
echo Lea est enrolle et pret. Journal : %LOG%
|
||||
) else (
|
||||
echo ERREUR : l'installation a echoue ^(code !RC!^).
|
||||
echo Consultez le journal : %LOG%
|
||||
)
|
||||
echo.
|
||||
pause
|
||||
endlocal
|
||||
75
docs/PROCEDURE_DEPLOIEMENT_LEA_JULIEN.md
Normal file
75
docs/PROCEDURE_DEPLOIEMENT_LEA_JULIEN.md
Normal file
@@ -0,0 +1,75 @@
|
||||
# Procédure de déploiement Léa — pour Julien (informaticien clinique)
|
||||
|
||||
> Version agent cible : **1.0.2** · Installeur : `Lea-Setup-v1.0.2.exe` (per-user, aucun droit admin requis).
|
||||
> Rédigé le 2026-07-06. Poste pilote validé : **Émilie**.
|
||||
|
||||
Trois cas. Le n°1 pour un poste **neuf**, le n°2/3 pour **mettre à jour** un poste déjà installé.
|
||||
|
||||
---
|
||||
|
||||
## 1. Installer Léa sur un NOUVEAU poste (install silencieuse)
|
||||
|
||||
1. Depuis un navigateur (dashboard Léa), télécharger le paquet :
|
||||
**`GET /api/fleet/installer`** → `Lea-Install-Silencieux-vX.Y.Z.zip`.
|
||||
*(Le ZIP contient l'EXE + `install_silencieux.bat` + `enroll.txt` déjà pré-rempli avec l'URL serveur et le token.)*
|
||||
2. Sur le poste cible : dézipper le paquet dans un dossier.
|
||||
3. Ouvrir **`enroll.txt`** (Bloc-notes), compléter **`USER_NAME`** et **`USER_EMAIL`** (l'URL et le token sont déjà remplis). Enregistrer.
|
||||
4. Double-cliquer **`install_silencieux.bat`**. Attendre le message **« Installation terminée - OK »**.
|
||||
5. Vérifier : icône Léa près de l'horloge (barre des tâches).
|
||||
|
||||
> L'installeur génère un **`machine_id` unique** pour ce poste : rien à pré-enregistrer.
|
||||
|
||||
---
|
||||
|
||||
## 2. Mettre à jour un poste déjà installé — voie MANUELLE (immédiate)
|
||||
|
||||
C'est la voie utilisée pour Émilie, à rejouer poste par poste **en attendant l'autorisation AD/GPO**.
|
||||
|
||||
1. Récupérer **`Lea-Setup-v1.0.2.exe`** (le même EXE, aucune régénération).
|
||||
2. Sur le poste, le lancer par **double-clic** (mode interactif).
|
||||
3. Le wizard doit s'afficher **pré-rempli** avec la config du poste (serveur/token/utilisateur).
|
||||
⚠️ **S'il est vide** → l'installeur n'a pas détecté l'install existante : **ne pas continuer**, prévenir AIVANOV (risque de créer un nouveau poste au lieu de mettre à jour).
|
||||
4. Valider. L'installeur **arrête Léa**, sauvegarde l'ancienne version (`<dossier>_backup`), met à jour en **préservant l'identité** du poste, purge les captures accumulées.
|
||||
5. Vérifier après MAJ (mêmes points qu'Émilie) : Léa relancée en **v1.0.2**, icône présente, capture d'écran OK, comportement RDP OK.
|
||||
|
||||
> **Rollback** si besoin : restaurer le dossier `<install>_backup` (le dossier d'install est `%LOCALAPPDATA%\Programs\Lea`).
|
||||
|
||||
---
|
||||
|
||||
## 3. Mettre à jour la flotte via AD/GPO (quand l'autorisation est en place)
|
||||
|
||||
Script fourni : **`deploy/gpo/Deploy-LeaUpdate.ps1`**.
|
||||
|
||||
### ⚠️ Point crucial : script d'OUVERTURE DE SESSION (contexte utilisateur)
|
||||
Léa est installée **par utilisateur** (`%LOCALAPPDATA%`). Un script de **démarrage machine** (contexte SYSTEM) **ne verrait pas** l'installation et ne mettrait rien à jour. Le script doit donc être en :
|
||||
**`User Configuration → Policies → Windows Settings → Scripts (Logon/Logoff) → Logon`.**
|
||||
|
||||
### Étapes
|
||||
1. Déposer `Lea-Setup-v1.0.2.exe` sur un partage du domaine accessible aux postes (ex. `\\SRV-FICHIERS\Deploiement$\Lea\`).
|
||||
2. Éditer les **3 lignes de paramètres** en tête de `Deploy-LeaUpdate.ps1` :
|
||||
- `$ExeSource` = chemin UNC (ou URL) de l'EXE ;
|
||||
- `$TargetVersion` = `1.0.2` (doit correspondre à l'EXE) ;
|
||||
- `$LogShare` = dossier partagé pour les journaux d'audit (ou vide → journal local).
|
||||
3. Ajouter le script en **Logon script** (commande : `powershell.exe -NoProfile -ExecutionPolicy Bypass -File Deploy-LeaUpdate.ps1`).
|
||||
4. À l'ouverture de session, le script : détecte la version installée, compare à la cible, met à jour **seulement si plus ancienne** (idempotent, silencieux, upgrade-safe), puis journalise.
|
||||
|
||||
### Comportement (garanti par le script)
|
||||
- Poste **déjà à jour** → ne fait rien.
|
||||
- Poste **sans Léa** → ignoré (les postes neufs passent par le cas 1).
|
||||
- Erreur (partage indisponible, etc.) → journalisée, **n'empêche jamais l'ouverture de session**.
|
||||
|
||||
### Audit
|
||||
Un journal par poste/utilisateur dans `$LogShare` : `<POSTE>_<UTILISATEUR>.log` (ligne datée : version installée → version après MAJ, ou motif d'échec).
|
||||
|
||||
---
|
||||
|
||||
## Aide-mémoire
|
||||
|
||||
| Besoin | Voie | Artefact |
|
||||
|---|---|---|
|
||||
| Poste neuf | Install silencieuse | Dashboard `GET /api/fleet/installer` |
|
||||
| MAJ immédiate d'un poste | Manuelle (double-clic) | `Lea-Setup-v1.0.2.exe` |
|
||||
| MAJ de toute la flotte | AD/GPO (logon script) | `deploy/gpo/Deploy-LeaUpdate.ps1` |
|
||||
| Revenir en arrière | Rollback | dossier `<install>_backup` |
|
||||
|
||||
En cas de doute ou de wizard **non** pré-rempli lors d'une MAJ : **s'arrêter et contacter AIVANOV**.
|
||||
@@ -2481,6 +2481,131 @@ def download_agent_package(machine_id):
|
||||
)
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# Fleet — Téléchargement de l'installeur SILENCIEUX (EXE, nouveaux postes)
|
||||
# =============================================================================
|
||||
#
|
||||
# Voie EXE (python-embedded, upgrade-safe) DISTINCTE de la voie ZIP/Python
|
||||
# ci-dessus (download_agent_package). Sert un paquet d'installation silencieuse
|
||||
# pour un NOUVEAU poste : l'EXE génère lui-même un machine_id unique → pas de
|
||||
# pré-enregistrement requis (contrairement à la voie ZIP, qui bake un
|
||||
# machine_id assigné). L'EXE lourd (~33 Mo binaire) n'est PAS versionné : il est
|
||||
# déposé sur l'hôte dans RPA_LEA_RELEASES_DIR (défaut deploy/installer/releases/)
|
||||
# après build sur .11.
|
||||
|
||||
_LEA_RELEASES_DIR = Path(
|
||||
os.getenv("RPA_LEA_RELEASES_DIR", str(BASE_PATH / "deploy" / "installer" / "releases"))
|
||||
)
|
||||
_LEA_SILENT_DIR = BASE_PATH / "deploy" / "installer" / "silent"
|
||||
|
||||
|
||||
def _silent_exe_version(name: str) -> str:
|
||||
"""Extrait la version d'un nom "Lea-Setup-v1.0.2.exe" → "1.0.2" (sans regex)."""
|
||||
stem = name[:-4] if name.lower().endswith(".exe") else name
|
||||
prefix = "Lea-Setup-v"
|
||||
return stem[len(prefix):] if stem.startswith(prefix) else "0.0.0"
|
||||
|
||||
|
||||
def _resolve_silent_installer_exe(releases_dir: "Path | None" = None) -> "Path | None":
|
||||
"""Retourne l'EXE Lea-Setup-v*.exe le plus récent du dossier releases, ou None.
|
||||
|
||||
Tri par version sémantique décroissante (pas lexicographique : 1.0.10 > 1.0.2).
|
||||
Paramètre injectable pour les tests (évite de démarrer Flask — DETTE-013).
|
||||
"""
|
||||
d = releases_dir or _LEA_RELEASES_DIR
|
||||
try:
|
||||
exes = list(d.glob("Lea-Setup-v*.exe"))
|
||||
except Exception:
|
||||
return None
|
||||
if not exes:
|
||||
return None
|
||||
|
||||
def _ver_key(p: Path):
|
||||
parts = []
|
||||
for tok in _silent_exe_version(p.name).split("."):
|
||||
parts.append(int(tok) if tok.isdigit() else 0)
|
||||
return parts
|
||||
|
||||
return sorted(exes, key=_ver_key, reverse=True)[0]
|
||||
|
||||
|
||||
def _build_silent_enroll(token: str) -> str:
|
||||
"""Génère enroll.txt (clés /CONFIG de l'installeur EXE) avec SERVER_URL et
|
||||
token injectés. USER_* laissés en placeholder : remplis par poste avant le
|
||||
lancement de install_silencieux.bat.
|
||||
"""
|
||||
server_url = _resolve_public_server_url()
|
||||
return f"""\
|
||||
# ============================================================
|
||||
# enroll.txt — Enrolement pour installation SILENCIEUSE
|
||||
# Genere par le dashboard Fleet. SERVER_URL et API_TOKEN sont
|
||||
# deja renseignes. A COMPLETER : USER_NAME / USER_EMAIL.
|
||||
# Puis lancer install_silencieux.bat.
|
||||
# ============================================================
|
||||
|
||||
# --- Identite du collaborateur (a remplir) ---
|
||||
USER_NAME=Prenom Nom
|
||||
USER_EMAIL=prenom.nom@clinique-wallerstein.fr
|
||||
USER_ID=
|
||||
|
||||
# --- Connexion serveur (pre-renseignee, ne pas modifier) ---
|
||||
SERVER_URL={server_url}
|
||||
API_TOKEN={token}
|
||||
"""
|
||||
|
||||
|
||||
@app.route('/api/fleet/installer')
|
||||
def download_silent_installer():
|
||||
"""Sert un paquet ZIP d'installation SILENCIEUSE pour un nouveau poste.
|
||||
|
||||
Contenu : Lea-Setup-v*.exe + install_silencieux.bat + enroll.txt
|
||||
(SERVER_URL/token pré-injectés) + LISEZMOI. L'auth Basic est gérée par
|
||||
before_request.
|
||||
"""
|
||||
exe = _resolve_silent_installer_exe()
|
||||
if exe is None:
|
||||
api_logger.error(
|
||||
"download_silent_installer — aucun Lea-Setup-v*.exe dans %s.",
|
||||
_LEA_RELEASES_DIR,
|
||||
)
|
||||
return jsonify({
|
||||
'error': 'Installeur EXE introuvable',
|
||||
'detail': (
|
||||
f'Aucun Lea-Setup-v*.exe dans {_LEA_RELEASES_DIR}. '
|
||||
'Déposer l\'EXE (buildé sur .11) dans ce dossier, ou définir '
|
||||
'la variable d\'environnement RPA_LEA_RELEASES_DIR.'
|
||||
),
|
||||
}), 404
|
||||
|
||||
version = _silent_exe_version(exe.name)
|
||||
token = os.environ.get('RPA_API_TOKEN', 'CONFIGURE_ME')
|
||||
enroll_txt = _build_silent_enroll(token)
|
||||
|
||||
# Artefacts d'accompagnement — source de vérité = deploy/installer/silent/.
|
||||
bat_path = _LEA_SILENT_DIR / "install_silencieux.bat"
|
||||
readme_path = _LEA_SILENT_DIR / "LISEZMOI_SILENCIEUX.txt"
|
||||
|
||||
output_buffer = io.BytesIO()
|
||||
with zipfile.ZipFile(output_buffer, 'w', zipfile.ZIP_DEFLATED) as z:
|
||||
z.write(exe, arcname=exe.name)
|
||||
if bat_path.exists():
|
||||
z.write(bat_path, arcname="install_silencieux.bat")
|
||||
if readme_path.exists():
|
||||
z.write(readme_path, arcname="LISEZMOI_SILENCIEUX.txt")
|
||||
z.writestr("enroll.txt", enroll_txt.encode('utf-8'))
|
||||
output_buffer.seek(0)
|
||||
|
||||
api_logger.info(
|
||||
"download_silent_installer — paquet servi (EXE %s, v%s).", exe.name, version
|
||||
)
|
||||
return send_file(
|
||||
output_buffer,
|
||||
as_attachment=True,
|
||||
download_name=f"Lea-Install-Silencieux-v{version}.zip",
|
||||
mimetype='application/zip',
|
||||
)
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# Cartographie des processus — Process Mining
|
||||
# =============================================================================
|
||||
|
||||
Reference in New Issue
Block a user