Skip to content

Commit f78cb9a

Browse files
rolandshoemakergopherbot
authored andcommitted
cmd/securitybot: make rollouts slightly more graceful
Catch SIGTERM and cancel the main context, which should cause things to shutdown slightly more cleanly (importantly deleting buildlets, rather than just orphaning them) when Kubernetes attempts to shutdown a workload. Change-Id: Ibfae309db9007778b31b4416578f9a8013286e4e Reviewed-on: https://go-review.googlesource.com/c/build/+/465935 TryBot-Result: Gopher Robot <[email protected]> Run-TryBot: Roland Shoemaker <[email protected]> Reviewed-by: Damien Neil <[email protected]> Auto-Submit: Roland Shoemaker <[email protected]>
1 parent f03e733 commit f78cb9a

File tree

1 file changed

+29
-5
lines changed

1 file changed

+29
-5
lines changed

cmd/securitybot/main.go

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@ import (
1616
"log"
1717
"net/http"
1818
"os"
19+
"os/signal"
1920
"path"
2021
"strings"
2122
"sync"
23+
"syscall"
2224
"text/tabwriter"
2325
"time"
2426

@@ -514,7 +516,24 @@ var firstClassBuilders = []string{
514516

515517
func main() {
516518
flag.Parse()
517-
ctx := context.Background()
519+
ctx, cancel := context.WithCancel(context.Background())
520+
521+
// When kubernetes attempts to kill a workload (i.e. during a restart or
522+
// rollout) it sends a SIGTERM, followed by a SIGKILL after a specified
523+
// timeout. In order to cleanly shutdown the service, as well as destroying
524+
// any created buildlets etc, cancel the global context we pass around,
525+
// which should cascade down.
526+
sigtermChan := make(chan os.Signal, 1)
527+
signal.Notify(sigtermChan, syscall.SIGTERM)
528+
go func() {
529+
<-sigtermChan
530+
// Cancelling the context should cause the program to exit, either via
531+
// a error leading to a log.Fatalf, or the select loop hitting ctx.Done.
532+
// TODO(roland): we may want to make the shutdown somewhat more graceful,
533+
// perhaps commenting that the current run was aborted if we are in the
534+
// middle of one, but for now just exiting cleanly is better than nothing.
535+
cancel()
536+
}()
518537

519538
creds, err := google.FindDefaultCredentials(ctx, gerrit.OAuth2Scopes...)
520539
if err != nil {
@@ -567,23 +586,28 @@ func main() {
567586
}
568587
} else {
569588
ticker := time.NewTicker(time.Minute)
570-
for range ticker.C {
571-
changes, err := t.findChanges(context.Background())
589+
for {
590+
select {
591+
case <-ticker.C:
592+
case <-ctx.Done():
593+
return
594+
}
595+
changes, err := t.findChanges(ctx)
572596
if err != nil {
573597
log.Fatalf("findChanges failed: %v", err)
574598
}
575599
log.Printf("found %d changes", len(changes))
576600

577601
for _, change := range changes {
578602
log.Printf("testing CL %d patchset %d (%s)", change.ChangeNumber, change.Revisions[change.CurrentRevision].PatchSetNumber, change.CurrentRevision)
579-
if err := t.commentBeginning(context.Background(), change); err != nil {
603+
if err := t.commentBeginning(ctx, change); err != nil {
580604
log.Fatalf("commentBeginning failed: %v", err)
581605
}
582606
results, err := t.run(ctx, change.CurrentRevision, change.Branch, builders)
583607
if err != nil {
584608
log.Fatalf("run failed: %v", err)
585609
}
586-
if err := t.commentResults(context.Background(), change, results); err != nil {
610+
if err := t.commentResults(ctx, change, results); err != nil {
587611
log.Fatalf("commentResults failed: %v", err)
588612
}
589613
}

0 commit comments

Comments
 (0)