safing-portmaster/service/core/core.go
2024-08-27 16:32:23 +02:00

117 lines
2.3 KiB
Go

package core
import (
"errors"
"flag"
"fmt"
"sync/atomic"
"github.com/safing/portmaster/base/log"
"github.com/safing/portmaster/base/metrics"
"github.com/safing/portmaster/base/utils/debug"
_ "github.com/safing/portmaster/service/broadcasts"
"github.com/safing/portmaster/service/mgr"
_ "github.com/safing/portmaster/service/netenv"
_ "github.com/safing/portmaster/service/netquery"
_ "github.com/safing/portmaster/service/status"
_ "github.com/safing/portmaster/service/sync"
_ "github.com/safing/portmaster/service/ui"
)
// Core is the core service module.
type Core struct {
m *mgr.Manager
instance instance
EventShutdown *mgr.EventMgr[struct{}]
EventRestart *mgr.EventMgr[struct{}]
}
// Manager returns the manager.
func (c *Core) Manager() *mgr.Manager {
return c.m
}
// Start starts the module.
func (c *Core) Start() error {
return start()
}
// Stop stops the module.
func (c *Core) Stop() error {
return nil
}
var disableShutdownEvent bool
func init() {
flag.BoolVar(
&disableShutdownEvent,
"disable-shutdown-event",
false,
"disable shutdown event to keep app and notifier open when core shuts down",
)
}
func prep() error {
// init config
err := registerConfig()
if err != nil {
return err
}
if err := registerAPIEndpoints(); err != nil {
return err
}
if err := initModulesIntegration(); err != nil {
return err
}
return nil
}
func start() error {
if err := startPlatformSpecific(); err != nil {
return fmt.Errorf("failed to start plattform-specific components: %w", err)
}
// Enable persistent metrics.
if err := metrics.EnableMetricPersistence("core:metrics/storage"); err != nil {
log.Warningf("core: failed to enable persisted metrics: %s", err)
}
return nil
}
var (
module *Core
shimLoaded atomic.Bool
)
// New returns a new NetEnv module.
func New(instance instance) (*Core, error) {
if !shimLoaded.CompareAndSwap(false, true) {
return nil, errors.New("only one instance allowed")
}
m := mgr.New("Core")
module = &Core{
m: m,
instance: instance,
EventShutdown: mgr.NewEventMgr[struct{}]("shutdown", m),
EventRestart: mgr.NewEventMgr[struct{}]("restart", m),
}
if err := prep(); err != nil {
return nil, err
}
return module, nil
}
type instance interface {
Shutdown()
AddWorkerInfoToDebugInfo(di *debug.Info)
}