Update and improve notifications according to new system

This commit is contained in:
Daniel 2021-05-05 00:27:34 +02:00
parent fa58de2e1b
commit 2e73d4fbe6
8 changed files with 96 additions and 49 deletions

View file

@ -16,12 +16,10 @@ var (
)
const (
filterlistsDisabled = "filterlists:disabled"
filterlistsUpdateFailed = "filterlists:update-failed"
filterlistsStaleDataSurvived = "filterlists:staledata"
filterlistsStaleDataDescr = "Removing stale filter list records failed. Some connections may be overblocked."
filterlistsUpdateInProgress = "filterlists:update-in-progress"
filterlistsUpdateInProgressDescr = "Performance slightly degraded during list update."
filterlistsDisabled = "filterlists:disabled"
filterlistsUpdateFailed = "filterlists:update-failed"
filterlistsStaleDataSurvived = "filterlists:staledata"
filterlistsUpdateInProgress = "filterlists:update-in-progress"
)
// booleans mainly used to decouple the module
@ -91,7 +89,7 @@ func start() error {
if err != nil {
log.Debugf("intel/filterlists: blocklists disabled, waiting for update (%s)", err)
module.Warning(filterlistsDisabled, "Blocklist features disabled, waiting for update")
warnAboutDisabledFilterLists()
} else {
log.Debugf("intel/filterlists: using cache database")
close(filterListsLoaded)
@ -104,3 +102,11 @@ func stop() error {
filterListsLoaded = make(chan struct{})
return nil
}
func warnAboutDisabledFilterLists() {
module.Warning(
filterlistsDisabled,
"Filter Lists Are Initializing",
"The Filter Lists are waiting for update system to check for updates in order to retrieve the filter list data. Until the filter lists are fully initialized, the filter lists feature is disabled.",
)
}

View file

@ -23,17 +23,19 @@ func tryListUpdate(ctx context.Context) error {
if err != nil {
if !isLoaded() {
module.Error(filterlistsDisabled, err.Error())
warnAboutDisabledFilterLists()
} else {
module.Warning(filterlistsUpdateFailed, err.Error())
module.Warning(
filterlistsUpdateFailed,
"Filter Lists Update Failed",
fmt.Sprintf("The filter lists system failed to process an update. Depending on the previous state, the filtering capabilities are now either impaired or not given. Refer to the error for more details: %s", err.Error()),
)
}
return err
}
// if the module is in an error, warning or hint state resolve that right now.
module.Resolve(filterlistsDisabled)
module.Resolve(filterlistsStaleDataSurvived)
module.Resolve(filterlistsUpdateInProgress)
// The list update suceeded, resolve any states.
module.Resolve("")
return nil
}
@ -44,7 +46,11 @@ func performUpdate(ctx context.Context) error {
}
defer updateInProgress.UnSet()
module.Hint(filterlistsUpdateInProgress, filterlistsUpdateInProgressDescr)
module.Hint(
filterlistsUpdateInProgress,
"Filter Lists Update In Progress",
"The filter list system is processing updates. While this might slightly degrade performance, the filter list system stays functional during this process.",
)
// First, update the list index.
err := updateListIndex()
@ -119,7 +125,11 @@ func performUpdate(ctx context.Context) error {
// if we failed to remove all stale cache entries
// we abort now WITHOUT updating the database version. This means
// we'll try again during the next update.
module.Warning(filterlistsStaleDataSurvived, filterlistsStaleDataDescr)
module.Warning(
filterlistsStaleDataSurvived,
"Filter Lists May Overblock",
fmt.Sprintf("The filter lists system successfully applied an update, but failed to delete old data. This means that the filtering system performs as usual, but may block more entries than it should. Refer to the error for more details: %s", err.Error()),
)
return fmt.Errorf("failed to cleanup stale cache records: %w", err)
}
}

View file

@ -10,8 +10,6 @@ import (
"sync/atomic"
"time"
"github.com/safing/portbase/database"
"github.com/safing/portbase/notifications"
"github.com/safing/portbase/log"
@ -257,10 +255,7 @@ func setCaptivePortal(portalURL *url.URL) {
func cleanUpPortalNotification() {
if captivePortalNotification != nil {
err := captivePortalNotification.Delete()
if err != nil && err != database.ErrNotFound {
log.Warningf("netenv: failed to delete old captive portal notification: %s", err)
}
captivePortalNotification.Delete()
captivePortalNotification = nil
}
}

View file

@ -123,7 +123,8 @@ func updateGlobalConfigProfile(ctx context.Context, task *modules.Task) error {
// Add module warning to inform user.
module.Warning(
globalConfigProfileErrorID,
fmt.Sprintf("Failed to process global settings: %s", err),
"Internal Settings Failure",
fmt.Sprintf("The app settings layering system failed to process the global settings. This means that some global settings might not be applied correctly. You can try restarting the Portmaster to resolve this problem. Refer to the error for more details: %s", err),
)
}

View file

@ -227,16 +227,22 @@ func loadResolvers() {
)
if len(newResolvers) == 0 {
msg := "no (valid) dns servers found in configuration or system, falling back to defaults"
log.Warningf("resolver: %s", msg)
module.Warning(missingResolversErrorID, msg)
log.Warning("resolver: no (valid) dns server found in config or system, falling back to global defaults")
module.Warning(
missingResolversErrorID,
"Using Factory Default DNS Servers",
"The Portmaster could not find any (valid) DNS servers in the settings or system. In order to prevent being disconnected, the factory defaults are being used instead.",
)
// load defaults directly, overriding config system
newResolvers = getConfiguredResolvers(defaultNameServers)
if len(newResolvers) == 0 {
msg = "no (valid) dns servers found in configuration or system"
log.Criticalf("resolver: %s", msg)
module.Error(missingResolversErrorID, msg)
log.Critical("resolver: no (valid) dns server found in config, system or global defaults")
module.Error(
missingResolversErrorID,
"No DNS Server Configured",
"The Portmaster could not find any (valid) DNS servers in the settings or system. You will experience severe connectivity problems until resolved.",
)
}
}

View file

@ -3,12 +3,15 @@ package updates
import (
"context"
"github.com/safing/portbase/notifications"
"github.com/safing/portbase/config"
"github.com/safing/portbase/log"
)
const (
cfgDevModeKey = "core/devMode"
cfgDevModeKey = "core/devMode"
updatesDisabledNotificationID = "updates:disabled"
)
var (
@ -85,7 +88,6 @@ func initConfig() {
func updateRegistryConfig(_ context.Context, _ interface{}) error {
changed := false
forceUpdate := false
if releaseChannel() != previousReleaseChannel {
registry.SetBeta(releaseChannel() == releaseChannelBeta)
@ -102,20 +104,33 @@ func updateRegistryConfig(_ context.Context, _ interface{}) error {
if enableUpdates() != updatesCurrentlyEnabled {
updatesCurrentlyEnabled = enableUpdates()
changed = true
forceUpdate = updatesCurrentlyEnabled
}
if changed {
registry.SelectVersions()
module.TriggerEvent(VersionUpdateEvent, nil)
if forceUpdate {
module.Resolve(updateFailed)
_ = TriggerUpdate()
log.Infof("updates: automatic updates enabled again.")
} else if !updatesCurrentlyEnabled {
module.Warning(updateFailed, "Automatic updates are disabled! This also affects security updates and threat intelligence.")
log.Warningf("updates: automatic updates are now disabled.")
if updatesCurrentlyEnabled {
module.Resolve("")
if err := TriggerUpdate(); err != nil {
log.Warningf("updates: failed to trigger update: %s", err)
}
log.Infof("updates: automatic updates are now enabled")
} else {
notifications.NotifyWarn(
updatesDisabledNotificationID,
"Automatic Updates Disabled",
"The automatic update system is disabled through configuration. Please note that this is potentially dangerous, as this also affects security updates as well as the filter lists and threat intelligence feeds.",
notifications.Action{
ID: "change",
Text: "Change",
Type: notifications.ActionTypeOpenSetting,
Payload: &notifications.ActionTypeOpenSettingPayload{
Key: enableUpdatesKey,
},
},
).AttachToModule(module)
log.Warningf("updates: automatic updates are now disabled")
}
}

View file

@ -278,13 +278,30 @@ func checkForUpdates(ctx context.Context) (err error) {
}
defer log.Debugf("updates: finished checking for updates")
module.Hint(updateInProgress, updateInProcessDescr)
module.Hint(
updateInProgress,
"Checking for Updates",
"The Portmaster is currently checking for and downloading any available updates.",
)
defer func() {
if err == nil {
module.Resolve(updateInProgress)
} else {
module.Warning(updateFailed, "Failed to update: "+err.Error())
notifications.NotifyWarn(
updateFailed,
"Update Check Failed",
"The Portmaster failed to check for updates. This might be a temporary issue of your device, your network or the update servers. The Portmaster will automatically try again later.",
notifications.Action{
ID: "retry",
Text: "Try Again",
Type: notifications.ActionTypeWebhook,
Payload: &notifications.ActionTypeWebhookPayload{
URL: apiPathCheckForUpdates,
ResultAction: "display",
},
},
).AttachToModule(module)
}
}()

View file

@ -109,10 +109,10 @@ func upgradeCoreNotify() error {
),
Category: "Core",
Message: fmt.Sprintf(
`:tada: Update to **Portmaster v%s** is available!
Please restart the Portmaster to apply the update.`,
`A new Portmaster version is available! Restart the Portmaster to upgrade to %s.`,
pmCoreUpdate.Version(),
),
ShowOnSystem: true,
AvailableActions: []*notifications.Action{
{
ID: "restart",
@ -257,13 +257,10 @@ func warnOnIncorrectParentPath() {
root := filepath.Dir(registry.StorageDir().Path)
if !strings.HasPrefix(absPath, root) {
log.Warningf("detected unexpected path %s for portmaster-start", absPath)
notifications.Notify(&notifications.Notification{
EventID: "updates:unsupported-parent",
Type: notifications.Warning,
Title: "Unsupported Launcher",
Category: "Core",
Message: fmt.Sprintf(
notifications.NotifyWarn(
"updates:unsupported-parent",
"Unsupported Launcher",
fmt.Sprintf(
"The portmaster has been launched by an unexpected %s binary at %s. Please configure your system to use the binary at %s as this version will be kept up to date automatically.",
expectedFileName,
absPath,