diff --git a/.drone.yml b/.drone.yml index 149c5208..9beb1aaf 100644 --- a/.drone.yml +++ b/.drone.yml @@ -7,7 +7,9 @@ steps: image: golang:1.13 commands: # wait for services to be ready. - - sleep 10 + - cd scripts/liveness_probe + - go run . + - cd ../.. - go mod download - go mod vendor # this is for when the Dockerfile gets built environment: @@ -17,7 +19,6 @@ steps: - name: cache path: /go - - name: build image: golang:1.13 commands: diff --git a/scripts/liveness_probe/go.mod b/scripts/liveness_probe/go.mod new file mode 100644 index 00000000..690cee89 --- /dev/null +++ b/scripts/liveness_probe/go.mod @@ -0,0 +1,3 @@ +module liveness_probe + +go 1.13 diff --git a/scripts/liveness_probe/main.go b/scripts/liveness_probe/main.go new file mode 100644 index 00000000..ff57a2ff --- /dev/null +++ b/scripts/liveness_probe/main.go @@ -0,0 +1,59 @@ +// Package main is a simple script for our CI/CD workflow +// that ensures our sidecar proxy is running before proceeding +package main + +import ( + "context" + "errors" + "fmt" + "net" + "net/http" + "os" + "time" +) + +var goproxy = os.Getenv("GOPROXY") + +func main() { + timeout := time.After(time.Minute) + for { + select { + case <-timeout: + fmt.Println("liveness probe timed out") + os.Exit(1) + default: + } + isLive, err := probe() + if err != nil { + shouldPrintErr := true + // connection-refused errors are expected, don't print them + var opErr *net.OpError + if errors.As(err, &opErr) && opErr.Op == "read" { + shouldPrintErr = false + } + if shouldPrintErr { + fmt.Println(err) + } + } + if isLive { + fmt.Println("proxy is live") + return + } + time.Sleep(time.Second) + } +} + +func probe() (bool, error) { + req, err := http.NewRequest(http.MethodGet, goproxy, nil) + if err != nil { + return false, err + } + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + req = req.WithContext(ctx) + resp, err := http.DefaultClient.Do(req) + if err != nil { + return false, err + } + return resp.StatusCode == http.StatusOK, nil +}