mirror of
https://github.com/openfaas/faas.git
synced 2025-06-09 08:46:48 +00:00
Fix issue in watchdog - not reading false config overrides.
This commit is contained in:
parent
93bdfba4b2
commit
469fc690da
@ -1,8 +1,11 @@
|
|||||||
FROM alpine:latest
|
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
|
RUN chmod +x /usr/bin/fwatchdog
|
||||||
|
|
||||||
# Populate example here
|
# Populate example here
|
||||||
# ENV fprocess="wc -l"
|
# ENV fprocess="wc -l"
|
||||||
|
|
||||||
|
HEALTHCHECK --interval=5s CMD [ -e /tmp/.lock ] || exit 1
|
||||||
CMD ["fwatchdog"]
|
CMD ["fwatchdog"]
|
||||||
|
5
sample-functions/AlpineFunction/README.md
Normal file
5
sample-functions/AlpineFunction/README.md
Normal 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`.
|
@ -6,8 +6,8 @@ EXPOSE 8080
|
|||||||
ENV http_proxy ""
|
ENV http_proxy ""
|
||||||
ENV https_proxy ""
|
ENV https_proxy ""
|
||||||
|
|
||||||
# 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/
|
# COPY fwatchdog /usr/bin/
|
||||||
RUN chmod +x /usr/bin/fwatchdog
|
RUN chmod +x /usr/bin/fwatchdog
|
||||||
|
|
||||||
COPY app .
|
COPY app .
|
||||||
|
@ -6,7 +6,8 @@ RUN go get -d -v
|
|||||||
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .
|
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
|
RUN chmod +x /usr/bin/fwatchdog
|
||||||
# COPY fwatchdog /usr/bin/
|
# COPY fwatchdog /usr/bin/
|
||||||
|
|
||||||
|
@ -25,13 +25,35 @@ ENV fprocess="/bin/cat"
|
|||||||
CMD ["fwatchdog"]
|
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:**
|
**Environmental overrides:**
|
||||||
|
|
||||||
A number of environmental overrides can be added for additional flexibility and options:
|
A number of environmental overrides can be added for additional flexibility and options:
|
||||||
|
|
||||||
| Option | Usage |
|
| 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 |
|
| `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 |
|
| `write_timeout` | HTTP timeout for writing a response body from your function |
|
||||||
| `read_timeout` | HTTP timeout for reading the payload from the client caller |
|
| `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. |
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
# Below makes use of "builder pattern" so that binary is extracted separate
|
# Below makes use of "builder pattern" so that binary is extracted separate
|
||||||
# from the golang runtime/SDK
|
# 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 .
|
-t functions/watchdog:build .
|
||||||
docker create --name buildoutput functions/watchdog:build echo
|
docker create --name buildoutput functions/watchdog:build echo
|
||||||
docker cp buildoutput:/go/src/github.com/alexellis/faas/watchdog/watchdog ./fwatchdog
|
docker cp buildoutput:/go/src/github.com/alexellis/faas/watchdog/watchdog ./fwatchdog
|
||||||
|
@ -29,19 +29,46 @@ func TestRead_WriteDebug_DefaultIsTrueConfig(t *testing.T) {
|
|||||||
config := readConfig.Read(defaults)
|
config := readConfig.Read(defaults)
|
||||||
|
|
||||||
if config.writeDebug != true {
|
if config.writeDebug != true {
|
||||||
t.Logf("writeDebug should have been true")
|
t.Logf("writeDebug should have been true (unspecified)")
|
||||||
t.Fail()
|
t.Fail()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func TestRead_WriteDebug_FalseConfig(t *testing.T) {
|
|
||||||
|
func TestRead_WriteDebug_FalseOverrideConfig(t *testing.T) {
|
||||||
defaults := NewEnvBucket()
|
defaults := NewEnvBucket()
|
||||||
readConfig := ReadConfig{}
|
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)
|
config := readConfig.Read(defaults)
|
||||||
|
|
||||||
if config.writeDebug != true {
|
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()
|
t.Fail()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -136,9 +136,11 @@ func main() {
|
|||||||
http.HandleFunc("/", makeRequestHandler(&config))
|
http.HandleFunc("/", makeRequestHandler(&config))
|
||||||
|
|
||||||
if config.suppressLock == false {
|
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 {
|
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())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ func parseBoolValue(val string) bool {
|
|||||||
if val == "true" {
|
if val == "true" {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return true
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseIntValue(val string) int {
|
func parseIntValue(val string) int {
|
||||||
@ -55,11 +55,15 @@ func (ReadConfig) Read(hasEnv HasEnv) WatchdogConfig {
|
|||||||
cfg.readTimeout = time.Duration(readTimeout) * time.Second
|
cfg.readTimeout = time.Duration(readTimeout) * time.Second
|
||||||
cfg.writeTimeout = time.Duration(writeTimeout) * 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.marshalRequest = parseBoolValue(hasEnv.Getenv("marshal_request"))
|
||||||
cfg.debugHeaders = parseBoolValue(hasEnv.Getenv("debug_headers"))
|
cfg.debugHeaders = parseBoolValue(hasEnv.Getenv("debug_headers"))
|
||||||
|
|
||||||
cfg.suppressLock = parseBoolValue(hasEnv.Getenv("suppress_lock"))
|
cfg.suppressLock = parseBoolValue(hasEnv.Getenv("suppress_lock"))
|
||||||
|
|
||||||
return cfg
|
return cfg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user