Replace dataroot module with BinDir and DataDir on instance, adapt modules

This commit is contained in:
Daniel
2024-11-06 10:48:02 +01:00
parent 0f3f3c360f
commit 7bc1c3b764
39 changed files with 819 additions and 482 deletions

View File

@@ -1,47 +1,49 @@
package main
import (
"bufio"
"errors"
"flag"
"fmt"
"io"
"log/slog"
"os"
"runtime"
"runtime/pprof"
"syscall"
"github.com/spf13/cobra"
"github.com/safing/portmaster/base/info"
"github.com/safing/portmaster/base/metrics"
"github.com/safing/portmaster/service"
"github.com/safing/portmaster/service/mgr"
"github.com/safing/portmaster/service/updates"
"github.com/safing/portmaster/spn/conf"
)
var (
printStackOnExit bool
enableInputSignals bool
rootCmd = &cobra.Command{
Use: "portmaster-core",
PersistentPreRun: initializeGlobals,
Run: cmdRun,
}
sigUSR1 = syscall.Signal(0xa) // dummy for windows
binDir string
dataDir string
svcCfg *service.ServiceConfig
)
func init() {
flag.BoolVar(&printStackOnExit, "print-stack-on-exit", false, "prints the stack before of shutting down")
flag.BoolVar(&enableInputSignals, "input-signals", false, "emulate signals using stdin")
// Add Go's default flag set.
rootCmd.Flags().AddGoFlagSet(flag.CommandLine)
// Add persisent flags for all commands.
rootCmd.PersistentFlags().StringVar(&binDir, "bin-dir", "", "set directory for executable binaries (rw/ro)")
rootCmd.PersistentFlags().StringVar(&dataDir, "data-dir", "", "set directory for variable data (rw)")
}
func main() {
flag.Parse()
// Call platform specific checks, that will execute commands like "recover-iptables"
platformSpecificChecks()
instance := initialize()
run(instance)
if err := rootCmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}
func initialize() *service.Instance {
func initializeGlobals(cmd *cobra.Command, args []string) {
// set information
info.Set("Portmaster", "", "GPLv3")
@@ -51,66 +53,13 @@ func initialize() *service.Instance {
// Configure user agent.
updates.UserAgent = fmt.Sprintf("Portmaster Core (%s %s)", runtime.GOOS, runtime.GOARCH)
// enable SPN client mode
conf.EnableClient(true)
conf.EnableIntegration(true)
// Create instance.
var execCmdLine bool
instance, err := service.New(&service.ServiceConfig{})
switch {
case err == nil:
// Continue
case errors.Is(err, mgr.ErrExecuteCmdLineOp):
execCmdLine = true
default:
fmt.Printf("error creating an instance: %s\n", err)
os.Exit(2)
}
// Execute command line operation, if requested or available.
switch {
case !execCmdLine:
// Run service.
case instance.CommandLineOperation == nil:
fmt.Println("command line operation execution requested, but not set")
os.Exit(3)
default:
// Run the function and exit.
err = instance.CommandLineOperation()
if err != nil {
fmt.Fprintf(os.Stderr, "command line operation failed: %s\n", err)
os.Exit(3)
}
os.Exit(0)
}
return instance
}
func printStackTo(writer io.Writer, msg string) {
_, err := fmt.Fprintf(writer, "===== %s =====\n", msg)
if err == nil {
err = pprof.Lookup("goroutine").WriteTo(writer, 1)
}
if err != nil {
slog.Error("failed to write stack trace", "err", err)
}
}
func inputSignals(signalCh chan os.Signal) {
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
switch scanner.Text() {
case "SIGHUP":
signalCh <- syscall.SIGHUP
case "SIGINT":
signalCh <- syscall.SIGINT
case "SIGQUIT":
signalCh <- syscall.SIGQUIT
case "SIGTERM":
signalCh <- syscall.SIGTERM
case "SIGUSR1":
signalCh <- sigUSR1
}
// Create service config.
svcCfg = &service.ServiceConfig{
BinDir: binDir,
DataDir: dataDir,
BinariesIndexURLs: service.DefaultBinaryIndexURLs,
IntelIndexURLs: service.DefaultIntelIndexURLs,
VerifyBinaryUpdates: service.BinarySigningTrustStore,
VerifyIntelUpdates: service.BinarySigningTrustStore,
}
}

108
cmds/portmaster-core/run.go Normal file
View File

@@ -0,0 +1,108 @@
package main
import (
"bufio"
"errors"
"flag"
"fmt"
"io"
"log/slog"
"os"
"runtime/pprof"
"syscall"
"github.com/spf13/cobra"
"github.com/safing/portmaster/service"
"github.com/safing/portmaster/service/mgr"
"github.com/safing/portmaster/spn/conf"
)
var (
printStackOnExit bool
enableInputSignals bool
sigUSR1 = syscall.Signal(0xa) // dummy for windows
)
func init() {
flag.BoolVar(&printStackOnExit, "print-stack-on-exit", false, "prints the stack before of shutting down")
flag.BoolVar(&enableInputSignals, "input-signals", false, "emulate signals using stdin")
}
func cmdRun(cmd *cobra.Command, args []string) {
// Call platform specific checks, that will execute commands like "recover-iptables"
platformSpecificChecks()
svcCfg.VerifyBinaryUpdates = nil // FIXME
svcCfg.VerifyIntelUpdates = nil // FIXME
instance := createInstance()
run(instance)
}
func createInstance() *service.Instance {
// enable SPN client mode
conf.EnableClient(true)
conf.EnableIntegration(true)
// Create instance.
var execCmdLine bool
instance, err := service.New(svcCfg)
switch {
case err == nil:
// Continue
case errors.Is(err, mgr.ErrExecuteCmdLineOp):
execCmdLine = true
default:
fmt.Printf("error creating an instance: %s\n", err)
os.Exit(2)
}
// Execute module command line operation, if requested or available.
switch {
case !execCmdLine:
// Run service.
case instance.CommandLineOperation == nil:
fmt.Println("command line operation execution requested, but not set")
os.Exit(3)
default:
// Run the function and exit.
fmt.Println("executing cmdline op")
err = instance.CommandLineOperation()
if err != nil {
fmt.Fprintf(os.Stderr, "command line operation failed: %s\n", err)
os.Exit(3)
}
os.Exit(0)
}
return instance
}
func printStackTo(writer io.Writer, msg string) {
_, err := fmt.Fprintf(writer, "===== %s =====\n", msg)
if err == nil {
err = pprof.Lookup("goroutine").WriteTo(writer, 1)
}
if err != nil {
slog.Error("failed to write stack trace", "err", err)
}
}
func inputSignals(signalCh chan os.Signal) {
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
switch scanner.Text() {
case "SIGHUP":
signalCh <- syscall.SIGHUP
case "SIGINT":
signalCh <- syscall.SIGINT
case "SIGQUIT":
signalCh <- syscall.SIGQUIT
case "SIGTERM":
signalCh <- syscall.SIGTERM
case "SIGUSR1":
signalCh <- sigUSR1
}
}
}

View File

@@ -129,7 +129,7 @@ func isRunningAsService() bool {
// Get the current process ID
pid := os.Getpid()
currentProcess, err := processInfo.NewProcess(int32(pid))
currentProcess, err := processInfo.NewProcess(int32(pid)) //nolint:gosec
if err != nil {
return false
}

View File

@@ -0,0 +1,77 @@
package main
import (
"fmt"
"github.com/spf13/cobra"
"github.com/safing/portmaster/base/log"
"github.com/safing/portmaster/base/notifications"
"github.com/safing/portmaster/service"
"github.com/safing/portmaster/service/updates"
)
var updateCmd = &cobra.Command{
Use: "update",
Short: "Force an update of all components.",
RunE: update,
}
func init() {
rootCmd.AddCommand(updateCmd)
}
func update(cmd *cobra.Command, args []string) error {
// Finalize config.
svcCfg.VerifyBinaryUpdates = nil // FIXME
svcCfg.VerifyIntelUpdates = nil // FIXME
err := svcCfg.Init()
if err != nil {
return fmt.Errorf("internal configuration error: %w", err)
}
// Start logging.
log.SetLogLevel(log.InfoLevel)
_ = log.Start()
defer log.Shutdown()
// Create updaters.
instance := &updateDummyInstance{}
binaryUpdateConfig, intelUpdateConfig, err := service.MakeUpdateConfigs(svcCfg)
if err != nil {
return fmt.Errorf("init updater config: %w", err)
}
binaryUpdates, err := updates.New(instance, "Binary Updater", *binaryUpdateConfig)
if err != nil {
return fmt.Errorf("configure binary updates: %w", err)
}
intelUpdates, err := updates.New(instance, "Intel Updater", *intelUpdateConfig)
if err != nil {
return fmt.Errorf("configure intel updates: %w", err)
}
// Force update all.
binErr := binaryUpdates.ForceUpdate()
if binErr != nil {
log.Errorf("binary update failed: %s", binErr)
}
intelErr := intelUpdates.ForceUpdate()
if intelErr != nil {
log.Errorf("intel update failed: %s", intelErr)
}
// Return error.
if binErr != nil {
return fmt.Errorf("binary update failed: %w", binErr)
}
if intelErr != nil {
return fmt.Errorf("intel update failed: %w", intelErr)
}
return nil
}
type updateDummyInstance struct{}
func (udi *updateDummyInstance) Restart() {}
func (udi *updateDummyInstance) Shutdown() {}
func (udi *updateDummyInstance) Notifications() *notifications.Notifications { return nil }

View File

@@ -9,7 +9,7 @@ import (
)
var (
bundleSettings = updates.IndexScanConfig{
scanConfig = updates.IndexScanConfig{
Name: "Portmaster Binaries",
PrimaryArtifact: "linux_amd64/portmaster-core",
BaseURL: "https://updates.safing.io/",
@@ -60,17 +60,17 @@ var (
RunE: scan,
}
bundleDir string
scanDir string
)
func init() {
rootCmd.AddCommand(scanCmd)
scanCmd.Flags().StringVarP(&bundleDir, "dir", "d", "", "directory to create index from (required)")
scanCmd.Flags().StringVarP(&scanDir, "dir", "d", "", "directory to create index from (required)")
_ = scanCmd.MarkFlagRequired("dir")
}
func scan(cmd *cobra.Command, args []string) error {
bundle, err := updates.GenerateBundleFromDir(bundleDir, bundleSettings)
bundle, err := updates.GenerateIndexFromDir(scanDir, scanConfig)
if err != nil {
return err
}