mirror of
https://github.com/safing/portbase
synced 2025-09-01 18:19:57 +00:00
Release to master
This commit is contained in:
commit
c35d42899a
7 changed files with 231 additions and 48 deletions
113
config/basic_config.go
Normal file
113
config/basic_config.go
Normal file
|
@ -0,0 +1,113 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
|
||||
"github.com/safing/portbase/log"
|
||||
)
|
||||
|
||||
// Configuration Keys.
|
||||
var (
|
||||
CfgDevModeKey = "core/devMode"
|
||||
defaultDevMode bool
|
||||
|
||||
CfgLogLevel = "core/log/level"
|
||||
defaultLogLevel = log.InfoLevel.String()
|
||||
logLevel StringOption
|
||||
)
|
||||
|
||||
func init() {
|
||||
flag.BoolVar(&defaultDevMode, "devmode", false, "enable development mode")
|
||||
}
|
||||
|
||||
func registerBasicOptions() error {
|
||||
// Get the default log level from the log package.
|
||||
defaultLogLevel = log.GetLogLevel().Name()
|
||||
|
||||
// Register logging setting.
|
||||
// The log package cannot do that, as it would trigger and import loop.
|
||||
if err := Register(&Option{
|
||||
Name: "Log Level",
|
||||
Key: CfgLogLevel,
|
||||
Description: "Configure the logging level.",
|
||||
OptType: OptTypeString,
|
||||
ExpertiseLevel: ExpertiseLevelDeveloper,
|
||||
ReleaseLevel: ReleaseLevelStable,
|
||||
DefaultValue: defaultLogLevel,
|
||||
Annotations: Annotations{
|
||||
DisplayOrderAnnotation: 513,
|
||||
DisplayHintAnnotation: DisplayHintOneOf,
|
||||
CategoryAnnotation: "Development",
|
||||
},
|
||||
PossibleValues: []PossibleValue{
|
||||
{
|
||||
Name: "Critical",
|
||||
Value: "critical",
|
||||
Description: "The critical level only logs errors that lead to a partial, but imminent failure.",
|
||||
},
|
||||
{
|
||||
Name: "Error",
|
||||
Value: "error",
|
||||
Description: "The error level logs errors that potentially break functionality. Everything logged by the critical level is included here too.",
|
||||
},
|
||||
{
|
||||
Name: "Warning",
|
||||
Value: "warning",
|
||||
Description: "The warning level logs minor errors and worse. Everything logged by the error level is included here too.",
|
||||
},
|
||||
{
|
||||
Name: "Info",
|
||||
Value: "info",
|
||||
Description: "The info level logs the main events that are going on and are interesting to the user. Everything logged by the warning level is included here too.",
|
||||
},
|
||||
{
|
||||
Name: "Debug",
|
||||
Value: "debug",
|
||||
Description: "The debug level logs some additional debugging details. Everything logged by the info level is included here too.",
|
||||
},
|
||||
{
|
||||
Name: "Trace",
|
||||
Value: "trace",
|
||||
Description: "The trace level logs loads of detailed information as well as operation and request traces. Everything logged by the debug level is included here too.",
|
||||
},
|
||||
},
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
logLevel = GetAsString(CfgLogLevel, defaultLogLevel)
|
||||
|
||||
// Register to hook to update the log level.
|
||||
if err := module.RegisterEventHook(
|
||||
"config",
|
||||
configChangeEvent,
|
||||
"update log level",
|
||||
setLogLevel,
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return Register(&Option{
|
||||
Name: "Development Mode",
|
||||
Key: CfgDevModeKey,
|
||||
Description: "In Development Mode, security restrictions are lifted/softened to enable unrestricted access for debugging and testing purposes.",
|
||||
OptType: OptTypeBool,
|
||||
ExpertiseLevel: ExpertiseLevelDeveloper,
|
||||
ReleaseLevel: ReleaseLevelStable,
|
||||
DefaultValue: defaultDevMode,
|
||||
Annotations: Annotations{
|
||||
DisplayOrderAnnotation: 512,
|
||||
CategoryAnnotation: "Development",
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func loadLogLevel() {
|
||||
setDefaultConfigOption(CfgLogLevel, log.GetLogLevel().Name(), false)
|
||||
}
|
||||
|
||||
func setLogLevel(ctx context.Context, data interface{}) error {
|
||||
log.SetLogLevel(log.ParseLevel(logLevel()))
|
||||
|
||||
return nil
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"flag"
|
||||
|
||||
"github.com/safing/portbase/log"
|
||||
)
|
||||
|
||||
// Configuration Keys.
|
||||
var (
|
||||
CfgDevModeKey = "core/devMode"
|
||||
defaultDevMode bool
|
||||
)
|
||||
|
||||
func init() {
|
||||
flag.BoolVar(&defaultDevMode, "devmode", false, "enable development mode")
|
||||
}
|
||||
|
||||
func logDevModeOverride() {
|
||||
if defaultDevMode {
|
||||
log.Warning("config: development mode is enabled by default by the -devmode flag")
|
||||
}
|
||||
}
|
||||
|
||||
func registerDevModeOption() error {
|
||||
return Register(&Option{
|
||||
Name: "Development Mode",
|
||||
Key: CfgDevModeKey,
|
||||
Description: "In Development Mode, security restrictions are lifted/softened to enable unrestricted access for debugging and testing purposes.",
|
||||
OptType: OptTypeBool,
|
||||
ExpertiseLevel: ExpertiseLevelDeveloper,
|
||||
ReleaseLevel: ReleaseLevelStable,
|
||||
DefaultValue: defaultDevMode,
|
||||
Annotations: Annotations{
|
||||
DisplayOrderAnnotation: 512,
|
||||
CategoryAnnotation: "Development",
|
||||
},
|
||||
})
|
||||
}
|
|
@ -47,18 +47,15 @@ func prep() error {
|
|||
modules.SetCmdLineOperation(exportConfigCmd)
|
||||
}
|
||||
|
||||
logDevModeOverride()
|
||||
err := registerDevModeOption()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
return registerBasicOptions()
|
||||
}
|
||||
|
||||
func start() error {
|
||||
configFilePath = filepath.Join(dataRoot.Path, "config.json")
|
||||
|
||||
// Load log level from log package after it started.
|
||||
loadLogLevel()
|
||||
|
||||
err := registerAsDatabase()
|
||||
if err != nil && !os.IsNotExist(err) {
|
||||
return err
|
||||
|
|
|
@ -192,5 +192,7 @@ func setDefaultConfigOption(key string, value interface{}, push bool) (err error
|
|||
// finalize change, activate triggers
|
||||
signalChanges()
|
||||
|
||||
return saveConfig()
|
||||
// Do not save the configuration, as it only saves the active values, not the
|
||||
// active default value.
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -102,7 +102,7 @@ var (
|
|||
logBuffer chan *logLine
|
||||
forceEmptyingOfBuffer = make(chan struct{})
|
||||
|
||||
logLevelInt = uint32(3)
|
||||
logLevelInt = uint32(InfoLevel)
|
||||
logLevel = &logLevelInt
|
||||
|
||||
pkgLevelsActive = abool.NewBool(false)
|
||||
|
@ -134,11 +134,36 @@ func UnSetPkgLevels() {
|
|||
pkgLevelsActive.UnSet()
|
||||
}
|
||||
|
||||
// GetLogLevel returns the current log level.
|
||||
func GetLogLevel() Severity {
|
||||
return Severity(atomic.LoadUint32(logLevel))
|
||||
}
|
||||
|
||||
// SetLogLevel sets a new log level. Only effective after Start().
|
||||
func SetLogLevel(level Severity) {
|
||||
atomic.StoreUint32(logLevel, uint32(level))
|
||||
}
|
||||
|
||||
// Name returns the name of the log level.
|
||||
func (s Severity) Name() string {
|
||||
switch s {
|
||||
case TraceLevel:
|
||||
return "trace"
|
||||
case DebugLevel:
|
||||
return "debug"
|
||||
case InfoLevel:
|
||||
return "info"
|
||||
case WarningLevel:
|
||||
return "warning"
|
||||
case ErrorLevel:
|
||||
return "error"
|
||||
case CriticalLevel:
|
||||
return "critical"
|
||||
default:
|
||||
return "none"
|
||||
}
|
||||
}
|
||||
|
||||
// ParseLevel returns the level severity of a log level name.
|
||||
func ParseLevel(level string) Severity {
|
||||
switch strings.ToLower(level) {
|
||||
|
|
84
utils/broadcastflag.go
Normal file
84
utils/broadcastflag.go
Normal file
|
@ -0,0 +1,84 @@
|
|||
package utils
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/tevino/abool"
|
||||
)
|
||||
|
||||
// BroadcastFlag is a simple system to broadcast a flag value.
|
||||
type BroadcastFlag struct {
|
||||
flag *abool.AtomicBool
|
||||
signal chan struct{}
|
||||
lock sync.Mutex
|
||||
}
|
||||
|
||||
// Flag receives changes from its broadcasting flag.
|
||||
// A Flag must only be used in one goroutine and is not concurrency safe,
|
||||
// but fast.
|
||||
type Flag struct {
|
||||
flag *abool.AtomicBool
|
||||
signal chan struct{}
|
||||
broadcaster *BroadcastFlag
|
||||
}
|
||||
|
||||
// NewBroadcastFlag returns a new BroadcastFlag.
|
||||
// In the initial state, the flag is not set and the singal does not trigger.
|
||||
func NewBroadcastFlag() *BroadcastFlag {
|
||||
return &BroadcastFlag{
|
||||
flag: abool.New(),
|
||||
signal: make(chan struct{}),
|
||||
lock: sync.Mutex{},
|
||||
}
|
||||
}
|
||||
|
||||
// NewFlag returns a new Flag that listens to this broadcasting flag.
|
||||
// In the initial state, the flag is set and the singal triggers.
|
||||
// You can call Refresh immediately to get the current state from the
|
||||
// broadcasting flag.
|
||||
func (bf *BroadcastFlag) NewFlag() *Flag {
|
||||
newFlag := &Flag{
|
||||
flag: abool.NewBool(true),
|
||||
signal: make(chan struct{}),
|
||||
broadcaster: bf,
|
||||
}
|
||||
close(newFlag.signal)
|
||||
return newFlag
|
||||
}
|
||||
|
||||
// NotifyAndReset notifies all flags of this broadcasting flag and resets the
|
||||
// internal broadcast flag state.
|
||||
func (bf *BroadcastFlag) NotifyAndReset() {
|
||||
bf.lock.Lock()
|
||||
defer bf.lock.Unlock()
|
||||
|
||||
// Notify all flags of the change.
|
||||
bf.flag.Set()
|
||||
close(bf.signal)
|
||||
|
||||
// Reset
|
||||
bf.flag = abool.New()
|
||||
bf.signal = make(chan struct{})
|
||||
}
|
||||
|
||||
// Signal returns a channel that waits for the flag to be set. This does not
|
||||
// reset the Flag itself, you'll need to call Refresh for that.
|
||||
func (f *Flag) Signal() <-chan struct{} {
|
||||
return f.signal
|
||||
}
|
||||
|
||||
// IsSet returns whether the flag was set since the last Refresh.
|
||||
// This does not reset the Flag itself, you'll need to call Refresh for that.
|
||||
func (f *Flag) IsSet() bool {
|
||||
return f.flag.IsSet()
|
||||
}
|
||||
|
||||
// Refresh fetches the current state from the broadcasting flag.
|
||||
func (f *Flag) Refresh() {
|
||||
f.broadcaster.lock.Lock()
|
||||
defer f.broadcaster.lock.Unlock()
|
||||
|
||||
// Copy current flag and signal from the broadcasting flag.
|
||||
f.flag = f.broadcaster.flag
|
||||
f.signal = f.broadcaster.signal
|
||||
}
|
|
@ -12,6 +12,7 @@ func RunPowershellCmd(script string) (output string, err error) {
|
|||
// Create command to execute.
|
||||
cmd := exec.Command(
|
||||
"powershell.exe",
|
||||
"-ExecutionPolicy", "Bypass",
|
||||
"-NoProfile",
|
||||
"-NonInteractive",
|
||||
"[System.Console]::OutputEncoding = [System.Text.Encoding]::UTF8\n"+script,
|
||||
|
|
Loading…
Add table
Reference in a new issue