Merge pull request #42 from safing/feature/update-trigger

Add update module status, allow disabling of updates
This commit is contained in:
Daniel 2020-04-21 15:44:24 +02:00 committed by GitHub
commit e7149ac226
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 110 additions and 12 deletions

View file

@ -5,14 +5,17 @@ import (
"fmt"
"github.com/safing/portbase/config"
"github.com/safing/portbase/log"
)
var (
releaseChannel config.StringOption
devMode config.BoolOption
disableUpdates config.BoolOption
previousReleaseChannel string
previousDevMode bool
previousReleaseChannel string
updatesCurrentlyDisabled bool
previousDevMode bool
)
func registerConfig() error {
@ -32,16 +35,35 @@ func registerConfig() error {
return err
}
return module.RegisterEventHook("config", "config change", "update registry config", updateRegistryConfig)
err = config.Register(&config.Option{
Name: "Disable Updates",
Key: disableUpdatesKey,
Description: "Disable automatic updates.",
OptType: config.OptTypeBool,
ExpertiseLevel: config.ExpertiseLevelExpert,
ReleaseLevel: config.ReleaseLevelStable,
RequiresRestart: false,
DefaultValue: false,
ExternalOptType: "disable updates",
})
if err != nil {
return err
}
return nil
}
func initConfig() {
releaseChannel = config.GetAsString(releaseChannelKey, releaseChannelStable)
disableUpdates = config.GetAsBool(disableUpdatesKey, false)
devMode = config.GetAsBool("core/devMode", false)
}
func updateRegistryConfig(_ context.Context, _ interface{}) error {
changed := false
forceUpdate := false
if releaseChannel() != previousReleaseChannel {
registry.SetBeta(releaseChannel() == releaseChannelBeta)
previousReleaseChannel = releaseChannel()
@ -49,14 +71,29 @@ func updateRegistryConfig(_ context.Context, _ interface{}) error {
}
if devMode() != previousDevMode {
registry.SetBeta(devMode())
registry.SetDevMode(devMode())
previousDevMode = devMode()
changed = true
}
if disableUpdates() != updatesCurrentlyDisabled {
updatesCurrentlyDisabled = disableUpdates()
changed = true
forceUpdate = !updatesCurrentlyDisabled
}
if changed {
registry.SelectVersions()
module.TriggerEvent(VersionUpdateEvent, nil)
if forceUpdate {
module.Resolve(updateFailed)
_ = TriggerUpdate()
log.Infof("updates: automatic updates enabled again.")
} else {
module.Warning(updateFailed, "Updates are disabled!")
log.Warningf("updates: automatic updates are now disabled.")
}
}
return nil

View file

@ -19,6 +19,8 @@ const (
releaseChannelStable = "stable"
releaseChannelBeta = "beta"
disableUpdatesKey = "core/disableUpdates"
// ModuleName is the name of the update module
// and can be used when declaring module dependencies.
ModuleName = "updates"
@ -36,6 +38,10 @@ const (
// to check if new versions of their resources are
// available by checking File.UpgradeAvailable().
ResourceUpdateEvent = "resource update"
// TriggerUpdateEvent is the event that can be emitted
// by the updates module to trigger an update.
TriggerUpdateEvent = "trigger update"
)
var (
@ -46,15 +52,51 @@ var (
disableTaskSchedule bool
)
const (
updateInProgress = "update-in-progress"
updateInProcessDescr = "Portmaster is currently checking and downloading updates."
updateFailed = "update-failed"
)
func init() {
module = modules.Register(ModuleName, registerConfig, start, stop, "base")
module = modules.Register(ModuleName, prep, start, stop, "base")
module.RegisterEvent(VersionUpdateEvent)
module.RegisterEvent(ResourceUpdateEvent)
}
func prep() error {
if err := registerConfig(); err != nil {
return err
}
module.RegisterEvent(TriggerUpdateEvent)
return nil
}
func start() error {
initConfig()
if err := module.RegisterEventHook(
"config",
"config change",
"update registry config",
updateRegistryConfig); err != nil {
return err
}
if err := module.RegisterEventHook(
module.Name,
TriggerUpdateEvent,
"Check for and download available updates",
func(context.Context, interface{}) error {
_ = TriggerUpdate()
return nil
},
); err != nil {
return err
}
var mandatoryUpdates []string
if onWindows {
mandatoryUpdates = []string{
@ -115,8 +157,8 @@ func start() error {
if !disableTaskSchedule {
updateTask.
Repeat(24 * time.Hour).
MaxDelay(1 * time.Hour).
Repeat(1 * time.Hour).
MaxDelay(30 * time.Minute).
Schedule(time.Now().Add(10 * time.Second))
}
@ -138,6 +180,7 @@ func TriggerUpdate() error {
updateASAP = true
} else {
updateTask.StartASAP()
log.Debugf("updates: triggering update to run as soon as possible")
}
return nil
@ -156,14 +199,32 @@ func DisableUpdateSchedule() error {
return nil
}
func checkForUpdates(ctx context.Context) error {
if err := registry.UpdateIndexes(); err != nil {
return fmt.Errorf("updates: failed to update indexes: %w", err)
func checkForUpdates(ctx context.Context) (err error) {
if updatesCurrentlyDisabled {
log.Debugf("updates: automatic updates are disabled")
return nil
}
defer log.Debugf("updates: finished checking for updates")
module.Hint(updateInProgress, updateInProcessDescr)
defer func() {
if err == nil {
module.Resolve(updateInProgress)
} else {
module.Warning(updateFailed, "Failed to check for updates: "+err.Error())
}
}()
if err = registry.UpdateIndexes(); err != nil {
err = fmt.Errorf("failed to update indexes: %w", err)
return
}
err := registry.DownloadUpdates(ctx)
err = registry.DownloadUpdates(ctx)
if err != nil {
return fmt.Errorf("updates: failed to update: %w", err)
err = fmt.Errorf("failed to update: %w", err)
return
}
registry.SelectVersions()