platform: modularize api/gui, add docs-tests-web foundation, and refresh root config

This commit is contained in:
beckline
2026-03-26 22:40:54 +03:00
parent 0e2d7f61ea
commit 6a56d734c2
562 changed files with 70151 additions and 16423 deletions

View File

@@ -0,0 +1,72 @@
package app
import (
"net/http"
)
func handleTransportClientLifecycleAction(w http.ResponseWriter, r *http.Request, id, action string) {
if r.Method != http.MethodPost {
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
return
}
lockIDs, ok := resolveTransportLifecycleLockIDs(id, action)
if !ok {
writeJSON(w, http.StatusNotFound, TransportClientLifecycleResponse{
OK: false,
Message: "not found",
Code: "TRANSPORT_CLIENT_NOT_FOUND",
})
return
}
status := http.StatusOK
resp := TransportClientLifecycleResponse{}
withTransportIfaceLocks(lockIDs, func() {
status, resp = executeTransportLifecycleActionWithPreflightLocked(id, action)
})
writeJSON(w, status, resp)
}
func executeTransportLifecycleActionWithPreflightLocked(id, action string) (int, TransportClientLifecycleResponse) {
if preStatus, preResp, handled := runTransportLifecyclePreflight(id, action); handled {
return preStatus, preResp
}
return executeTransportLifecycleActionLocked(id, action)
}
func resolveTransportLifecycleLockIDsForSnapshot(items []TransportClient, ifaces transportInterfacesState, id, action string) ([]string, bool) {
idx := findTransportClientIndex(items, id)
if idx < 0 {
return nil, false
}
targetBinding := resolveTransportIfaceBinding(items[idx], ifaces)
lockIDs := []string{targetBinding.IfaceID}
if action == "start" || action == "restart" {
_, peers := matchTransportSingBoxPeersInSameNetnsForLock(items, idx, ifaces)
for _, peer := range peers {
lockIDs = append(lockIDs, peer.Binding.IfaceID)
}
}
return lockIDs, true
}
func resolveTransportLifecycleLockIDs(id, action string) ([]string, bool) {
transportMu.Lock()
clientsState := loadTransportClientsState()
idx := findTransportClientIndex(clientsState.Items, id)
if idx < 0 {
transportMu.Unlock()
return nil, false
}
ifacesState := loadTransportInterfacesState()
ifacesSnapshot := captureTransportInterfacesStateSnapshot(clientsState, ifacesState)
transportMu.Unlock()
normIfaces, changed := normalizeTransportInterfacesState(ifacesState, clientsState.Items)
if changed {
_ = saveTransportInterfacesIfSnapshotCurrent(ifacesSnapshot, normIfaces)
}
return resolveTransportLifecycleLockIDsForSnapshot(clientsState.Items, normIfaces, id, action)
}