# ============================================================ # Omika - Installation du service Windows OmikaLanguesApi (deploiement 6/6) # ============================================================ # CIBLE : Windows Server 2025 (SRV-OMIKA), PowerShell ADMINISTRATEUR. # NE PAS executer depuis le poste de developpement. # # A QUOI SERT CE SERVICE : # Service dedie au telechargement des modeles de langue ONNX (traduction hors # ligne mobile). STATELESS : aucun acces HFSQL, aucune authentification # (les modeles sont des fichiers generiques publics). Le mobile obtient son # URL de base via le parametre HFSQL SRV_LANGUES, expose par Omika.Api au # bootstrap. # # CE QUE CE SCRIPT FAIT : # 1. Cree le dossier des modeles et le dossier de journalisation. # 2. Pose les ACL NTFS minimales : LECTURE SEULE sur les modeles # (le service ne fait que les lire et les streamer). # 3. Valide le compte de service (existence + droit de connexion). # 4. CONTROLE la disponibilite du port loopback, si -Port est fourni. # 5. Cree le service Windows OmikaLanguesApi (idempotent, Manual). # 6. Verifie ce qui a ete reellement cree. # # CE QU'IL NE FAIT PAS : # - AUCUN demarrage de service. # - AUCUN port choisi en dur : voir -Port et DEPLOIEMENT_API_LANGUES.md §6bis. # - AUCUN modele telecharge, AUCUN manifest.json ecrit. # - AUCUNE ligne SRV_LANGUES ecrite dans HFSQL. # # PREREQUIS MANUELS : # - Compte local dedie + droit « Ouvrir une session en tant que service ». # - Publication copiee dans \Apps\LanguesApi. # - Le service doit contenir UseWindowsService() : sans lui, le demarrage # echoue avec l'erreur 1053 (« le service n'a pas repondu a temps »). # # IDEMPOTENT - prend en charge -WhatIf. # # EXEMPLES : # .\Install-OmikaLanguesApi.ps1 -Port 5099 # .\Install-OmikaLanguesApi.ps1 -Port 5099 -WhatIf # .\Install-OmikaLanguesApi.ps1 -Desinstaller # ============================================================ [CmdletBinding(SupportsShouldProcess = $true)] param( [string]$InstallRoot = 'C:\Omika', [string]$ServiceName = 'OmikaLanguesApi', [string]$Account = '.\svc_omika_langues', # Port loopback a verifier AVANT de le fixer dans ASPNETCORE_URLS. # Aucune valeur par defaut : le port se decide contre le plan Apache # (DEPLOIEMENT_API_LANGUES.md §6bis), jamais en recopiant un exemple. [ValidateRange(1, 65535)] [int]$Port = 0, # Dossier racine des modeles (variable Langues__RootPath). [string]$RootPathLangues, [ValidateSet('Manual', 'Automatic', 'Disabled')] [string]$StartupType = 'Manual', [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 # --- Definition du service --------------------------------------------------- $NomAffiche = 'Omika Langues Api' $DossierApps = 'LanguesApi' $Executable = 'Omika.Langues.Api.exe' $Description = 'Omika - API de telechargement des modeles de langue (ONNX) pour la traduction hors ligne mobile. Anonyme, sans base de donnees.' if (-not $RootPathLangues) { $RootPathLangues = Join-Path $InstallRoot 'Data\Langues' } # Lecture seule : le service streame des fichiers, il n'ecrit jamais dans les modeles. $DossiersLecture = @( $RootPathLangues ) try { Assert-OmikaAdmin $chemins = Get-OmikaPaths -InstallRoot $InstallRoot $cheminExe = Join-Path (Join-Path $chemins.Apps $DossierApps) $Executable # --- Rollback ------------------------------------------------------------ if ($Desinstaller) { Write-OmikaStep "Desinstallation du service $ServiceName" Remove-OmikaService -Name $ServiceName -WhatIf:$Simulation | Out-Null Write-OmikaServiceSummary -Name $ServiceName -Supprime exit 0 } # --- 1. Dossiers --------------------------------------------------------- Write-OmikaStep 'Dossiers du service' New-OmikaDirectory -Path (Join-Path $InstallRoot 'Logs\LanguesApi') -WhatIf:$Simulation | Out-Null New-OmikaDirectory -Path $RootPathLangues -WhatIf:$Simulation | Out-Null # --- 2. ACL -------------------------------------------------------------- Write-OmikaStep 'ACL NTFS minimales' Grant-OmikaAcl -Path (Join-Path $InstallRoot 'Logs\LanguesApi') -Account $Account -Right 'M' ` -RequireExisting -WhatIf:$Simulation | Out-Null # Modeles : LECTURE SEULE. Le service ne doit jamais pouvoir les modifier. foreach ($dossier in $DossiersLecture) { Grant-OmikaAcl -Path $dossier -Account $Account -Right 'R' ` -RequireExisting -WhatIf:$Simulation | Out-Null } # --- 3. Compte de service ------------------------------------------------ Write-OmikaStep 'Compte de service' Assert-OmikaServiceAccount -Account $Account | Out-Null # --- 4. Port loopback ---------------------------------------------------- if ($Port -gt 0) { Write-OmikaStep "Verification du port loopback $Port" $verdict = Test-OmikaPortLibre -Port $Port if ($verdict.Libre) { Write-OmikaOk "Port $Port disponible : peut etre fixe dans ASPNETCORE_URLS." } else { Write-OmikaWarn "Port $Port NON disponible : $($verdict.Raisons)" Write-OmikaWarn ' -> choisissez un autre port AVANT de configurer le service,' Write-OmikaWarn ' et reportez le meme numero dans le ProxyPass du vhost Apache.' } } else { Write-OmikaStep 'Port loopback (non verifie)' Write-OmikaInfo 'Aucun -Port fourni : le port se decide contre le plan Apache' Write-OmikaInfo ' (DEPLOIEMENT_API_LANGUES.md §6bis). Relancez avec -Port pour le verifier.' } # --- 5. Service Windows -------------------------------------------------- Write-OmikaStep "Creation du service Windows ($StartupType)" Install-OmikaService -Name $ServiceName -DisplayName $NomAffiche ` -ExePath $cheminExe -Account $Account -Description $Description ` -StartupType $StartupType -WhatIf:$Simulation | Out-Null # --- 6. Recapitulatif ---------------------------------------------------- $rappelPort = 'ASPNETCORE_URLS=http://127.0.0.1: (voir §6bis, aucune valeur en dur)' if ($Port -gt 0) { $rappelPort = "ASPNETCORE_URLS=http://127.0.0.1:$Port (verifie disponible par ce script)" } Write-OmikaServiceSummary -Name $ServiceName -ExePath $cheminExe -Account $Account -Rappels @( 'Injecter la configuration en variables MACHINE (aucun secret : ce service est anonyme) :' " Langues__RootPath=$RootPathLangues" " $rappelPort" ' ASPNETCORE_ENVIRONMENT=Production' 'Ce service ne consomme AUCUN secret : ni HFSQL, ni PostgreSQL, ni cle.' 'Reporter le MEME port dans le ProxyPass du vhost Apache (expose en HTTPS).' 'Deployer les modeles + manifest.json dans Langues__RootPath (aucun redemarrage requis ensuite).' 'Ecrire la ligne HFSQL ParametreSysteme SRV_LANGUES = URL publique du service.' 'Le service est ANONYME : ne pas l''exposer sur Internet sans le reverse proxy.' ) exit 0 } catch { Write-OmikaFail $_.Exception.Message exit 1 }