mirror of
https://github.com/safing/portmaster
synced 2025-04-22 03:49:09 +00:00
* Move portbase into monorepo * Add new simple module mgr * [WIP] Switch to new simple module mgr * Add StateMgr and more worker variants * [WIP] Switch more modules * [WIP] Switch more modules * [WIP] swtich more modules * [WIP] switch all SPN modules * [WIP] switch all service modules * [WIP] Convert all workers to the new module system * [WIP] add new task system to module manager * [WIP] Add second take for scheduling workers * [WIP] Add FIXME for bugs in new scheduler * [WIP] Add minor improvements to scheduler * [WIP] Add new worker scheduler * [WIP] Fix more bug related to new module system * [WIP] Fix start handing of the new module system * [WIP] Improve startup process * [WIP] Fix minor issues * [WIP] Fix missing subsystem in settings * [WIP] Initialize managers in constructor * [WIP] Move module event initialization to constrictors * [WIP] Fix setting for enabling and disabling the SPN module * [WIP] Move API registeration into module construction * [WIP] Update states mgr for all modules * [WIP] Add CmdLine operation support * Add state helper methods to module group and instance * Add notification and module status handling to status package * Fix starting issues * Remove pilot widget and update security lock to new status data * Remove debug logs * Improve http server shutdown * Add workaround for cleanly shutting down firewall+netquery * Improve logging * Add syncing states with notifications for new module system * Improve starting, stopping, shutdown; resolve FIXMEs/TODOs * [WIP] Fix most unit tests * Review new module system and fix minor issues * Push shutdown and restart events again via API * Set sleep mode via interface * Update example/template module * [WIP] Fix spn/cabin unit test * Remove deprecated UI elements * Make log output more similar for the logging transition phase * Switch spn hub and observer cmds to new module system * Fix log sources * Make worker mgr less error prone * Fix tests and minor issues * Fix observation hub * Improve shutdown and restart handling * Split up big connection.go source file * Move varint and dsd packages to structures repo * Improve expansion test * Fix linter warnings * Fix interception module on windows * Fix linter errors --------- Co-authored-by: Vladimir Stoilov <vladimir@safing.io>
135 lines
3.2 KiB
Go
135 lines
3.2 KiB
Go
package updates
|
|
|
|
import (
|
|
"os/exec"
|
|
"runtime"
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/tevino/abool"
|
|
|
|
"github.com/safing/portmaster/base/log"
|
|
"github.com/safing/portmaster/service/mgr"
|
|
)
|
|
|
|
var (
|
|
// RebootOnRestart defines whether the whole system, not just the service,
|
|
// should be restarted automatically when triggering a restart internally.
|
|
RebootOnRestart bool
|
|
|
|
restartPending = abool.New()
|
|
restartTriggered = abool.New()
|
|
|
|
restartTime time.Time
|
|
restartTimeLock sync.Mutex
|
|
)
|
|
|
|
// IsRestarting returns whether a restart has been triggered.
|
|
func IsRestarting() bool {
|
|
return restartTriggered.IsSet()
|
|
}
|
|
|
|
// RestartIsPending returns whether a restart is pending.
|
|
func RestartIsPending() (pending bool, restartAt time.Time) {
|
|
if restartPending.IsNotSet() {
|
|
return false, time.Time{}
|
|
}
|
|
|
|
restartTimeLock.Lock()
|
|
defer restartTimeLock.Unlock()
|
|
|
|
return true, restartTime
|
|
}
|
|
|
|
// DelayedRestart triggers a restart of the application by shutting down the
|
|
// module system gracefully and returning with RestartExitCode. The restart
|
|
// may be further delayed by up to 10 minutes by the internal task scheduling
|
|
// system. This only works if the process is managed by portmaster-start.
|
|
func DelayedRestart(delay time.Duration) {
|
|
// Check if restart is already pending.
|
|
if !restartPending.SetToIf(false, true) {
|
|
return
|
|
}
|
|
|
|
// Schedule the restart task.
|
|
log.Warningf("updates: restart triggered, will execute in %s", delay)
|
|
restartAt := time.Now().Add(delay)
|
|
module.restartWorkerMgr.Delay(delay)
|
|
|
|
// Set restartTime.
|
|
restartTimeLock.Lock()
|
|
defer restartTimeLock.Unlock()
|
|
restartTime = restartAt
|
|
}
|
|
|
|
// AbortRestart aborts a (delayed) restart.
|
|
func AbortRestart() {
|
|
if restartPending.SetToIf(true, false) {
|
|
log.Warningf("updates: restart aborted")
|
|
|
|
// Cancel schedule.
|
|
module.restartWorkerMgr.Delay(0)
|
|
}
|
|
}
|
|
|
|
// 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() {
|
|
module.restartWorkerMgr.Go()
|
|
}
|
|
}
|
|
|
|
// RestartNow immediately executes a restart.
|
|
// This only works if the process is managed by portmaster-start.
|
|
func RestartNow() {
|
|
restartPending.Set()
|
|
module.restartWorkerMgr.Go()
|
|
}
|
|
|
|
func automaticRestart(w *mgr.WorkerCtx) error {
|
|
// Check if the restart is still scheduled.
|
|
if restartPending.IsNotSet() {
|
|
return nil
|
|
}
|
|
|
|
// Trigger restart.
|
|
if restartTriggered.SetToIf(false, true) {
|
|
log.Warning("updates: initiating (automatic) restart")
|
|
|
|
// Check if we should reboot instead.
|
|
var rebooting bool
|
|
if RebootOnRestart {
|
|
// Trigger system reboot and record success.
|
|
rebooting = triggerSystemReboot()
|
|
if !rebooting {
|
|
log.Warningf("updates: rebooting failed, only restarting service instead")
|
|
}
|
|
}
|
|
|
|
// Set restart exit code.
|
|
if !rebooting {
|
|
module.instance.Restart()
|
|
} else {
|
|
module.instance.Shutdown()
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func triggerSystemReboot() (success bool) {
|
|
switch runtime.GOOS {
|
|
case "linux":
|
|
err := exec.Command("systemctl", "reboot").Run()
|
|
if err != nil {
|
|
log.Errorf("updates: triggering reboot with systemctl failed: %s", err)
|
|
return false
|
|
}
|
|
default:
|
|
log.Warningf("updates: rebooting is not support on %s", runtime.GOOS)
|
|
return false
|
|
}
|
|
|
|
return true
|
|
}
|