Skip to content

Commit

Permalink
Merge pull request #95 from ochinchina/stou-v0.3-test
Browse files Browse the repository at this point in the history
get pid with:supervisord ctl pid
  • Loading branch information
ochinchina authored Jun 23, 2018
2 parents 8dc3c50 + 3fafa44 commit 5f297ce
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 73 deletions.
177 changes: 106 additions & 71 deletions ctl.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,97 +47,132 @@ func (x *CtlCommand) Execute(args []string) error {
// STATUS
////////////////////////////////////////////////////////////////////////////////
case "status":
processes := args[1:]
processesMap := make(map[string]bool)
for _, process := range processes {
processesMap[strings.ToLower(process)] = true
}
if reply, err := rpcc.GetAllProcessInfo(); err == nil {
x.showProcessInfo(&reply, processesMap)
}
x.status(rpcc, args[1:])

////////////////////////////////////////////////////////////////////////////////
// START or STOP
////////////////////////////////////////////////////////////////////////////////
case "start", "stop":
state := map[string]string{
"start": "started",
"stop": "stopped",
}
processes := args[1:]
if len(processes) <= 0 {
fmt.Printf("Please specify process for %s\n", verb)
}
for _, pname := range processes {
if pname == "all" {
reply, err := rpcc.ChangeAllProcessState(verb)
if err == nil {
x.showProcessInfo(&reply, make(map[string]bool))
} else {
fmt.Printf("Fail to change all process state to %s", state)
}
} else {
if reply, err := rpcc.ChangeProcessState(verb, pname); err == nil {
fmt.Printf("%s: ", pname)
if !reply.Value {
fmt.Printf("not ")
}
fmt.Printf("%s\n", state[verb])
} else {
fmt.Printf("%s: failed [%v]\n", pname, err)
}
}
}
x.startStopProcesses(rpcc, verb, args[1:])

////////////////////////////////////////////////////////////////////////////////
// SHUTDOWN
////////////////////////////////////////////////////////////////////////////////
case "shutdown":
if reply, err := rpcc.Shutdown(); err == nil {
if reply.Value {
fmt.Printf("Shut Down\n")
} else {
fmt.Printf("Hmmm! Something gone wrong?!\n")
}
}
x.shutdown(rpcc)
case "reload":
if reply, err := rpcc.ReloadConfig(); err == nil {

if len(reply.AddedGroup) > 0 {
fmt.Printf("Added Groups: %s\n", strings.Join(reply.AddedGroup, ","))
}
if len(reply.ChangedGroup) > 0 {
fmt.Printf("Changed Groups: %s\n", strings.Join(reply.ChangedGroup, ","))
}
if len(reply.RemovedGroup) > 0 {
fmt.Printf("Removed Groups: %s\n", strings.Join(reply.RemovedGroup, ","))
}
}
x.reload(rpcc)
case "signal":
sig_name, processes := args[1], args[2:]
for _, process := range processes {
if process == "all" {
reply, err := rpcc.SignalAll(process)
if err == nil {
x.showProcessInfo(&reply, make(map[string]bool))
} else {
fmt.Printf("Fail to send signal %s to all process", sig_name)
}
x.signal( rpcc, sig_name, processes )
case "pid":
x.getPid( rpcc, args[1] )
default:
fmt.Println("unknown command")
}

return nil
}

// get the status of processes
func (x *CtlCommand) status(rpcc *xmlrpcclient.XmlRPCClient, processes []string) {
processesMap := make(map[string]bool)
for _, process := range processes {
processesMap[strings.ToLower(process)] = true
}
if reply, err := rpcc.GetAllProcessInfo(); err == nil {
x.showProcessInfo(&reply, processesMap)
}
}

// start or stop the processes
// verb must be: start or stop
func (x *CtlCommand) startStopProcesses(rpcc *xmlrpcclient.XmlRPCClient, verb string, processes []string) {
state := map[string]string{
"start": "started",
"stop": "stopped",
}
if len(processes) <= 0 {
fmt.Printf("Please specify process for %s\n", verb)
}
for _, pname := range processes {
if pname == "all" {
reply, err := rpcc.ChangeAllProcessState(verb)
if err == nil {
x.showProcessInfo(&reply, make(map[string]bool))
} else {
reply, err := rpcc.SignalProcess(sig_name, process)
if err == nil && reply.Success {
fmt.Printf("Succeed to send signal %s to process %s\n", sig_name, process)
} else {
fmt.Printf("Fail to send signal %s to process %s\n", sig_name, process)
fmt.Printf("Fail to change all process state to %s", state)
}
} else {
if reply, err := rpcc.ChangeProcessState(verb, pname); err == nil {
fmt.Printf("%s: ", pname)
if !reply.Value {
fmt.Printf("not ")
}
fmt.Printf("%s\n", state[verb])
} else {
fmt.Printf("%s: failed [%v]\n", pname, err)
}
}
}
}

default:
fmt.Println("unknown command")
// shutdown the supervisord
func (x *CtlCommand) shutdown(rpcc *xmlrpcclient.XmlRPCClient) {
if reply, err := rpcc.Shutdown(); err == nil {
if reply.Value {
fmt.Printf("Shut Down\n")
} else {
fmt.Printf("Hmmm! Something gone wrong?!\n")
}
}
}

return nil
// reload all the programs in the supervisord
func (x *CtlCommand) reload(rpcc *xmlrpcclient.XmlRPCClient) {
if reply, err := rpcc.ReloadConfig(); err == nil {

if len(reply.AddedGroup) > 0 {
fmt.Printf("Added Groups: %s\n", strings.Join(reply.AddedGroup, ","))
}
if len(reply.ChangedGroup) > 0 {
fmt.Printf("Changed Groups: %s\n", strings.Join(reply.ChangedGroup, ","))
}
if len(reply.RemovedGroup) > 0 {
fmt.Printf("Removed Groups: %s\n", strings.Join(reply.RemovedGroup, ","))
}
}
}

// send signal to one or more processes
func (x *CtlCommand) signal(rpcc *xmlrpcclient.XmlRPCClient, sig_name string, processes []string) {
for _, process := range processes {
if process == "all" {
reply, err := rpcc.SignalAll(process)
if err == nil {
x.showProcessInfo(&reply, make(map[string]bool))
} else {
fmt.Printf("Fail to send signal %s to all process", sig_name)
}
} else {
reply, err := rpcc.SignalProcess(sig_name, process)
if err == nil && reply.Success {
fmt.Printf("Succeed to send signal %s to process %s\n", sig_name, process)
} else {
fmt.Printf("Fail to send signal %s to process %s\n", sig_name, process)
}
}
}
}

// get the pid of running program
func (x *CtlCommand) getPid(rpcc *xmlrpcclient.XmlRPCClient, process string) {
procInfo, err := rpcc.GetProcessInfo( process )
if err != nil {
fmt.Printf("Fail to get information of process:%s\n", process )
} else {
fmt.Printf("%d\n", procInfo.Pid )
}
}

func (x *CtlCommand) showProcessInfo(reply *xmlrpcclient.AllProcessInfoReply, processesMap map[string]bool) {
Expand Down
2 changes: 1 addition & 1 deletion supervisor.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ func (s *Supervisor) GetAllProcessInfo(r *http.Request, args *struct{}, reply *s
}

func (s *Supervisor) GetProcessInfo(r *http.Request, args *struct{ Name string }, reply *struct{ ProcInfo types.ProcessInfo }) error {
log.Debug("Get process info of: ", args.Name)
log.Info("Get process info of: ", args.Name)
proc := s.procMgr.Find(args.Name)
if proc == nil {
return fmt.Errorf("no process named %s", args.Name)
Expand Down
20 changes: 19 additions & 1 deletion xmlrpcclient/xmlrpc-client.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ func (r *XmlRPCClient) post(method string, data interface{}) (*http.Response, er
req.SetBasicAuth(r.user, r.password)
}
req.Header.Set("Content-Type", "text/xml")
err = req.Write(conn)
err = req.Write(conn)
if err != nil {
fmt.Printf("Fail to write to unix socket %s\n", r.serverurl)
return nil, err
Expand Down Expand Up @@ -270,3 +270,21 @@ func (r *XmlRPCClient) SignalAll(signal string) (reply AllProcessInfoReply, err

return
}

func (r *XmlRPCClient) GetProcessInfo( process string)( reply types.ProcessInfo, err error ) {
ins := struct{ Name string }{process}
resp, err := r.post("supervisor.getProcessInfo", &ins)
if err != nil {
return
}
defer resp.Body.Close()
result := struct { Reply types.ProcessInfo}{}
err = xml.DecodeClientResponse(resp.Body, &result)
if err != nil {
fmt.Printf( "Fail to decode to types.ProcessInfo\n")
} else {
reply = result.Reply
}

return
}

0 comments on commit 5f297ce

Please sign in to comment.