From 0a7635b12a10af2b07b55dfe45f4f5245336d444 Mon Sep 17 00:00:00 2001 From: Jakub Zych Date: Sat, 3 Oct 2026 20:06:42 +0200 Subject: [PATCH] fix(14-02): parity:upstream writes its sidecar on interrupt or SIGTERM - the command context had no signal handling, so stopping the proxy killed it before Flush and no sidecar was ever written - a background proxy (SIGINT ignored by the shell) now stops on SIGTERM --- cmd/summer/parity.go | 8 ++++++++ docs/services/parity-testing.md | 2 +- modules/tide/README.md | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/cmd/summer/parity.go b/cmd/summer/parity.go index 112f8d0..60f3807 100644 --- a/cmd/summer/parity.go +++ b/cmd/summer/parity.go @@ -4,8 +4,10 @@ import ( "context" "fmt" "os" + "os/signal" "path/filepath" "strings" + "syscall" "time" "git.golem15.com/golem15/summercms/modules/bonfire" @@ -140,6 +142,12 @@ func runParityUpstream(ctx context.Context, in bonfire.Input, out bonfire.Output out.Info(fmt.Sprintf("upstream proxy listening on %s", listen)) out.Info(fmt.Sprintf("parity CA certificate: %s", certPath)) out.Info(fmt.Sprintf("point the reference backend at it: HTTPS_PROXY=http://%s, curl.cainfo and openssl.cafile=%s", listen, certPath)) + // The sidecar is written only after the proxy stops, so an interrupt or + // SIGTERM must end serving gracefully instead of killing the process. A + // shell starts background jobs with SIGINT ignored; NotifyContext + // re-enables it. + ctx, stop := signal.NotifyContext(ctx, os.Interrupt, syscall.SIGTERM) + defer stop() if err := proxy.ListenAndServe(ctx); err != nil { return err } diff --git a/docs/services/parity-testing.md b/docs/services/parity-testing.md index 5414562..364c6b3 100644 --- a/docs/services/parity-testing.md +++ b/docs/services/parity-testing.md @@ -161,7 +161,7 @@ summer parity:upstream --ca-dir /tmp/parity/ca --vars /tmp/parity/vars.yaml \ --out testdata/parity/routes/POST_items_jwt__ok.upstream.yaml ``` -It prints the path of its CA certificate. Start the reference backend with `HTTPS_PROXY=http://127.0.0.1:8425` and that certificate as its curl and OpenSSL CA file, run the case, then interrupt the command to write the sidecar. In the default `script` mode each request is answered from the script file, a list of `responses` entries (`tide.UpstreamScriptResponse`: `method`, `host`, `path` and the `response` to send), so recording needs no real vendor and no real credential; a request no entry matches is answered with status 599 and the sidecar is not written. `--mode forward` sends each request once to the real vendor through a guarded client instead. Use it only by hand, never in CI. +It prints the path of its CA certificate. Start the reference backend with `HTTPS_PROXY=http://127.0.0.1:8425` and that certificate as its curl and OpenSSL CA file, run the case, then interrupt the command (Ctrl-C, or SIGTERM when it runs in the background) to write the sidecar. In the default `script` mode each request is answered from the script file, a list of `responses` entries (`tide.UpstreamScriptResponse`: `method`, `host`, `path` and the `response` to send), so recording needs no real vendor and no real credential; a request no entry matches is answered with status 599 and the sidecar is not written. `--mode forward` sends each request once to the real vendor through a guarded client instead. Use it only by hand, never in CI. The rules match the other recorders: the proxy listens on loopback only, the CA key is kept with mode 0600 in `--ca-dir` outside the fixtures tree, and every value from the variables file is replaced by its `{{name}}` placeholder. `tide.WriteUpstream` refuses to write an Authorization or X-Api-Key header that no variable masks. diff --git a/modules/tide/README.md b/modules/tide/README.md index 06ef90a..f5b4c7e 100644 --- a/modules/tide/README.md +++ b/modules/tide/README.md @@ -181,7 +181,7 @@ summer parity:upstream \ --out testdata/parity/routes/POST_items_jwt__ok.upstream.yaml ``` -`--listen` defaults to `127.0.0.1:8425` and `--mode` to `script`. The command prints the CA certificate path; run the reference backend with `HTTPS_PROXY` pointing at the proxy and that certificate as its CA file, then interrupt the command to write the sidecar. Security rules: the proxy listens on loopback only; the CA key stays mode 0600 in `--ca-dir`, outside the fixtures tree; the vars file is outside the sidecar's directory and every value in it is masked; an unmasked Authorization or X-Api-Key value refuses the write; `--mode forward` reaches the real vendor and is for hand recording only, never CI. +`--listen` defaults to `127.0.0.1:8425` and `--mode` to `script`. The command prints the CA certificate path; run the reference backend with `HTTPS_PROXY` pointing at the proxy and that certificate as its CA file, then interrupt the command (Ctrl-C, or SIGTERM when it runs in the background) to write the sidecar. Security rules: the proxy listens on loopback only; the CA key stays mode 0600 in `--ca-dir`, outside the fixtures tree; the vars file is outside the sidecar's directory and every value in it is masked; an unmasked Authorization or X-Api-Key value refuses the write; `--mode forward` reaches the real vendor and is for hand recording only, never CI. ## Dependencies