Files
speedrun/pkg/portal/service.go

159 lines
4.2 KiB
Go

package portal
import (
"context"
"fmt"
"strings"
"github.com/apex/log"
"github.com/coreos/go-systemd/v22/dbus"
"github.com/dpogorzelski/speedrun/proto/portal"
)
func (s *Server) ServiceRestart(ctx context.Context, service *portal.ServiceRequest) (*portal.ServiceResponse, error) {
fields := log.Fields{
"context": "service",
"command": "restart",
"name": service.GetName(),
}
log := log.WithFields(fields)
log.Debug("Received service restart request")
conn, err := dbus.NewWithContext(ctx)
if err != nil {
log.Error(err.Error())
return nil, err
}
defer conn.Close()
responseChan := make(chan string, 1)
serviceName := fmt.Sprintf("%s.service", service.GetName())
_, err = conn.RestartUnitContext(ctx, serviceName, "replace", responseChan)
if err != nil {
log.Error(err.Error())
return nil, err
}
res := <-responseChan
log.Debugf("Service restart result: %v", res)
return &portal.ServiceResponse{State: portal.State_CHANGED, Message: strings.Title(res)}, nil
}
func (s *Server) ServiceStop(ctx context.Context, service *portal.ServiceRequest) (*portal.ServiceResponse, error) {
fields := log.Fields{
"context": "service",
"command": "stop",
"name": service.GetName(),
}
log := log.WithFields(fields)
log.Debug("Received service stop request")
conn, err := dbus.NewWithContext(ctx)
if err != nil {
log.Error(err.Error())
return nil, err
}
defer conn.Close()
responseChan := make(chan string, 1)
serviceName := fmt.Sprintf("%s.service", service.GetName())
list, err := conn.ListUnitsByNamesContext(ctx, []string{serviceName})
if err != nil {
log.Error(err.Error())
return nil, err
}
log.Debugf("Fetched service list by name: %v", list)
if list[0].ActiveState == "inactive" {
return &portal.ServiceResponse{State: portal.State_UNCHANGED, Message: "Service already stopped"}, nil
}
_, err = conn.StopUnitContext(ctx, serviceName, "replace", responseChan)
if err != nil {
log.Error(err.Error())
return nil, err
}
res := <-responseChan
log.Debugf("Service stop result: %v", res)
return &portal.ServiceResponse{State: portal.State_CHANGED, Message: strings.Title(res)}, nil
}
func (s *Server) ServiceStart(ctx context.Context, service *portal.ServiceRequest) (*portal.ServiceResponse, error) {
fields := log.Fields{
"context": "service",
"command": "start",
"name": service.GetName(),
}
log := log.WithFields(fields)
log.Debug("Received service start request")
conn, err := dbus.NewWithContext(ctx)
if err != nil {
log.Error(err.Error())
return nil, err
}
defer conn.Close()
responseChan := make(chan string, 1)
serviceName := fmt.Sprintf("%s.service", service.GetName())
list, err := conn.ListUnitsByNamesContext(ctx, []string{serviceName})
if err != nil {
log.Error(err.Error())
return nil, err
}
log.Debugf("Fetched service list by name: %v", list)
if list[0].ActiveState == "active" {
return &portal.ServiceResponse{State: portal.State_UNCHANGED, Message: "Service already running"}, nil
}
_, err = conn.StartUnitContext(ctx, serviceName, "replace", responseChan)
if err != nil {
log.Error(err.Error())
return nil, err
}
res := <-responseChan
log.Debugf("Service start result: %v", res)
return &portal.ServiceResponse{State: portal.State_CHANGED, Message: strings.Title(res)}, nil
}
func (s *Server) ServiceStatus(ctx context.Context, service *portal.ServiceRequest) (*portal.ServiceStatusResponse, error) {
fields := log.Fields{
"context": "service",
"command": "status",
"name": service.GetName(),
}
log := log.WithFields(fields)
log.Debug("Received service status request")
conn, err := dbus.NewWithContext(ctx)
if err != nil {
log.Error(err.Error())
return nil, err
}
defer conn.Close()
serviceName := fmt.Sprintf("%s.service", service.GetName())
res, err := conn.ListUnitsByNamesContext(ctx, []string{serviceName})
if err != nil {
log.Error(err.Error())
return nil, err
}
log.Debugf("Fetched service list by name: %v", res[0])
if res[0].LoadState == "not-found" {
log.Error("service not found")
return nil, fmt.Errorf("service not found")
}
return &portal.ServiceStatusResponse{
State: portal.State_UNCHANGED,
Activestate: res[0].ActiveState,
Loadstate: res[0].LoadState,
Substate: res[0].SubState,
}, nil
}