From e1d69cbc1563fbffa163dc0cbdafa3ed1a9a88e2 Mon Sep 17 00:00:00 2001 From: omaroughriss Date: Wed, 13 Aug 2025 17:19:16 +0200 Subject: [PATCH] Update ps script to install and run docker --- run.ps1 | 217 +++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 175 insertions(+), 42 deletions(-) diff --git a/run.ps1 b/run.ps1 index fc5123b..e72e870 100644 --- a/run.ps1 +++ b/run.ps1 @@ -1,56 +1,189 @@ -# run.ps1 — script d'installation et de démarrage +# 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() +Param( + [switch]$PostReboot +) -# 1. Detection de la CLI Docker (docker vs docker-compose) -Write-Host "=== Verification de Docker CLI ===" -$dockerCmd = $null -try { - docker version --format '{{.Client.Version}}' > $null 2>&1 - $dockerCmd = 'docker' -} catch { - try { - docker-compose version > $null 2>&1 - $dockerCmd = 'docker-compose' - } catch { - $dockerCmd = $null - } +# --- 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 -if ($dockerCmd) { - Write-Host "Docker CLI detectee : $dockerCmd" -} else { - Write-Host "Docker non trouve. Installation de Docker Desktop..." - $installerUrl = 'https://desktop.docker.com/win/stable/Docker%20Desktop%20Installer.exe' - $installerPath = Join-Path -Path $PSScriptRoot -ChildPath 'docker-installer.exe' - Invoke-WebRequest -UseBasicParsing -Uri $installerUrl -OutFile $installerPath - Start-Process -FilePath $installerPath -ArgumentList '/quiet' -Wait - Remove-Item -Path $installerPath -Force - Write-Host "Installation de Docker Desktop terminee." - $dockerCmd = 'docker' -} - -# 2. Se placer dans le repertoire contenant docker-compose.yml -Push-Location +# --- Dossiers / chemins --- $installRoot = Split-Path -Path $MyInvocation.MyCommand.Path -Parent -Set-Location $installRoot - -# 3. Creation du dossier de logs $logDir = Join-Path -Path $installRoot -ChildPath 'logs' -if (-not (Test-Path $logDir)) { - New-Item -ItemType Directory -Path $logDir | Out-Null +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 } -# 4. Demarrage de la stack et redirection des logs -$composeCmd = if ($dockerCmd -eq 'docker') { 'docker compose' } else { 'docker-compose' } -Write-Host "Lancement de '$composeCmd up -d'..." +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 d’attente (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 l’UI 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' -# On passe par cmd.exe pour que > et 2>&1 fonctionnent correctement & cmd.exe /c "$composeCmd up -d > `"$runLog`" 2>&1" if ($LASTEXITCODE -ne 0) { - Write-Host "Erreur lors du demarrage. Voir le log : $runLog" -} else { - Write-Host "Stack demarree. Logs disponibles dans : $runLog" + 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