Fix issue in watchdog - not reading false config overrides.

This commit is contained in:
Alex Ellis 2017-04-05 09:06:47 +01:00 committed by Alex Ellis
parent 93bdfba4b2
commit 469fc690da
9 changed files with 80 additions and 16 deletions

View File

@ -1,8 +1,11 @@
FROM alpine:latest
ADD https://github.com/alexellis/faas/releases/download/v0.5-alpha/fwatchdog /usr/bin
ADD https://github.com/alexellis/faas/releases/download/0.5.1-alpha/fwatchdog /usr/bin
# COPY ./fwatchdog /usr/bin/
RUN chmod +x /usr/bin/fwatchdog
# Populate example here
# ENV fprocess="wc -l"
HEALTHCHECK --interval=5s CMD [ -e /tmp/.lock ] || exit 1
CMD ["fwatchdog"]

View File

@ -0,0 +1,5 @@
## AlpineFunction
This is a base image for Alpine Linux which already has the watchdog added and configured with a healthcheck.
This image is published on the Docker hub as `functions/alpine`.

View File

@ -6,8 +6,8 @@ EXPOSE 8080
ENV http_proxy ""
ENV https_proxy ""
# ADD https://github.com/alexellis/faas/releases/download/v0.5-alpha/fwatchdog /usr/bin
COPY fwatchdog /usr/bin/
ADD https://github.com/alexellis/faas/releases/download/0.5.1-alpha/fwatchdog /usr/bin
# COPY fwatchdog /usr/bin/
RUN chmod +x /usr/bin/fwatchdog
COPY app .

View File

@ -6,7 +6,8 @@ RUN go get -d -v
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .
ADD https://github.com/alexellis/faas/releases/download/v0.5-alpha/fwatchdog /usr/bin
ADD https://github.com/alexellis/faas/releases/download/0.5.1-alpha/fwatchdog /usr/bin
RUN chmod +x /usr/bin/fwatchdog
# COPY fwatchdog /usr/bin/

View File

@ -25,13 +25,35 @@ ENV fprocess="/bin/cat"
CMD ["fwatchdog"]
```
**Implementing the a healthcheck**
Docker swarm will keep your function out of the DNS-RR / IPVS pool if the task (container) is not healthy.
Here is an example of the `echo` function implementing a healthcheck with a 5-second checking interval.
```
FROM functions/alpine
ENV fprocess="cat /etc/hostname"
HEALTHCHECK --interval=5s CMD [ -e /tmp/.lock ] || exit 1
```
The watchdog process creates a .lock file in `/tmp/` on starting its internal Golang HTTP server. `[ -e file_name ]` is shell to check if a file exists.
Swarm tutorial on Healthchecks:
* [Test-drive Docker Healthcheck in 10 minutes](http://blog.alexellis.io/test-drive-healthcheck/)
**Environmental overrides:**
A number of environmental overrides can be added for additional flexibility and options:
| Option | Usage |
|------------------------|--------------|
| `fprocess` | The process to invoke for each function call. This must be a UNIX binary and accept input via STDIN and output via STDOUT. |
| `fprocess` | The process to invoke for each function call. This must be a UNIX binary and accept input via STDIN and output via STDOUT. |
| `marshal_requests` | Instead of re-directing the raw HTTP body into your fprocess, it will first be marshalled into JSON. Use this if you need to work with HTTP headers |
| `write_timeout` | HTTP timeout for writing a response body from your function |
| `read_timeout` | HTTP timeout for reading the payload from the client caller |
| `write_timeout` | HTTP timeout for writing a response body from your function |
| `read_timeout` | HTTP timeout for reading the payload from the client caller |
| `suppress_lock` | The watchdog will attempt to write a lockfile to /tmp/ for swarm healthchecks - set this to true to disable behaviour. |

View File

@ -3,7 +3,7 @@
# Below makes use of "builder pattern" so that binary is extracted separate
# from the golang runtime/SDK
docker build --build-arg https_proxy=$https_proxy --build-arg http_proxy=$http_proxy \
docker build --no-cache --build-arg https_proxy=$https_proxy --build-arg http_proxy=$http_proxy \
-t functions/watchdog:build .
docker create --name buildoutput functions/watchdog:build echo
docker cp buildoutput:/go/src/github.com/alexellis/faas/watchdog/watchdog ./fwatchdog

View File

@ -29,19 +29,46 @@ func TestRead_WriteDebug_DefaultIsTrueConfig(t *testing.T) {
config := readConfig.Read(defaults)
if config.writeDebug != true {
t.Logf("writeDebug should have been true")
t.Logf("writeDebug should have been true (unspecified)")
t.Fail()
}
}
func TestRead_WriteDebug_FalseConfig(t *testing.T) {
func TestRead_WriteDebug_FalseOverrideConfig(t *testing.T) {
defaults := NewEnvBucket()
readConfig := ReadConfig{}
defaults.Setenv("writeDebug", "true")
defaults.Setenv("write_debug", "false")
config := readConfig.Read(defaults)
if config.writeDebug != false {
t.Logf("writeDebug should have been false (specified)")
t.Fail()
}
}
func TestRead_WriteDebug_TrueConfig(t *testing.T) {
defaults := NewEnvBucket()
readConfig := ReadConfig{}
defaults.Setenv("write_debug", "true")
config := readConfig.Read(defaults)
if config.writeDebug != true {
t.Logf("writeDebug should have been true")
t.Logf("writeDebug should have been true (specified)")
t.Fail()
}
}
func TestRead_SuppressLockConfig(t *testing.T) {
defaults := NewEnvBucket()
readConfig := ReadConfig{}
defaults.Setenv("suppress_lock", "true")
config := readConfig.Read(defaults)
if config.suppressLock != true {
t.Logf("suppress_lock envVariable incorrect, got: %s.\n", config.faasProcess)
t.Fail()
}
}

View File

@ -136,9 +136,11 @@ func main() {
http.HandleFunc("/", makeRequestHandler(&config))
if config.suppressLock == false {
writeErr := ioutil.WriteFile("/tmp/.lock", []byte{}, 0660)
path := "/tmp/.lock"
log.Printf("Writing lock-file to: %s\n", path)
writeErr := ioutil.WriteFile(path, []byte{}, 0660)
if writeErr != nil {
log.Panicf("Cannot write /tmp/.lock for healthcheck: %s \n", writeErr.Error())
log.Panicf("Cannot write %s. Error: %s\n", path, writeErr.Error())
}
}

View File

@ -18,7 +18,7 @@ func parseBoolValue(val string) bool {
if val == "true" {
return true
}
return true
return false
}
func parseIntValue(val string) int {
@ -55,11 +55,15 @@ func (ReadConfig) Read(hasEnv HasEnv) WatchdogConfig {
cfg.readTimeout = time.Duration(readTimeout) * time.Second
cfg.writeTimeout = time.Duration(writeTimeout) * time.Second
cfg.writeDebug = parseBoolValue(hasEnv.Getenv("write_debug"))
if len(hasEnv.Getenv("write_debug")) > 0 {
cfg.writeDebug = parseBoolValue(hasEnv.Getenv("write_debug"))
}
cfg.marshalRequest = parseBoolValue(hasEnv.Getenv("marshal_request"))
cfg.debugHeaders = parseBoolValue(hasEnv.Getenv("debug_headers"))
cfg.suppressLock = parseBoolValue(hasEnv.Getenv("suppress_lock"))
return cfg
}