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

106 lines
3.8 KiB
Go

package app
import (
"fmt"
"strings"
"time"
)
func transportSystemdRunPreActionHooks(
client TransportClient,
action string,
units []string,
netnsEnabled bool,
aggOut *[]string,
aggErr *[]string,
) *transportBackendActionResult {
if action == "start" || action == "restart" {
migOut, migErr := transportSystemdMaybeMigrateLegacySingBoxUnits(client, units)
*aggOut = append(*aggOut, migOut...)
*aggErr = append(*aggErr, migErr...)
}
if netnsEnabled && (action == "start" || action == "restart") {
if msg, err := transportEnsureNetnsForClient(client); strings.TrimSpace(msg) != "" || err != nil {
if s := strings.TrimSpace(msg); s != "" {
*aggOut = append(*aggOut, "netns: "+s)
appendTraceLine("transport", fmt.Sprintf("netns setup: client=%s action=%s %s", client.ID, action, s))
}
if err != nil {
*aggErr = append(*aggErr, "netns: "+err.Error())
appendTraceLineRateLimited("transport", fmt.Sprintf("netns setup failed: client=%s action=%s err=%v", client.ID, action, err), 30*time.Second)
if transportNetnsStrict(client) {
return &transportBackendActionResult{
OK: false,
Code: "TRANSPORT_BACKEND_NETNS_SETUP_FAILED",
Message: err.Error(),
ExitCode: -1,
Stdout: strings.Join(*aggOut, "\n"),
Stderr: strings.Join(*aggErr, "\n"),
Retryable: true,
}
}
}
}
}
if !netnsEnabled {
if msg, err := transportMaybeSyncBootstrapBypass(client, action); strings.TrimSpace(msg) != "" || err != nil {
if s := strings.TrimSpace(msg); s != "" {
*aggOut = append(*aggOut, "bootstrap: "+s)
appendTraceLine("transport", fmt.Sprintf("bootstrap bypass: client=%s action=%s %s", client.ID, action, s))
}
if err != nil {
*aggErr = append(*aggErr, "bootstrap: "+err.Error())
appendTraceLineRateLimited("transport", fmt.Sprintf("bootstrap bypass failed: client=%s action=%s err=%v", client.ID, action, err), 30*time.Second)
if (action == "start" || action == "restart") && transportBootstrapBypassStrict(client) {
return &transportBackendActionResult{
OK: false,
Code: "TRANSPORT_BACKEND_BOOTSTRAP_BYPASS_FAILED",
Message: err.Error(),
ExitCode: -1,
Stdout: strings.Join(*aggOut, "\n"),
Stderr: strings.Join(*aggErr, "\n"),
Retryable: true,
}
}
}
}
}
if action == "start" || action == "restart" {
transportSystemdResetFailedUnits(units)
}
return nil
}
func transportSystemdResetFailedUnits(units []string) {
for _, unit := range units {
stdout, stderr, code, err := transportRunCommand(transportBackendActionTimeout, "systemctl", "reset-failed", unit)
// reset-failed is best-effort: do not block lifecycle on this step.
if err != nil || code != 0 {
appendTraceLineRateLimited("transport", fmt.Sprintf("systemctl reset-failed stdout: unit=%s out=%q", unit, strings.TrimSpace(stdout)), 20*time.Second)
appendTraceLineRateLimited("transport", fmt.Sprintf("systemctl reset-failed stderr: unit=%s err=%q", unit, strings.TrimSpace(stderr)), 20*time.Second)
appendTraceLineRateLimited("transport", fmt.Sprintf("systemctl reset-failed warning: unit=%s code=%d err=%v", unit, code, err), 20*time.Second)
}
}
}
func transportSystemdRunPostStopCleanup(
client TransportClient,
action string,
aggOut *[]string,
aggErr *[]string,
) {
if msg, err := transportCleanupNetnsForClient(client); strings.TrimSpace(msg) != "" || err != nil {
if s := strings.TrimSpace(msg); s != "" {
*aggOut = append(*aggOut, "netns: "+s)
appendTraceLine("transport", fmt.Sprintf("netns cleanup: client=%s action=%s %s", client.ID, action, s))
}
if err != nil {
*aggErr = append(*aggErr, "netns: "+err.Error())
appendTraceLineRateLimited("transport", fmt.Sprintf("netns cleanup warning: client=%s action=%s err=%v", client.ID, action, err), 30*time.Second)
}
}
}