mirror of
https://github.com/safing/portmaster
synced 2025-09-02 02:29:12 +00:00
Add automatic upgrades for spn-hub
This commit is contained in:
parent
6ded9b3f8c
commit
092da058a5
3 changed files with 112 additions and 17 deletions
|
@ -5,12 +5,12 @@ import (
|
||||||
|
|
||||||
"github.com/safing/portbase/log"
|
"github.com/safing/portbase/log"
|
||||||
"github.com/safing/portbase/modules"
|
"github.com/safing/portbase/modules"
|
||||||
|
"github.com/safing/portmaster/updates"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
eventShutdown = "shutdown"
|
eventShutdown = "shutdown"
|
||||||
eventRestart = "restart"
|
eventRestart = "restart"
|
||||||
restartCode = 23
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func registerEvents() {
|
func registerEvents() {
|
||||||
|
@ -43,7 +43,7 @@ func shutdown(ctx context.Context, _ interface{}) error {
|
||||||
// restart restarts the Portmaster.
|
// restart restarts the Portmaster.
|
||||||
func restart(ctx context.Context, data interface{}) error {
|
func restart(ctx context.Context, data interface{}) error {
|
||||||
log.Info("core: user requested restart")
|
log.Info("core: user requested restart")
|
||||||
modules.SetExitStatusCode(restartCode)
|
modules.SetExitStatusCode(updates.RestartExitCode)
|
||||||
// Do not use a worker, as this would block itself here.
|
// Do not use a worker, as this would block itself here.
|
||||||
go modules.Shutdown() //nolint:errcheck
|
go modules.Shutdown() //nolint:errcheck
|
||||||
return nil
|
return nil
|
||||||
|
|
48
updates/restart.go
Normal file
48
updates/restart.go
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
package updates
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/safing/portbase/log"
|
||||||
|
"github.com/safing/portbase/modules"
|
||||||
|
"github.com/tevino/abool"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// RestartExitCode will instruct portmaster-start to restart the process immediately, potentially with a new version.
|
||||||
|
RestartExitCode = 23
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
restartTask *modules.Task
|
||||||
|
restartPending *abool.AtomicBool
|
||||||
|
restartTriggered *abool.AtomicBool
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
restartTask = module.NewTask("automatic restart", automaticRestart)
|
||||||
|
}
|
||||||
|
|
||||||
|
func triggerRestart(delay time.Duration) {
|
||||||
|
restartPending.Set()
|
||||||
|
restartTask.Schedule(time.Now().Add(delay))
|
||||||
|
}
|
||||||
|
|
||||||
|
// TriggerRestartIfPending triggers an automatic restart, if one is pending. This can be used to prepone a scheduled restart if the conditions are preferable.
|
||||||
|
func TriggerRestartIfPending() {
|
||||||
|
if restartPending.IsSet() {
|
||||||
|
_ = automaticRestart(module.Ctx, nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func automaticRestart(_ context.Context, _ *modules.Task) error {
|
||||||
|
if restartTriggered.SetToIf(false, true) {
|
||||||
|
log.Info("updates: initiating automatic restart")
|
||||||
|
modules.SetExitStatusCode(RestartExitCode)
|
||||||
|
// Do not use a worker, as this would block itself here.
|
||||||
|
go modules.Shutdown() //nolint:errcheck
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -11,16 +11,15 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/tevino/abool"
|
|
||||||
|
|
||||||
"github.com/google/renameio"
|
"github.com/google/renameio"
|
||||||
|
processInfo "github.com/shirou/gopsutil/process"
|
||||||
|
"github.com/tevino/abool"
|
||||||
|
|
||||||
"github.com/safing/portbase/info"
|
"github.com/safing/portbase/info"
|
||||||
"github.com/safing/portbase/log"
|
"github.com/safing/portbase/log"
|
||||||
"github.com/safing/portbase/notifications"
|
"github.com/safing/portbase/notifications"
|
||||||
|
"github.com/safing/portbase/rng"
|
||||||
"github.com/safing/portbase/updater"
|
"github.com/safing/portbase/updater"
|
||||||
|
|
||||||
processInfo "github.com/shirou/gopsutil/process"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -29,12 +28,13 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// UpgradeCore specifies if portmaster-core should be upgraded.
|
|
||||||
UpgradeCore = true
|
|
||||||
|
|
||||||
upgraderActive = abool.NewBool(false)
|
upgraderActive = abool.NewBool(false)
|
||||||
pmCtrlUpdate *updater.File
|
|
||||||
pmCoreUpdate *updater.File
|
pmCtrlUpdate *updater.File
|
||||||
|
pmCoreUpdate *updater.File
|
||||||
|
|
||||||
|
spnHubUpdate *updater.File
|
||||||
|
hubUpgradeStarted bool
|
||||||
|
|
||||||
rawVersionRegex = regexp.MustCompile(`^[0-9]+\.[0-9]+\.[0-9]+b?\*?$`)
|
rawVersionRegex = regexp.MustCompile(`^[0-9]+\.[0-9]+\.[0-9]+b?\*?$`)
|
||||||
)
|
)
|
||||||
|
@ -61,24 +61,35 @@ func upgrader(_ context.Context, _ interface{}) error {
|
||||||
log.Warningf("updates: failed to upgrade portmaster-start: %s", err)
|
log.Warningf("updates: failed to upgrade portmaster-start: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if UpgradeCore {
|
binName := strings.TrimSuffix(
|
||||||
|
filepath.Base(os.Args[0]),
|
||||||
|
".exe",
|
||||||
|
)
|
||||||
|
switch binName {
|
||||||
|
case "portmaster-core":
|
||||||
err = upgradeCoreNotify()
|
err = upgradeCoreNotify()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warningf("updates: failed to notify about core upgrade: %s", err)
|
log.Warningf("updates: failed to notify about core upgrade: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case "spn-hub":
|
||||||
|
err = upgradeHub()
|
||||||
|
if err != nil {
|
||||||
|
log.Warningf("updates: failed to initiate hub upgrade: %s", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func upgradeCoreNotify() error {
|
func upgradeCoreNotify() error {
|
||||||
identifier := "core/portmaster-core" // identifier, use forward slash!
|
|
||||||
if onWindows {
|
|
||||||
identifier += exeExt
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if we can upgrade
|
// check if we can upgrade
|
||||||
if pmCoreUpdate == nil || pmCoreUpdate.UpgradeAvailable() {
|
if pmCoreUpdate == nil || pmCoreUpdate.UpgradeAvailable() {
|
||||||
|
identifier := "core/portmaster-core" // identifier, use forward slash!
|
||||||
|
if onWindows {
|
||||||
|
identifier += exeExt
|
||||||
|
}
|
||||||
|
|
||||||
// get newest portmaster-core
|
// get newest portmaster-core
|
||||||
new, err := GetPlatformFile(identifier)
|
new, err := GetPlatformFile(identifier)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -128,6 +139,42 @@ func upgradeCoreNotifyActionHandler(n *notifications.Notification) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func upgradeHub() error {
|
||||||
|
if hubUpgradeStarted {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if we can upgrade
|
||||||
|
if spnHubUpdate == nil || spnHubUpdate.UpgradeAvailable() {
|
||||||
|
identifier := "hub/spn-hub" // identifier, use forward slash!
|
||||||
|
if onWindows {
|
||||||
|
identifier += exeExt
|
||||||
|
}
|
||||||
|
|
||||||
|
// get newest spn-hub
|
||||||
|
new, err := GetPlatformFile(identifier)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
spnHubUpdate = new
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if info.GetInfo().Version != spnHubUpdate.Version() {
|
||||||
|
// get random delay with up to three hours
|
||||||
|
delayMinutes, err := rng.Number(3 * 60)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
triggerRestart(time.Duration(delayMinutes) * time.Minute)
|
||||||
|
hubUpgradeStarted = true
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func upgradePortmasterStart() error {
|
func upgradePortmasterStart() error {
|
||||||
filename := "portmaster-start"
|
filename := "portmaster-start"
|
||||||
if onWindows {
|
if onWindows {
|
||||||
|
|
Loading…
Add table
Reference in a new issue