diff --git a/dist/supervisorTemplate.json b/dist/supervisorTemplate.json index c78cdb1..407ce10 100644 --- a/dist/supervisorTemplate.json +++ b/dist/supervisorTemplate.json @@ -1,11 +1,20 @@ { "processes":[{ "name":"Database DBM", + "description":"data description", "executePath":"dist/test-windows-amd64.exe", "workingDirectory":".", "startDelay":1000, "priority":0, "arguments":["-sleep 5"] +}, +{ + "name":"Pau", + "description":"my lovely wife", + "executePath":"explorer.exe", + "workingDirectory":".", + "startDelay":1000, + "priority":2 } ] } \ No newline at end of file diff --git a/handlers/mainPage.go b/handlers/mainPage.go deleted file mode 100644 index a5ec2fb..0000000 --- a/handlers/mainPage.go +++ /dev/null @@ -1,100 +0,0 @@ -package handlers - -import ( - "embed" - "html/template" - "log" - "net/http" - "os" - "processSupervisor/models" -) - -type MainPage struct { - templates *embed.FS - Supervisor *models.Supervisor -} - -func NewMainPage(templates *embed.FS) (*MainPage, error) { - var supervisor models.Supervisor - if _, err := os.Stat("cfg/"); err != nil { - s, err := models.ReadTemplate("dist/supervisorTemplate.json") - if err != nil { - return nil, err - } - supervisor = s - } - - if err := supervisor.StartProcesses(); err != nil { - return nil, err - } - return &MainPage{ - templates: templates, - Supervisor: &supervisor, - }, nil -} - -func (m *MainPage) UpdateMainPage(w http.ResponseWriter, r *http.Request) { - tmpl := template.Must( - template.New("index.html").ParseFS( - m.templates, - "templates/index.html", - ), - ) - - // tmpl := template.Must( - // template.New("index.html").ParseFiles( - // "templates/index.html", - // ), - // ) - tmpl.Execute(w, m) -} - -func (m *MainPage) StartProcess(w http.ResponseWriter, r *http.Request) { - name := r.PostFormValue("name") - - // This is where you trigger the .Start method - err := m.Supervisor.StartProcessByName(name) - if err != nil { - log.Println("Failed to start process", err) - - //http.Error(w, "Failed to start process", http.StatusInternalServerError) - //return - } - m.UpdateMainPage(w, r) - //w.WriteHeader(http.StatusOK) -} - -func (m *MainPage) StopProcess(w http.ResponseWriter, r *http.Request) { - name := r.PostFormValue("name") - - err := m.Supervisor.StopProcessByName(name) - if err != nil { - log.Println("Failed to stop process", err) - //http.Error(w, "Failed to stop process", http.StatusInternalServerError) - //return - } - m.UpdateMainPage(w, r) - //w.WriteHeader(http.StatusOK) -} - -func (m *MainPage) RestartProcess(w http.ResponseWriter, r *http.Request) { - name := r.PostFormValue("name") - - err := m.Supervisor.StopProcessByName(name) - if err != nil { - log.Println("Failed to start process", err) - - //http.Error(w, "Failed to start process", http.StatusInternalServerError) - //return - } - - err = m.Supervisor.StartProcessByName(name) - if err != nil { - log.Println("Failed to stop process", err) - - // http.Error(w, "Failed to stop process", http.StatusInternalServerError) - // return - } - m.UpdateMainPage(w, r) - //w.WriteHeader(http.StatusOK) -} diff --git a/handlers/htopHandler.go b/htop/htopHandler.go similarity index 74% rename from handlers/htopHandler.go rename to htop/htopHandler.go index 83beff8..0fad5d7 100644 --- a/handlers/htopHandler.go +++ b/htop/htopHandler.go @@ -1,26 +1,26 @@ -package handlers +package htop import ( "embed" "encoding/json" "html/template" "net/http" - "processSupervisor/models" ) +//go:embed templates +var templatesFS embed.FS + type HTopHandler struct { - Table *models.HtopTable - templates *embed.FS + Table *HtopTable } -func NewHTopHandler(templates *embed.FS) (*HTopHandler, error) { - table, err := models.NewTable() +func NewHTopHandler() (*HTopHandler, error) { + table, err := NewTable() if err != nil { return nil, err } return &HTopHandler{ - Table: table, - templates: templates, + Table: table, }, nil } @@ -42,8 +42,8 @@ func (h *HTopHandler) UpdateHTop(w http.ResponseWriter, r *http.Request) { if r.Header.Get("HX-Request") == "true" { tmpl := template.Must( template.New("table.html").Funcs(funcMap).ParseFS( - h.templates, - "templates/htop/table.html", + templatesFS, + "templates/table.html", ), ) tmpl.Execute(w, h.Table) @@ -52,9 +52,9 @@ func (h *HTopHandler) UpdateHTop(w http.ResponseWriter, r *http.Request) { tmpl := template.Must( template.New("htop.html").Funcs(funcMap).ParseFS( - h.templates, - "templates/htop/htop.html", - "templates/htop/table.html", + templatesFS, + "templates/htop.html", + "templates/table.html", ), ) tmpl.Execute(w, h.Table) @@ -90,7 +90,7 @@ func toFloat64(v any) float64 { // GET /taskmanager/usage func UsageHandler(w http.ResponseWriter, r *http.Request) { - cpu, mem, err := models.GetSystemUsage() + cpu, mem, err := GetSystemUsage() if err != nil { http.Error(w, "Failed to get usage", 500) return diff --git a/models/htopTable.go b/htop/htopTable.go similarity index 88% rename from models/htopTable.go rename to htop/htopTable.go index 213c132..6a28da5 100644 --- a/models/htopTable.go +++ b/htop/htopTable.go @@ -1,8 +1,9 @@ -package models +package htop import ( "fmt" "net/http" + "processSupervisor/htop/models" "sort" "strconv" @@ -11,13 +12,13 @@ import ( ) type HtopTable struct { - Processes []Process + Processes []models.Process CurrentSort string CurrentOrder string } func NewTable() (*HtopTable, error) { - processes, err := GetProcesses() + processes, err := models.GetProcesses() if err != nil { return &HtopTable{}, err } @@ -28,7 +29,7 @@ func NewTable() (*HtopTable, error) { func (t *HtopTable) UpdateTable() error { var err error - t.Processes, err = GetProcesses() + t.Processes, err = models.GetProcesses() if err != nil { return err } diff --git a/handlers/killHandler.go b/htop/killHandler.go similarity index 82% rename from handlers/killHandler.go rename to htop/killHandler.go index d495faa..a37a22f 100644 --- a/handlers/killHandler.go +++ b/htop/killHandler.go @@ -1,10 +1,10 @@ -package handlers +package htop import ( "html/template" "net/http" "os" - "processSupervisor/models" + "processSupervisor/htop/models" "strconv" ) @@ -35,6 +35,6 @@ func KillHandler(w http.ResponseWriter, r *http.Request) { return } - tmpl := template.Must(template.ParseFiles("templates/htop/table.html")) + tmpl := template.Must(template.ParseFiles("templates/table.html")) tmpl.Execute(w, processes) } diff --git a/models/process.go b/htop/models/process.go similarity index 100% rename from models/process.go rename to htop/models/process.go diff --git a/templates/htop/htop.html b/htop/templates/htop.html similarity index 100% rename from templates/htop/htop.html rename to htop/templates/htop.html diff --git a/templates/htop/table.html b/htop/templates/table.html similarity index 94% rename from templates/htop/table.html rename to htop/templates/table.html index cc5e977..693432c 100644 --- a/templates/htop/table.html +++ b/htop/templates/table.html @@ -63,7 +63,7 @@ hx-get="/taskmanager/kill?pid={{.PID}}" hx-target="#process-table" hx-swap="outerHTML" - hx-confirm="Are you sure you want to kill this process?"> + hx-confirm="Are you sure you want to kill {{.Cmd}} process?"> Kill diff --git a/main.go b/main.go index bfeb514..88311bc 100644 --- a/main.go +++ b/main.go @@ -7,24 +7,23 @@ import ( "io/fs" "log" "net/http" - "processSupervisor/handlers" + "processSupervisor/htop" + "processSupervisor/mainPage" ) -//go:embed templates/*.html templates/*/*.html -var templatesFS embed.FS - //go:embed static var staticFS embed.FS func main() { port := flag.Uint("port", 9400, "listening port") - htop, err := handlers.NewHTopHandler(&templatesFS) + cfgDir := flag.String("cfg", "./dist", "configuration directory") + htopHandler, err := htop.NewHTopHandler() if err != nil { panic(err) } - mainPage, err := handlers.NewMainPage(&templatesFS) + mP, err := mainPage.NewMainPage(*cfgDir) if err != nil { panic(err) } @@ -36,13 +35,14 @@ func main() { http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.FS(staticSub)))) - http.HandleFunc("/taskmanager/htop", htop.UpdateHTop) - http.HandleFunc("/", mainPage.UpdateMainPage) - http.HandleFunc("/start-process", mainPage.StartProcess) - http.HandleFunc("/stop-process", mainPage.StopProcess) - http.HandleFunc("/restart-process", mainPage.RestartProcess) - http.HandleFunc("/taskmanager/kill", handlers.KillHandler) - http.HandleFunc("/taskmanager/usage", handlers.UsageHandler) + http.HandleFunc("/taskmanager/htop", htopHandler.UpdateHTop) + http.HandleFunc("/", mP.LoadMainPage) + http.HandleFunc("/start-process", mP.StartProcess) + http.HandleFunc("/stop-process", mP.StopProcess) + http.HandleFunc("/restart-process", mP.RestartProcess) + http.HandleFunc("/processes", mP.UpdateMainPage) + http.HandleFunc("/taskmanager/kill", htop.KillHandler) + http.HandleFunc("/taskmanager/usage", htop.UsageHandler) log.Printf("Listening on http://localhost:%d\n", *port) log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", *port), nil)) diff --git a/mainPage/mainPage.go b/mainPage/mainPage.go new file mode 100644 index 0000000..1019069 --- /dev/null +++ b/mainPage/mainPage.go @@ -0,0 +1,96 @@ +package mainPage + +import ( + "embed" + "html/template" + "log" + "net/http" + "os" + "path/filepath" + "processSupervisor/supervisor" + "time" +) + +//go:embed templates +var templatesFS embed.FS + +type MainPage struct { + Supervisor *supervisor.Supervisor +} + +func NewMainPage(cfgDir string) (*MainPage, error) { + var sv supervisor.Supervisor + file := filepath.Join(cfgDir, "supervisorTemplate.json") + if _, err := os.Stat(file); err == nil { + sv, err = supervisor.ReadTemplate(file) + if err != nil { + return nil, err + } + } + + if err := sv.StartProcesses(); err != nil { + return nil, err + } + m := MainPage{ + Supervisor: &sv, + } + + return &m, nil +} + +func (m *MainPage) LoadMainPage(w http.ResponseWriter, r *http.Request) { + tmpl := template.Must( + template.New("index.html").ParseFS( + templatesFS, + "templates/index.html", + "templates/processes.html", + ), + ) + tmpl.Execute(w, m) +} + +func (m *MainPage) UpdateMainPage(w http.ResponseWriter, r *http.Request) { + tmpl := template.Must( + template.New("processes.html").ParseFS( + templatesFS, + "templates/processes.html", + ), + ) + tmpl.Execute(w, m) +} + +func (m *MainPage) StartProcess(w http.ResponseWriter, r *http.Request) { + name := r.PostFormValue("name") + + // This is where you trigger the .Start method + err := m.Supervisor.StartProcessByName(name) + if err != nil { + log.Println("Failed to start process", err) + } + m.UpdateMainPage(w, r) +} + +func (m *MainPage) StopProcess(w http.ResponseWriter, r *http.Request) { + name := r.PostFormValue("name") + + err := m.Supervisor.StopProcessByName(name) + if err != nil { + log.Println("Failed to stop process", err) + } + m.UpdateMainPage(w, r) +} + +func (m *MainPage) RestartProcess(w http.ResponseWriter, r *http.Request) { + name := r.PostFormValue("name") + + err := m.Supervisor.StopProcessByName(name) + if err != nil { + log.Println(err) + } + time.Sleep(time.Second) + err = m.Supervisor.StartProcessByName(name) + if err != nil { + log.Println(err) + } + m.UpdateMainPage(w, r) +} diff --git a/mainPage/templates/index.html b/mainPage/templates/index.html new file mode 100644 index 0000000..328b9b5 --- /dev/null +++ b/mainPage/templates/index.html @@ -0,0 +1,56 @@ + + + + + Process Dashboard + + + + +