Skip to content
This repository has been archived by the owner on May 6, 2021. It is now read-only.

Commit

Permalink
takes env vars value for poll interval and verbosity. default interva…
Browse files Browse the repository at this point in the history
…l is 1 sec.
  • Loading branch information
sathishvj committed Aug 24, 2017
1 parent bb8cb75 commit 6632df1
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 6 deletions.
45 changes: 45 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,47 @@
# fabric8-dependency-wait-service
A small go binary that waits for service dependencies to be up and running that can be used as a kubernetes init-container to simplify the startup of complex applications

# Environment variables
DEPENDENCY_LOG_VERBOSE: true/false, default=false. puts out a little more extra logs.
DEPENDENCY_POLL_INTERVAL: a positive integer, default=1. The interval between each poll of the dependency check.

# Usage
This utility is used as part of the init-containers. An example is given below.
```
spec:
template:
metadata:
annotations:
pod.beta.kubernetes.io/init-containers: |-
[
{
"name": "init-dependencyservice1",
"image": "fabric8io/fabric8-dependency-wait-service:withEnvVars",
"imagePullPolicy": "IfNotPresent",
"command": ["sh", "-c", "fabric8-dependency-wait-service-linux-amd64 postgres://wit@wit-db:5432"],
"env": [{
"name": "DEPENDENCY_POLL_INTERVAL",
"value": "9"
}, {
"name": "DEPENDENCY_LOG_VERBOSE",
"value": "true"
}]
},
{
"name": "init-dependencyservice2",
"image": "fabric8io/fabric8-dependency-wait-service:withEnvVars",
"imagePullPolicy": "IfNotPresent",
"command": ["sh", "-c", "fabric8-dependency-wait-service-linux-amd64 http://keycloak:80"],
"env": [{
"name": "DEPENDENCY_POLL_INTERVAL",
"value": "11"
}, {
"name": "DEPENDENCY_LOG_VERBOSE",
"value": "true"
}]
},
```

* the protocols can be only http or postgres (as of now)
* http: for this a get request is made and if the response is 200 then it is ok.
* postgres: for this the pg_isready utility is used. The given postgres url is parsed for username, host, and port and passed to the utility. The db is considered up when a "accepting connections" response is received.
56 changes: 50 additions & 6 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,16 @@ import (
"net/url"
"os"
"os/exec"
"strconv"
"strings"
"time"
)

var PollIntervals = []int{
var defaultPollIntervals = []int{
//1, 2, 2, // polls after 1sec, 2secs, 2secs, then stops
//1, -2, // polls after 1sec, then infinitely every 2 seconds
0, -5, // polls immediately, then infinitely every 5 seconds
//0, -5, // polls immediately, then infinitely every 5 seconds
0, -1, // polls immediately, then infinitely every 1 seconds

// 1, 2, 2, 5, 5, 10, 10, 10, 10, 10, 10, 10, 10, 10,
// 1, 2, 2,
Expand All @@ -27,12 +29,14 @@ var gVerbose bool

func main() {

gVerbose = true
gVerbose = getVerbosity()

if len(os.Args) == 1 {
return
}

pollIntervals := getPollIntervals()

// first check if all urls are valid
err := isAllProtocolsValid(os.Args[1:])
if err != nil {
Expand All @@ -43,15 +47,15 @@ func main() {
for _, v := range os.Args[1:] {
smallv := strings.ToLower(v)
if strings.HasPrefix(smallv, "http") {
isUp, totSecs := pollHTTP200(smallv, PollIntervals)
isUp, totSecs := pollHTTP200(smallv, pollIntervals)
if !isUp {
log.Fatalf("\tNot ok. Service %s polling timedout after %d seconds.\n", smallv, totSecs)
} else {
log.Printf("\tOk. Service %s is up after about %d seconds.\n", smallv, totSecs)
}
} else if strings.HasPrefix(smallv, "postgres") {
useDbPing := false
isUp, totSecs := pollPostgres(smallv, PollIntervals, useDbPing)
isUp, totSecs := pollPostgres(smallv, pollIntervals, useDbPing)
if !isUp {
log.Fatalf("\tNot ok. Service %s polling timedout after %d seconds.\n", smallv, totSecs)
} else {
Expand Down Expand Up @@ -89,7 +93,7 @@ func pollHTTP200(url string, pollIntervals []int) (bool, int) {
time.Sleep(time.Second * time.Duration(pollInt))

if gVerbose {
log.Printf("\tGoing to checck %s\n", url)
log.Printf("\tGoing to check %s\n", url)
}
ok := httpPoll(url)
if ok {
Expand Down Expand Up @@ -252,3 +256,43 @@ func splitPostgresURL(pgURL string) (string, string, string, error) {

return host, port, username, nil
}

func getPollIntervals() []int {
key := "DEPENDENCY_POLL_INTERVAL"
intervalStr := strings.TrimSpace(os.Getenv(key))
if len(intervalStr) == 0 {
return defaultPollIntervals
}

interval, err := strconv.Atoi(intervalStr)
if err != nil || interval <= 0 {
log.Printf("Error: Dependency service key %s has invalid value: %s. Should be a positive integer.\n", key, intervalStr)
os.Exit(1)
}

if gVerbose {
log.Printf("Got env value for poll interval. Will poll every %d seconds.\n", interval)
}

return []int{0, -interval}
}

func getVerbosity() bool {
key := "DEPENDENCY_LOG_VERBOSE"
verbosityStr := strings.TrimSpace(os.Getenv(key))
if len(verbosityStr) == 0 {
return false
}

verbosity, err := strconv.ParseBool(verbosityStr)
if err != nil {
log.Printf("Error: Dependency service key %s has invalid value: %s. Should be true/false.\n", key, verbosityStr)
os.Exit(1)
}

if verbosity {
log.Printf("Got env value verbose: %t.\n", verbosity)
}

return verbosity
}

0 comments on commit 6632df1

Please sign in to comment.