diff --git a/bootstrap.sh b/bootstrap.sh new file mode 100755 index 0000000..ddefc74 --- /dev/null +++ b/bootstrap.sh @@ -0,0 +1,2 @@ +#!/bin/bash +gcloud compute scp --recurse kelvinly-server kelvin@senor-servidor1:/home/kelvin/ diff --git a/install.sh b/install.sh old mode 100644 new mode 100755 index 85bcbb7..51858b8 --- a/install.sh +++ b/install.sh @@ -2,7 +2,8 @@ sudo add-apt-repository ppa:gophers/archive sudo apt-get update -sudo apt-get install golang-1.10-go +sudo apt-get -y install golang-1.10-go +sudo apt-get -y install iptables-persistent mkdir -p ~/go @@ -12,3 +13,4 @@ cat "export GOPATH=~/go" >> ~/.bashrc source ~/.bashrc go get -u gopkg.in/russross/blackfriday.v2 go get -u https://github.com/shurcooL/github_flavored_markdown +go get -u github.com/sevlyar/go-daemon diff --git a/main.go b/main.go index bd463b8..5a85f68 100644 --- a/main.go +++ b/main.go @@ -2,17 +2,29 @@ package main import ( "bytes" + "context" + "flag" "fmt" "io/ioutil" "log" "net/http" + "os" "strings" + "syscall" + "github.com/sevlyar/go-daemon" gfm "github.com/shurcooL/github_flavored_markdown" "github.com/shurcooL/github_flavored_markdown/gfmstyle" //blackfriday "gopkg.in/russross/blackfriday.v2" ) +var ( + signal = flag.String("s", "", `send signal to the daemon + quit — graceful shutdown + stop — fast shutdown + reload — reloading the configuration file`) +) + const HTML_HEADER = ` @@ -71,11 +83,86 @@ func rootHandler(w http.ResponseWriter, r *http.Request) { } } +var ( + shutdown chan struct{} = make(chan struct{}) + serverShutdown chan struct{} = make(chan struct{}) +) + func main() { - log.Print("installing handlers") - http.HandleFunc("/", rootHandler) - http.Handle("/gfm/", http.StripPrefix("/gfm", http.FileServer(gfmstyle.Assets))) - http.HandleFunc("/main.css", func(w http.ResponseWriter, r *http.Request) { http.ServeFile(w, r, "main.css") }) - log.Print("starting server") - log.Fatal(http.ListenAndServe(":80", nil)) + flag.Parse() + daemon.AddCommand(daemon.StringFlag(signal, "quit"), syscall.SIGQUIT, termHandler) + daemon.AddCommand(daemon.StringFlag(signal, "stop"), syscall.SIGTERM, termHandler) + daemon.AddCommand(daemon.StringFlag(signal, "reload"), syscall.SIGHUP, reloadHandler) + + cntxt := &daemon.Context{ + PidFileName: "/tmp/kelvinly-server-pid", + PidFilePerm: 0644, + LogFileName: "/tmp/kelvinly-server-log", + LogFilePerm: 0640, + WorkDir: "./", + Umask: 027, + } + // TODO: figure out the daemonizing stuff + + if len(daemon.ActiveFlags()) > 0 { + d, err := cntxt.Search() + if err != nil { + log.Fatalln("Unable to send signal to daemon:", err) + } + daemon.SendCommands(d) + return + } + + d, err := cntxt.Reborn() + if err != nil { + log.Fatalln(err) + } + if d != nil { + return + } + defer cntxt.Release() + + var srv http.Server + + go startServer(&srv) + + go func() { + <-shutdown + log.Println("shutting down server...") + if err := srv.Shutdown(context.Background()); err != nil { + log.Printf("server shutdown error: %v\n", err) + } + }() + + err = daemon.ServeSignals() + if err != nil { + log.Println("Error: ", err) + } + + log.Println("server terminated") +} + +func termHandler(sig os.Signal) error { + log.Printf("sending shutdown signal...") + close(shutdown) + return daemon.ErrStop +} + +func reloadHandler(sig os.Signal) error { + log.Printf("[WARN] reloading not supported yet") + return nil +} + +func startServer(srv *http.Server) { + log.Print("installing handlers") + serveMux := http.NewServeMux() + serveMux.HandleFunc("/", rootHandler) + serveMux.Handle("/gfm/", http.StripPrefix("/gfm", http.FileServer(gfmstyle.Assets))) + serveMux.HandleFunc("/main.css", func(w http.ResponseWriter, r *http.Request) { http.ServeFile(w, r, "main.css") }) + + srv.Addr = ":8000" + srv.Handler = serveMux + log.Print("starting server") + log.Fatal(srv.ListenAndServe()) + close(serverShutdown) } diff --git a/stop-server.sh b/stop-server.sh new file mode 100755 index 0000000..9309526 --- /dev/null +++ b/stop-server.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +kill `cat /tmp/kelvinly-server-pid`