diff --git a/base/info/version.go b/base/info/version.go index 91bad092..6140adc2 100644 --- a/base/info/version.go +++ b/base/info/version.go @@ -10,6 +10,8 @@ import ( "sync" ) +// FIXME: version does not show in portmaster + var ( name string license string diff --git a/cmds/hub/main.go b/cmds/hub/main.go index b0b6e1d1..9c0379e8 100644 --- a/cmds/hub/main.go +++ b/cmds/hub/main.go @@ -24,6 +24,7 @@ import ( func init() { // flag.BoolVar(&updates.RebootOnRestart, "reboot-on-restart", false, "reboot server on auto-upgrade") + // FIXME } var sigUSR1 = syscall.Signal(0xa) @@ -48,6 +49,8 @@ func main() { log.SetLogLevel(log.WarningLevel) _ = log.Start() + // FIXME: Use service? + // Create instance. var execCmdLine bool instance, err := spn.New() @@ -109,7 +112,7 @@ func main() { slog.Warn("program was interrupted, stopping") } - case <-instance.Stopped(): + case <-instance.ShutdownComplete(): log.Shutdown() os.Exit(instance.ExitCode()) } diff --git a/cmds/observation-hub/main.go b/cmds/observation-hub/main.go index 1cb9bafd..a6ced810 100644 --- a/cmds/observation-hub/main.go +++ b/cmds/observation-hub/main.go @@ -78,6 +78,8 @@ func main() { } instance.AddModule(observer) + // FIXME: Use service? + // Execute command line operation, if requested or available. switch { case !execCmdLine: @@ -126,7 +128,7 @@ func main() { slog.Warn("program was interrupted, stopping") } - case <-instance.Stopped(): + case <-instance.ShuttingDown(): log.Shutdown() os.Exit(instance.ExitCode()) } diff --git a/cmds/portmaster-core/main.go b/cmds/portmaster-core/main.go index 993ffb55..0b4d0e01 100644 --- a/cmds/portmaster-core/main.go +++ b/cmds/portmaster-core/main.go @@ -58,7 +58,7 @@ func initializeGlobals(cmd *cobra.Command, args []string) { svcCfg = &service.ServiceConfig{ BinDir: binDir, DataDir: dataDir, - BinariesIndexURLs: service.DefaultBinaryIndexURLs, + BinariesIndexURLs: service.DefaultStableBinaryIndexURLs, IntelIndexURLs: service.DefaultIntelIndexURLs, VerifyBinaryUpdates: service.BinarySigningTrustStore, VerifyIntelUpdates: service.BinarySigningTrustStore, diff --git a/service/config.go b/service/config.go index b9d9b5c1..0d613315 100644 --- a/service/config.go +++ b/service/config.go @@ -60,7 +60,8 @@ func (sc *ServiceConfig) Init() error { // Apply defaults for required fields. if len(sc.BinariesIndexURLs) == 0 { - sc.BinariesIndexURLs = DefaultBinaryIndexURLs + // FIXME: Select based on setting. + sc.BinariesIndexURLs = DefaultStableBinaryIndexURLs } if len(sc.IntelIndexURLs) == 0 { sc.IntelIndexURLs = DefaultIntelIndexURLs diff --git a/service/process/process.go b/service/process/process.go index 60dac7eb..4e0eeeae 100644 --- a/service/process/process.go +++ b/service/process/process.go @@ -256,7 +256,7 @@ func loadProcess(ctx context.Context, key string, pInfo *processInfo.Process) (* // Username process.UserName, err = pInfo.UsernameWithContext(ctx) if err != nil { - return nil, fmt.Errorf("process: failed to get Username for p%d: %w", pInfo.Pid, err) + log.Tracer(ctx).Warningf("process: failed to get username (PID %d): %s", pInfo.Pid, err) } // TODO: User Home diff --git a/service/updates.go b/service/updates.go index c9ee185e..3c717951 100644 --- a/service/updates.go +++ b/service/updates.go @@ -9,9 +9,19 @@ import ( ) var ( - DefaultBinaryIndexURLs = []string{ + DefaultStableBinaryIndexURLs = []string{ "https://updates.safing.io/stable.v3.json", } + DefaultBetaBinaryIndexURLs = []string{ + "https://updates.safing.io/beta.v3.json", + } + DefaultStagingBinaryIndexURLs = []string{ + "https://updates.safing.io/staging.v3.json", + } + DefaultSupportBinaryIndexURLs = []string{ + "https://updates.safing.io/support.v3.json", + } + DefaultIntelIndexURLs = []string{ "https://updates.safing.io/intel.v3.json", } @@ -53,6 +63,7 @@ func MakeUpdateConfigs(svcCfg *ServiceConfig) (binaryUpdateConfig, intelUpdateCo IndexURLs: svcCfg.BinariesIndexURLs, IndexFile: "index.json", Verify: svcCfg.VerifyBinaryUpdates, + AutoCheck: true, // FIXME: Get from setting. AutoDownload: false, AutoApply: false, NeedsRestart: true, @@ -66,6 +77,7 @@ func MakeUpdateConfigs(svcCfg *ServiceConfig) (binaryUpdateConfig, intelUpdateCo IndexURLs: svcCfg.IntelIndexURLs, IndexFile: "index.json", Verify: svcCfg.VerifyIntelUpdates, + AutoCheck: true, // FIXME: Get from setting. AutoDownload: true, AutoApply: true, NeedsRestart: false, @@ -82,6 +94,7 @@ func MakeUpdateConfigs(svcCfg *ServiceConfig) (binaryUpdateConfig, intelUpdateCo IndexURLs: svcCfg.BinariesIndexURLs, IndexFile: "index.json", Verify: svcCfg.VerifyBinaryUpdates, + AutoCheck: true, // FIXME: Get from setting. AutoDownload: false, AutoApply: false, NeedsRestart: true, @@ -95,6 +108,7 @@ func MakeUpdateConfigs(svcCfg *ServiceConfig) (binaryUpdateConfig, intelUpdateCo IndexURLs: svcCfg.IntelIndexURLs, IndexFile: "index.json", Verify: svcCfg.VerifyIntelUpdates, + AutoCheck: true, // FIXME: Get from setting. AutoDownload: true, AutoApply: true, NeedsRestart: false, diff --git a/service/updates/module.go b/service/updates/module.go index 4ae6022c..e5b32129 100644 --- a/service/updates/module.go +++ b/service/updates/module.go @@ -41,6 +41,7 @@ var ( ErrNotFound = errors.New("file not found") ErrSameIndex = errors.New("same index") + ErrAutoCheckDisabled = errors.New("automatic update checks are disabled") ErrNoUpdateAvailable = errors.New("no update available") ErrActionRequired = errors.New("action required") ) @@ -67,6 +68,8 @@ type Config struct { // Verify enables and specifies the trust the index signatures will be checked against. Verify jess.TrustStore + // AutoCheck defines that new indexes may be downloaded automatically without outside trigger. + AutoCheck bool // AutoDownload defines that updates may be downloaded automatically without outside trigger. AutoDownload bool // AutoApply defines that updates may be automatically applied without outside trigger. @@ -157,8 +160,7 @@ func New(instance instance, name string, cfg Config) (*Updater, error) { } // Create Workers. - module.updateCheckWorkerMgr = m.NewWorkerMgr("update checker", module.updateCheckWorker, nil). - Repeat(updateTaskRepeatDuration) + module.updateCheckWorkerMgr = m.NewWorkerMgr("update checker", module.updateCheckWorker, nil) module.upgradeWorkerMgr = m.NewWorkerMgr("upgrader", module.upgradeWorker, nil) // Load index. @@ -207,12 +209,13 @@ func (u *Updater) updateAndUpgrade(w *mgr.WorkerCtx, indexURLs []string, ignoreV } } + // Get index to check version. + u.indexLock.Lock() + index := u.index + u.indexLock.Unlock() + // Check if there is a new version. - if !ignoreVersion { - // Get index to check version. - u.indexLock.Lock() - index := u.index - u.indexLock.Unlock() + if !ignoreVersion && index != nil { // Check with local pointer to index. if err := index.ShouldUpgradeTo(downloader.index); err != nil { if errors.Is(err, ErrSameIndex) { @@ -351,44 +354,31 @@ func (u *Updater) updateAndUpgrade(w *mgr.WorkerCtx, indexURLs []string, ignoreV } // Notify user that a restart is required. - if u.cfg.Notify && u.instance.Notifications() != nil { - - u.instance.Notifications().Notify(¬ifications.Notification{ - EventID: restartRequiredNotificationID, - Type: notifications.Info, - Title: "Restart Required", - Message: "Portmaster v" + downloader.index.Version + " is installed. Restart to use new version.", - AvailableActions: []*notifications.Action{ - { - ID: "ack", - Text: "Later", - }, - { - ID: "restart", - Text: "Restart Now", - Type: notifications.ActionTypeWebhook, - Payload: notifications.ActionTypeWebhookPayload{ - Method: "POST", - URL: "updates/apply", + if u.cfg.Notify { + if u.instance.Notifications() != nil { + u.instance.Notifications().Notify(¬ifications.Notification{ + EventID: restartRequiredNotificationID, + Type: notifications.Info, + Title: "Restart Required", + Message: "Portmaster v" + downloader.index.Version + " is installed. Restart to use new version.", + AvailableActions: []*notifications.Action{ + { + ID: "ack", + Text: "Later", + }, + { + ID: "restart", + Text: "Restart Now", + Type: notifications.ActionTypeWebhook, + Payload: notifications.ActionTypeWebhookPayload{ + Method: "POST", + URL: "updates/apply", + }, }, }, - }, - }) + }) + } - u.instance.Notifications().NotifyInfo( - updateAvailableNotificationID, - "Restart Required", - "Portmaster v"+downloader.index.Version+" is installed. Restart to use new version.", - notifications.Action{ - ID: "restart", - Text: "Restart Now", - Type: notifications.ActionTypeWebhook, - Payload: notifications.ActionTypeWebhookPayload{ - Method: "POST", - URL: "core/restart", - }, - }, - ) return fmt.Errorf("%w: restart required", ErrActionRequired) } @@ -470,6 +460,7 @@ func (u *Updater) Manager() *mgr.Manager { // Start starts the module. func (u *Updater) Start() error { if u.corruptedInstallation && u.cfg.Notify && u.instance.Notifications() != nil { + // FIXME: this might make sense as a module state u.instance.Notifications().NotifyError( corruptInstallationNotificationID, "Install Corruption", @@ -477,7 +468,12 @@ func (u *Updater) Start() error { ) } - u.updateCheckWorkerMgr.Delay(15 * time.Second) + // Check for updates automatically, if enabled. + if u.cfg.AutoCheck { + u.updateCheckWorkerMgr. + Repeat(updateTaskRepeatDuration). + Delay(15 * time.Second) + } return nil } diff --git a/service/updates/upgrade.go b/service/updates/upgrade.go index 593c3dd5..86077ee1 100644 --- a/service/updates/upgrade.go +++ b/service/updates/upgrade.go @@ -12,6 +12,8 @@ import ( "github.com/safing/portmaster/base/log" ) +// FIXME: previous update system did in-place service file upgrades. Check if this is still necessary and if changes are in current installers. + const ( defaultFileMode = os.FileMode(0o0644) executableFileMode = os.FileMode(0o0744) @@ -25,7 +27,7 @@ func (u *Updater) upgrade(downloader *Downloader, ignoreVersion bool) error { defer u.indexLock.Unlock() // Check if we should upgrade at all. - if !ignoreVersion { + if !ignoreVersion && u.index != nil { if err := u.index.ShouldUpgradeTo(downloader.index); err != nil { return fmt.Errorf("cannot upgrade: %w", ErrNoUpdateAvailable) }