mirror of
https://github.com/EnumeratedDev/enit.git
synced 2026-09-16 02:26:11 +00:00
Move service enable/disable functionality to esvm
This commit is contained in:
@@ -1,5 +1,3 @@
|
|||||||
module ectl
|
module ectl
|
||||||
|
|
||||||
go 1.23.4
|
go 1.23.4
|
||||||
|
|
||||||
require gopkg.in/yaml.v3 v3.0.1
|
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
|
||||||
|
|||||||
+1
-99
@@ -13,8 +13,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"gopkg.in/yaml.v3"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Build-time variables
|
// Build-time variables
|
||||||
@@ -88,7 +86,7 @@ func main() {
|
|||||||
} else if len(flag.Args()) <= 2 {
|
} else if len(flag.Args()) <= 2 {
|
||||||
fmt.Printf("Usage: ectl service %s <service>\n", flag.Args()[1])
|
fmt.Printf("Usage: ectl service %s <service>\n", flag.Args()[1])
|
||||||
return
|
return
|
||||||
} else if flag.Arg(1) == "start" || flag.Arg(1) == "stop" || flag.Arg(1) == "restart" {
|
} else if flag.Arg(1) == "start" || flag.Arg(1) == "stop" || flag.Arg(1) == "restart" || flag.Arg(1) == "enable" || flag.Arg(1) == "disable" {
|
||||||
type ServiceCommandJsonStruct struct {
|
type ServiceCommandJsonStruct struct {
|
||||||
Command string `json:"command"`
|
Command string `json:"command"`
|
||||||
Service string `json:"service"`
|
Service string `json:"service"`
|
||||||
@@ -136,102 +134,6 @@ func main() {
|
|||||||
log.Fatal("Connection returned empty string!")
|
log.Fatal("Connection returned empty string!")
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
|
||||||
} else if flag.Args()[1] == "enable" {
|
|
||||||
// Check if service exists
|
|
||||||
found := false
|
|
||||||
entries, err := os.ReadDir(path.Join(sysconfdir, "esvm/services/"))
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("Could not enable service! Error: %s\n", err)
|
|
||||||
}
|
|
||||||
type minimalServiceStruct struct {
|
|
||||||
Name string `yaml:"name"`
|
|
||||||
}
|
|
||||||
for _, entry := range entries {
|
|
||||||
if entry.IsDir() || !strings.HasSuffix(entry.Name(), ".esv") {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
bytes, err := os.ReadFile(path.Join(sysconfdir, "esvm/services", entry.Name()))
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("Could not enable service! Error: %s\n", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
sv := minimalServiceStruct{Name: ""}
|
|
||||||
err = yaml.Unmarshal(bytes, &sv)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("Could not enable service! Error: %s\n", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if sv.Name == flag.Args()[2] {
|
|
||||||
found = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !found {
|
|
||||||
log.Fatalf("Service does not exist!")
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := os.Stat(path.Join(sysconfdir, "esvm/enabled_services")); err != nil {
|
|
||||||
err := os.WriteFile(path.Join(sysconfdir, "esvm/enabled_services"), []byte(flag.Args()[2]+"\n"), 0644)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("Could not enable service! Error: %s\n", err)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
file, err := os.ReadFile(path.Join(sysconfdir, "esvm/enabled_services"))
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("Could not enable service! Error: %s\n", err)
|
|
||||||
}
|
|
||||||
for _, line := range strings.Split(string(file), "\n") {
|
|
||||||
if strings.TrimSpace(line) == flag.Args()[2] {
|
|
||||||
fmt.Println("Service is already enabled!")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
err = os.WriteFile(path.Join(sysconfdir, "esvm/enabled_services"), []byte(string(file)+flag.Args()[2]+"\n"), 0644)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("Could not enable service! Error: %s\n", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Printf("Service (%s) has been enabled!\n", flag.Args()[2])
|
|
||||||
return
|
|
||||||
} else if flag.Args()[1] == "disable" {
|
|
||||||
if _, err := os.Stat(path.Join(sysconfdir, "esvm/enabled_services")); err != nil {
|
|
||||||
fmt.Println("Service is already disabled!")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
file, err := os.ReadFile(path.Join(sysconfdir, "esvm/enabled_services"))
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("Could not disable service! Error: %s\n", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
lines := strings.Split(string(file), "\n")
|
|
||||||
found := false
|
|
||||||
for i := len(lines) - 1; i >= 0; i-- {
|
|
||||||
line := strings.TrimSpace(lines[i])
|
|
||||||
if strings.TrimSpace(line) == flag.Args()[2] {
|
|
||||||
lines = append(lines[:i], lines[i+1:]...)
|
|
||||||
found = true
|
|
||||||
} else if strings.TrimSpace(line) == "" {
|
|
||||||
lines = append(lines[:i], lines[i+1:]...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !found {
|
|
||||||
fmt.Println("Service is already disabled!")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = os.WriteFile(path.Join(sysconfdir, "esvm/enabled_services"), []byte(strings.Join(lines, "\n")+"\n"), 0644)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("Could not disable service! Error: %s\n", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Printf("Service (%s) has been disabled!\n", flag.Args()[2])
|
|
||||||
return
|
return
|
||||||
} else if flag.Args()[1] == "status" {
|
} else if flag.Args()[1] == "status" {
|
||||||
if _, err := os.Stat(path.Join(runstatedir, "esvm", flag.Args()[2])); err != nil {
|
if _, err := os.Stat(path.Join(runstatedir, "esvm", flag.Args()[2])); err != nil {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path"
|
"path"
|
||||||
@@ -308,3 +309,64 @@ func (service *EnitService) RestartService() error {
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Functions will be rewritten at some point to allow enabling unloaded services
|
||||||
|
|
||||||
|
func (service *EnitService) isEnabled() bool {
|
||||||
|
contents, err := os.ReadFile(path.Join(serviceConfigDir, "enabled_services"))
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, line := range strings.Split(string(contents), "\n") {
|
||||||
|
line = strings.TrimSpace(line)
|
||||||
|
if line == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if line == service.Name {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (service *EnitService) SetEnabled(isEnabled bool) error {
|
||||||
|
// Return if service is already in correct state
|
||||||
|
if service.isEnabled() == isEnabled {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create or open enabled_services file
|
||||||
|
file, err := os.OpenFile(path.Join(serviceConfigDir, "enabled_services"), os.O_CREATE|os.O_RDWR, 0644)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
// Get enabled_services file contents
|
||||||
|
contents, err := io.ReadAll(file)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Modify contents
|
||||||
|
strContents := string(contents)
|
||||||
|
if isEnabled {
|
||||||
|
strContents += service.Name + "\n"
|
||||||
|
} else {
|
||||||
|
strContents = strings.ReplaceAll(strContents, service.Name+"\n", "")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write new contents to file
|
||||||
|
file.Truncate(0)
|
||||||
|
file.Seek(0, 0)
|
||||||
|
_, err = file.WriteString(strContents)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
file.Sync()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ func initSocket() (socket net.Listener, err error) {
|
|||||||
commandHandlers["start"] = handleStartServiceCommand
|
commandHandlers["start"] = handleStartServiceCommand
|
||||||
commandHandlers["stop"] = handleStopServiceCommand
|
commandHandlers["stop"] = handleStopServiceCommand
|
||||||
commandHandlers["restart"] = handleRestartServiceCommand
|
commandHandlers["restart"] = handleRestartServiceCommand
|
||||||
|
commandHandlers["enable"] = handleEnableServiceCommand
|
||||||
|
commandHandlers["disable"] = handleDisableServiceCommand
|
||||||
|
|
||||||
return socket, nil
|
return socket, nil
|
||||||
}
|
}
|
||||||
@@ -143,6 +145,68 @@ func handleRestartServiceCommand(conn net.Conn, jsonData map[string]any) {
|
|||||||
conn.Write(wrapSuccessMsgInJson(fmt.Sprintf("Service (%s) has restarted sucessfully", serviceName.(string))))
|
conn.Write(wrapSuccessMsgInJson(fmt.Sprintf("Service (%s) has restarted sucessfully", serviceName.(string))))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func handleEnableServiceCommand(conn net.Conn, jsonData map[string]any) {
|
||||||
|
// Get service name from json data
|
||||||
|
serviceName, ok := jsonData["service"]
|
||||||
|
if !ok {
|
||||||
|
conn.Write(wrapErrorInJson(fmt.Errorf("'service' field missing")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure service exists
|
||||||
|
service := GetServiceByName(serviceName.(string))
|
||||||
|
if service == nil {
|
||||||
|
conn.Write(wrapErrorInJson(fmt.Errorf("Service (%s) not found", serviceName.(string))))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if service is already enabled
|
||||||
|
if service.isEnabled() {
|
||||||
|
conn.Write(wrapSuccessMsgInJson(fmt.Sprintf("Service (%s) is already enabled", serviceName.(string))))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enable service
|
||||||
|
err := service.SetEnabled(true)
|
||||||
|
if err != nil {
|
||||||
|
conn.Write(wrapErrorInJson(fmt.Errorf("Could not enable service! Error: %s", err)))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
conn.Write(wrapSuccessMsgInJson(fmt.Sprintf("Service (%s) was enabled sucessfully", serviceName.(string))))
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleDisableServiceCommand(conn net.Conn, jsonData map[string]any) {
|
||||||
|
// Get service name from json data
|
||||||
|
serviceName, ok := jsonData["service"]
|
||||||
|
if !ok {
|
||||||
|
conn.Write(wrapErrorInJson(fmt.Errorf("'service' field missing")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure service exists
|
||||||
|
service := GetServiceByName(serviceName.(string))
|
||||||
|
if service == nil {
|
||||||
|
conn.Write(wrapErrorInJson(fmt.Errorf("Service (%s) not found", serviceName.(string))))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if service is already disabled
|
||||||
|
if !service.isEnabled() {
|
||||||
|
conn.Write(wrapSuccessMsgInJson(fmt.Sprintf("Service (%s) is already disabled", serviceName.(string))))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disable service
|
||||||
|
err := service.SetEnabled(false)
|
||||||
|
if err != nil {
|
||||||
|
conn.Write(wrapErrorInJson(fmt.Errorf("Could not disable service! Error: %s", err)))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
conn.Write(wrapSuccessMsgInJson(fmt.Sprintf("Service (%s) was disabled sucessfully", serviceName.(string))))
|
||||||
|
}
|
||||||
|
|
||||||
func wrapErrorInJson(err error) []byte {
|
func wrapErrorInJson(err error) []byte {
|
||||||
// Wrap error in struct
|
// Wrap error in struct
|
||||||
type jsonErrorStruct struct {
|
type jsonErrorStruct struct {
|
||||||
|
|||||||
Reference in New Issue
Block a user