Skip to content

Run the setup failure paths in the release lab - #786

Merged
Sev7eNup merged 4 commits into
mainfrom
test/release-lab-failure-paths
Nov 3, 2026
Merged

Sev7eNup merged 4 commits into
mainfrom
test/release-lab-failure-paths

Conversation

@Sev7eNup

@Sev7eNup Sev7eNup commented Nov 3, 2026

Copy link
Copy Markdown
Owner

Stacked on #783, #784 and #785; the change of its own is the last commit. Merge after those three, because the new cases expect their behaviour.

Why

Until now the release matrix exercised only installs, updates and uninstalls that succeed. The rollback and abort paths fixed in #783/#784 were checked once by hand in the lab and never again. These four cases put them into every release run.

Case Setup What it does Passes when
I2 server fresh install as gMSA A, then a reinstall as gMSA B that is denied CONNECT SQL the second setup exits non-zero; the service runs as A again and becomes ready; the admin signs in; jwt-secret.key belongs to A; the install directory DACL equals the one before; B's SID is on neither the directory nor NodePilot.Api.exe; no ROLLBACK ALSO FAILED
X1 server uninstall with /PURGEDATA=1 while Administrators may not delete the service (sc sdset, deny SD) service, deploy\Uninstall-NodePilot.ps1, marker, Apps & features entry and data stay, and the Inno log reports the abort; with the right restored, the same uninstall meets the normal uninstall criteria
T2b desktop staged Update-Desktop.ps1 from a copy of the installed payload without postgres.exe non-zero exit, rollback reported complete, both service registrations unchanged, services and /healthz/ready up, admin signs in, smoke workflow succeeds
T8a desktop uninstall while the API service cannot be deleted API service, program files with deploy\Uninstall-Desktop.ps1 and the Apps & features entry stay, abort in the Inno log; T8 then repeats the uninstall

The server matrix grows from 30 to 32 scenarios; the desktop cases run inside the existing second phase. Test-UpgradeMatrix.ps1 pins the new count and both new server cases.

Lab prerequisite

I2 needs a second gMSA the server VM may retrieve, set in server.secondGmsaAccount. The one from the manual lab run was deleted afterwards, so it has to be created once and kept (command in the README). The server matrix refuses to start without the key instead of skipping I2.

Testing

  • Test-UpgradeMatrix.ps1 and Test-RemoteSqlCleanup.ps1 pass (Windows PowerShell 5.1); all changed lab scripts parse.
  • Read-only checks on this machine: the deny ACE lands first in the DACL of real service descriptors with mask 0x10000 (DELETE); the service-registration fingerprint works under StrictMode 3; the I2 answer file names the second gMSA, I1 and the first install keep the first one.
  • DocumentationCountsTests: 29 pass.
  • Not run: the guest scripts themselves. They only run in the Hyper-V lab, so the first real run is the next release-lab run, after the gMSA above exists.

🤖 Generated with Claude Code

Sev7eNup and others added 4 commits November 3, 2026 21:31
- Setup health probe and first login pin the configured server
  certificate per request and reject redirects, instead of switching
  off certificate validation for the whole process (D01).
- A failed reinstall that changes the service account restores the
  install root DACL before the old binaries come back (#735).
- Uninstall stops when the service cannot be deleted, keeps the
  marker and deploy\ until everything else is gone, and the Inno
  uninstaller aborts on a failed cleanup so it can be repeated (#714,
  server part).
- PurgeData takes ownership with takeown /A item by item, so it works
  on German Windows, and deletes nothing when a native step fails
  (#731).
- The gMSA repair command reads the existing retrieval principals and
  adds this host; the deploy README drops the blanket RBCD recipe
  (#713).

Closes #713
Closes #731
Closes #735
Refs #714

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Update-Desktop.ps1 passes the custom data path and service names to
  re-provisioning instead of letting it fall back to defaults (#709).
- The staged update snapshots both service registrations and the
  component ACLs; the rollback registers the services again before the
  database restore and fails explicitly when one is missing (#710).
- Setup identifies the account that started it (ExecAsOriginalUser) and
  passes its SID as -HandoffUserSid; the provisioner no longer falls
  back to the console user or its own profile (#732).
- The desktop uninstaller aborts on a failed or missing cleanup, so the
  uninstall can be repeated (#714, desktop part).

Closes #709
Closes #710
Closes #714
Closes #732

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Switching to NodePilot also stops SCOrch jobs, but the preflight only
validated the NodePilot side, so a remote http:// SCOrch URL was used
with Windows credentials. The preflight now validates SCOrch for both
targets, and the ScorchApiClient constructor enforces the same
loopback-or-HTTPS rule.

Closes #728

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The matrix only exercised installs, updates and uninstalls that
succeed. The rollback and abort paths fixed in #783 and #784 were
checked once by hand in the lab. They now run on every release:

- I2 (server): reinstall as a second gMSA that is denied CONNECT SQL,
  so the setup must roll back to the first one with its install
  directory access, key owner and a ready service.
- X1 (server): uninstall while Administrators may not delete the
  service. It must stop with everything in place, and the same
  uninstall must succeed once the right is back.
- T2b (desktop): staged update from a payload without postgres.exe.
  The rollback must register both services as before.
- T8a (desktop): the blocked uninstall on the desktop setup, then T8
  repeats it.

I2 needs a second lab gMSA in server.secondGmsaAccount; the server
matrix refuses to start without it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
public async Task Preflight_RejectsRemoteHttpScorchSourceOrDestination(bool toNodePilot)
{
var target = toNodePilot ? SwitchTarget.NodePilot : SwitchTarget.SystemCenterOrchestrator;
File.WriteAllText(Path.Combine(_directory, "np.exe"), string.Empty);
{
var target = toNodePilot ? SwitchTarget.NodePilot : SwitchTarget.SystemCenterOrchestrator;
File.WriteAllText(Path.Combine(_directory, "np.exe"), string.Empty);
var config = Path.Combine(_directory, "custom.json");
@Sev7eNup
Sev7eNup merged commit 9f7c093 into main Nov 3, 2026
17 checks passed
@Sev7eNup
Sev7eNup deleted the test/release-lab-failure-paths branch November 3, 2026 21:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants