99 lines
2.6 KiB
Go
99 lines
2.6 KiB
Go
package app
|
|
|
|
import (
|
|
"strings"
|
|
"time"
|
|
|
|
transportcfgpkg "selective-vpn-api/app/transportcfg"
|
|
)
|
|
|
|
func prepareSingBoxClientProfile(client TransportClient, checkBinary bool) transportBackendActionResult {
|
|
if client.Kind != TransportClientSingBox {
|
|
return transportBackendActionResult{
|
|
OK: true,
|
|
Message: "singbox preflight skipped",
|
|
}
|
|
}
|
|
|
|
singBoxProfilesMu.Lock()
|
|
defer singBoxProfilesMu.Unlock()
|
|
|
|
st := loadSingBoxProfilesState()
|
|
idx := findSingBoxProfileIndexForClient(st, client.ID)
|
|
if idx < 0 {
|
|
return transportBackendActionResult{
|
|
OK: false,
|
|
Code: singBoxProfileCodeNotFound,
|
|
Message: "singbox profile not linked to client " + client.ID,
|
|
ExitCode: -1,
|
|
}
|
|
}
|
|
cur := st.Items[idx]
|
|
now := time.Now().UTC().Format(time.RFC3339Nano)
|
|
|
|
eval := evaluateSingBoxProfile(cur, checkBinary)
|
|
cur.LastValidatedAt = now
|
|
cur.UpdatedAt = now
|
|
if !eval.Valid {
|
|
cur.LastError = joinSingBoxIssueMessages(eval.Errors)
|
|
st.Items[idx] = cur
|
|
_ = saveSingBoxProfilesState(st)
|
|
return transportBackendActionResult{
|
|
OK: false,
|
|
Code: singBoxProfileCodeValidationFailed,
|
|
Message: "profile preflight failed: " + strings.TrimSpace(cur.LastError),
|
|
ExitCode: -1,
|
|
}
|
|
}
|
|
|
|
renderPath, err := writeSingBoxRenderedConfig(cur.ID, eval.Config)
|
|
if err != nil {
|
|
cur.LastError = err.Error()
|
|
st.Items[idx] = cur
|
|
_ = saveSingBoxProfilesState(st)
|
|
return transportBackendActionResult{
|
|
OK: false,
|
|
Code: singBoxProfileCodeRenderFailed,
|
|
Message: "profile preflight render failed: " + err.Error(),
|
|
ExitCode: -1,
|
|
}
|
|
}
|
|
|
|
configPath := transportSingBoxConfigPath(client)
|
|
if strings.TrimSpace(configPath) == "" {
|
|
configPath = defaultSingBoxAppliedConfigPath(cur.ID)
|
|
}
|
|
if err := transportcfgpkg.WriteJSONConfigFile(configPath, eval.Config); err != nil {
|
|
cur.LastError = err.Error()
|
|
st.Items[idx] = cur
|
|
_ = saveSingBoxProfilesState(st)
|
|
return transportBackendActionResult{
|
|
OK: false,
|
|
Code: singBoxProfileCodeApplyFailed,
|
|
Message: "profile preflight write failed: " + err.Error(),
|
|
ExitCode: -1,
|
|
Stdout: renderPath,
|
|
}
|
|
}
|
|
|
|
cur.LastError = ""
|
|
st.Items[idx] = cur
|
|
if err := saveSingBoxProfilesState(st); err != nil {
|
|
return transportBackendActionResult{
|
|
OK: false,
|
|
Code: singBoxProfileCodeSaveFailed,
|
|
Message: "profile preflight save failed: " + err.Error(),
|
|
ExitCode: -1,
|
|
Stdout: renderPath,
|
|
}
|
|
}
|
|
|
|
return transportBackendActionResult{
|
|
OK: true,
|
|
ExitCode: 0,
|
|
Message: "profile preflight ready: " + cur.ID,
|
|
Stdout: strings.TrimSpace(configPath),
|
|
Stderr: strings.TrimSpace(renderPath),
|
|
}
|
|
}
|