253 lines
9.7 KiB
PowerShell
253 lines
9.7 KiB
PowerShell
# ============================================================
|
|
# Omika - Installation de TOUS les services Windows (orchestrateur)
|
|
# ============================================================
|
|
# CIBLE : Windows Server 2025 (SRV-OMIKA), PowerShell ADMINISTRATEUR.
|
|
# NE PAS executer depuis le poste de developpement.
|
|
#
|
|
# Ce script ne fait plus le travail lui-meme : il appelle, DANS L'ORDRE, un
|
|
# script dedie par deploiement. Chaque service reste installable seul.
|
|
#
|
|
# 1. Install-OmikaApi.ps1 (spool JSONL de l'API)
|
|
# 2. Install-OmikaWorker.ps1
|
|
# 3. Install-OmikaDiagnosticsApi.ps1 (spool central) [optionnel]
|
|
# 4. Install-OmikaDiagnosticsWorker.ps1 (lit les 2 spools)
|
|
# 5. Install-OmikaDiagnosticsWeb.ps1
|
|
# 6. Install-OmikaLanguesApi.ps1 [optionnel]
|
|
#
|
|
# POURQUOI CET ORDRE : les ACL inter-services (le Worker Diagnostics lit le
|
|
# spool produit par l'API et celui produit par l'API centrale) ne peuvent etre
|
|
# posees que si le dossier existe deja. L'ancien script monolithique posait les
|
|
# ACL en bloc et IGNORAIT SILENCIEUSEMENT les dossiers absents ; ici, le
|
|
# proprietaire du dossier est installe AVANT ses lecteurs.
|
|
#
|
|
# CE QUE CE SCRIPT NE FAIT PAS :
|
|
# - AUCUN demarrage de service (doctrine : activation != demarrage).
|
|
# - AUCUN secret ecrit, AUCUNE regle firewall, AUCUN IIS, AUCUNE base modifiee.
|
|
#
|
|
# PREREQUIS MANUELS :
|
|
# - Comptes locaux dedies crees + droit « Ouvrir une session en tant que
|
|
# service » (chaque script le verifie et avertit).
|
|
# - Publications copiees dans <InstallRoot>\Apps (Install-OmikaServerFiles.ps1).
|
|
#
|
|
# IDEMPOTENT - prend en charge -WhatIf.
|
|
#
|
|
# EXEMPLES :
|
|
# .\Install-OmikaServices.ps1
|
|
# .\Install-OmikaServices.ps1 -WhatIf
|
|
# .\Install-OmikaServices.ps1 -InclureLangues -PortLangues 5099
|
|
# .\Install-OmikaServices.ps1 -SansDiagnosticsApi # serveur mono-serveur
|
|
# .\Install-OmikaServices.ps1 -Desinstaller
|
|
# ============================================================
|
|
|
|
[CmdletBinding(SupportsShouldProcess = $true)]
|
|
param(
|
|
[string]$InstallRoot = 'C:\Omika',
|
|
|
|
# --- Noms de services ----------------------------------------------------
|
|
[string]$ApiServiceName = 'OmikaApi',
|
|
[string]$WorkerServiceName = 'OmikaWorker',
|
|
[string]$DiagServiceName = 'OmikaDiagnosticsWorker',
|
|
[string]$DiagWebServiceName = 'OmikaDiagnosticsWeb',
|
|
[string]$DiagApiServiceName = 'OmikaDiagnosticsApi',
|
|
[string]$LanguesServiceName = 'OmikaLanguesApi',
|
|
|
|
# --- Comptes de service (jamais LocalSystem, jamais un compte humain) ----
|
|
[string]$ApiAccount = '.\svc_omika_api',
|
|
[string]$WorkerAccount = '.\svc_omika_worker',
|
|
[string]$DiagAccount = '.\svc_omika_diag',
|
|
[string]$DiagWebAccount = '.\svc_omika_diagweb',
|
|
[string]$DiagApiAccount = '.\svc_omika_diagapi',
|
|
[string]$LanguesAccount = '.\svc_omika_langues',
|
|
|
|
[ValidateSet('Manual', 'Automatic', 'Disabled')]
|
|
[string]$StartupType = 'Manual',
|
|
|
|
# --- Perimetre -----------------------------------------------------------
|
|
# Le service Langues n'existe que si la traduction hors ligne mobile est deployee.
|
|
[switch]$InclureLangues,
|
|
|
|
# Sur un serveur MONO-SERVEUR, l'API centrale de diagnostics est inutile
|
|
# (l'API metier ecrit son JSONL localement, sans forwarding).
|
|
[switch]$SansDiagnosticsApi,
|
|
|
|
# Port loopback a verifier avant de le fixer dans ASPNETCORE_URLS (§6bis).
|
|
[ValidateRange(0, 65535)]
|
|
[int]$PortLangues = 0,
|
|
|
|
# --- Rollback ------------------------------------------------------------
|
|
[switch]$Desinstaller
|
|
)
|
|
|
|
$ErrorActionPreference = 'Stop'
|
|
|
|
Import-Module (Join-Path $PSScriptRoot 'Omika.Deploy.Common.psm1') -Force
|
|
|
|
# Le module a son propre etat de session : $WhatIfPreference ne s'y propage pas.
|
|
$Simulation = [bool]$WhatIfPreference
|
|
|
|
try {
|
|
Assert-OmikaAdmin
|
|
Write-OmikaStep 'Perimetre du deploiement'
|
|
|
|
# --- Composition de la sequence -----------------------------------------
|
|
$sequence = New-Object System.Collections.Generic.List[object]
|
|
|
|
$sequence.Add(@{
|
|
Script = 'Install-OmikaApi.ps1'
|
|
Libelle = 'OmikaApi'
|
|
Parametres = @{
|
|
InstallRoot = $InstallRoot
|
|
ServiceName = $ApiServiceName
|
|
Account = $ApiAccount
|
|
StartupType = $StartupType
|
|
}
|
|
})
|
|
|
|
$sequence.Add(@{
|
|
Script = 'Install-OmikaWorker.ps1'
|
|
Libelle = 'OmikaWorker'
|
|
Parametres = @{
|
|
InstallRoot = $InstallRoot
|
|
ServiceName = $WorkerServiceName
|
|
Account = $WorkerAccount
|
|
StartupType = $StartupType
|
|
}
|
|
})
|
|
|
|
if (-not $SansDiagnosticsApi) {
|
|
$sequence.Add(@{
|
|
Script = 'Install-OmikaDiagnosticsApi.ps1'
|
|
Libelle = 'OmikaDiagnosticsApi'
|
|
Parametres = @{
|
|
InstallRoot = $InstallRoot
|
|
ServiceName = $DiagApiServiceName
|
|
Account = $DiagApiAccount
|
|
AccountWorker = $DiagAccount
|
|
StartupType = $StartupType
|
|
}
|
|
})
|
|
}
|
|
else {
|
|
Write-OmikaInfo 'OmikaDiagnosticsApi EXCLU (-SansDiagnosticsApi).'
|
|
}
|
|
|
|
$sequence.Add(@{
|
|
Script = 'Install-OmikaDiagnosticsWorker.ps1'
|
|
Libelle = 'OmikaDiagnosticsWorker'
|
|
Parametres = @{
|
|
InstallRoot = $InstallRoot
|
|
ServiceName = $DiagServiceName
|
|
Account = $DiagAccount
|
|
AccountApi = $ApiAccount
|
|
AccountDiagApi = $DiagApiAccount
|
|
StartupType = $StartupType
|
|
}
|
|
})
|
|
|
|
$sequence.Add(@{
|
|
Script = 'Install-OmikaDiagnosticsWeb.ps1'
|
|
Libelle = 'OmikaDiagnosticsWeb'
|
|
Parametres = @{
|
|
InstallRoot = $InstallRoot
|
|
ServiceName = $DiagWebServiceName
|
|
Account = $DiagWebAccount
|
|
StartupType = $StartupType
|
|
}
|
|
})
|
|
|
|
if ($InclureLangues) {
|
|
$parametresLangues = @{
|
|
InstallRoot = $InstallRoot
|
|
ServiceName = $LanguesServiceName
|
|
Account = $LanguesAccount
|
|
StartupType = $StartupType
|
|
}
|
|
if ($PortLangues -gt 0) { $parametresLangues['Port'] = $PortLangues }
|
|
$sequence.Add(@{
|
|
Script = 'Install-OmikaLanguesApi.ps1'
|
|
Libelle = 'OmikaLanguesApi'
|
|
Parametres = $parametresLangues
|
|
})
|
|
}
|
|
else {
|
|
Write-OmikaInfo 'OmikaLanguesApi EXCLU (ajoutez -InclureLangues pour l''installer).'
|
|
}
|
|
|
|
$mode = 'INSTALLATION'
|
|
if ($Desinstaller) { $mode = 'DESINSTALLATION' }
|
|
if ($Simulation) { $mode += ' (SIMULATION -WhatIf)' }
|
|
Write-OmikaInfo ("{0} - {1} service(s) dans la sequence" -f $mode, $sequence.Count)
|
|
|
|
# --- Execution -----------------------------------------------------------
|
|
$resultats = @()
|
|
|
|
foreach ($etape in $sequence) {
|
|
$nomService = [string]$etape.Parametres['ServiceName']
|
|
$cheminScript = Join-Path $PSScriptRoot $etape.Script
|
|
|
|
if (-not (Test-Path -LiteralPath $cheminScript)) {
|
|
Write-OmikaFail ("Script introuvable : {0} (service {1} ignore)" -f $etape.Script, $nomService)
|
|
$resultats += [pscustomobject]@{ Service = $nomService; Resultat = 'SCRIPT ABSENT' }
|
|
continue
|
|
}
|
|
|
|
$parametres = $etape.Parametres.Clone()
|
|
$parametres['WhatIf'] = $Simulation
|
|
if ($Desinstaller) { $parametres['Desinstaller'] = $true }
|
|
|
|
& $cheminScript @parametres
|
|
$code = $LASTEXITCODE
|
|
|
|
if ($code -eq 0) {
|
|
$resultats += [pscustomobject]@{ Service = $nomService; Resultat = 'OK' }
|
|
}
|
|
else {
|
|
$resultats += [pscustomobject]@{ Service = $nomService; Resultat = ("ECHEC (code $code)") }
|
|
}
|
|
}
|
|
|
|
# --- Recapitulatif -------------------------------------------------------
|
|
Write-Host ''
|
|
Write-Host '=== RECAPITULATIF ===' -ForegroundColor Cyan
|
|
foreach ($ligne in $resultats) {
|
|
$couleur = 'Red'
|
|
if ($ligne.Resultat -eq 'OK') { $couleur = 'Green' }
|
|
Write-Host (" {0,-26} {1}" -f $ligne.Service, $ligne.Resultat) -ForegroundColor $couleur
|
|
}
|
|
|
|
Write-Host ''
|
|
Write-Host 'Etat reel des services :' -ForegroundColor Cyan
|
|
$noms = @($sequence | ForEach-Object { [string]$_.Parametres['ServiceName'] })
|
|
Get-Service | Where-Object { $noms -contains $_.Name } |
|
|
Select-Object Name, Status, StartType | Format-Table -AutoSize
|
|
|
|
$echecs = @($resultats | Where-Object { $_.Resultat -ne 'OK' })
|
|
|
|
Write-Host ''
|
|
if ($echecs.Count -eq 0) {
|
|
Write-Host 'ACTIVATION TERMINEE (services MANUAL + STOPPED).' -ForegroundColor Green
|
|
Write-Host 'AUCUN service demarre : le demarrage reste une action MANUELLE.' -ForegroundColor Yellow
|
|
Write-Host ''
|
|
Write-Host 'Ordre de demarrage (consommateurs avant producteurs) :' -ForegroundColor Yellow
|
|
Write-Host ' OmikaDiagnosticsWorker -> OmikaDiagnosticsWeb -> OmikaDiagnosticsApi -> OmikaWorker -> OmikaApi' -ForegroundColor Yellow
|
|
}
|
|
else {
|
|
Write-Host ("ACTIVATION INCOMPLETE : {0} etape(s) en echec." -f $echecs.Count) -ForegroundColor Red
|
|
Write-Host 'Corrigez chaque echec, puis relancez ce script (idempotent).' -ForegroundColor Red
|
|
}
|
|
|
|
Write-Host ''
|
|
Write-Host 'RAPPELS (jamais automatises ici) :' -ForegroundColor Yellow
|
|
Write-Host ' - Injecter les secrets par service (voir les rappels de chaque script).'
|
|
Write-Host ' - Verifier le provider OLE DB PCSOFT.HFSQL (64 bits) enregistre.'
|
|
Write-Host ' - Installer LibreOffice si la generation PDF des rapports est utilisee.'
|
|
Write-Host ' - Appliquer les migrations PostgreSQL 001 -> 010 (retention incluse) avant demarrage.'
|
|
|
|
if ($echecs.Count -gt 0) { exit 1 }
|
|
exit 0
|
|
}
|
|
catch {
|
|
Write-OmikaFail $_.Exception.Message
|
|
exit 1
|
|
}
|