diff --git a/main.go b/main.go index 460ae29..55d466d 100644 --- a/main.go +++ b/main.go @@ -2,55 +2,142 @@ package main import ( "bufio" - "fmt" + "flag" + "fmt" "log" "os" "os/exec" + "strings" "time" ) var ( - controlFile = "/adm/services" - services = make(map[string]string) + startup []string + daemon = false + serviceFile = "/adm/services" + services = make(map[string]string) + controlSocket = "/adm/headless9/ctl/headless9.ctl" + logPath = "/adm/headless9/log/" ) func main() { - log.Println("Starting headless9") + flag.Parse() + if flag.NArg() == 0 { + log.Println("Starting headless9") + daemon = true + runDaemon() + } + if flag.NArg() != 2 { + fmt.Println("Command structure: \"headless9 $verb $service\"") + return + } + verb := flag.Args()[1] + service := flag.Args()[2] + + f := getCtl() + _, err := fmt.Fprintf(f, "%+v %+v", verb, service) + if err != nil { + fmt.Printf("Unable to write to Control Socket. Please check the file %+v and that it's permissions are 700", controlSocket) + } + f.Close() + err = watchFile(controlSocket) + if err != nil { + log.Println(err) + } + fmt.Println(strings.Join(sysTail(10, controlSocket), "\n")) + +} + +func getCtl() *os.File { + f, err := os.OpenFile(controlSocket, os.O_TRUNC, 0700) + if err != nil { + if daemon { + log.Printf("Unable to open Control Socket. Please check the file %+v and that it's permissions are 700", controlSocket) + } else { + fmt.Printf("Unable to open Control Socket. Please check the file %+v and that it's permissions are 700", controlSocket) + } + } + err = f.Truncate(0) + if err != nil { + if daemon { + log.Printf("Unable to clear Control Socket. Please check the file %+v and that it's permissions are 700", controlSocket) + } else { + fmt.Printf("Unable to clear Control Socket. Please check the file %+v and that it's permissions are 700", controlSocket) + } + } + _, err = f.Seek(0, 0) + if err != nil { + if daemon { + log.Printf("Unable to rewind Control Socket. Please check the file %+v and that it's permissions are 700", controlSocket) + } else { + fmt.Printf("Unable to rewind Control Socket. Please check the file %+v and that it's permissions are 700", controlSocket) + } + } + return f +} + +func runDaemon() { + go headlessControls() for { - log.Printf("Refreshing controlFile %+v", controlFile) - startup, err := readLines(controlFile) + log.Printf("Refreshing controlFile %+v", serviceFile) + startup, err := readLines(serviceFile) if err != nil { log.Fatalln(err) } for _, svc := range startup { running := false + svcArgs := strings.Split(svc, " ") for runningProc := range services { - if svc == runningProc { + if svcArgs[0] == runningProc { running = true - log.Printf("%+v exists as PID %+v", svc, services[svc]) + log.Printf("%+v exists as PID %+v", svcArgs[0], services[svcArgs[0]]) } } if !running { - log.Printf("Svc not detected, starting: %+v", svc) - go execCommand(svc) + log.Printf("Svc not detected, starting: %+v", svcArgs[0]) + go execCommand(svcArgs[0], svcArgs[1:]...) } } - err = watchFile(controlFile) + err = watchFile(serviceFile) if err != nil { log.Println(err) } } } +func headlessControls() { + for { + err := watchFile(controlSocket) + if err != nil { + log.Println(err) + } + pendingCommands, err := readLines(controlSocket) + if err != nil { + log.Println(err) + } else { + for _, cmd := range pendingCommands { + log.Printf("Processing command: %+v", cmd) + } + } + + + } +} + + func execCommand(cmd string, arg ...string) { defer PanicSafe() + if len(cmd) < 2 { + log.Printf("Invalid command `%v`, skipping. Args: { %+v }", cmd, arg) + return + } proc := exec.Command(cmd, arg...) // open the out file for writing - outfile, err := os.Create(fmt.Sprintf("/adm/log/%+v.log", cmd)) + outfile, err := os.Create(fmt.Sprintf("%+v/%+v.log", logPath, cmd)) if err != nil { panic(err) } - infile, err := os.Create(fmt.Sprintf("/adm/log/%+v.ctl", cmd)) + infile, err := os.Create(fmt.Sprintf("%+v/%+v.ctl", logPath, cmd)) if err != nil { panic(err) } @@ -61,7 +148,8 @@ func execCommand(cmd string, arg ...string) { proc.Stdin = infile err = proc.Start() if err != nil { - panic(err) + log.Printf("Error starting service %+v, see log for more info.", cmd) + return } services[cmd] = fmt.Sprint(proc.Process.Pid) proc.Wait() @@ -106,11 +194,20 @@ func watchFile(filePath string) error { return nil } - // PanicSafe is a deferrable function to recover from a panic operation. func PanicSafe(a ...interface{}) { if r := recover(); r != nil { log.Printf("Panic detected: %+v", r) log.Printf("Optional panic data: %+v", a...) } +} + +// count for number of lines, path of file +func sysTail(count int, path string) []string { + c := exec.Command("tail", fmt.Sprintf("-%d", count+1), path) + output, _ := c.Output() + //log.Printf("SysTail call output: %+v\nEND", string(output)) + lines := strings.Split(string(output), "\n") + + return lines[:len(lines)-1] } \ No newline at end of file