mirror of https://github.com/hak5/overseer.git
6df2e197eb | ||
---|---|---|
cmd | ||
example | ||
fetcher | ||
.gitignore | ||
LICENSE | ||
README.md | ||
graceful.go | ||
overseer.go | ||
proc_master.go | ||
proc_slave.go | ||
sys_posix.go | ||
sys_unsupported.go |
README.md
overseer
Daemonizable self-upgrading binaries in Go (golang).
The main goal of this project is to facilitate the creation of self-upgrading binaries which play nice with standard process managers. The secondary goal is user simplicity. ⚠️ This is beta software.
Features
- Works with process managers
- Simple
- Graceful, zero-down time restarts
- Allows self-upgrading binaries
Install
go get github.com/jpillora/overseer
Quick Usage
package main
import (
"fmt"
"log"
"net/http"
"time"
"github.com/jpillora/overseer"
"github.com/jpillora/overseer/fetcher"
)
//convert your main() into a 'prog(state)' and then
//create another main() to run the main process
func main() {
overseer.Run(overseer.Config{
Program: prog,
Address: ":3000",
Fetcher: &fetcher.HTTP{
URL: "http://localhost:4000/binaries/myapp",
Interval: 1 * time.Second,
},
// Log: false, //display log of overseer actions
})
}
//prog(state) runs in a child process
func prog(state overseer.State) {
log.Printf("app (%s) listening...", state.ID)
http.Handle("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "app (%s) says hello\n", state.ID)
}))
http.Serve(state.Listener, nil)
}
$ cd example/
$ sh example.sh
serving . on port 4000
BUILT APP (1)
RUNNING APP
app#1 (96015cccdebcec119adad34f49b93e02552f3ad9) listening...
app#1 (96015cccdebcec119adad34f49b93e02552f3ad9) says hello
app#1 (96015cccdebcec119adad34f49b93e02552f3ad9) says hello
BUILT APP (2)
app#2 (ccc073a1c8e94fd4f2d76ebefb2bbc96790cb795) listening...
app#2 (ccc073a1c8e94fd4f2d76ebefb2bbc96790cb795) says hello
app#2 (ccc073a1c8e94fd4f2d76ebefb2bbc96790cb795) says hello
app#1 (96015cccdebcec119adad34f49b93e02552f3ad9) says hello
app#1 (96015cccdebcec119adad34f49b93e02552f3ad9) exiting...
BUILT APP (3)
app#3 (286848c2aefcd3f7321a65b5e4efae987fb17911) listening...
app#3 (286848c2aefcd3f7321a65b5e4efae987fb17911) says hello
app#3 (286848c2aefcd3f7321a65b5e4efae987fb17911) says hello
app#2 (ccc073a1c8e94fd4f2d76ebefb2bbc96790cb795) says hello
app#2 (ccc073a1c8e94fd4f2d76ebefb2bbc96790cb795) exiting...
app#3 (286848c2aefcd3f7321a65b5e4efae987fb17911) says hello
app#3 (286848c2aefcd3f7321a65b5e4efae987fb17911) exiting...
Warnings
- Bind
Addresses
can only be changed by restarting the main process - Only supported on darwin and linux
Documentation
Architecture overview
overseer
uses the main process to check for and install upgrades and a child process to runProgram
- All child process pipes are connected back to the main process
- All signals received on the main process are forwarded through to the child process
- The provided
fetcher.Interface
will be used toFetch()
the latest build of the binary - The
fetcher.HTTP
accepts aURL
, it polls this URL with HEAD requests and until it detects a change. On change, weGET
theURL
and stream it back out tooverseer
. - Once a binary is received, it is run with a simple echo token to confirm it is a
overseer
binary. - Except for scheduled upgrades, the child process exiting will cause the main process to exit with the same code. So,
overseer
is not a process manager.
Docker
-
Compile your
overseer
ableapp
to a/path/on/docker/host/myapp/app
-
Then run it with
#run app inside alpine linux (5MB linux distro) docker run -d -v /path/on/docker/host/myapp/:/home/ -w /home/ alpine -w /home/app
-
For testing, swap out
-d
(daemonize) for--rm -it
(remove on exit, input, terminal) -
app
can use the current working directory as storage
Alternatives
TODO
- Github fetcher (given a repo)
- S3 fetcher (given a bucket and credentials)
- etcd fetcher (given a cluster, watch key)
overseer
CLI tool (TODO)upgrade
package- Execute and verify calculated delta updates with https://github.com/kr/binarydist
- Omaha client support