mirror of
https://github.com/safing/portmaster
synced 2025-09-01 18:19:12 +00:00
[WIP] Add fallback on corrupted install
This commit is contained in:
parent
a1a4bf6325
commit
02791a4d42
2 changed files with 53 additions and 6 deletions
|
@ -13,9 +13,10 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
updateTaskRepeatDuration = 1 * time.Hour
|
updateTaskRepeatDuration = 1 * time.Hour
|
||||||
updateAvailableNotificationID = "updates:update-available"
|
updateAvailableNotificationID = "updates:update-available"
|
||||||
updateFailedNotificationID = "updates:update-failed"
|
updateFailedNotificationID = "updates:update-failed"
|
||||||
|
corruptInstallationNotificationID = "updates:corrupt-installation"
|
||||||
|
|
||||||
// ResourceUpdateEvent is emitted every time the
|
// ResourceUpdateEvent is emitted every time the
|
||||||
// updater successfully performed a resource update.
|
// updater successfully performed a resource update.
|
||||||
|
@ -59,6 +60,8 @@ type Updates struct {
|
||||||
autoApply bool
|
autoApply bool
|
||||||
needsRestart bool
|
needsRestart bool
|
||||||
|
|
||||||
|
corruptedInstallation bool
|
||||||
|
|
||||||
isUpdateRunning *abool.AtomicBool
|
isUpdateRunning *abool.AtomicBool
|
||||||
|
|
||||||
instance instance
|
instance instance
|
||||||
|
@ -96,7 +99,14 @@ func New(instance instance, name string, index UpdateIndex) (*Updates, error) {
|
||||||
var err error
|
var err error
|
||||||
module.registry, err = CreateRegistry(index)
|
module.registry, err = CreateRegistry(index)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to create registry: %w", err)
|
// Installation is corrupt, set flag and fall back to folder scanning for artifacts discovery.
|
||||||
|
log.Criticalf("updates: failed to create registry: %s (falling back to folder scanning)", err)
|
||||||
|
module.corruptedInstallation = true
|
||||||
|
|
||||||
|
module.registry, err = CreateRegistryFromFolder(index)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.downloader = CreateDownloader(index)
|
module.downloader = CreateDownloader(index)
|
||||||
|
@ -194,14 +204,16 @@ func (u *Updates) applyUpdates(downloader Downloader, force bool) error {
|
||||||
currentBundle := u.registry.bundle
|
currentBundle := u.registry.bundle
|
||||||
downloadBundle := downloader.bundle
|
downloadBundle := downloader.bundle
|
||||||
|
|
||||||
if !force {
|
if !force && u.registry.version != nil {
|
||||||
if u.downloader.version.LessThanOrEqual(u.registry.version) {
|
if u.downloader.version.LessThanOrEqual(u.registry.version) {
|
||||||
// No new version, silently return.
|
// No new version, silently return.
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if currentBundle != nil {
|
||||||
|
log.Infof("update: starting update: %s %s -> %s", currentBundle.Name, currentBundle.Version, downloadBundle.Version)
|
||||||
|
}
|
||||||
|
|
||||||
log.Infof("update: starting update: %s %s -> %s", currentBundle.Name, currentBundle.Version, downloadBundle.Version)
|
|
||||||
err := u.registry.performRecoverableUpgrade(downloader.dir, downloader.indexFile)
|
err := u.registry.performRecoverableUpgrade(downloader.dir, downloader.indexFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Notify the user that update failed.
|
// Notify the user that update failed.
|
||||||
|
@ -247,6 +259,11 @@ func (u *Updates) Start() error {
|
||||||
_ = u.downloader.deleteUnfinishedDownloads()
|
_ = u.downloader.deleteUnfinishedDownloads()
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if u.corruptedInstallation {
|
||||||
|
notifications.NotifyError(corruptInstallationNotificationID, "Corrupted installation. Reinstall the software.", "")
|
||||||
|
}
|
||||||
|
|
||||||
u.updateCheckWorkerMgr.Go()
|
u.updateCheckWorkerMgr.Go()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
semver "github.com/hashicorp/go-version"
|
semver "github.com/hashicorp/go-version"
|
||||||
|
|
||||||
|
@ -54,6 +55,35 @@ func CreateRegistry(index UpdateIndex) (Registry, error) {
|
||||||
return registry, nil
|
return registry, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func CreateRegistryFromFolder(index UpdateIndex) (Registry, error) {
|
||||||
|
registry := Registry{
|
||||||
|
dir: index.Directory,
|
||||||
|
purgeDir: index.PurgeDirectory,
|
||||||
|
files: make(map[string]File),
|
||||||
|
}
|
||||||
|
|
||||||
|
files, err := os.ReadDir(index.Directory)
|
||||||
|
if err != nil {
|
||||||
|
return Registry{}, nil
|
||||||
|
}
|
||||||
|
for _, file := range files {
|
||||||
|
// Skip dirs
|
||||||
|
if file.IsDir() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip the uninstaller. (Windows)
|
||||||
|
if strings.Contains(strings.ToLower(file.Name()), "uninstall") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
artifactPath := filepath.Join(registry.dir, file.Name())
|
||||||
|
registry.files[file.Name()] = File{id: file.Name(), path: artifactPath, version: "", sha256: ""}
|
||||||
|
}
|
||||||
|
|
||||||
|
return registry, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (r *Registry) performUpgrade(downloadDir string, indexFile string) error {
|
func (r *Registry) performUpgrade(downloadDir string, indexFile string) error {
|
||||||
// Make sure provided update is valid
|
// Make sure provided update is valid
|
||||||
indexFilepath := filepath.Join(downloadDir, indexFile)
|
indexFilepath := filepath.Join(downloadDir, indexFile)
|
||||||
|
|
Loading…
Add table
Reference in a new issue