finish sub commands

master
codeskyblue 8 years ago
parent 1b40e01933
commit 416a05367d

@ -10,7 +10,7 @@ triggers:
cmd: sh ./build.sh
shell: true
delay: 100ms
signal: KILL
signal: TERM
watch_paths:
- .
watch_depth: 0

@ -1,3 +1,3 @@
#!/bin/bash -
go build && ./gosuv serv
go build && ./gosuv start-server -f

@ -181,7 +181,7 @@ func (p *Process) startCommand() {
p.Stdout.Reset()
p.Stderr.Reset()
p.Output.Reset()
log.Println("start cmd:", p.Name, p.Command)
log.Printf("start cmd(%s): %s", p.Name, p.Command)
p.cmd = p.buildCommand()
p.SetState(Running)

@ -1,7 +1,9 @@
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"os"
@ -13,15 +15,63 @@ var (
Version string = "dev"
)
func actionServ(c *cli.Context) error {
fmt.Println("added serv: ", c.Args().First())
log.Fatal(http.ListenAndServe(":8000", nil))
func actionStartServer(c *cli.Context) error {
if err := registerHTTPHandlers(); err != nil {
return err
}
addr := c.String("address")
if c.Bool("foreground") {
fmt.Println("added serv: ", addr)
log.Fatal(http.ListenAndServe(addr, nil))
} else {
log.Fatal("Not implement daemon mode")
}
return nil
}
func actionStatus(c *cli.Context) error {
log.Println("Status")
resp, err := http.Get("http://localhost:8000/api/status")
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
var ret JSONResponse
err = json.Unmarshal(body, &ret)
if err != nil {
log.Fatal(err)
}
fmt.Println(ret.Value)
return nil
}
func actionShutdown(c *cli.Context) error {
resp, err := http.Get("http://localhost:8000/api/shutdown")
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
var ret JSONResponse
err = json.Unmarshal(body, &ret)
if err != nil {
log.Fatal(err)
}
fmt.Println(ret.Value)
return nil
}
func actionConfigTest(c *cli.Context) error {
if err := registerHTTPHandlers(); err != nil {
log.Fatal(err)
}
log.Println("test is successful")
return nil
}
@ -32,9 +82,20 @@ func main() {
app.Usage = "golang port of python-supervisor"
app.Commands = []cli.Command{
{
Name: "serv",
Usage: "Should only called by itself",
Action: actionServ,
Name: "start-server",
Usage: "Start supervisor and run in background",
Flags: []cli.Flag{
cli.BoolFlag{
Name: "foreground, f",
Usage: "start in foreground",
},
cli.StringFlag{
Name: "address, addr",
Usage: "listen address",
Value: ":8000",
},
},
Action: actionStartServer,
},
{
Name: "status",
@ -42,6 +103,17 @@ func main() {
Usage: "Show program status",
Action: actionStatus,
},
{
Name: "shutdown",
Usage: "Shutdown server",
Action: actionShutdown,
},
{
Name: "conftest",
Aliases: []string{"t"},
Usage: "Test if config file is valid",
Action: actionConfigTest,
},
}
if err := app.Run(os.Args); err != nil {
os.Exit(1)

@ -181,6 +181,17 @@ func (s *Supervisor) renderHTML(w http.ResponseWriter, name string, data interfa
t.ExecuteTemplate(w, baseName, data)
}
type JSONResponse struct {
Status int `json:"status"`
Value interface{} `json:"value"`
}
func (s *Supervisor) renderJSON(w http.ResponseWriter, data JSONResponse) {
w.Header().Set("Content-Type", "application/json")
bytes, _ := json.Marshal(data)
w.Write(bytes)
}
func (s *Supervisor) hIndex(w http.ResponseWriter, r *http.Request) {
s.renderHTML(w, "./res/index.html", nil)
}
@ -189,6 +200,27 @@ func (s *Supervisor) hSetting(w http.ResponseWriter, r *http.Request) {
s.renderHTML(w, "./res/setting.html", nil)
}
func (s *Supervisor) hStatus(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
data, _ := json.Marshal(map[string]interface{}{
"status": 0,
"value": "server is running",
})
w.Write(data)
}
func (s *Supervisor) hShutdown(w http.ResponseWriter, r *http.Request) {
s.Close()
s.renderJSON(w, JSONResponse{
Status: 0,
Value: "gosuv has been shutdown",
})
go func() {
time.Sleep(500 * time.Millisecond)
os.Exit(0)
}()
}
func (s *Supervisor) hGetProgram(w http.ResponseWriter, r *http.Request) {
procs := make([]*Process, 0, len(s.pgs))
for _, pg := range s.pgs {
@ -342,23 +374,27 @@ func (s *Supervisor) wsLog(w http.ResponseWriter, r *http.Request) {
})
}
func (s *Supervisor) Close() {
for _, proc := range s.procMap {
s.stopAndWait(proc.Name)
}
fmt.Println("Supervisor closed")
}
func (s *Supervisor) catchExitSignal() {
c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
go func() {
sig := <-c
fmt.Printf("Got signal: %v, stopping all running process\n", sig)
for _, proc := range s.procMap {
proc.stopCommand()
}
fmt.Println("Finished. Exit with code 0")
s.Close()
os.Exit(0)
}()
}
var defaultConfigDir = filepath.Join(UserHomeDir(), ".gosuv")
func init() {
func registerHTTPHandlers() error {
suv := &Supervisor{
ConfigDir: defaultConfigDir,
pgMap: make(map[string]*Program, 0),
@ -367,13 +403,15 @@ func init() {
eventB: NewBroadcastString(),
}
if err := suv.loadDB(); err != nil {
log.Fatal(err)
return err
}
suv.catchExitSignal()
r := mux.NewRouter()
r.HandleFunc("/", suv.hIndex)
r.HandleFunc("/settings/{name}", suv.hSetting)
r.HandleFunc("/api/status", suv.hStatus)
r.HandleFunc("/api/shutdown", suv.hShutdown)
r.HandleFunc("/api/programs", suv.hGetProgram).Methods("GET")
r.HandleFunc("/api/programs", suv.hAddProgram).Methods("POST")
r.HandleFunc("/api/programs/{name}/start", suv.hStartProgram).Methods("POST")
@ -384,4 +422,5 @@ func init() {
fs := http.FileServer(http.Dir("res"))
http.Handle("/", r)
http.Handle("/res/", http.StripPrefix("/res/", fs))
return nil
}

Loading…
Cancel
Save