Skip to content

refactor(config): separate source loading from resolution#830

Open
natalie-o-perret wants to merge 10 commits intomasterfrom
refactor/config-resolution
Open

refactor(config): separate source loading from resolution#830
natalie-o-perret wants to merge 10 commits intomasterfrom
refactor/config-resolution

Conversation

@natalie-o-perret
Copy link
Copy Markdown
Contributor

@natalie-o-perret natalie-o-perret commented May 5, 2026

Follow-up to #817.

Splits config source loading from resolution into a small, testable layer. Each source (env vars, config file profile, built-in defaults) is loaded independently, then merged by resolve() with explicit precedence:

CLI flags > env vars > config file profile > built-in defaults

What changed:

  • New cmd/config_resolution.go with envSources, fileSources, and resolve(). Replaces the old envAccountOverrides / useEnvOnlyAccount / finalizeCurrentAccount tangle.
  • Fixed --config vs EXOSCALE_CONFIG precedence: the env-to-flag mapping was missing a Changed guard, so EXOSCALE_CONFIG silently won. CLI flags now always win.
  • Fixed EXOSCALE_ZONE: it now overrides the default zone from the active config profile as documented.
  • Fixed a race where Ctrl+C during the secret key prompt killed the process before it could print the cancellation message (three timing paths for SIGINT covered, plus SIGHUP from PTY session leader exit).
  • 11 unit tests for resolve(), 2 new e2e scenarios for the fixed behaviors.
  • With-API e2e CI split into parallel compute/dbaas jobs for independent failure reporting.

Testing:

go test ./cmd/...
make build && cd tests/e2e && go test -run TestScriptsLocal -count=1 .

@natalie-o-perret natalie-o-perret force-pushed the refactor/config-resolution branch from 00da573 to 62dede7 Compare May 5, 2026 13:44
When exo runs inside a PTY spawned by testscript, the testscript wrapper
binary (mainExo) is the PTY session leader. On Ctrl+C:

1. SIGINT goes to the whole foreground process group: wrapper + exo.
2. The wrapper has no signal.Notify, so Go's default SIGINT handler
   kills it immediately.
3. On session-leader exit, the kernel sends SIGHUP to the remaining
   process group members — including exo.  With no SIGHUP handler,
   exo is killed before it can print "Error: Operation Cancelled".

Fix: add syscall.SIGHUP to the signal.Notify in Execute() so SIGHUP
cancels the context instead of killing the process.

Also overhaul readPasswordInterruptible to cover all SIGINT timing paths:
sigCh fires first, unix.Read returns EINTR first, or ctx.Done fires first
(when cobra's goroutine cancels the context before signal.Notify runs).
@natalie-o-perret natalie-o-perret marked this pull request as ready for review May 6, 2026 13:45
@natalie-o-perret
Copy link
Copy Markdown
Contributor Author

[SC-178713]

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.

1 participant