106 lines
3.8 KiB
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)
|
|
}
|
|
}
|
|
}
|