diff --git a/updater/fetch.go b/updater/fetch.go index 753d9090..6b306c05 100644 --- a/updater/fetch.go +++ b/updater/fetch.go @@ -145,7 +145,7 @@ func (reg *ResourceRegistry) fetchFile(ctx context.Context, client *http.Client, } } - log.Infof("%s: fetched %s (stored to %s)", reg.Name, downloadURL, rv.storagePath()) + log.Debugf("%s: fetched %s and stored to %s", reg.Name, downloadURL, rv.storagePath()) return nil } @@ -223,7 +223,7 @@ func (reg *ResourceRegistry) fetchMissingSig(ctx context.Context, client *http.C } } - log.Infof("%s: fetched %s (stored to %s)", reg.Name, rv.versionedSigPath(), rv.storageSigPath()) + log.Debugf("%s: fetched %s and stored to %s", reg.Name, rv.versionedSigPath(), rv.storageSigPath()) return nil } diff --git a/updater/registry.go b/updater/registry.go index 8e15eae1..b05d1ade 100644 --- a/updater/registry.go +++ b/updater/registry.go @@ -47,7 +47,7 @@ type ResourceRegistry struct { Online bool // StateNotifyFunc may be set to receive any changes to the registry state. - // The specified function may lock the state, but may not block are take a + // The specified function may lock the state, but may not block or take a // lot of time. StateNotifyFunc func(*RegistryState) } diff --git a/updater/state.go b/updater/state.go index 64059698..21bc6d1e 100644 --- a/updater/state.go +++ b/updater/state.go @@ -1,8 +1,11 @@ package updater import ( + "sort" "sync" "time" + + "github.com/safing/portbase/utils" ) // Registry States. @@ -120,6 +123,8 @@ func (s *RegistryState) EndOperation() { func (s *RegistryState) ReportUpdateCheck(pendingDownload []string, failed error) { defer s.notify() + sort.Strings(pendingDownload) + s.Lock() defer s.Unlock() @@ -137,6 +142,8 @@ func (s *RegistryState) ReportUpdateCheck(pendingDownload []string, failed error func (s *RegistryState) ReportDownloads(downloaded []string, failed error) { defer s.notify() + sort.Strings(downloaded) + s.Lock() defer s.Unlock() @@ -146,17 +153,15 @@ func (s *RegistryState) ReportDownloads(downloaded []string, failed error) { s.Updates.LastDownload = downloaded // Remove downloaded resources from the pending list. - var newPendingDownload []string -outer: - for _, pend := range s.Updates.PendingDownload { - for _, down := range downloaded { - if pend == down { - continue outer + if len(s.Updates.PendingDownload) > 0 { + newPendingDownload := make([]string, 0, len(s.Updates.PendingDownload)) + for _, pending := range s.Updates.PendingDownload { + if !utils.StringInSlice(downloaded, pending) { + newPendingDownload = append(newPendingDownload, pending) } } - newPendingDownload = append(newPendingDownload, pend) + s.Updates.PendingDownload = newPendingDownload } - s.Updates.PendingDownload = newPendingDownload if failed == nil { s.Updates.LastSuccessAt = &now diff --git a/updater/updating.go b/updater/updating.go index e2f6c131..0acca37e 100644 --- a/updater/updating.go +++ b/updater/updating.go @@ -9,6 +9,8 @@ import ( "path/filepath" "strings" + "golang.org/x/exp/slices" + "github.com/safing/jess/filesig" "github.com/safing/jess/lhash" "github.com/safing/portbase/log" @@ -205,11 +207,17 @@ func (reg *ResourceRegistry) DownloadUpdates(ctx context.Context, automaticOnly } // download updates - log.Infof("%s: starting to download %d updates", reg.Name, len(toUpdate)+len(missingSigs)) + log.Infof("%s: starting to download %d updates", reg.Name, len(toUpdate)) client := &http.Client{} var reportError error for i, rv := range toUpdate { + log.Infof( + "%s: downloading update [%d/%d]: %s version %s", + reg.Name, + i+1, len(toUpdate), + rv.resource.Identifier, rv.VersionNumber, + ) var err error for tries := 0; tries < 3; tries++ { err = reg.fetchFile(ctx, client, rv, tries) @@ -236,22 +244,26 @@ func (reg *ResourceRegistry) DownloadUpdates(ctx context.Context, automaticOnly }) } - for _, rv := range missingSigs { - var err error - for tries := 0; tries < 3; tries++ { - err = reg.fetchMissingSig(ctx, client, rv, tries) - if err == nil { - // Update resource version state. - rv.resource.Lock() - rv.SigAvailable = true - rv.resource.Unlock() + if len(missingSigs) > 0 { + log.Infof("%s: downloading %d missing signatures", reg.Name, len(missingSigs)) - break + for _, rv := range missingSigs { + var err error + for tries := 0; tries < 3; tries++ { + err = reg.fetchMissingSig(ctx, client, rv, tries) + if err == nil { + // Update resource version state. + rv.resource.Lock() + rv.SigAvailable = true + rv.resource.Unlock() + + break + } + } + if err != nil { + reportError := fmt.Errorf("failed to download missing sig of %s version %s: %w", rv.resource.Identifier, rv.VersionNumber, err) + log.Warningf("%s: %s", reg.Name, reportError) } - } - if err != nil { - reportError := fmt.Errorf("failed to download missing sig of %s version %s: %w", rv.resource.Identifier, rv.VersionNumber, err) - log.Warningf("%s: %s", reg.Name, reportError) } } @@ -326,6 +338,13 @@ func (reg *ResourceRegistry) GetPendingDownloads(manual, auto bool) (resources, }() } + slices.SortFunc[*ResourceVersion](toUpdate, func(a, b *ResourceVersion) bool { + return a.resource.Identifier < b.resource.Identifier + }) + slices.SortFunc[*ResourceVersion](missingSigs, func(a, b *ResourceVersion) bool { + return a.resource.Identifier < b.resource.Identifier + }) + return toUpdate, missingSigs }