mirror of
https://github.com/safing/portmaster
synced 2025-09-01 10:09:11 +00:00
Add control db interface for triggering hooks, add shutdown/restart hooks
This commit is contained in:
parent
350555f843
commit
d2d69139b9
4 changed files with 156 additions and 1 deletions
100
core/control.go
Normal file
100
core/control.go
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
package core
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/safing/portbase/database"
|
||||||
|
"github.com/safing/portbase/database/record"
|
||||||
|
"github.com/safing/portbase/database/storage"
|
||||||
|
)
|
||||||
|
|
||||||
|
// StorageInterface provices a storage.Interface to the storage manager.
|
||||||
|
type StorageInterface struct {
|
||||||
|
storage.InjectBase
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get returns a database record.
|
||||||
|
func (s *StorageInterface) Get(key string) (record.Record, error) {
|
||||||
|
msg := newMessage(key)
|
||||||
|
splittedKey := strings.Split(key, "/")
|
||||||
|
|
||||||
|
switch splittedKey[0] {
|
||||||
|
case "module":
|
||||||
|
return controlModule(msg, splittedKey)
|
||||||
|
default:
|
||||||
|
return nil, storage.ErrNotFound
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func controlModule(msg *MessageRecord, splittedKey []string) (record.Record, error) {
|
||||||
|
// format: module/moduleName/action/param
|
||||||
|
var moduleName string
|
||||||
|
var action string
|
||||||
|
var param string
|
||||||
|
var err error
|
||||||
|
|
||||||
|
// parse elements
|
||||||
|
switch len(splittedKey) {
|
||||||
|
case 4:
|
||||||
|
param = splittedKey[3]
|
||||||
|
fallthrough
|
||||||
|
case 3:
|
||||||
|
moduleName = splittedKey[1]
|
||||||
|
action = splittedKey[2]
|
||||||
|
default:
|
||||||
|
return nil, storage.ErrNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
// execute
|
||||||
|
switch action {
|
||||||
|
case "trigger":
|
||||||
|
err = module.InjectEvent(fmt.Sprintf("user triggered the '%s/%s' event", moduleName, param), moduleName, param, nil)
|
||||||
|
default:
|
||||||
|
return nil, storage.ErrNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
msg.Message = err.Error()
|
||||||
|
} else {
|
||||||
|
msg.Success = true
|
||||||
|
}
|
||||||
|
|
||||||
|
return msg, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func registerControlDatabase() error {
|
||||||
|
_, err := database.Register(&database.Database{
|
||||||
|
Name: "control",
|
||||||
|
Description: "Control Interface for the Portmaster",
|
||||||
|
StorageType: "injected",
|
||||||
|
PrimaryAPI: "",
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = database.InjectDatabase("control", &StorageInterface{})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MessageRecord is a simple record used for control database feedback
|
||||||
|
type MessageRecord struct {
|
||||||
|
record.Base
|
||||||
|
sync.Mutex
|
||||||
|
|
||||||
|
Success bool
|
||||||
|
Message string
|
||||||
|
}
|
||||||
|
|
||||||
|
func newMessage(key string) *MessageRecord {
|
||||||
|
m := &MessageRecord{}
|
||||||
|
m.SetKey("control:" + key)
|
||||||
|
m.UpdateMeta()
|
||||||
|
return m
|
||||||
|
}
|
|
@ -31,10 +31,19 @@ func init() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func prep() error {
|
||||||
|
registerEvents()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func start() error {
|
func start() error {
|
||||||
if err := startPlatformSpecific(); err != nil {
|
if err := startPlatformSpecific(); err != nil {
|
||||||
return fmt.Errorf("failed to start plattform-specific components: %s", err)
|
return fmt.Errorf("failed to start plattform-specific components: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := registerEventHooks(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,5 +46,5 @@ func registerDatabases() error {
|
||||||
// return err
|
// return err
|
||||||
// }
|
// }
|
||||||
|
|
||||||
return nil
|
return registerControlDatabase()
|
||||||
}
|
}
|
||||||
|
|
46
core/events.go
Normal file
46
core/events.go
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
package core
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/safing/portbase/log"
|
||||||
|
"github.com/safing/portbase/modules"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
eventShutdown = "shutdown"
|
||||||
|
eventRestart = "restart"
|
||||||
|
restartCode = 23
|
||||||
|
)
|
||||||
|
|
||||||
|
func registerEvents() {
|
||||||
|
module.RegisterEvent(eventShutdown)
|
||||||
|
module.RegisterEvent(eventRestart)
|
||||||
|
}
|
||||||
|
|
||||||
|
func registerEventHooks() error {
|
||||||
|
err := module.RegisterEventHook("core", eventShutdown, "execute shutdown", shutdown)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = module.RegisterEventHook("core", eventRestart, "execute shutdown", restart)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func shutdown(ctx context.Context, _ interface{}) error {
|
||||||
|
log.Warning("core: user requested shutdown")
|
||||||
|
go modules.Shutdown() //nolint:errcheck
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func restart(ctx context.Context, data interface{}) error {
|
||||||
|
log.Info("core: user requested restart")
|
||||||
|
modules.SetExitStatusCode(restartCode)
|
||||||
|
go modules.Shutdown() //nolint:errcheck
|
||||||
|
return nil
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue