-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.go
More file actions
56 lines (49 loc) · 2.15 KB
/
Copy pathmain.go
File metadata and controls
56 lines (49 loc) · 2.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
// © 2025 Platform Engineering Labs Inc.
//
// SPDX-License-Identifier: Apache-2.0
package main
import (
"log"
"os"
"os/signal"
"syscall"
"time"
"github.com/platform-engineering-labs/formae-plugin-k8s/pkg/resources/helm"
"github.com/platform-engineering-labs/formae/pkg/plugin/sdk"
)
// drainTimeout bounds how long a graceful stop waits for in-flight Helm
// operations to unwind. Only a single release-record write has to land, so this
// is generous; it is a ceiling on shutdown, not a target.
const drainTimeout = 10 * time.Second
func main() {
go drainHelmOnSignal()
sdk.RunWithManifest(&Plugin{}, sdk.RunConfig{})
}
// drainHelmOnSignal cancels in-flight Helm operations when the plugin is asked
// to stop, so a graceful restart leaves recoverable releases behind.
//
// Cancelling makes Helm run failRelease (install.go:411, upgrade.go:399), which
// records the release as `failed` — a state the next apply simply upgrades over.
// Being killed without cancelling leaves it `pending-install`, which Helm
// refuses to install OR upgrade and which only `helm uninstall` clears. The
// difference between those two outcomes is one Secret write.
//
// Best-effort by construction. The SDK installs its own SIGTERM handler and
// calls node.Stop() (pkg/plugin/run.go:190-197); Go delivers to every
// signal.Notify receiver concurrently and offers no ordering hook, so this
// races the node teardown that follows. Winning is the common case because the
// write is a single API call, and losing costs nothing — the outcome is then
// exactly what it was before this existed. SIGKILL is out of reach either way,
// and stalled() plus the recovery message in stalledMessage remain the floor.
func drainHelmOnSignal() {
sig := make(chan os.Signal, 1)
signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)
<-sig
if helm.DrainInFlight(drainTimeout) {
return
}
// Worth saying out loud: whatever did not unwind is a release left pending
// in the cluster, and the operator will meet it as a blocked apply later.
log.Printf("helm: in-flight operations did not unwind within %s; "+
"releases left pending may need `helm uninstall` before the next apply", drainTimeout)
}