lecoffre_node/run.ps1
2025-08-13 17:19:16 +02:00

190 lines
7.3 KiB
PowerShell
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.

# run.ps1 — installation & démarrage automatiques (Windows)
# - Installe Docker Desktop si absent
# - Active WSL2/VirtualMachinePlatform si nécessaire
# - Démarre Docker Desktop (headless) et attend le daemon
# - Lance `docker compose up -d`
# - Enregistre une reprise RunOnce + retourne 3010 si un reboot est requis
Param(
[switch]$PostReboot
)
# --- Sécurité / contexte ---
$IsAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()
).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
if (-not $IsAdmin) {
Write-Host "Relance en administrateur..."
Start-Process -Verb RunAs -FilePath "powershell.exe" -ArgumentList "-NoProfile", "-ExecutionPolicy", "Bypass", "-File", "`"$PSCommandPath`""
exit
}
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
# --- Dossiers / chemins ---
$installRoot = Split-Path -Path $MyInvocation.MyCommand.Path -Parent
$logDir = Join-Path -Path $installRoot -ChildPath 'logs'
if (-not (Test-Path $logDir)) { New-Item -ItemType Directory -Path $logDir | Out-Null }
$PsLog = Join-Path $logDir 'install-ps.log' # <— log distinct pour éviter le verrou NSIS
Push-Location $installRoot
$ProgramFilesDocker = Join-Path $Env:ProgramFiles 'Docker\Docker'
$DockerExe = Join-Path $ProgramFilesDocker 'resources\bin\docker.exe'
$DockerDesktopExe = Join-Path $ProgramFilesDocker 'Docker Desktop.exe'
$DockerCliExe = Join-Path $ProgramFilesDocker 'DockerCli.exe'
function Write-Log($msg) {
$stamp = (Get-Date).ToString("yyyy-MM-dd HH:mm:ss")
try { Add-Content -Path $PsLog -Value "$stamp $msg" -Encoding utf8 -ErrorAction SilentlyContinue } catch { }
Write-Host $msg
}
function Test-PendingReboot {
$paths = @(
'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending',
'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired',
'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager'
)
foreach ($p in $paths) {
if (Test-Path $p) {
if ($p -like '*Session Manager*') {
$val = (Get-ItemProperty -Path $p -Name 'PendingFileRenameOperations' -ErrorAction SilentlyContinue)
if ($val) { return $true }
}
else { return $true }
}
}
return $false
}
function Register-RunOnce {
$runOnceKey = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\RunOnce'
New-Item -Path $runOnceKey -Force | Out-Null
$cmd = "powershell.exe -NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`" -PostReboot"
Set-ItemProperty -Path $runOnceKey -Name 'KogusPostInstall' -Value $cmd
Write-Log "RunOnce enregistré : $cmd"
}
function Enable-WSLPrereqs {
Write-Log "Activation des fonctionnalités Windows (WSL2 / VirtualMachinePlatform) si nécessaire..."
$rebootNeeded = $false
& dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart | Out-Null
if ($LASTEXITCODE -eq 3010) { $rebootNeeded = $true }
& dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart | Out-Null
if ($LASTEXITCODE -eq 3010) { $rebootNeeded = $true }
try { wsl.exe --set-default-version 2 > $null 2>&1 } catch { }
return $rebootNeeded
}
function Install-DockerDesktop {
if (Test-Path $DockerExe) { return $false }
Write-Log "Docker Desktop absent : installation silencieuse…"
$installerUrl = 'https://desktop.docker.com/win/main/amd64/Docker%20Desktop%20Installer.exe'
$installerPath = Join-Path -Path $installRoot -ChildPath 'docker-installer.exe'
try {
Invoke-WebRequest -UseBasicParsing -Uri $installerUrl -OutFile $installerPath
}
catch {
Write-Log "Téléchargement direct échoué, tentative via winget…"
try {
winget --version > $null 2>&1
winget install --id Docker.DockerDesktop -e --accept-source-agreements --accept-package-agreements
return $true
}
catch { throw "Impossible de télécharger Docker Desktop ($($_.Exception.Message))." }
}
$InstallerArguments = @('install', '--quiet', '--accept-license', '--backend=wsl-2', '--always-run-service') # flags officiels
Start-Process -FilePath $installerPath -ArgumentList $InstallerArguments -Wait
Remove-Item -Path $installerPath -Force -ErrorAction SilentlyContinue
Write-Log "Installation de Docker Desktop terminée."
return $true
}
function Ensure-UserInDockerUsers {
try { & net localgroup docker-users $env:USERNAME /add > $null 2>&1 } catch { }
}
function Start-DockerDesktop-And-Wait {
# 1) s'assurer que le service est en auto + démarré
try { Set-Service -Name 'com.docker.service' -StartupType Automatic -ErrorAction SilentlyContinue } catch { }
try { Start-Service -Name 'com.docker.service' -ErrorAction SilentlyContinue } catch { }
# 2) démarrage headless via Docker Desktop CLI (4.37+) → docker desktop start/status/engine use
try { & $DockerExe desktop start > $null 2>&1 } catch { }
try { & $DockerExe desktop engine use linux > $null 2>&1 } catch { } # force le moteur Linux
# 3) boucle dattente (statut Desktop + daemon Engine)
$deadline = (Get-Date).AddMinutes(10)
while ((Get-Date) -lt $deadline) {
try {
$status = (& $DockerExe desktop status 2>$null).Trim()
if ($status -match 'running') {
& $DockerExe version --format '{{.Server.Version}}' > $null 2>&1
if ($LASTEXITCODE -eq 0) {
Write-Log "Docker Desktop: $status (daemon OK)"
return $true
}
}
}
catch { }
Start-Sleep -Seconds 3
}
# 4) fallback : lancer lUI si nécessaire (premier démarrage/initialisation WSL)
try { Start-Process -FilePath $DockerDesktopExe -ErrorAction SilentlyContinue } catch { }
$deadline2 = (Get-Date).AddMinutes(10)
while ((Get-Date) -lt $deadline2) {
try {
& $DockerExe version --format '{{.Server.Version}}' > $null 2>&1
if ($LASTEXITCODE -eq 0) { Write-Log "Docker daemon prêt (après lancement UI)."; return $true }
}
catch { }
Start-Sleep -Seconds 3
}
Write-Log "Le daemon Docker ne répond pas (timeout)."
return $false
}
# --- Orchestration ---
$rebootNeeded = $false
if (-not $PostReboot) {
if (Enable-WSLPrereqs) { $rebootNeeded = $true }
}
$installedNow = $false
if (-not (Get-Command $DockerExe -ErrorAction SilentlyContinue)) {
$installedNow = Install-DockerDesktop
}
if ($rebootNeeded -or (Test-PendingReboot)) {
Write-Log "Un redémarrage Windows est requis. Enregistrement d'une reprise automatique…"
Register-RunOnce
Pop-Location
exit 3010
}
Ensure-UserInDockerUsers
if (-not (Start-DockerDesktop-And-Wait)) {
Write-Log "Docker n'est pas prêt. Un redémarrage peut être requis."
Pop-Location
exit 1
}
# Lancer la stack
$composeCmd = "`"$DockerExe`" compose"
Write-Log "Lancement de '$composeCmd up -d'…"
$runLog = Join-Path -Path $logDir -ChildPath 'run.log'
& cmd.exe /c "$composeCmd up -d > `"$runLog`" 2>&1"
if ($LASTEXITCODE -ne 0) {
Write-Log "Erreur lors du démarrage. Voir le log : $runLog"
Pop-Location
exit 1
}
else {
Write-Log "Stack démarrée. Logs : $runLog"
}
Pop-Location
exit 0