Monitorable, gracefully restarting, self-upgrading binaries in Go (golang)
 
 
Go to file
Jaime Pillora 6df2e197eb rename to overseer, allow manual restarts with USR2, fetcher now optional, added fetcher init method 2016-02-09 14:46:45 +11:00
cmd rename to overseer, allow manual restarts with USR2, fetcher now optional, added fetcher init method 2016-02-09 14:46:45 +11:00
example rename to overseer, allow manual restarts with USR2, fetcher now optional, added fetcher init method 2016-02-09 14:46:45 +11:00
fetcher rename to overseer, allow manual restarts with USR2, fetcher now optional, added fetcher init method 2016-02-09 14:46:45 +11:00
.gitignore fixed on linux with mv 2016-02-09 00:20:50 +11:00
LICENSE rewrite complete, mostly working now 2016-02-08 12:06:54 +11:00
README.md rename to overseer, allow manual restarts with USR2, fetcher now optional, added fetcher init method 2016-02-09 14:46:45 +11:00
graceful.go rename to overseer, allow manual restarts with USR2, fetcher now optional, added fetcher init method 2016-02-09 14:46:45 +11:00
overseer.go rename to overseer, allow manual restarts with USR2, fetcher now optional, added fetcher init method 2016-02-09 14:46:45 +11:00
proc_master.go rename to overseer, allow manual restarts with USR2, fetcher now optional, added fetcher init method 2016-02-09 14:46:45 +11:00
proc_slave.go rename to overseer, allow manual restarts with USR2, fetcher now optional, added fetcher init method 2016-02-09 14:46:45 +11:00
sys_posix.go rename to overseer, allow manual restarts with USR2, fetcher now optional, added fetcher init method 2016-02-09 14:46:45 +11:00
sys_unsupported.go rename to overseer, allow manual restarts with USR2, fetcher now optional, added fetcher init method 2016-02-09 14:46:45 +11:00

README.md

overseer

GoDoc

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 run Program
  • 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 to Fetch() the latest build of the binary
  • The fetcher.HTTP accepts a URL, it polls this URL with HEAD requests and until it detects a change. On change, we GET the URL and stream it back out to overseer.
  • 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 overseerable app 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