package app import ( "net/http" "strings" "time" ) func runTransportLifecyclePreflight(id, action string) (int, TransportClientLifecycleResponse, bool) { if action != "start" && action != "restart" { return 0, TransportClientLifecycleResponse{}, false } transportMu.Lock() preState := loadTransportClientsState() preIdx := findTransportClientIndex(preState.Items, id) if preIdx < 0 { transportMu.Unlock() return http.StatusNotFound, TransportClientLifecycleResponse{ OK: false, Message: "not found", Code: "TRANSPORT_CLIENT_NOT_FOUND", }, true } preClient := preState.Items[preIdx] transportMu.Unlock() if preClient.Kind != TransportClientSingBox { return 0, TransportClientLifecycleResponse{}, false } checkBinary := true if transportConfigHasKey(preClient.Config, "singbox_preflight_check_binary") { checkBinary = transportConfigBool(preClient.Config, "singbox_preflight_check_binary") } preflight := prepareSingBoxClientProfile(preClient, checkBinary) if preflight.OK { return 0, TransportClientLifecycleResponse{}, false } now := time.Now().UTC() msg := strings.TrimSpace(preflight.Message) if msg == "" { msg = "singbox profile preflight failed" } events.push("transport_client_preflight_failed", map[string]any{ "id": id, "action": action, "code": preflight.Code, "error": msg, }) return http.StatusOK, TransportClientLifecycleResponse{ OK: false, Message: msg, Code: preflight.Code, ExitCode: preflight.ExitCode, Stdout: preflight.Stdout, Stderr: preflight.Stderr, ClientID: id, Kind: preClient.Kind, Action: action, StatusBefore: preClient.Status, StatusAfter: preClient.Status, Health: preClient.Health, Runtime: transportRuntimeSnapshot(preClient, now), }, true }