Files
elmprodvpn/selective-vpn-api/app/transport_backends_adapter_systemd_action.go

74 lines
2.1 KiB
Go

package app
import (
"fmt"
"strings"
)
func (transportSystemdBackend) ID() string { return "systemd" }
func (transportSystemdBackend) Action(client TransportClient, action string) transportBackendActionResult {
action = strings.ToLower(strings.TrimSpace(action))
if action != "start" && action != "stop" && action != "restart" {
return transportBackendActionResult{
OK: false,
Code: "TRANSPORT_BACKEND_ACTION_FAILED",
Message: "unsupported action: " + action,
ExitCode: -1,
}
}
units, errCode, errMsg := transportSystemdActionUnits(client, action)
if len(units) == 0 {
return transportBackendActionResult{
OK: false,
Code: errCode,
Message: errMsg,
ExitCode: -1,
}
}
aggOut := make([]string, 0, len(units))
aggErr := make([]string, 0, len(units))
netnsEnabled := transportNetnsEnabled(client)
if res := transportSystemdRunPreActionHooks(client, action, units, netnsEnabled, &aggOut, &aggErr); res != nil {
return *res
}
if res := transportSystemdRunActionUnits(client, action, units, &aggOut, &aggErr); res != nil {
return *res
}
if netnsEnabled && action == "stop" && transportNetnsAutoCleanup(client) {
transportSystemdRunPostStopCleanup(client, action, &aggOut, &aggErr)
}
msg := fmt.Sprintf("systemctl %s ok (%s)", action, strings.Join(units, ", "))
if len(aggErr) > 0 {
msg += "; with warnings"
}
return transportBackendActionResult{
OK: true,
ExitCode: 0,
Stdout: strings.Join(aggOut, "\n"),
Stderr: strings.Join(aggErr, "\n"),
Message: msg,
}
}
func transportSystemdStopMissingUnitNoop(stdout, stderr string, exitCode int, err error) bool {
return transportSystemdUnitMissingError(stdout, stderr, exitCode, err)
}
func transportSystemdUnitMissingError(stdout, stderr string, exitCode int, err error) bool {
if err == nil && exitCode == 0 {
return false
}
msg := strings.ToLower(strings.TrimSpace(stderr + "\n" + stdout))
if msg == "" {
return false
}
return strings.Contains(msg, "not loaded") ||
strings.Contains(msg, "not found") ||
strings.Contains(msg, "could not be found") ||
strings.Contains(msg, "unknown unit")
}