261 lines
6.4 KiB
Go
261 lines
6.4 KiB
Go
package services
|
|
|
|
import (
|
|
"backend/models"
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"gitea.tecamino.com/paadi/statusServer"
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
type ServicesHandler struct {
|
|
cfgDir string
|
|
cfgFile string
|
|
config models.Configuration
|
|
statusWs *statusServer.StatusWebsocket
|
|
}
|
|
|
|
func NewServicesHandler(cfgDir, cfgFile string) *ServicesHandler {
|
|
return &ServicesHandler{cfgDir: cfgDir, cfgFile: cfgFile}
|
|
}
|
|
|
|
func (s *ServicesHandler) LinkStatusServer(statusServer *statusServer.StatusWebsocket) {
|
|
s.statusWs = statusServer
|
|
}
|
|
|
|
func (s *ServicesHandler) GetAllAvaiableServices(c *gin.Context) {
|
|
var services []models.Service
|
|
|
|
defaultCfg, err := s.readDefaultConfig()
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, models.NewJsonErrorResponse(err))
|
|
return
|
|
}
|
|
|
|
configFile := filepath.Join(s.cfgDir, defaultCfg.CfgFileName)
|
|
if _, err := os.Stat(configFile); err != nil {
|
|
c.JSON(http.StatusOK, gin.H{"services": defaultCfg.Services})
|
|
return
|
|
}
|
|
|
|
content, err := os.ReadFile(configFile)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, models.NewJsonErrorResponse(err))
|
|
return
|
|
}
|
|
|
|
var cfg models.Configuration
|
|
err = json.Unmarshal(content, &cfg)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, models.NewJsonErrorResponse(err))
|
|
return
|
|
}
|
|
|
|
// check wether service was already initiated then skip
|
|
next:
|
|
for _, new := range defaultCfg.Services {
|
|
for _, old := range cfg.Services {
|
|
if new.Name == old.Name {
|
|
continue next
|
|
}
|
|
}
|
|
services = append(services, new)
|
|
}
|
|
c.JSON(http.StatusOK, gin.H{"services": services})
|
|
}
|
|
|
|
func (s *ServicesHandler) LoadAllServices(c *gin.Context) {
|
|
|
|
defaultCfg, err := s.readDefaultConfig()
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, models.NewJsonErrorResponse(err))
|
|
return
|
|
}
|
|
|
|
configFile := filepath.Join(s.cfgDir, defaultCfg.CfgFileName)
|
|
if _, err := os.Stat(configFile); err != nil {
|
|
c.JSON(http.StatusOK, gin.H{"message": "no services"})
|
|
return
|
|
}
|
|
|
|
content, err := os.ReadFile(configFile)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, models.NewJsonErrorResponse(err))
|
|
return
|
|
}
|
|
|
|
err = json.Unmarshal(content, &s.config)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, models.NewJsonErrorResponse(err))
|
|
return
|
|
}
|
|
|
|
if len(s.config.Services) == 0 {
|
|
c.JSON(http.StatusOK, gin.H{"message": "no services"})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{"services": s.config.Services})
|
|
}
|
|
|
|
func (s *ServicesHandler) AddNewService(c *gin.Context) {
|
|
body, err := io.ReadAll(c.Request.Body)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, models.NewJsonErrorResponse(err))
|
|
return
|
|
}
|
|
|
|
var newService struct {
|
|
Name string `json:"name"`
|
|
}
|
|
|
|
err = json.Unmarshal(body, &newService)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, models.NewJsonErrorResponse(err))
|
|
return
|
|
}
|
|
|
|
defaultCfg, err := s.readDefaultConfig()
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, models.NewJsonErrorResponse(err))
|
|
return
|
|
}
|
|
|
|
var config models.Configuration
|
|
|
|
if _, err := os.Stat(filepath.Join(s.cfgDir, defaultCfg.CfgFileName)); err == nil {
|
|
content, err := os.ReadFile(filepath.Join(s.cfgDir, defaultCfg.CfgFileName))
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, models.NewJsonErrorResponse(err))
|
|
return
|
|
}
|
|
err = json.Unmarshal(content, &config)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, models.NewJsonErrorResponse(err))
|
|
return
|
|
}
|
|
}
|
|
|
|
for _, service := range defaultCfg.Services {
|
|
if service.Name == newService.Name {
|
|
config.Services = append(config.Services, service)
|
|
|
|
f, err := os.OpenFile(filepath.Join(s.cfgDir, defaultCfg.CfgFileName), os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0774)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, models.NewJsonErrorResponse(err))
|
|
return
|
|
}
|
|
defer f.Close()
|
|
|
|
output, err := json.Marshal(config)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, models.NewJsonErrorResponse(err))
|
|
return
|
|
}
|
|
|
|
_, err = f.Write(output)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, models.NewJsonErrorResponse(err))
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{"message": "service '" + newService.Name + "' added"})
|
|
return
|
|
}
|
|
}
|
|
c.JSON(http.StatusBadRequest, models.NewJsonErrorResponse(errors.New("no service '"+newService.Name+"' found")))
|
|
}
|
|
|
|
func (s *ServicesHandler) StartService(c *gin.Context) {
|
|
service := c.Param("service")
|
|
|
|
s.statusWs.Publish("status/"+service, gin.H{
|
|
"state": "Starting",
|
|
})
|
|
|
|
for i := range s.config.Services {
|
|
if s.config.Services[i].Name == service {
|
|
if err := s.config.Services[i].Start(func(e string) {
|
|
s.statusWs.Publish("status/"+service, gin.H{"state": "Error", "message": e})
|
|
}); err != nil {
|
|
c.JSON(http.StatusBadRequest, models.NewJsonErrorResponse(err))
|
|
s.statusWs.Publish("status/"+service, gin.H{
|
|
"state": "Error",
|
|
"message": err.Error(),
|
|
})
|
|
return
|
|
}
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"message": fmt.Sprintf("service '%s' started", service),
|
|
})
|
|
s.statusWs.Publish("status/"+service, gin.H{
|
|
"state": "Started",
|
|
})
|
|
return
|
|
}
|
|
}
|
|
|
|
c.JSON(http.StatusBadRequest, models.NewJsonErrorMessageResponse(fmt.Sprintf("no service '%s' found", service)))
|
|
s.statusWs.Publish("status/"+service, gin.H{
|
|
"state": "Error",
|
|
"message": fmt.Sprintf("no service '%s' found", service),
|
|
})
|
|
}
|
|
|
|
func (s *ServicesHandler) StopService(c *gin.Context) {
|
|
service := c.Param("service")
|
|
s.statusWs.Publish("status/"+service, gin.H{
|
|
"state": "Stopping",
|
|
})
|
|
|
|
for i := range s.config.Services {
|
|
if s.config.Services[i].Name == service {
|
|
if err := s.config.Services[i].Stop(); err != nil {
|
|
c.JSON(http.StatusBadGateway, gin.H{
|
|
"error": true,
|
|
"message": fmt.Sprintf("service '%s' error; %v", service, err),
|
|
})
|
|
|
|
s.statusWs.Publish("status/"+service, gin.H{
|
|
"state": "Error",
|
|
"message": fmt.Sprintf("service '%s' error; %v", service, err),
|
|
})
|
|
return
|
|
}
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"message": fmt.Sprintf("service '%s' stopped", service),
|
|
})
|
|
|
|
s.statusWs.Publish("status/"+service, gin.H{
|
|
"state": "Stopped",
|
|
})
|
|
return
|
|
}
|
|
}
|
|
|
|
c.JSON(http.StatusBadRequest, gin.H{
|
|
"error": true,
|
|
"message": fmt.Sprintf("no service '%s' found", service),
|
|
})
|
|
|
|
s.statusWs.Publish("status/"+service, gin.H{
|
|
"state": "Stopped",
|
|
"message": fmt.Sprintf("no service '%s' found", service),
|
|
})
|
|
}
|
|
|
|
func (s *ServicesHandler) readDefaultConfig() (data models.Configuration, err error) {
|
|
content, err := os.ReadFile(filepath.Join(s.cfgDir, s.cfgFile))
|
|
if err != nil {
|
|
return
|
|
}
|
|
err = json.Unmarshal(content, &data)
|
|
return
|
|
}
|