From 5e64ac32500c5685069aae66542dd54301115d1a Mon Sep 17 00:00:00 2001 From: John Cardinal Date: Fri, 23 Oct 2026 14:44:50 -0700 Subject: [PATCH] case 4690 - NET10-PORT: Windows standalone installer test results; VC++ runtime, launcher shutdown impact and bundled runtime version recorded Co-Authored-By: Claude Opus 5.5 --- devdocs/modernization/NET10-PORT.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/devdocs/modernization/NET10-PORT.md b/devdocs/modernization/NET10-PORT.md index a7920dae..ad4682b8 100644 --- a/devdocs/modernization/NET10-PORT.md +++ b/devdocs/modernization/NET10-PORT.md @@ -144,7 +144,7 @@ suite is waiting on (case 4653, case 4654, the contract issue). - **Subscription server setup script** (`sockeye-client/src/views/biz-subscription-server.vue`, around lines 1350-1423; filled in per server and copied to the clipboard from the "Script" menu, used for every new subscription droplet): `apt-get install -y aspnetcore-runtime-8.0` (line 1377) → the .NET 10 runtime from whichever source the test droplet confirms; remove the `mkdir`/`chmod g+rwx` of `/var/ayanova/Chrome` and `ChromeHeadlessShell` (lines 1396-1397, 1402-1403), the browser now downloads to `/var/ayanova/data/report-browser`. Verify by running the updated script on the test droplet. Part of this port (John, 2026-10-22). Runtime and Chrome-folder change committed in `sockeye-client` `main` (2026-10-23); **do not deploy a Sockeye client built from it before 8.3.0 is released** (the script installs the released zip; 8.2.4 needs .NET 8). 26.04 support and hardening committed in `sockeye-client` `main` (`64d8f62`, 2026-10-23), tested end to end on a fresh 26.04.1 droplet: PostgreSQL via `postgresql-common`'s `apt.postgresql.org.sh` (`apt-key` is gone in newer Ubuntu); `libgdk-pixbuf2.0-0` → `libgdk-pixbuf-2.0-0` (the only library name missing on 26.04); unique random PostgreSQL password and JWT secret per server, written to PostgreSQL, `config.json` and `/root/ayanova-secrets.txt` (600); `config.json` 640 `root:www-data`; John's `52no-phasing` apt setting - Self-hosted Linux customers (server and desktop zips are framework-dependent) - Windows LAN: `lan.iss` prompts for the ASP.NET Core Hosting Bundle. Text and link updated to .NET 10 (2026-10-23); installer test still in section 4 - - Windows standalone and the launcher are self-contained: no runtime needed on the customer's machine + - Windows standalone and the launcher are self-contained: no runtime needed on the customer's machine. **But they carry the .NET runtime of the build machine's SDK:** SDK 10.0.103 → runtime 10.0.3 (the Sandbox test logged `.Net Version - 10.0.3`; Linux hosts run 10.0.13). Before the final release build, update the workstation's .NET 10 SDK to the newest release (`winget upgrade --id Microsoft.DotNet.SDK.10`; 10.0.402 offered on 2026-10-23) so the standalone package ships the current runtime with its security fixes. 8.2.4 did the same with .NET 8.0.13 - [x] Customer manual (`docs/`): system requirements and upgrade instructions for self-hosted customers. Report browser move (section 3): manual already updated in the same commit (`ops-config-report-render-browser-path.md`, `ops-install-linux-server.md`, `ops-upgrade-linux-server.md`, `ops-upgrade-linux-desktop.md`). .NET 10 runtime install and upgrade steps (Windows LAN and IIS, Linux server and desktop), Ubuntu 24.04/26.04, backup password note and the 8.3.0 changelog draft: `111d7922` (2026-10-23). Changelog wording to be finalised by John before release - [ ] Build machines: the workstation already has the .NET 10 SDK (10.0.103). The backup laptop needs it before it can build 8.3.0 (`winget install --id Microsoft.DotNet.SDK.10 -e --source winget`; the .NET 8 SDK is no longer needed); tracked with the laptop's other catch-up items in `devdocs/build/BUILD.md`. `devdocs/build/DEV-VM-SETUP.md` and `devdocs/build/BUILD.md` updated (2026-10-23). The build VM is deprecated (John, 2026-10-23): n/a - [ ] Final gate runs on the finished code @@ -184,7 +184,10 @@ Found during the port, out of scope. One line each. - `License.DoFetchAsync` (`License.cs:629-661`) rethrows at `x == 3`, so the fifth server (Sockeye) is never tried, and it can return `null` to a caller that dereferences it - Stray `raven-client\ayanova\cypress.json`: the Cypress suite lives in `raven-test\e2e` - **Race, affects production after every restart:** `FormFieldReference.FormFieldReferenceList` (`biz/FormFieldReference.cs:57-59`) builds a static dictionary lazily with no lock, assigning it before filling it. A concurrent first request sees it half-built and throws `FormFieldReferenceList: is not valid`. Seen twice on .NET 10, each time on the first form-field use after boot: `VendorCrud.CRUD`, then `FormCustom.FormCustomUpdate`. Fix: build the dictionary fully before publishing it (`Lazy` or a static initialiser). Pre-existing, not a port change. John's decision: its own case, fixed with the other cases going into this release, not under the port -- `raven-launcher` `Program.cs:98` calls `PGProcess.StandardInput.Close()` but standard input was never redirected, so it throws `InvalidOperationException` at shutdown: the "Postgres shut down" step never runs and the launcher exits with an error when the server stops. Postgres was started detached by `pg_ctl start`, so it probably stays running. Pre-existing; candidate for its own case +- `raven-launcher` `Program.cs:98` calls `PGProcess.StandardInput.Close()` but standard input was never redirected, so it throws `InvalidOperationException` at shutdown: the "Postgres shut down" step never runs and the launcher exits with an error when the server stops. Postgres was started detached by `pg_ctl start`, so it probably stays running. Pre-existing; candidate for its own case. **Confirmed in the Sandbox test (8.2.4 and 8.3.0):** after "Shut down server" the launcher crashes with exactly this exception and 7 `postgres` processes stay running. Every standalone upgrade then stops at Setup's "files in use" page listing PostgreSQL Server, and "automatically close the applications" fails ("Setup was unable to automatically close all applications"): the customer must end the processes or restart Windows first. One-line fix (stop PostgreSQL with `pg_ctl stop` instead of writing to its standard input). Suggested for the "next release" cases (John to decide) +- **Standalone install needs the Visual C++ runtime (pre-existing, same in 8.2.4; suggested for the "next release" cases, John to decide):** the bundled PostgreSQL (`local-postgres\bin\pg_ctl.exe`, `postgres.exe`) needs `VCRUNTIME140.dll`, which neither the installer nor `local-postgres` provides. A Windows without it (a new PC, Windows Sandbox) shows "pg_ctl.exe - System Error: VCRUNTIME140.dll was not found" and AyaNova never starts. Confirmed fix: copying `vcruntime140.dll`, `vcruntime140_1.dll` and `msvcp140.dll` (x64, 14.44) into `local-postgres\bin` made PostgreSQL start. Ship those three in `dist\win-x64\postgres-standalone\bin` (app-local, allowed by Microsoft's redistribution terms) rather than running `vc_redist.x64.exe` (it crashed Windows Sandbox mid-install) +- Standalone `config.json` (launcher template) has no `AYANOVA_JWT_SECRET`, so every boot logs a warning and generates a random one (logins are lost on restart). Pre-existing; noted from the Sandbox test logs +- Standalone and LAN installers share the same Inno Setup `AppId` (`{B2BB79DB-0690-497C-B92B-955F7B468429}`) although they are different products (`AyaNova` vs `AyaNova server`): installing one over the other would be treated as the same application. Pre-existing; not tested - Sockeye 8.1.0 has the NLog 6 archive naming problem fixed here for AyaNova: archives are `log-sockeye_NN.txt`, old `-0` to `-8` archives are never deleted, and its log viewer still sorts by name (it also filters on `ayanova.txt`, not `sockeye.txt`, so the current file is listed twice). Same fix applies: `ArchiveSuffixFormat = "-{0}"` and the date sort - **SuperUser can be deleted (serious, pre-existing, own case; John's decision 2026-10-23: fixed with the other "next release" cases before 8.3.0 ships, not under the port):** `UserBiz.ValidateCanDelete` (`biz/UserBiz.cs:1055`) only refuses a delete when the user has related records; nothing protects user id 1, although updates to it are blocked (`UserBiz.cs:946`). On the droplet, whose sample data left SuperUser with no related records, the integration test `UserWithActivityShouldNotBeDeleteable` (`DELETE User/1`) succeeded and removed the account; `AYANOVA_SET_SUPERUSER_PW` cannot bring it back (it only resets an existing user 1). Same code in 8.2.4; likely also why `superuser` could not log in on the reused local database at the first baseline attempt. Any user with delete rights on Users can do this - `RunProgram.Run` (and its `RunWindows`/`RunLinuxShell`/`RunOSX` helpers) has no callers since the backup moved to `RunNoShell`. It runs through `cmd.exe /C` or `/bin/sh -c` and logs its full command line on error: delete it rather than reuse it @@ -229,3 +232,4 @@ Found during the port, out of scope. One line each. | 2026-10-23 | Build tooling: `build-release.bat` logs all output to `build-output.txt` (UTF-16, overwritten each build, git-ignored) as well as the console; sets `PYTHONUTF8=1` (mkdocs-material 9.7 banner otherwise crashes MkDocs when output is piped). `raven-client` `vue.config.js`: Sass `quietDeps` | Wrapper tested on a dummy script: live console output, stderr captured, Unicode intact. Client build: Sass deprecation warnings 475 → 33 (the rest are Vuetify component styles compiled as the entry stylesheet, which `quietDeps` cannot tell apart); CSS output byte-identical to the 8.3.0 release build | | 2026-10-23 | Linux packages from `build-release.bat` on a fresh Ubuntu 24.04.5 droplet (`devtestn10`): 8.2.4 subscription server set up by John with the deployed setup script, trial licence, sample data, one report rendered on 8.2.4 | **Subscription zip**, the manual's steps 1.5 and 2 with the built zip: .NET 10.0.13 from `noble-updates`, boots 8.3.0, schema 20, trial licence kept, 0 errors; 22/22 reports (1.5–2.8 s, first 7.5 s with the download); browser in `data/report-browser` (`ChromeHeadlessShell` only, 272 MB); old `Chrome`/`ChromeHeadlessShell` removed with the manual's command. The E1090 in the log is the 8.2.4 server, restarted by `needrestart` during `apt-get upgrade` and cancelled mid-boot by the manual's `systemctl stop`; not 8.3.0. DataProtection ephemeral-key warnings at boot: same in 8.2.4. **Perpetual server zip**, fresh folder, own database, port 7576, as `www-data`: boots unlicensed (E1020), creates the database, 0 errors, login page 200. **Desktop zip**, the desktop manual's steps as an ordinary user (`sudo ./AyaNova`): `AyaNova` apphost runs on .NET 10, boots, creates the database, 0 errors, login page 200; data goes to `/root/.ayanova-data` (see Deferred). Test databases, folders and user removed afterwards | | 2026-10-23 | `standalone.iss`: create the 13 empty folders PostgreSQL 14 needs in a new database (`pg_notify`, `pg_tblspc`, `pg_twophase`, `pg_stat`, `pg_stat_tmp`, `pg_commit_ts`, `pg_dynshmem`, `pg_replslot`, `pg_serial`, `pg_snapshots`, `pg_logical\mappings`, `pg_logical\snapshots`, `pg_wal\archive_status`) | **Release blocker found in the Sandbox test:** fresh standalone installs built on this PC failed, `pg_ctl` "could not start server", `postgres.log` "could not open directory pg_notify". `dist\win-x64\postgres-empty-database` was checked out from Git on 2026-02-19 and Git does not keep empty folders; compared with a reference `initdb` of the bundled PostgreSQL 14, exactly these 13 were missing. 8.2.4 (built on the old machine) is not affected; upgrades are not affected (existing database kept). Fixed in the installer rather than on disk so a fresh checkout cannot break it again. Fixed installer: fresh install in a clean Sandbox starts PostgreSQL first time, schema 20 created, boot complete | +| 2026-10-23 | Windows standalone installer in Windows Sandbox (clean Windows 11, `C:\temp\ayanova-sandbox\ayanova-test.wsb`, checks by `check.ps1`): 8.2.4 production installer, trial licence with sample data (John), upgrade with the 8.3.0 build, uninstall, fresh install | **8.2.4 install:** needed the Visual C++ runtime first (see Deferred; `vc_redist.x64.exe` crashed the Sandbox, the three DLLs copied into `local-postgres\bin` worked); report 10 Customer Work Order 1.6 s, `Chrome`/`ChromeHeadlessShell` in the program folder. **Shutdown:** launcher crash at `Program.cs:98`, 7 `postgres` left running (see Deferred). **Upgrade to 8.3.0:** Setup "files in use" (PostgreSQL Server ×7), automatic close failed, installer cancelled itself; after the leftover processes were gone, upgrade went through: 8.3.0 (`a223a2bc`), `net10.0`, schema 20, trial licence and data kept, PostgreSQL recovered from the unclean stop; report 10 rendered in 13.9 s with the browser download, browser in `%ProgramData%\ayanova\report-browser`; runtime `10.0.3` (see section 5). **Uninstall** (delete data: yes): `Chrome`/`ChromeHeadlessShell` removed with the program folder, data folder removed; only the hand-copied runtime DLLs left behind. **Fresh install:** failed to start PostgreSQL (missing empty folders, fixed in `standalone.iss`, see the next row); with the fixed installer: starts first time, schema 20 created, no `Chrome` folders |