safing-portmaster/service/updates/helper/indexes.go
2024-03-27 16:17:58 +01:00

136 lines
3.6 KiB
Go

package helper
import (
"errors"
"fmt"
"io/fs"
"os"
"path/filepath"
"github.com/safing/jess/filesig"
"github.com/safing/portbase/updater"
)
// Release Channel Configuration Keys.
const (
ReleaseChannelKey = "core/releaseChannel"
ReleaseChannelJSONKey = "core.releaseChannel"
)
// Release Channels.
const (
ReleaseChannelStable = "stable"
ReleaseChannelBeta = "beta"
ReleaseChannelStaging = "staging"
ReleaseChannelSupport = "support"
)
const jsonSuffix = ".json"
// SetIndexes sets the update registry indexes and also configures the registry
// to use pre-releases based on the channel.
func SetIndexes(
registry *updater.ResourceRegistry,
releaseChannel string,
deleteUnusedIndexes bool,
autoDownload bool,
autoDownloadIntel bool,
) (warning error) {
usePreReleases := false
// Be reminded that the order is important, as indexes added later will
// override the current release from earlier indexes.
// Reset indexes before adding them (again).
registry.ResetIndexes()
// Add the intel index first, in order to be able to override it with the
// other indexes when needed.
registry.AddIndex(updater.Index{
Path: "all/intel/intel.json",
AutoDownload: autoDownloadIntel,
})
// Always add the stable index as a base.
registry.AddIndex(updater.Index{
Path: ReleaseChannelStable + jsonSuffix,
AutoDownload: autoDownload,
})
// Add beta index if in beta or staging channel.
indexPath := ReleaseChannelBeta + jsonSuffix
if releaseChannel == ReleaseChannelBeta ||
releaseChannel == ReleaseChannelStaging ||
(releaseChannel == "" && indexExists(registry, indexPath)) {
registry.AddIndex(updater.Index{
Path: indexPath,
PreRelease: true,
AutoDownload: autoDownload,
})
usePreReleases = true
} else if deleteUnusedIndexes {
err := deleteIndex(registry, indexPath)
if err != nil {
warning = fmt.Errorf("failed to delete unused index %s: %w", indexPath, err)
}
}
// Add staging index if in staging channel.
indexPath = ReleaseChannelStaging + jsonSuffix
if releaseChannel == ReleaseChannelStaging ||
(releaseChannel == "" && indexExists(registry, indexPath)) {
registry.AddIndex(updater.Index{
Path: indexPath,
PreRelease: true,
AutoDownload: autoDownload,
})
usePreReleases = true
} else if deleteUnusedIndexes {
err := deleteIndex(registry, indexPath)
if err != nil {
warning = fmt.Errorf("failed to delete unused index %s: %w", indexPath, err)
}
}
// Add support index if in support channel.
indexPath = ReleaseChannelSupport + jsonSuffix
if releaseChannel == ReleaseChannelSupport ||
(releaseChannel == "" && indexExists(registry, indexPath)) {
registry.AddIndex(updater.Index{
Path: indexPath,
AutoDownload: autoDownload,
})
usePreReleases = true
} else if deleteUnusedIndexes {
err := deleteIndex(registry, indexPath)
if err != nil {
warning = fmt.Errorf("failed to delete unused index %s: %w", indexPath, err)
}
}
// Set pre-release usage.
registry.SetUsePreReleases(usePreReleases)
return warning
}
func indexExists(registry *updater.ResourceRegistry, indexPath string) bool {
_, err := os.Stat(filepath.Join(registry.StorageDir().Path, indexPath))
return err == nil
}
func deleteIndex(registry *updater.ResourceRegistry, indexPath string) error {
// Remove index itself.
err := os.Remove(filepath.Join(registry.StorageDir().Path, indexPath))
if err != nil && !errors.Is(err, fs.ErrNotExist) {
return err
}
// Remove any accompanying signature.
err = os.Remove(filepath.Join(registry.StorageDir().Path, indexPath+filesig.Extension))
if err != nil && !errors.Is(err, fs.ErrNotExist) {
return err
}
return nil
}