taler-windows

Windows packaging
Log | Files | Refs

commit 2dfb472bf88c37df43dd64a89d23f1da457eb7ab
parent 2d7a43ded79da78587e0e874de66e474d6bc72e7
Author: Christian Grothoff <christian@grothoff.org>
Date:   Sun,  1 Nov 2026 16:58:36 +0100

improve translations and installer robustness

Diffstat:
MCLAUDE.md | 78+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------
Mreadme.txt | 11++++++++++-
Mtaler-installer-taler.nsi | 400++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
Mtest-db.sh | 9+++++++--
4 files changed, 451 insertions(+), 47 deletions(-)

diff --git a/CLAUDE.md b/CLAUDE.md @@ -19,10 +19,22 @@ Twelve tracked files, no build system, no test suite. It is also the odd one out makensis taler-installer-taler.nsi # produces taler-installer.exe (gitignored) ``` -`makensis` is **not installed in this workspace** and the result only runs on Windows with -WSL available, so changes here cannot be compiled or exercised locally — they are reviewed -by reading. Required at compile time in the same directory: `logo-header.ico`, -`logo-header.bmp`, `logo-welcome.bmp`, and the four scripts listed in the `File` directives. +`makensis` is not installed in this workspace, but it does **not** have to be: the Debian +package can be unpacked into the scratchpad without root and run from there, which does +compile this installer (verified with 3.11). That catches every syntax error, missing +`LangString` and encoding problem — do it instead of reviewing the `.nsi` by eye: + +```sh +cd "$SCRATCH" && apt-get download nsis nsis-common +for f in *.deb; do dpkg-deb -x "$f" root; done +cd /home/claude/taler-windows +NSISDIR="$SCRATCH/root/usr/share/nsis" "$SCRATCH/root/usr/bin/makensis" -WX \ + taler-installer-taler.nsi && rm -f taler-installer.exe +``` + +Only *running* the result needs Windows with WSL. Required at compile time in the same +directory: `logo-header.ico`, `logo-header.bmp`, `logo-welcome.bmp`, and the four scripts +listed in the `File` directives. ## Control flow @@ -103,14 +115,35 @@ Scattered, and worth knowing before debugging a user report: | Path | Written by | | --- | --- | +| `C:\Users\Public\install.log` | the `.nsi` itself, via `TalerLog` (truncated at each start) | | `C:\Users\Public\taler-bat.log` | `setup-wsl-debian.bat` (truncated at each start) | | `C:\Users\Public\taler-sh.log` | `install-taler-from-apt.sh` (via `exec > >(tee -a)`) | | `C:\Users\Public\install-bat.log` | copied out of WSL at the end of step 7 | | `/home/taleruser/taler-installer/install-sh.log`, `test-db.log` | the bash scripts | | `/tmp/dbtest.log` | `test-db.sh` | -`readme.txt` and `.onInstFailed` both point at `C:\Users\Public\install.log`, which nothing -writes. +`install.log` is the Windows-side timeline that `readme.txt`, `MSG_INSTALL_FAILED` and +`.onInstFailed` have always promised: the machine and Windows build, the four wizard +answers, the exit code of every `nsExec` call, the reverse-proxy probe, the verdict, and a +closing list of the other log paths. It exists because when WSL is what failed, every log +in the table below it is unreachable. Rules for extending it: + +- **Write through `${TLog}` (log only) or `${TSay}` (log *and* details view),** never a + bare `DetailPrint` for anything diagnostic. `TalerLog` reopens the file per line on + purpose — the installer can be killed inside a ten-minute `nsExec` call, and what was + written before that has to already be on disk. +- **Nothing secret may be written there.** `C:\Users\Public` is readable by every account + on the machine. The external-database URL carries a password, so it goes through + `RedactDbUrl` (drop everything through the last `@`) before it reaches either the log or + the details view; `test-db.sh` does the same with `${1##*@}` for its own two logs. +- **Do not log the `[2/8]`..`[6/8]` lines.** They are cosmetic `DetailPrint`s; all of that + work actually happens in the single `setup-wsl-debian.bat ALL` call, and a log claiming + six steps that never individually ran would be worse than no log. +- `nsExec::ExecToLog` pushes one value, `ExecToStack` pushes the output *and then* the exit + code, so the latter needs two `Pop`s (verified in `Contrib/nsExec/nsexec.c`; it pushes a + single value only when it cannot build a command line at all, which needs an empty + command string). Several calls here used to pop nothing and both lost the diagnostic and + left entries on the global stack. ## Test harness @@ -230,7 +263,7 @@ Still open, and worth knowing before debugging a user report: re-asks everything. For automated runs, snapshot a VM with the WSL features already enabled. - **`.onGUIEnd` shows a MessageBox and opens a browser on any exit**, including user - cancel and failure. + cancel and failure. (It now at least logs which of those happened.) - **Progress percentages are fake** — `Sleep`-driven `DetailPrint` lines, because the long `nsExec` calls block the GUI. - **Start-menu shortcut** points at `$INSTDIR\taler-installer.exe`, which the section @@ -246,10 +279,33 @@ Still open, and worth knowing before debugging a user report: want it). Step 5 runs `dos2unix` in WSL as a belt-and-braces measure, so a stray CRLF in a `.sh` survives — keep them LF anyway. - GPLv2.1+ header with `Author: Léa Oualli` on the `.bat`/`.nsi`/`.sh` files that have one. -- Comments and some log messages are in **French**, user-facing strings are bilingual: every - new wizard string needs a `LangString` for both `${LANG_ENGLISH}` and `${LANG_FRENCH}`. - Avoid accented characters in `LangString` values — the existing French ones are written - unaccented ("Etape", "redemarrer") because of NSIS codepage handling. +- Comments and some log messages are in **French**; user-facing strings are localised into + six languages. Every new wizard string needs a `LangString` for all of + `${LANG_ENGLISH}`, `${LANG_FRENCH}`, `${LANG_GERMAN}`, `${LANG_ITALIAN}`, + `${LANG_SPANISH}` and `${LANG_DUTCH}` — an id missing from one language falls back to + the first declared language (English) with no warning, so keep the six lines per id + adjacent and check with + `grep -c 'LANG_GERMAN}' taler-installer-taler.nsi` against the other five. +- **`taler-installer-taler.nsi` must keep its UTF-8 BOM.** `Unicode true` governs the + *output*, not how the *source* is read. The BOM is what makes the source decode as UTF-8 + unconditionally: measured with `makensis` 3.11, a BOM'd script compiles as UTF-8 even + when overridden with `-INPUTCHARSET CP1252` (all accents intact), while the same script + with the BOM stripped obeys that codepage and turns 3 of 4 probe strings into mojibake. + BOM-less UTF-8 is merely auto-detected as a fallback, which is why it happens to work on + a Linux host whose ACP is already UTF-8 and cannot be relied on for a Windows build. + Dropping the BOM therefore corrupts every `ä ö ü ß è à á í ñ ¿ ¡ ï` in a `LangString` — + that is why the French strings used to be written unaccented ("Etape", "redemarrer"). + They may now be accented properly; several still are not. +- Never put U+202F (narrow no-break space, the French space before `?`/`!`) in a + `LangString`. It exists in no Windows ANSI codepage and renders as three stray glyphs + if the BOM is ever lost. +- Translated terminology comes from the workspace glossary `../dictionary.csv`, not from + taste: `merchant` is Händler / comerciante / commerçant / venditore / verkoper, and + `backend` stays an English loanword inflected natively. +- `.onInit` exists only to `!insertmacro MUI_LANGDLL_DISPLAY`. The `MUI_LANGDLL_*` defines + near the top configure that dialog but do not show it; drop the `.onInit` and the + installer silently runs in the system language, or English, and every translation + becomes unreachable. - `test-if.bat` is a scratch file for checking the `MODE`/`TYPE` branch logic, not part of the installer. `run-admin.bat` just re-launches `setup-wsl-debian.bat` elevated via PowerShell for manual testing outside the wizard. diff --git a/readme.txt b/readme.txt @@ -77,5 +77,14 @@ This document clearly explains the purpose and function of each file included in * Start the installation using `taler-installer.exe`. * Follow the steps provided in the NSIS interface. -* Installation logs are generated in `C:\Users\Public\install.log` to facilitate debugging. +* The installer writes `C:\Users\Public\install.log`: the Windows-side timeline of + the run -- the answers given in the wizard, the exit code of every step, the + result of the final reverse-proxy probe, and the verdict. It never contains the + database password. +* The scripts it drives keep their own, more detailed logs: + `C:\Users\Public\taler-bat.log` (`setup-wsl-debian.bat`), + `C:\Users\Public\taler-sh.log` (`install-taler-from-apt.sh`), + `C:\Users\Public\install-bat.log` (copied out of WSL at step 7), and + `/home/taleruser/taler-installer/install-sh.log` plus `test-db.log` inside WSL. + `install.log` ends with a list of these paths. diff --git a/taler-installer-taler.nsi b/taler-installer-taler.nsi @@ -1,4 +1,4 @@ -; This file is part of GNU Taler. +; This file is part of GNU Taler. ; Copyright (C) 2025 Taler Systems SA ; ; Author: Léa Oualli @@ -12,6 +12,9 @@ Unicode true !include "nsDialogs.nsh" !define MUI_ABORTWARNING +; MUI owns .onUserAbort (that is how MUI_ABORTWARNING works), so the +; cancellation is logged through MUI's own hook instead of a second one. +!define MUI_CUSTOMFUNCTION_ABORT "TalerOnAbort" !define MUI_LANGDLL_DISPLAY !define MUI_LANGDLL_REGISTRY_ROOT "HKCU" !define MUI_LANGDLL_REGISTRY_KEY "Software\TalerInstaller" @@ -30,6 +33,11 @@ Icon "logo-header.ico" !define MUI_HEADERIMAGE_BITMAP_NOSTRETCH !define MUI_WELCOMEFINISHPAGE_BITMAP "logo-welcome.bmp" +; MSG_WELCOME_TITLE / MSG_WELCOME_TEXT were translated but never +; referenced, so the welcome page showed the generic MUI text in every +; language. $_CLICK is supplied by the MUI language files. +!define MUI_WELCOMEPAGE_TITLE "$(MSG_WELCOME_TITLE)" +!define MUI_WELCOMEPAGE_TEXT "$(MSG_WELCOME_TEXT)$\r$\n$\r$\n$_CLICK" !insertmacro MUI_PAGE_WELCOME !insertmacro MUI_PAGE_DIRECTORY Page custom DistroPage DistroPageLeave @@ -42,6 +50,10 @@ Page custom DBUrlPage DBUrlPageLeave !insertmacro MUI_LANGUAGE "English" !insertmacro MUI_LANGUAGE "French" +!insertmacro MUI_LANGUAGE "German" +!insertmacro MUI_LANGUAGE "Italian" +!insertmacro MUI_LANGUAGE "Spanish" +!insertmacro MUI_LANGUAGE "Dutch" Var /GLOBAL HWND_PROGRESS_LABEL Var /GLOBAL DOMAIN_INPUT @@ -61,69 +73,319 @@ Var /GLOBAL INSTALL_OK LangString MSG_WELCOME_TITLE ${LANG_ENGLISH} "GNU Taler-Merchant backend for Windows" LangString MSG_WELCOME_TITLE ${LANG_FRENCH} "Backend GNU Taler-Merchant pour Windows" +LangString MSG_WELCOME_TITLE ${LANG_GERMAN} "GNU Taler-Merchant-Backend für Windows" +LangString MSG_WELCOME_TITLE ${LANG_ITALIAN} "Backend GNU Taler-Merchant per Windows" +LangString MSG_WELCOME_TITLE ${LANG_SPANISH} "Backend de GNU Taler-Merchant para Windows" +LangString MSG_WELCOME_TITLE ${LANG_DUTCH} "GNU Taler-Merchant-backend voor Windows" LangString MSG_WELCOME_TEXT ${LANG_ENGLISH} "This wizard will install The GNU Taler-Merchant using WSL and Debian or Ubuntu." -LangString MSG_WELCOME_TEXT ${LANG_FRENCH} "Cet assistant va installer GNU Taler-Merchant avec WSL et Debian ou Ubuntu." +LangString MSG_WELCOME_TEXT ${LANG_FRENCH} "Cet assistant va installer le backend GNU Taler-Merchant avec WSL et Debian ou Ubuntu." +LangString MSG_WELCOME_TEXT ${LANG_GERMAN} "Dieser Assistent installiert das GNU Taler-Merchant-Backend mit WSL und Debian oder Ubuntu." +LangString MSG_WELCOME_TEXT ${LANG_ITALIAN} "Questa procedura guidata installerà il backend GNU Taler-Merchant tramite WSL e Debian o Ubuntu." +LangString MSG_WELCOME_TEXT ${LANG_SPANISH} "Este asistente instalará el backend de GNU Taler-Merchant mediante WSL y Debian o Ubuntu." +LangString MSG_WELCOME_TEXT ${LANG_DUTCH} "Deze wizard installeert de GNU Taler-Merchant-backend met WSL en Debian of Ubuntu." LangString ENTER_DOMAIN ${LANG_ENGLISH} "Enter your Taler-Merchant domain name:" -LangString ENTER_DOMAIN ${LANG_FRENCH} "Entrez le nom de votre domaine Taler-Merchant:" +LangString ENTER_DOMAIN ${LANG_FRENCH} "Entrez le nom de domaine de votre backend Taler-Merchant :" +LangString ENTER_DOMAIN ${LANG_GERMAN} "Geben Sie den Domainnamen Ihres Taler-Merchant-Backends ein:" +LangString ENTER_DOMAIN ${LANG_ITALIAN} "Inserire il nome di dominio del backend Taler-Merchant:" +LangString ENTER_DOMAIN ${LANG_SPANISH} "Introduzca el nombre de dominio de su backend Taler-Merchant:" +LangString ENTER_DOMAIN ${LANG_DUTCH} "Voer de domeinnaam van uw Taler-Merchant-backend in:" LangString MSG_DOMAIN_REQUIRED ${LANG_ENGLISH} "Please enter a domain name." LangString MSG_DOMAIN_REQUIRED ${LANG_FRENCH} "Veuillez saisir un nom de domaine." +LangString MSG_DOMAIN_REQUIRED ${LANG_GERMAN} "Bitte geben Sie einen Domainnamen ein." +LangString MSG_DOMAIN_REQUIRED ${LANG_ITALIAN} "Inserire un nome di dominio." +LangString MSG_DOMAIN_REQUIRED ${LANG_SPANISH} "Introduzca un nombre de dominio." +LangString MSG_DOMAIN_REQUIRED ${LANG_DUTCH} "Voer een domeinnaam in." LangString MSG_LOCALHOST_WARN ${LANG_ENGLISH} "Warning: using 'localhost' means your merchant will not be publicly accessible." -LangString MSG_LOCALHOST_WARN ${LANG_FRENCH} "Attention : utiliser 'localhost' signifie que votre marchand ne sera pas accessible publiquement." +LangString MSG_LOCALHOST_WARN ${LANG_FRENCH} "Attention : utiliser 'localhost' signifie que votre commerçant ne sera pas accessible publiquement." +LangString MSG_LOCALHOST_WARN ${LANG_GERMAN} "Warnung: Mit 'localhost' ist Ihr Händler nicht öffentlich erreichbar." +LangString MSG_LOCALHOST_WARN ${LANG_ITALIAN} "Attenzione: usando 'localhost' il venditore non sarà raggiungibile pubblicamente." +LangString MSG_LOCALHOST_WARN ${LANG_SPANISH} "Advertencia: al usar 'localhost', su comerciante no será accesible públicamente." +LangString MSG_LOCALHOST_WARN ${LANG_DUTCH} "Waarschuwing: met 'localhost' is uw verkoper niet openbaar toegankelijk." LangString MSG_STEP1 ${LANG_ENGLISH} "Step 1: Enabling WSL and VirtualMachinePlatform.$\r$\n$\r$\nThis is the slowest step and can take several minutes (up to 10 minutes on some computers).$\r$\n$\r$\nPlease DO NOT close the installer. You will see the progress bar freeze during this step.$\r$\n$\r$\nThe installation will continue automatically once this step is done." -LangString MSG_STEP1 ${LANG_FRENCH} "Etape 1 : Activation de WSL et VirtualMachinePlatform.$\r$\n$\r$\nC'est l'etape la plus lente et cela peut prendre plusieurs minutes (jusqu'a 10 minutes sur certains ordinateurs).$\r$\n$\r$\nVeuillez NE PAS fermer l'installateur. La barre de progression peut sembler bloquee.$\r$\n$\r$\nL'installation continuera automatiquement des que cette etape sera terminee." +LangString MSG_STEP1 ${LANG_FRENCH} "Étape 1 : activation de WSL et VirtualMachinePlatform.$\r$\n$\r$\nC'est l'étape la plus lente et elle peut prendre plusieurs minutes (jusqu'à 10 minutes sur certains ordinateurs).$\r$\n$\r$\nVeuillez NE PAS fermer l'installateur. La barre de progression peut sembler bloquée pendant cette étape.$\r$\n$\r$\nL'installation continuera automatiquement dès que cette étape sera terminée." +LangString MSG_STEP1 ${LANG_GERMAN} "Schritt 1: WSL und VirtualMachinePlatform werden aktiviert.$\r$\n$\r$\nDies ist der langsamste Schritt und kann mehrere Minuten dauern (auf manchen Rechnern bis zu 10 Minuten).$\r$\n$\r$\nSchließen Sie das Installationsprogramm NICHT. Der Fortschrittsbalken bleibt in diesem Schritt scheinbar stehen.$\r$\n$\r$\nDie Installation wird automatisch fortgesetzt, sobald dieser Schritt abgeschlossen ist." +LangString MSG_STEP1 ${LANG_ITALIAN} "Passo 1: attivazione di WSL e VirtualMachinePlatform.$\r$\n$\r$\nQuesto è il passo più lento e può richiedere diversi minuti (fino a 10 minuti su alcuni computer).$\r$\n$\r$\nNON chiudere il programma di installazione. In questa fase la barra di avanzamento sembrerà bloccata.$\r$\n$\r$\nL'installazione continuerà automaticamente al termine di questo passo." +LangString MSG_STEP1 ${LANG_SPANISH} "Paso 1: activación de WSL y VirtualMachinePlatform.$\r$\n$\r$\nEste es el paso más lento y puede tardar varios minutos (hasta 10 minutos en algunos equipos).$\r$\n$\r$\nNO cierre el instalador. Durante este paso la barra de progreso parecerá detenida.$\r$\n$\r$\nLa instalación continuará automáticamente cuando el paso haya terminado." +LangString MSG_STEP1 ${LANG_DUTCH} "Stap 1: WSL en VirtualMachinePlatform worden geactiveerd.$\r$\n$\r$\nDit is de langzaamste stap en kan enkele minuten duren (op sommige computers tot 10 minuten).$\r$\n$\r$\nSluit het installatieprogramma NIET. De voortgangsbalk lijkt tijdens deze stap stil te staan.$\r$\n$\r$\nDe installatie gaat automatisch verder zodra deze stap klaar is." LangString MSG_NEED_REBOOT ${LANG_ENGLISH} "WSL features have just been enabled. You must restart your computer NOW to continue the installation. Please run this installer again after reboot." -LangString MSG_NEED_REBOOT ${LANG_FRENCH} "Les fonctionnalites WSL viennent d'etre activees. Vous devez redemarrer votre ordinateur MAINTENANT pour poursuivre l'installation. Relancez cet installateur apres redemarrage." +LangString MSG_NEED_REBOOT ${LANG_FRENCH} "Les fonctionnalités WSL viennent d'être activées. Vous devez redémarrer votre ordinateur MAINTENANT pour poursuivre l'installation. Relancez cet installateur après le redémarrage." +LangString MSG_NEED_REBOOT ${LANG_GERMAN} "Die WSL-Funktionen wurden gerade aktiviert. Sie müssen Ihren Computer JETZT neu starten, um die Installation fortzusetzen. Starten Sie dieses Installationsprogramm nach dem Neustart erneut." +LangString MSG_NEED_REBOOT ${LANG_ITALIAN} "Le funzionalità WSL sono state appena attivate. È necessario riavviare il computer ORA per continuare l'installazione. Eseguire di nuovo questo programma di installazione dopo il riavvio." +LangString MSG_NEED_REBOOT ${LANG_SPANISH} "Las funciones de WSL se acaban de activar. Debe reiniciar el equipo AHORA para continuar la instalación. Vuelva a ejecutar este instalador después del reinicio." +LangString MSG_NEED_REBOOT ${LANG_DUTCH} "De WSL-functies zijn net geactiveerd. U moet uw computer NU opnieuw opstarten om de installatie voort te zetten. Start dit installatieprogramma na het opnieuw opstarten nogmaals." LangString MSG_UPDATE_WSL ${LANG_ENGLISH} "A Windows update window will now appear to update WSL. Please follow the instructions in the black window and press any key if prompted. Click OK to continue." -LangString MSG_UPDATE_WSL ${LANG_FRENCH} "Une fenetre de mise a jour Windows va apparaitre pour mettre a jour WSL. Suivez les instructions et appuyez sur une touche si demande. Cliquez sur OK pour continuer." +LangString MSG_UPDATE_WSL ${LANG_FRENCH} "Une fenêtre Windows va apparaître pour mettre à jour WSL. Suivez les instructions affichées dans la fenêtre noire et appuyez sur une touche si cela vous est demandé. Cliquez sur OK pour continuer." +LangString MSG_UPDATE_WSL ${LANG_GERMAN} "Es erscheint nun ein Windows-Fenster, um WSL zu aktualisieren. Folgen Sie den Anweisungen im schwarzen Fenster und drücken Sie eine beliebige Taste, wenn Sie dazu aufgefordert werden. Klicken Sie auf OK, um fortzufahren." +LangString MSG_UPDATE_WSL ${LANG_ITALIAN} "Verrà ora visualizzata una finestra di Windows per aggiornare WSL. Seguire le istruzioni nella finestra nera e premere un tasto qualsiasi se richiesto. Fare clic su OK per continuare." +LangString MSG_UPDATE_WSL ${LANG_SPANISH} "Ahora aparecerá una ventana de Windows para actualizar WSL. Siga las instrucciones de la ventana negra y pulse cualquier tecla si se le solicita. Haga clic en OK para continuar." +LangString MSG_UPDATE_WSL ${LANG_DUTCH} "Er verschijnt nu een Windows-venster om WSL bij te werken. Volg de instructies in het zwarte venster en druk op een willekeurige toets als daarom wordt gevraagd. Klik op OK om verder te gaan." LangString MSG_INSTALL_FAILED ${LANG_ENGLISH} "Installation failed. Opening install.log..." -LangString MSG_INSTALL_FAILED ${LANG_FRENCH} "L'installation a echoue. Ouverture du fichier install.log..." +LangString MSG_INSTALL_FAILED ${LANG_FRENCH} "L'installation a échoué. Ouverture du fichier install.log..." +LangString MSG_INSTALL_FAILED ${LANG_GERMAN} "Die Installation ist fehlgeschlagen. install.log wird geöffnet..." +LangString MSG_INSTALL_FAILED ${LANG_ITALIAN} "Installazione non riuscita. Apertura di install.log..." +LangString MSG_INSTALL_FAILED ${LANG_SPANISH} "La instalación ha fallado. Abriendo install.log..." +LangString MSG_INSTALL_FAILED ${LANG_DUTCH} "De installatie is mislukt. install.log wordt geopend..." LangString MSG_REVERSE_PROXY_TITLE ${LANG_ENGLISH} "Select reverse proxy mode:" LangString MSG_REVERSE_PROXY_TITLE ${LANG_FRENCH} "Choisissez le mode du reverse proxy :" +LangString MSG_REVERSE_PROXY_TITLE ${LANG_GERMAN} "Wählen Sie den Reverse-Proxy-Modus:" +LangString MSG_REVERSE_PROXY_TITLE ${LANG_ITALIAN} "Selezionare la modalità del reverse proxy:" +LangString MSG_REVERSE_PROXY_TITLE ${LANG_SPANISH} "Seleccione el modo del proxy inverso:" +LangString MSG_REVERSE_PROXY_TITLE ${LANG_DUTCH} "Selecteer de modus van de reverse proxy:" LangString MSG_HTTP_ONLY ${LANG_ENGLISH} "HTTP only" LangString MSG_HTTP_ONLY ${LANG_FRENCH} "HTTP uniquement" +LangString MSG_HTTP_ONLY ${LANG_GERMAN} "Nur HTTP" +LangString MSG_HTTP_ONLY ${LANG_ITALIAN} "Solo HTTP" +LangString MSG_HTTP_ONLY ${LANG_SPANISH} "Solo HTTP" +LangString MSG_HTTP_ONLY ${LANG_DUTCH} "Alleen HTTP" LangString MSG_HTTPS ${LANG_ENGLISH} "HTTPS" LangString MSG_HTTPS ${LANG_FRENCH} "HTTPS" +LangString MSG_HTTPS ${LANG_GERMAN} "HTTPS" +LangString MSG_HTTPS ${LANG_ITALIAN} "HTTPS" +LangString MSG_HTTPS ${LANG_SPANISH} "HTTPS" +LangString MSG_HTTPS ${LANG_DUTCH} "HTTPS" -LangString MSG_DOMAIN_PING_FAIL ${LANG_FRENCH} "Le domaine '$0' ne repond pas au ping.$\r$\n$\r$\nCliquez sur Retry pour reessayer ce domaine, ou Cancel pour utiliser 'localhost'. Pour changer de domaine, cliquez sur Precedent." LangString MSG_DOMAIN_PING_FAIL ${LANG_ENGLISH} "The domain '$0' did not respond to ping.$\r$\n$\r$\nClick Retry to try this domain again, or Cancel to use 'localhost'. To change domain, click Previous." +LangString MSG_DOMAIN_PING_FAIL ${LANG_FRENCH} "Le domaine '$0' ne répond pas au ping.$\r$\n$\r$\nCliquez sur Réessayer pour retenter ce domaine, ou sur Annuler pour utiliser 'localhost'. Pour changer de domaine, cliquez sur Précédent." +LangString MSG_DOMAIN_PING_FAIL ${LANG_GERMAN} "Die Domain '$0' hat nicht auf den Ping geantwortet.$\r$\n$\r$\nKlicken Sie auf Wiederholen, um es mit dieser Domain erneut zu versuchen, oder auf Abbrechen, um 'localhost' zu verwenden. Klicken Sie auf Zurück, um die Domain zu ändern." +LangString MSG_DOMAIN_PING_FAIL ${LANG_ITALIAN} "Il dominio '$0' non ha risposto al ping.$\r$\n$\r$\nFare clic su Riprova per riprovare con questo dominio oppure su Annulla per usare 'localhost'. Per cambiare dominio, fare clic su Indietro." +LangString MSG_DOMAIN_PING_FAIL ${LANG_SPANISH} "El dominio '$0' no ha respondido al ping.$\r$\n$\r$\nHaga clic en Reintentar para volver a probar este dominio o en Cancelar para usar 'localhost'. Para cambiar de dominio, haga clic en Atrás." +LangString MSG_DOMAIN_PING_FAIL ${LANG_DUTCH} "Het domein '$0' heeft niet op de ping geantwoord.$\r$\n$\r$\nKlik op Opnieuw om dit domein nogmaals te proberen, of op Annuleren om 'localhost' te gebruiken. Klik op Vorige om een ander domein op te geven." LangString CHOOSE_DISTRO_LABEL ${LANG_ENGLISH} "Choose the WSL Linux distribution to install:" -LangString CHOOSE_DISTRO_LABEL ${LANG_FRENCH} "Choisissez la distribution Linux WSL a installer :" - +LangString CHOOSE_DISTRO_LABEL ${LANG_FRENCH} "Choisissez la distribution Linux WSL à installer :" +LangString CHOOSE_DISTRO_LABEL ${LANG_GERMAN} "Wählen Sie die zu installierende WSL-Linux-Distribution:" +LangString CHOOSE_DISTRO_LABEL ${LANG_ITALIAN} "Scegliere la distribuzione Linux WSL da installare:" +LangString CHOOSE_DISTRO_LABEL ${LANG_SPANISH} "Elija la distribución de Linux para WSL que desea instalar:" +LangString CHOOSE_DISTRO_LABEL ${LANG_DUTCH} "Kies de WSL-Linux-distributie die moet worden geïnstalleerd:" LangString ASK_DB_LABEL ${LANG_ENGLISH} "Installation finished. Do you want to use an external PostgreSQL database?" -LangString ASK_DB_LABEL ${LANG_FRENCH} "Installation terminée. Voulez-vous utiliser une base de donnees PostgreSQL externe ?" +LangString ASK_DB_LABEL ${LANG_FRENCH} "Installation terminée. Voulez-vous utiliser une base de données PostgreSQL externe ?" +LangString ASK_DB_LABEL ${LANG_GERMAN} "Die Installation ist abgeschlossen. Möchten Sie eine externe PostgreSQL-Datenbank verwenden?" +LangString ASK_DB_LABEL ${LANG_ITALIAN} "Installazione completata. Utilizzare un database PostgreSQL esterno?" +LangString ASK_DB_LABEL ${LANG_SPANISH} "Instalación finalizada. ¿Desea utilizar una base de datos PostgreSQL externa?" +LangString ASK_DB_LABEL ${LANG_DUTCH} "De installatie is voltooid. Wilt u een externe PostgreSQL-database gebruiken?" LangString ASK_DB_YES ${LANG_ENGLISH} "Yes, configure an external database" -LangString ASK_DB_YES ${LANG_FRENCH} "Oui, configurer une base externe" +LangString ASK_DB_YES ${LANG_FRENCH} "Oui, configurer une base de données externe" +LangString ASK_DB_YES ${LANG_GERMAN} "Ja, eine externe Datenbank einrichten" +LangString ASK_DB_YES ${LANG_ITALIAN} "Sì, configurare un database esterno" +LangString ASK_DB_YES ${LANG_SPANISH} "Sí, configurar una base de datos externa" +LangString ASK_DB_YES ${LANG_DUTCH} "Ja, een externe database instellen" LangString ASK_DB_NO ${LANG_ENGLISH} "No, use local database (default)" -LangString ASK_DB_NO ${LANG_FRENCH} "Non, utiliser la base locale (par défaut)" +LangString ASK_DB_NO ${LANG_FRENCH} "Non, utiliser la base de données locale (par défaut)" +LangString ASK_DB_NO ${LANG_GERMAN} "Nein, die lokale Datenbank verwenden (Standard)" +LangString ASK_DB_NO ${LANG_ITALIAN} "No, usare il database locale (predefinito)" +LangString ASK_DB_NO ${LANG_SPANISH} "No, usar la base de datos local (predeterminado)" +LangString ASK_DB_NO ${LANG_DUTCH} "Nee, de lokale database gebruiken (standaard)" LangString ENTER_DB_URL_LABEL ${LANG_ENGLISH} "Enter the external PostgreSQL URL (e.g.: postgresql://user:pass@host:5432/dbname):" -LangString ENTER_DB_URL_LABEL ${LANG_FRENCH} "Entrez l'URL PostgreSQL externe (ex:postgresql://user:pass@host:5432/dbname) :" +LangString ENTER_DB_URL_LABEL ${LANG_FRENCH} "Entrez l'URL PostgreSQL externe (par exemple postgresql://user:pass@host:5432/dbname) :" +LangString ENTER_DB_URL_LABEL ${LANG_GERMAN} "Geben Sie die URL der externen PostgreSQL-Datenbank ein (z. B. postgresql://user:pass@host:5432/dbname):" +LangString ENTER_DB_URL_LABEL ${LANG_ITALIAN} "Inserire l'URL PostgreSQL esterno (ad es. postgresql://user:pass@host:5432/dbname):" +LangString ENTER_DB_URL_LABEL ${LANG_SPANISH} "Introduzca la URL de PostgreSQL externa (p. ej. postgresql://user:pass@host:5432/dbname):" +LangString ENTER_DB_URL_LABEL ${LANG_DUTCH} "Voer de externe PostgreSQL-URL in (bijv. postgresql://user:pass@host:5432/dbname):" LangString DB_URL_REQUIRED ${LANG_ENGLISH} "You must enter a valid URL." LangString DB_URL_REQUIRED ${LANG_FRENCH} "Vous devez entrer une URL valide." +LangString DB_URL_REQUIRED ${LANG_GERMAN} "Sie müssen eine gültige URL eingeben." +LangString DB_URL_REQUIRED ${LANG_ITALIAN} "È necessario inserire un URL valido." +LangString DB_URL_REQUIRED ${LANG_SPANISH} "Debe introducir una URL válida." +LangString DB_URL_REQUIRED ${LANG_DUTCH} "U moet een geldige URL invoeren." LangString DB_CONN_OK ${LANG_ENGLISH} "External database configured successfully!" -LangString DB_CONN_OK ${LANG_FRENCH} "Base externe configuree avec succès !" +LangString DB_CONN_OK ${LANG_FRENCH} "Base de données externe configurée avec succès !" +LangString DB_CONN_OK ${LANG_GERMAN} "Die externe Datenbank wurde erfolgreich eingerichtet!" +LangString DB_CONN_OK ${LANG_ITALIAN} "Database esterno configurato correttamente!" +LangString DB_CONN_OK ${LANG_SPANISH} "¡La base de datos externa se ha configurado correctamente!" +LangString DB_CONN_OK ${LANG_DUTCH} "De externe database is ingesteld!" LangString DB_CONN_FAIL ${LANG_ENGLISH} "Connection to the database failed. Retry/modify URL or Cancel to use local." -LangString DB_CONN_FAIL ${LANG_FRENCH} "La connexion a la base a echoue. Reessayer/modifier l'URL ou Annuler pour rester en local." +LangString DB_CONN_FAIL ${LANG_FRENCH} "La connexion à la base de données a échoué. Cliquez sur Réessayer pour corriger l'URL, ou sur Annuler pour rester en local." +LangString DB_CONN_FAIL ${LANG_GERMAN} "Die Verbindung zur Datenbank ist fehlgeschlagen. Wiederholen bzw. URL ändern, oder Abbrechen, um die lokale Datenbank zu verwenden." +LangString DB_CONN_FAIL ${LANG_ITALIAN} "Connessione al database non riuscita. Riprovare o modificare l'URL, oppure Annulla per usare il database locale." +LangString DB_CONN_FAIL ${LANG_SPANISH} "La conexión con la base de datos ha fallado. Reintente o modifique la URL, o pulse Cancelar para usar la base local." +LangString DB_CONN_FAIL ${LANG_DUTCH} "De verbinding met de database is mislukt. Probeer het opnieuw of pas de URL aan, of klik op Annuleren om de lokale database te gebruiken." + +LangString MSG_DONE_OPEN_BROWSER ${LANG_ENGLISH} "Installation is complete! Your browser will now open your domain." +LangString MSG_DONE_OPEN_BROWSER ${LANG_FRENCH} "L'installation est terminée ! Votre navigateur va maintenant ouvrir votre domaine." +LangString MSG_DONE_OPEN_BROWSER ${LANG_GERMAN} "Die Installation ist abgeschlossen! Ihr Browser öffnet nun Ihre Domain." +LangString MSG_DONE_OPEN_BROWSER ${LANG_ITALIAN} "Installazione completata! Il browser aprirà ora il dominio configurato." +LangString MSG_DONE_OPEN_BROWSER ${LANG_SPANISH} "¡La instalación ha finalizado! Su navegador abrirá ahora su dominio." +LangString MSG_DONE_OPEN_BROWSER ${LANG_DUTCH} "De installatie is voltooid! Uw browser opent nu uw domein." + +; ------------------------------------------------------------------ install.log +; readme.txt, MSG_INSTALL_FAILED and .onInstFailed have always pointed the +; operator at C:\Users\Public\install.log, but nothing ever wrote it: a failed +; install popped up an error box naming a file that did not exist. This is +; that file. It records the Windows side of the run -- what the wizard was +; told, what each step returned, and where the other logs are -- because +; everything the batch and bash scripts log is itself unreachable when WSL is +; what failed to come up. +; +; The path is hard-coded the way readme.txt advertises it, next to the +; taler-bat.log that setup-wsl-debian.bat hard-codes for itself. +; C:\Users\Public is readable by every account on the machine, so NOTHING +; secret may be written here -- see RedactDbUrl. +!define TALER_LOGFILE "C:\Users\Public\install.log" + +; Appends one timestamped line. Opening and closing the file per line is +; deliberate: this installer can sit for ten minutes inside a single nsExec +; call and be killed there, and the lines written before that have to already +; be on disk. A log that cannot be opened is never fatal -- an unwritable log +; must not stop an install that would otherwise work. +Function TalerLog + Exch $R0 + Push $R1 + Push $R2 + Push $R3 + Push $R4 + Push $R5 + Push $R6 + Push $R7 + Push $R8 + ${GetTime} "" "L" $R2 $R3 $R4 $R5 $R6 $R7 $R8 + ; The error flag is cumulative and no successful instruction resets it + ; (exec.c: g_exec_flags.exec_error += exec_error), so it has to be cleared + ; here and not before GetTime -- otherwise a GetTime that failed would + ; silently discard every later line even though the file opened fine. + ClearErrors + FileOpen $R1 "${TALER_LOGFILE}" a + ; Mode "a" is OPEN_ALWAYS and leaves the pointer at 0, hence the seek. + ${IfNot} ${Errors} + FileSeek $R1 0 END + FileWrite $R1 "$R4-$R3-$R2 $R6:$R7:$R8 $R0$\r$\n" + FileClose $R1 + ${EndIf} + ClearErrors + Pop $R8 + Pop $R7 + Pop $R6 + Pop $R5 + Pop $R4 + Pop $R3 + Pop $R2 + Pop $R1 + Pop $R0 +FunctionEnd + +; ${TLog} goes to install.log only; ${TSay} also shows the line in the details +; view, for the events an operator should watch happening. +!macro TALER_LOG TEXT + Push "${TEXT}" + Call TalerLog +!macroend +!define TLog "!insertmacro TALER_LOG" + +!macro TALER_SAY TEXT + DetailPrint "${TEXT}" + Push "${TEXT}" + Call TalerLog +!macroend +!define TSay "!insertmacro TALER_SAY" + +; The external database URL carries a password, and install.log is world +; readable, so neither the log nor the details view may ever see it whole. +; Everything up to and including the last '@' is dropped; a PostgreSQL URI +; cannot carry an unescaped '@' in its credentials, so what survives is the +; host and database name -- which is the part worth having when a connection +; fails. An URL with no credentials at all is passed through unchanged. +Function RedactDbUrl + Exch $R0 + Push $R1 + Push $R2 + Push $R3 + StrCpy $R1 0 + StrCpy $R3 "" + rdu_scan: + StrCpy $R2 $R0 1 $R1 + StrCmp $R2 "" rdu_scanned + StrCmp $R2 "@" 0 rdu_next + StrCpy $R3 $R1 + rdu_next: + IntOp $R1 $R1 + 1 + Goto rdu_scan + rdu_scanned: + StrCmp $R3 "" rdu_out + IntOp $R3 $R3 + 1 + StrCpy $R0 $R0 "" $R3 + StrCpy $R0 "(credentials hidden)@$R0" + rdu_out: + Pop $R3 + Pop $R2 + Pop $R1 + Exch $R0 +FunctionEnd + +; Truncates install.log and records what is known before anything is +; attempted: the machine, the installer and the chosen language. One file per +; run, so the log always describes the run being reported. +Function TalerLogStart + ClearErrors + FileOpen $R0 "${TALER_LOGFILE}" w + ${IfNot} ${Errors} + FileClose $R0 + ${EndIf} + ClearErrors + + ${TLog} "=== GNU Taler-Merchant backend installer ===" + ${TLog} "installer : $EXEPATH" + ${TLog} "target dir : $INSTDIR" + ${TLog} "language : LCID $LANGUAGE" + + ; A 32-bit installer is handed the redirected registry, so ask for the + ; real 64-bit view and put it back afterwards. + SetRegView 64 + ReadRegStr $R1 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion" "ProductName" + ReadRegStr $R2 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion" "DisplayVersion" + ReadRegStr $R3 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion" "CurrentBuild" + ReadRegDWORD $R4 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion" "UBR" + SetRegView default + ClearErrors + ${TLog} "windows : $R1 $R2 (build $R3.$R4)" + + ReadEnvStr $R1 "PROCESSOR_ARCHITECTURE" + ReadEnvStr $R2 "PROCESSOR_ARCHITEW6432" + ClearErrors + ${If} $R2 == "" + StrCpy $R2 "n/a" + ${EndIf} + ${TLog} "architecture: $R1 (native: $R2)" + ${If} ${Silent} + ${TLog} "mode : silent (/S) -- the wizard pages never run, so distro, domain and proxy mode stay empty" + ${EndIf} +FunctionEnd +; The logs this installer cannot reach from Windows, named in install.log so +; whoever reads it knows what else to ask the merchant for. +Function TalerLogWhereElse + ${TLog} "see also: C:\Users\Public\taler-bat.log (setup-wsl-debian.bat)" + ${TLog} "see also: C:\Users\Public\taler-sh.log (install-taler-from-apt.sh)" + ${TLog} "see also: C:\Users\Public\install-bat.log (copied out of WSL at step 7)" + ${TLog} "see also: /home/taleruser/taler-installer/install-sh.log (inside WSL)" + ${TLog} "see also: /home/taleruser/taler-installer/test-db.log (inside WSL)" +FunctionEnd + +; The MUI_LANGDLL_* defines above only configure the language selection +; dialog; it is shown solely by this macro. Without a .onInit inserting it, +; NSIS picked the system language and fell back to the first one declared, +; so these translations were unreachable except on a matching Windows. +Function .onInit + !insertmacro MUI_LANGDLL_DISPLAY + Call TalerLogStart +FunctionEnd ; --- PAGE DISTRO --- Function DistroPage @@ -154,6 +416,7 @@ Function DistroPageLeave ${If} $WSL_DISTRO == "" StrCpy $WSL_DISTRO "Debian" ${EndIf} + ${TLog} "choice: distribution = $WSL_DISTRO" FunctionEnd ; --- PAGE DOMAINE --- @@ -179,17 +442,26 @@ Function DomainPageLeave ${If} $0 == "localhost" MessageBox MB_OK $(MSG_LOCALHOST_WARN) StrCpy $DOMAIN_VALUE $0 + ${TLog} "choice: domain = localhost (entered; not publicly reachable)" Return ${EndIf} StrCpy $1 0 loop_ping: nsExec::ExecToStack 'ping -n 1 -w 1000 $0' + ; ExecToStack pushes the output and then the exit code, so the code + ; comes off first and the output has to be popped too; popping only + ; the code left one entry per attempt on the global stack. (nsExec + ; pushes a single value instead only when it cannot build a command + ; line at all, which needs an empty command string -- $0 is checked + ; non-empty above, so that cannot happen here.) Pop $2 + Pop $3 ${If} $2 == 0 StrCpy $DOMAIN_VALUE $0 + ${TLog} "choice: domain = $DOMAIN_VALUE (ping answered)" Return ${Else} - Push $0 + ${TLog} "ping of '$0' failed with code $2 (attempt $1)" MessageBox MB_RETRYCANCEL|MB_ICONEXCLAMATION "$(MSG_DOMAIN_PING_FAIL)" IDRETRY retry_ping IDCANCEL use_localhost retry_ping: IntOp $1 $1 + 1 @@ -198,6 +470,7 @@ Function DomainPageLeave ${EndIf} use_localhost: StrCpy $DOMAIN_VALUE "localhost" + ${TLog} "choice: domain = localhost (fallback, '$0' never answered)" MessageBox MB_OK $(MSG_LOCALHOST_WARN) ${EndIf} FunctionEnd @@ -244,11 +517,13 @@ Function ReverseProxyPageLeave ${Else} StrCpy $REVERSE_PROXY_MODE "https" ${EndIf} + ${TLog} "choice: reverse proxy = $REVERSE_PROXY_MODE" FunctionEnd ; -------- SECTION INSTALL PRINCIPALE -------- Section "Install Taler-Merchant" StrCpy $INSTALL_OK "1" + ${TLog} "=== install section started ===" SetOutPath "$INSTDIR" SetDetailsView show File "setup-wsl-debian.bat" @@ -261,7 +536,7 @@ Section "Install Taler-Merchant" GetDlgItem $HWND_PROGRESS_LABEL $0 1006 DetailPrint "---------------------------------------------------------" - DetailPrint "[1/8] Enabling WSL and VirtualMachinePlatform..." + ${TSay} "[1/8] Enabling WSL and VirtualMachinePlatform..." SendMessage $HWND_PROGRESS_LABEL ${WM_SETTEXT} 0 "STR:Progress: 5%" Sleep 2000 @@ -285,7 +560,9 @@ Section "Install Taler-Merchant" nsExec::ExecToLog '"$INSTDIR\setup-wsl-debian.bat" 1 "" $WSL_DISTRO' Pop $0 + ${TLog} "step 1 (enable the WSL optional features) returned $0" ${If} $0 != 0 + ${TLog} "=== stopping: the machine must reboot before the install can continue ===" MessageBox MB_OK $(MSG_NEED_REBOOT) Quit ${EndIf} @@ -297,6 +574,10 @@ Section "Install Taler-Merchant" DetailPrint "NOTICE: A black window may appear for the WSL update. If it does, simply press any key when prompted." Sleep 1000 + ; [2/8] to [6/8] are cosmetic: the work for all of them happens inside the + ; single "ALL" call below, so they are deliberately NOT written to + ; install.log. A log claiming six steps that never individually ran would + ; be worse than no log at all. DetailPrint "[2/8] Installing $WSL_DISTRO..." SendMessage $HWND_PROGRESS_LABEL ${WM_SETTEXT} 0 "STR:Progress: 35%" Sleep 1000 @@ -317,44 +598,56 @@ Section "Install Taler-Merchant" SendMessage $HWND_PROGRESS_LABEL ${WM_SETTEXT} 0 "STR:Progress: 65%" Sleep 1000 - DetailPrint "[7/8] Restarting WSL and launching installation..." + ${TSay} "[7/8] Restarting WSL and launching installation..." SendMessage $HWND_PROGRESS_LABEL ${WM_SETTEXT} 0 "STR:Progress: 70%" + ${TLog} "running setup-wsl-debian.bat ALL (distro $WSL_DISTRO) -- this is steps 1 to 8" nsExec::ExecToLog '"$INSTDIR\setup-wsl-debian.bat" ALL "" $WSL_DISTRO' Pop $0 + ${TLog} "setup-wsl-debian.bat ALL returned $0" ${If} $0 != 0 - DetailPrint "ERROR: the installation step failed with code $0." + ${TSay} "ERROR: the installation step failed with code $0." StrCpy $INSTALL_OK "0" ${EndIf} - DetailPrint "[8/8] Configuring reverse proxy for $DOMAIN_VALUE in $REVERSE_PROXY_MODE mode..." + ${TSay} "[8/8] Configuring reverse proxy for $DOMAIN_VALUE in $REVERSE_PROXY_MODE mode..." SendMessage $HWND_PROGRESS_LABEL ${WM_SETTEXT} 0 "STR:Progress: 80%" nsExec::ExecToLog '"$INSTDIR\setup-wsl-debian.bat" 8 $DOMAIN_VALUE $WSL_DISTRO $REVERSE_PROXY_MODE' Pop $0 + ${TLog} "step 8 (reverse proxy, $REVERSE_PROXY_MODE, domain $DOMAIN_VALUE) returned $0" ${If} $0 != 0 - DetailPrint "ERROR: configuring the reverse proxy failed with code $0." + ${TSay} "ERROR: configuring the reverse proxy failed with code $0." StrCpy $INSTALL_OK "0" ${EndIf} - DetailPrint "Testing access to merchant reverse proxy..." + ${TSay} "Testing access to merchant reverse proxy..." nsExec::ExecToLog 'wsl -d $WSL_DISTRO -- bash -c "curl -v http://localhost"' + ; This result used to be dropped on the floor -- never popped, so the + ; diagnostic was lost and the value stayed on the global stack. It is the + ; one end-to-end check the installer makes, so it belongs in the log. + Pop $0 + ${TLog} "probe: curl http://localhost inside WSL returned $0 (0 = the proxy answered)" SendMessage $HWND_PROGRESS_LABEL ${WM_SETTEXT} 0 "STR:Progress: 85%" Sleep 2000 DetailPrint "Checking passed domain in $WSL_DISTRO..." nsExec::ExecToLog 'wsl -d $WSL_DISTRO -- bash -c "echo Received domain: '\''$DOMAIN_VALUE'\''"' + Pop $0 + ${TLog} "probe: wsl -d $WSL_DISTRO runs commands: returned $0" SendMessage $HWND_PROGRESS_LABEL ${WM_SETTEXT} 0 "STR:Progress: 90%" Sleep 2000 SendMessage $HWND_PROGRESS_LABEL ${WM_SETTEXT} 0 "STR:Progress: 99%" Sleep 1000 ${If} $INSTALL_OK == "1" - DetailPrint "Installation complete." + ${TSay} "Installation complete." SendMessage $HWND_PROGRESS_LABEL ${WM_SETTEXT} 0 "STR:Progress: 100%" ${Else} - DetailPrint "Installation FAILED - see C:\Users\Public\taler-bat.log" + ${TSay} "Installation FAILED - see ${TALER_LOGFILE}" SendMessage $HWND_PROGRESS_LABEL ${WM_SETTEXT} 0 "STR:Installation failed" MessageBox MB_OK|MB_ICONSTOP $(MSG_INSTALL_FAILED) ${EndIf} + ${TLog} "=== install section finished, INSTALL_OK = $INSTALL_OK ===" + Call TalerLogWhereElse CreateShortCut "$SMPROGRAMS\Taler-Merchant.lnk" "$INSTDIR\taler-installer.exe" SectionEnd @@ -379,8 +672,10 @@ Function AskExternalDBPageLeave ${NSD_GetState} $ASK_DB_YESNO $0 ${If} $0 == 1 StrCpy $USE_EXTERNAL_DB "1" + ${TLog} "choice: external PostgreSQL database = yes" ${Else} StrCpy $USE_EXTERNAL_DB "0" + ${TLog} "choice: external PostgreSQL database = no, keep the local one" ${EndIf} Return FunctionEnd @@ -413,17 +708,42 @@ Function DBUrlPageLeave Abort ${EndIf} - DetailPrint "Testing connection to the external database..." StrCpy $WSL_SCRIPT_DIR "/home/taleruser/taler-installer" -DetailPrint "Testing with DB_URL='$DB_URL'" - nsExec::ExecToStack 'wsl -d $WSL_DISTRO -- bash -c "/home/taleruser/taler-installer/test-db.sh ''$DB_URL''"' + + ; $DB_URL holds the database password. It used to be echoed verbatim into + ; the details view; it must not go there, nor into install.log. Report the + ; host and database only. + Push $DB_URL + Call RedactDbUrl + Pop $1 + ${TSay} "Testing connection to the external database at $1..." + + nsExec::ExecToStack 'wsl -d $WSL_DISTRO -- bash -c "/home/taleruser/taler-installer/test-db.sh ''$DB_URL''"' Pop $0 + ; test-db.sh echoes back the URL it was handed, password and all, so its + ; output is popped off the stack and dropped rather than logged. + Pop $2 + ${TLog} "test-db.sh returned $0 (0 = reachable, 1 = refused, 2 = psql missing in WSL)" ${If} $0 == 0 - DetailPrint "Connection succeeded. Updating configuration..." - nsExec::ExecToStack 'wsl -d $WSL_DISTRO -- bash -c "/home/taleruser/taler-installer/set-db.sh ''$DB_URL''"' + ${TSay} "Connection succeeded. Updating configuration..." + nsExec::ExecToStack 'wsl -d $WSL_DISTRO -- bash -c "/home/taleruser/taler-installer/set-db.sh ''$DB_URL''"' + ; set-db.sh writes the secret snippet and then runs + ; taler-merchant-dbconfig. Its result was previously discarded and + ; success announced regardless, so a database that was reachable but + ; could not be configured still reported "configured successfully". + Pop $0 + Pop $2 + ${TLog} "set-db.sh returned $0" + ${Else} + ${TLog} "the external database is not reachable; no configuration was written" + ${EndIf} + + ${If} $0 == 0 + ${TLog} "external database configured: $1" MessageBox MB_OK $(DB_CONN_OK) ${Else} + ${TSay} "ERROR: the external database was not configured (code $0)." MessageBox MB_RETRYCANCEL $(DB_CONN_FAIL) IDRETRY retry_dburl IDCANCEL fin_dburl retry_dburl: Abort @@ -438,23 +758,37 @@ Function .onGUIEnd ; so announcing success here unconditionally told operators the install had ; worked when it had not. Only celebrate when the section actually succeeded. ${If} $INSTALL_OK != "1" + ${TLog} "=== GUI closed without a successful install ===" Return ${EndIf} - MessageBox MB_OK|MB_ICONINFORMATION "Installation is complete! Your browser will now open your domain." + ${TLog} "=== install reported success ===" + MessageBox MB_OK|MB_ICONINFORMATION $(MSG_DONE_OPEN_BROWSER) ; Force WSL à démarrer Apache AVANT le navigateur nsExec::ExecToLog 'wsl -d $WSL_DISTRO -- bash -c "sudo service apache2 restart"' + Pop $0 + ${TLog} "apache2 restart returned $0" Sleep 2000 ${If} $REVERSE_PROXY_MODE == "https" + ${TLog} "opening https://$DOMAIN_VALUE" ExecShell "open" "https://$DOMAIN_VALUE" ${Else} + ${TLog} "opening http://$DOMAIN_VALUE" ExecShell "open" "http://$DOMAIN_VALUE" ${EndIf} FunctionEnd +; Logged so that a report of "it just closed" can be told from a crash. +; Called by MUI's .onUserAbort via MUI_CUSTOMFUNCTION_ABORT. +Function TalerOnAbort + ${TLog} "=== cancelled by the user ===" +FunctionEnd + Function .onInstFailed + ${TLog} "=== installation aborted (.onInstFailed) ===" + Call TalerLogWhereElse MessageBox MB_OK $(MSG_INSTALL_FAILED) - ExecShell "open" "C:\Users\Public\install.log" + ExecShell "open" "${TALER_LOGFILE}" FunctionEnd \ No newline at end of file diff --git a/test-db.sh b/test-db.sh @@ -3,10 +3,15 @@ # Usage: ./test-db.sh <POSTGRES_URL> mkdir -p /home/taleruser/taler-installer 2>/dev/null echo "=== [DEBUG] test-db.sh called ===" | tee -a /home/taleruser/taler-installer/test-db.log -echo "Received URL: $1" | tee -a /home/taleruser/taler-installer/test-db.log +# Never echo $1: it carries the database password, and this log is kept +# for support. "${1##*@}" drops everything up to the last "@", which is +# the credentials -- a PostgreSQL URI cannot carry an unescaped "@" in +# them -- and leaves the host and database name, which is the part worth +# having when a connection fails. +echo "Received URL (credentials stripped): ${1##*@}" | tee -a /home/taleruser/taler-installer/test-db.log POSTGRES_URL="$1" -echo "Testing $POSTGRES_URL" > /tmp/dbtest.log +echo "Testing ${POSTGRES_URL##*@}" > /tmp/dbtest.log if command -v psql >/dev/null 2>&1; then if psql "$POSTGRES_URL" -c '\q' >> /tmp/dbtest.log 2>&1; then