diff --git a/api/endpoints_debug.go b/api/endpoints_debug.go index aed729f..2157b70 100644 --- a/api/endpoints_debug.go +++ b/api/endpoints_debug.go @@ -3,6 +3,7 @@ package api import ( "bytes" "context" + "errors" "fmt" "net/http" "os" @@ -11,6 +12,7 @@ import ( "time" "github.com/safing/portbase/info" + "github.com/safing/portbase/modules" "github.com/safing/portbase/utils/debug" ) @@ -25,6 +27,16 @@ func registerDebugEndpoints() error { return err } + if err := RegisterEndpoint(Endpoint{ + Path: "ready", + Read: PermitAnyone, + ActionFunc: ready, + Name: "Ready", + Description: "Check if Portmaster has completed starting and is ready.", + }); err != nil { + return err + } + if err := RegisterEndpoint(Endpoint{ Path: "debug/stack", Read: PermitAnyone, @@ -118,9 +130,22 @@ You can easily view this data in your browser with this command (with Go install // ping responds with pong. func ping(ar *Request) (msg string, err error) { + // TODO: Remove upgrade to "ready" when all UI components have transitioned. + if modules.IsStarting() || modules.IsShuttingDown() { + return "", ErrorWithStatus(errors.New("portmaster is not ready"), http.StatusTooEarly) + } + return "Pong.", nil } +// ready checks if Portmaster has completed starting. +func ready(ar *Request) (msg string, err error) { + if modules.IsStarting() || modules.IsShuttingDown() { + return "", ErrorWithStatus(errors.New("portmaster is not ready"), http.StatusTooEarly) + } + return "Portmaster is ready.", nil +} + // getStack returns the current goroutine stack. func getStack(_ *Request) (data []byte, err error) { buf := &bytes.Buffer{} diff --git a/modules/start.go b/modules/start.go index d73da5e..74730f2 100644 --- a/modules/start.go +++ b/modules/start.go @@ -24,6 +24,11 @@ func SetGlobalPrepFn(fn func() error) { } } +// IsStarting returns whether the initial global start is still in progress. +func IsStarting() bool { + return !initialStartCompleted.IsSet() +} + // Start starts all modules in the correct order. In case of an error, it will automatically shutdown again. func Start() error { if !modulesLocked.SetToIf(false, true) {