setup-wsl-debian.bat (16341B)
1 @echo off 2 :: This file is part of GNU Taler. 3 :: Copyright (C) 2025 Taler Systems SA 4 :: 5 :: TALER is free software; you can redistribute it and/or modify it under the 6 :: terms of the GNU Lesser General Public License as published by the Free Software 7 :: Foundation; either version 2.1, or (at your option) any later version. 8 :: 9 :: TALER is distributed in the hope that it will be useful, but WITHOUT ANY 10 :: WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 11 :: A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 :: 13 :: You should have received a copy of the GNU Lesser General Public License along with 14 :: TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> 15 :: 16 :: Author: Léa Oualli 17 18 setlocal enabledelayedexpansion 19 20 REM -------------------------- LOGFILE GLOBALE --------------------------- 21 set LOGFILE=C:\Users\Public\taler-bat.log 22 23 echo [%DATE% %TIME%] === [START] GNU Taler-Merchant Installer === >> %LOGFILE% 24 echo [%DATE% %TIME%] Arguments : STEP="%1" DOMAIN="%2" DISTRO="%3" PROXY_MODE="%4" >> %LOGFILE% 25 26 set WSL_USER=taleruser 27 set INSTALL_FAILED=0 28 :: The tilde modifier below strips surrounding quotes. NSIS invokes this file 29 :: as: ALL "" Debian -- so a plain percent-2 yields the two quote characters, 30 :: which is not empty, so the localhost fallback never fired and an empty 31 :: --domain made taler-merchant-rproxy-setup swallow --httponly as the domain. 32 :: (Do not write a tilde-percent sequence in a comment: cmd still parses it.) 33 set STEP=%~1 34 set DOMAIN=%~2 35 set DISTRO=%~3 36 set PROXY_MODE=%~4 37 set WSL=wsl.exe 38 if exist "%WINDIR%\Sysnative\wsl.exe" set WSL=%WINDIR%\Sysnative\wsl.exe 39 40 if "%STEP%"=="" ( 41 set STEP=ALL 42 ) 43 44 if "%DISTRO%"=="" ( 45 set DISTRO=Debian 46 ) 47 48 echo [%DATE% %TIME%] Initial STEP="%STEP%", DOMAIN="%DOMAIN%", DISTRO="%DISTRO%", PROXY_MODE="%PROXY_MODE%" >> %LOGFILE% 49 50 if "%STEP%"=="1" goto step1 51 if "%STEP%"=="2" goto step2 52 if "%STEP%"=="3" goto step3 53 if "%STEP%"=="4" goto step4 54 if "%STEP%"=="5" goto step5 55 if "%STEP%"=="6" goto step6 56 if "%STEP%"=="7" goto step7 57 if "%STEP%"=="8" goto step8 58 59 :step1 60 echo [%DATE% %TIME%] [1/8] Checking WSL and VirtualMachinePlatform... >> %LOGFILE% 61 62 :: Check if WSL is enabled 63 powershell -Command "(Get-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux).State" | find /I "Enabled" >nul 64 set WSL_ENABLED=%errorlevel% 65 :: Check if VirtualMachinePlatform is enabled 66 powershell -Command "(Get-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatform).State" | find /I "Enabled" >nul 67 set VMP_ENABLED=%errorlevel% 68 69 if %WSL_ENABLED% equ 0 ( 70 echo [%DATE% %TIME%] WSL already enabled. >> %LOGFILE% 71 ) else ( 72 echo [%DATE% %TIME%] Enabling WSL feature... >> %LOGFILE% 73 powershell.exe -Command "Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux -NoRestart" 74 set NEED_REBOOT=1 75 ) 76 77 if %VMP_ENABLED% equ 0 ( 78 echo [%DATE% %TIME%] VirtualMachinePlatform already enabled. >> %LOGFILE% 79 ) else ( 80 echo [%DATE% %TIME%] Enabling VirtualMachinePlatform feature... >> %LOGFILE% 81 powershell.exe -Command "Enable-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatform -NoRestart" 82 set NEED_REBOOT=1 83 ) 84 85 if defined NEED_REBOOT ( 86 echo [%DATE% %TIME%] [INFO] REBOOT REQUIRED! >> %LOGFILE% 87 echo [INFO] A restart is required to finish enabling WSL features. Please restart your computer and run the installer again. 88 pause 89 exit /b 1 90 ) else ( 91 echo [%DATE% %TIME%] [INFO] WSL and VirtualMachinePlatform are ready. >> %LOGFILE% 92 ) 93 94 if not "%STEP%"=="ALL" exit /b 95 96 echo [%DATE% %TIME%] Checking for the WSL runtime... >> %LOGFILE% 97 98 :: The in-box wsl.exe in System32 is only a stub. On a machine that has no WSL 99 :: runtime it answers "The Windows Subsystem for Linux is not installed" to 100 :: --update, to a bare --install and to every flagged form, so it cannot be 101 :: relied on to bootstrap itself. Install Microsoft's official MSI instead; 102 :: msiexec /quiet does it without any prompt. This only runs when WSL really 103 :: is missing, so machines that already have it pay nothing. 104 %WSL% --version >nul 2>&1 105 if not errorlevel 1 goto wsl_runtime_present 106 107 echo [%DATE% %TIME%] WSL runtime absent; installing it from the official MSI. >> %LOGFILE% 108 echo [INFO] Installing the Windows Subsystem for Linux, a one-time download of about 350 MB. 109 set "WSLMSI=%TEMP%\wsl-runtime.msi" 110 powershell -NoProfile -ExecutionPolicy Bypass -File "%~dp0get-wsl-msi.ps1" "%WSLMSI%" >> %LOGFILE% 2>&1 111 if errorlevel 1 goto wsl_msi_download_failed 112 113 msiexec /i "%WSLMSI%" /quiet /norestart 114 set MSIRC=!errorlevel! 115 echo [%DATE% %TIME%] msiexec returned !MSIRC! >> %LOGFILE% 116 del "%WSLMSI%" >nul 2>&1 117 118 :: 3010 is ERROR_SUCCESS_REBOOT_REQUIRED. Measured on Windows 11 26H2 the MSI 119 :: returns 0 and WSL works at once, but honour 3010 if a build asks for it. 120 if !MSIRC! equ 3010 goto wsl_msi_reboot 121 if !MSIRC! neq 0 goto wsl_msi_failed 122 echo [%DATE% %TIME%] WSL runtime installed from MSI. >> %LOGFILE% 123 goto wsl_runtime_present 124 125 :wsl_msi_download_failed 126 echo [%DATE% %TIME%] [ERREUR] Could not download the WSL runtime. >> %LOGFILE% 127 echo [ERREUR] Could not download the Windows Subsystem for Linux installer. 128 exit /b 1 129 130 :wsl_msi_reboot 131 echo [%DATE% %TIME%] [INFO] WSL installed, restart required. >> %LOGFILE% 132 echo [INFO] The Windows Subsystem for Linux was installed and Windows must restart. 133 echo [INFO] Please restart your computer and run this installer again. 134 exit /b 1 135 136 :wsl_msi_failed 137 echo [%DATE% %TIME%] [ERREUR] msiexec failed with !MSIRC! >> %LOGFILE% 138 echo [ERREUR] Installing the Windows Subsystem for Linux failed, code !MSIRC!. 139 exit /b 1 140 141 :wsl_runtime_present 142 %WSL% --update 143 144 if not "%STEP%"=="ALL" exit /b 145 146 :step2 147 echo [%DATE% %TIME%] [2/8] Installing %DISTRO%... >> %LOGFILE% 148 :: --no-launch is essential: without it wsl.exe runs the distro's first-run 149 :: setup, which blocks on "Please create a default UNIX user account" with no 150 :: visible window. Step 3 creates %WSL_USER% directly instead. 151 %WSL% --install -d %DISTRO% --no-launch --web-download 152 153 154 echo [%DATE% %TIME%] Initializing %DISTRO% first launch... >> %LOGFILE% 155 %WSL% -d %DISTRO% -- bash -c "echo %DISTRO% ready" 156 if not "%STEP%"=="ALL" exit /b 157 158 :step3 159 echo [%DATE% %TIME%] [3/8] Creating Debian user if needed... >> %LOGFILE% 160 echo [%DATE% %TIME%] DISTRO="%DISTRO%", WSL_USER="%WSL_USER%" >> %LOGFILE% 161 %WSL% -d %DISTRO% -- bash -c "id %WSL_USER% >/dev/null 2>&1 || sudo useradd -m %WSL_USER%" 162 163 echo [%DATE% %TIME%] Waiting for user "%WSL_USER%" to be present... >> %LOGFILE% 164 set WAIT_TRIES=0 165 :wait_for_taleruser 166 %WSL% -d %DISTRO% -- bash -c "id %WSL_USER%" >nul 2>&1 167 if %errorlevel% neq 0 ( 168 ping -n 3 127.0.0.1 >nul 2>&1 169 set /a WAIT_TRIES+=1 170 if !WAIT_TRIES! lss 60 goto wait_for_taleruser 171 echo [%DATE% %TIME%] [ERREUR] User %WSL_USER% did not appear in %DISTRO% after ~2 minutes. >> %LOGFILE% 172 echo [ERREUR] Could not create the %WSL_USER% account inside %DISTRO%. 173 exit /b 1 174 ) 175 echo [%DATE% %TIME%] User "%WSL_USER%" exists in Debian! >> %LOGFILE% 176 177 %WSL% -d %DISTRO% -- bash -c "echo '%WSL_USER% ALL=(ALL) NOPASSWD:ALL' | sudo tee /etc/sudoers.d/%WSL_USER%" 178 %WSL% -d %DISTRO% -- bash -c "sudo chmod 0440 /etc/sudoers.d/%WSL_USER%" 179 echo [%DATE% %TIME%] Sudoers file updated. >> %LOGFILE% 180 181 REM "wsl --manage --set-default-user" is the supported way to do this. Editing 182 REM [user] into /etc/wsl.conf by hand also risks clobbering the [boot] 183 REM systemd=true stanza the Debian image ships, which every systemctl call here 184 REM depends on. Fall back to the manual edit only on older wsl.exe builds. 185 %WSL% --manage %DISTRO% --set-default-user %WSL_USER% 186 if errorlevel 1 ( 187 echo [%DATE% %TIME%] --set-default-user unavailable, editing wsl.conf >> %LOGFILE% 188 %WSL% -d %DISTRO% -u root -- bash -c "sed -i '/^\[user\]/d;/^default *=/d' /etc/wsl.conf 2>/dev/null; printf '[user]\ndefault = %WSL_USER%\n' >> /etc/wsl.conf" 189 ) 190 echo [%DATE% %TIME%] default WSL user set to %WSL_USER%. >> %LOGFILE% 191 192 :: Pour appliquer immédiatement, termine la distro : 193 %WSL% --terminate %DISTRO% 194 echo [%DATE% %TIME%] Distro %DISTRO% terminated for user change. >> %LOGFILE% 195 if not "%STEP%"=="ALL" exit /b 196 197 :step4 198 echo [%DATE% %TIME%] [4/8] Adding user to www-data group... >> %LOGFILE% 199 echo [DEBUG] DISTRO="%DISTRO%", WSL_USER="%WSL_USER%", DOMAIN="%DOMAIN%" >> %LOGFILE% 200 %WSL% -d %DISTRO% -- bash -c "sudo usermod -aG www-data %WSL_USER% || echo 'Warning: Could not add user to www-data (might already be a member)'" 201 echo [%DATE% %TIME%] User %WSL_USER% added to www-data (or already a member). >> %LOGFILE% 202 if not "%STEP%"=="ALL" exit /b 203 204 :step5 205 echo [%DATE% %TIME%] [5/8] Preparing and copying scripts... >> %LOGFILE% 206 207 REM 1. Installer dos2unix (si pas déjà installé) 208 %WSL% -d %DISTRO% -- bash -c "sudo apt-get update && sudo apt-get install -y dos2unix" 209 210 REM 2. Prepare the folder 211 %WSL% -d %DISTRO% -- bash -c "sudo mkdir -p /home/%WSL_USER%/taler-installer" 212 213 REM 3. Remove the old scripts 214 %WSL% -d %DISTRO% -- bash -c "sudo rm -f /home/%WSL_USER%/taler-installer/install-taler-from-apt.sh" 215 %WSL% -d %DISTRO% -- bash -c "sudo rm -f /home/%WSL_USER%/taler-installer/test-db.sh" 216 %WSL% -d %DISTRO% -- bash -c "sudo rm -f /home/%WSL_USER%/taler-installer/set-db.sh" 217 218 REM 4. Past the script form Windows to %TEMP% 219 copy /Y "%~dp0install-taler-from-apt.sh" "%TEMP%\install-taler-from-apt.sh" 220 copy /Y "%~dp0test-db.sh" "%TEMP%\test-db.sh" 221 copy /Y "%~dp0set-db.sh" "%TEMP%\set-db.sh" 222 223 REM 5. copy the script into WSL (via tee) 224 type "%TEMP%\install-taler-from-apt.sh" | %WSL% -d %DISTRO% -- bash -c "sudo tee /home/%WSL_USER%/taler-installer/install-taler-from-apt.sh > /dev/null" 225 type "%TEMP%\test-db.sh" | %WSL% -d %DISTRO% -- bash -c "sudo tee /home/%WSL_USER%/taler-installer/test-db.sh > /dev/null" 226 type "%TEMP%\set-db.sh" | %WSL% -d %DISTRO% -- bash -c "sudo tee /home/%WSL_USER%/taler-installer/set-db.sh > /dev/null" 227 echo [%DATE% %TIME%] Scripts copied to WSL. >> %LOGFILE% 228 229 REM 6. Convert all the scripts into UNIX format 230 %WSL% -d %DISTRO% -- bash -c "sudo dos2unix /home/%WSL_USER%/taler-installer/*.sh" 231 232 REM 7. Make the script executable 233 %WSL% -d %DISTRO% -- bash -c "sudo chmod +x /home/%WSL_USER%/taler-installer/*.sh" 234 235 REM ------------------------------------------------------------------------------ 236 237 if not "%STEP%"=="ALL" exit /b 238 239 :step6 240 echo [%DATE% %TIME%] [6/8] Checks permissions... >> %LOGFILE% 241 242 REM Check the version dos2unix (pour debug) 243 %WSL% -d %DISTRO% -- bash -c "dos2unix --version" 244 245 REM Display the format .sh ( ASCII text, Not CRLF) 246 %WSL% -d %DISTRO% -- bash -c "file /home/%WSL_USER%/taler-installer/*.sh" 247 248 REM Show the 5 firs lines of the code 249 %WSL% -d %DISTRO% -- bash -c "for f in /home/%WSL_USER%/taler-installer/*.sh; do echo '----- $f'; head -n 5 \$f; done" 250 251 REM Vérifier les droits d'exécution 252 %WSL% -d %DISTRO% -- bash -c "ls -l /home/%WSL_USER%/taler-installer/*.sh" 253 254 REM Fin du step 255 echo [%DATE% %TIME%] Scripts verified (permissions/format/headers). >> %LOGFILE% 256 if not "%STEP%"=="ALL" exit /b 257 258 :step7 259 echo [%DATE% %TIME%] [7/8] Restarting WSL... >> %LOGFILE% 260 echo [DEBUG] DISTRO="%DISTRO%" >> %LOGFILE% 261 %WSL% --shutdown 262 ping -n 4 127.0.0.1 >nul 2>&1 263 264 echo [%DATE% %TIME%] Running final installation script... >> %LOGFILE% 265 %WSL% -d %DISTRO% -- bash -c "sudo -u %WSL_USER% bash /home/%WSL_USER%/taler-installer/install-taler-from-apt.sh | tee /home/%WSL_USER%/taler-installer/install-bat.log" 266 set STEP7_STATUS=!errorlevel! 267 %WSL% -d %DISTRO% -- bash -c "sudo cp /home/%WSL_USER%/taler-installer/install-bat.log /mnt/c/Users/Public/install-bat.log" 268 echo [%DATE% %TIME%] Final install script returned !STEP7_STATUS!, log copied to Windows. >> %LOGFILE% 269 if not "!STEP7_STATUS!"=="0" set INSTALL_FAILED=1 270 if not "!STEP7_STATUS!"=="0" echo [%DATE% %TIME%] [ERREUR] install-taler-from-apt.sh failed. >> %LOGFILE% 271 if not "%STEP%"=="ALL" exit /b 272 273 :step8 274 echo [%DATE% %TIME%] [8/8] Configuring reverse proxy... >> %LOGFILE% 275 echo [%DATE% %TIME%] DISTRO="%DISTRO%", DOMAIN="%DOMAIN%", PROXY_MODE="%PROXY_MODE%" >> %LOGFILE% 276 277 echo [%DATE% %TIME%] --- Démarrage configuration reverse proxy --- >> %LOGFILE% 278 279 if "%DOMAIN%"=="" ( 280 set DOMAIN=localhost 281 echo [%DATE% %TIME%] Domaine vide, fallback sur localhost >> %LOGFILE% 282 ) 283 284 if "%PROXY_MODE%"=="" ( 285 set PROXY_MODE=http 286 echo [%DATE% %TIME%] Mode proxy vide, fallback sur HTTP >> %LOGFILE% 287 ) 288 289 REM Installe Apache (dans tous les cas) 290 echo [%DATE% %TIME%] Installation Apache2... >> %LOGFILE% 291 %WSL% -d %DISTRO% -- bash -c "sudo apt-get update && sudo apt-get install -y apache2" >> %LOGFILE% 2>&1 292 set APACHE_STATUS=!errorlevel! 293 if not "!APACHE_STATUS!"=="0" set INSTALL_FAILED=1 294 if not "!APACHE_STATUS!"=="0" echo [%DATE% %TIME%] [ERREUR] apache2 install failed (!APACHE_STATUS!). >> %LOGFILE% 295 296 if /I "%PROXY_MODE%"=="https" ( 297 echo [%DATE% %TIME%] Mode HTTPS sélectionné pour %DOMAIN% >> %LOGFILE% 298 echo [%DATE% %TIME%] Setting up HTTPS with Let's Encrypt for %DOMAIN% ... >> %LOGFILE% 299 %WSL% -d %DISTRO% -- bash -c "sudo taler-merchant-rproxy-setup --domain !DOMAIN! --apache --httpsonly" >> %LOGFILE% 2>&1 300 set CERT_STATUS=!errorlevel! 301 echo [%DATE% %TIME%] HTTPS return code : !CERT_STATUS! >> %LOGFILE% 302 if not "!CERT_STATUS!"=="0" set INSTALL_FAILED=1 303 if not "!CERT_STATUS!"=="0" ( 304 echo [%DATE% %TIME%] [ERREUR] Certificat HTTPS échec pour %DOMAIN% >> %LOGFILE% 305 echo [ERREUR] Impossible d’obtenir un certificat HTTPS valide pour %DOMAIN%. 306 echo [ERREUR] Veuillez vérifier que le domaine pointe bien sur cette machine et soit accessible publiquement. 307 ping -n 6 127.0.0.1 >nul 2>&1 308 ) 309 ) else ( 310 echo [%DATE% %TIME%] Mode HTTP sélectionné pour %DOMAIN% >> %LOGFILE% 311 echo [%DATE% %TIME%] Setting up HTTP only for %DOMAIN% ... >> %LOGFILE% 312 %WSL% -d %DISTRO% -- bash -c "sudo taler-merchant-rproxy-setup --domain !DOMAIN! --httponly --apache" >> %LOGFILE% 2>&1 313 set PROXY_STATUS=!errorlevel! 314 echo [%DATE% %TIME%] HTTP only proxy finished for !DOMAIN! with return code !PROXY_STATUS! >> %LOGFILE% 315 if not "!PROXY_STATUS!"=="0" set INSTALL_FAILED=1 316 if not "!PROXY_STATUS!"=="0" ( 317 echo [%DATE% %TIME%] [ERREUR] Echec configuration du reverse proxy HTTP pour !DOMAIN! >> %LOGFILE% 318 echo [ERREUR] Impossible de configurer le reverse proxy HTTP pour !DOMAIN!. 319 ) 320 ) 321 322 echo [%DATE% %TIME%] --- Fin configuration reverse proxy --- >> %LOGFILE% 323 324 325 echo. 326 echo Verifying domain configured in Apache... 327 %WSL% -d %DISTRO% -- bash -c "grep 'ServerName' /etc/apache2/sites-available/taler-merchant.conf || echo 'ServerName not found!'" 328 329 REM Start Apache service 330 %WSL% -d %DISTRO% -- bash -c "sudo service apache2 start" 331 332 REM Scheduled task (on next boot): Apache will start automatically 333 powershell -Command "Register-ScheduledTask -Action (New-ScheduledTaskAction -Execute '%WINDIR%\System32\wsl.exe' -Argument '-d %DISTRO% -- bash -c \"sudo service apache2 start && while true; do sleep 3600; done\"') -Trigger (New-ScheduledTaskTrigger -AtLogOn) -TaskName 'StartTalerApacheWSL' -User '$env:USERNAME' -RunLevel Highest -Force" 334 335 echo [%DATE% %TIME%] status: step7=[!STEP7_STATUS!] apache=[!APACHE_STATUS!] proxy=[!PROXY_STATUS!] cert=[!CERT_STATUS!] failed=[!INSTALL_FAILED!] >> %LOGFILE% 336 337 :: Only claim success when nothing above failed. This used to print 338 :: unconditionally -- two seconds after logging "return code 1" -- so a wizard 339 :: that had installed nothing still told the operator it had worked. 340 if !INSTALL_FAILED!==0 goto install_ok 341 342 echo [%DATE% %TIME%] [ERREUR] GNU Taler-Merchant installation FAILED. >> %LOGFILE% 343 echo [%DATE% %TIME%] === [END] GNU Taler-Merchant Installer (failed) === >> %LOGFILE% 344 echo. 345 echo [ERREUR] The installation did not complete. See %LOGFILE% 346 ping -n 6 127.0.0.1 >nul 2>&1 347 exit /b 1 348 349 :install_ok 350 echo [%DATE% %TIME%] GNU Taler-Merchant installed successfully! >> %LOGFILE% 351 echo [%DATE% %TIME%] === [END] GNU Taler-Merchant Installer === >> %LOGFILE% 352 ping -n 6 127.0.0.1 >nul 2>&1 353 exit /b 0