Watchtower HTTP API based updates (#432)

* Added HTTP API trigger to update running images

* Adds HTTP API authentication token parameter and handling

* Exposes port 8080 in Dockerfile to allow inter-container update triggering via HTTP API

* Fixes codacy issue

* Adds API usage doc

* Fix grammar

* Moves api logic to a package of its own

* Makes WT exit if token has not been set in HTTP API mode

* Adds lock to prevent concurrent updates when in HTTP API mode

Co-authored-by: Simon Aronsson <simme@arcticbit.se>
This commit is contained in:
Victor Moura 2020-04-20 11:17:14 -03:00 committed by GitHub
parent 557f4abcb4
commit 0217e116c4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 143 additions and 0 deletions

61
pkg/api/api.go Normal file
View file

@ -0,0 +1,61 @@
package api
import (
"os"
"net/http"
"errors"
log "github.com/sirupsen/logrus"
"io"
)
var (
lock chan bool
)
func init() {
lock = make(chan bool, 1)
lock <- true
}
func SetupHTTPUpdates(apiToken string, updateFunction func()) error {
if apiToken == "" {
return errors.New("API token is empty or has not been set. Not starting API.")
}
log.Println("Watchtower HTTP API started.")
http.HandleFunc("/v1/update", func(w http.ResponseWriter, r *http.Request){
log.Info("Updates triggered by HTTP API request.")
_, err := io.Copy(os.Stdout, r.Body)
if err != nil {
log.Println(err)
return
}
if r.Header.Get("Token") != apiToken {
log.Println("Invalid token. Not updating.")
return
}
log.Println("Valid token found. Attempting to update.")
select {
case chanValue := <- lock:
defer func() { lock <- chanValue }()
updateFunction()
default:
log.Debug("Skipped. Another update already running.")
}
})
return nil
}
func WaitForHTTPUpdates() error {
log.Fatal(http.ListenAndServe(":8080", nil))
os.Exit(0)
return nil
}