Establish beta and staging release channels, move indexes to helper

This commit is contained in:
Daniel
2021-06-03 23:28:41 +02:00
parent 8a46e78c0f
commit 642e2eb112
7 changed files with 161 additions and 120 deletions

View File

@@ -4,6 +4,7 @@ import (
"context"
"github.com/safing/portbase/notifications"
"github.com/safing/portmaster/updates/helper"
"github.com/tevino/abool"
"github.com/safing/portbase/config"
@@ -20,6 +21,7 @@ var (
devMode config.BoolOption
enableUpdates config.BoolOption
initialReleaseChannel string
previousReleaseChannel string
updatesCurrentlyEnabled bool
previousDevMode bool
@@ -29,21 +31,28 @@ var (
func registerConfig() error {
err := config.Register(&config.Option{
Name: "Release Channel",
Key: releaseChannelKey,
Key: helper.ReleaseChannelKey,
Description: "Switch release channel.",
OptType: config.OptTypeString,
ExpertiseLevel: config.ExpertiseLevelDeveloper,
ReleaseLevel: config.ReleaseLevelExperimental,
RequiresRestart: false,
DefaultValue: releaseChannelStable,
RequiresRestart: true,
DefaultValue: helper.ReleaseChannelStable,
PossibleValues: []config.PossibleValue{
{
Name: "Stable",
Value: releaseChannelStable,
Name: "Stable",
Description: "Production releases.",
Value: helper.ReleaseChannelStable,
},
{
Name: "Beta",
Value: releaseChannelBeta,
Name: "Beta",
Description: "Production releases for testing new features that may break and cause interruption.",
Value: helper.ReleaseChannelBeta,
},
{
Name: "Staging",
Description: "Development releases for testing random things and experimenting. Dangerous - only use when told so.",
Value: helper.ReleaseChannelStaging,
},
},
Annotations: config.Annotations{
@@ -78,7 +87,8 @@ func registerConfig() error {
}
func initConfig() {
releaseChannel = config.GetAsString(releaseChannelKey, releaseChannelStable)
releaseChannel = config.GetAsString(helper.ReleaseChannelKey, helper.ReleaseChannelStable)
initialReleaseChannel = releaseChannel()
previousReleaseChannel = releaseChannel()
enableUpdates = config.GetAsBool(enableUpdatesKey, true)
@@ -107,7 +117,7 @@ func updateRegistryConfig(_ context.Context, _ interface{}) error {
changed := false
if releaseChannel() != previousReleaseChannel {
registry.SetBeta(releaseChannel() == releaseChannelBeta)
registry.SetUsePreReleases(releaseChannel() != helper.ReleaseChannelStable)
previousReleaseChannel = releaseChannel()
changed = true
}

View File

@@ -11,14 +11,14 @@ import (
"github.com/safing/portbase/info"
"github.com/safing/portbase/log"
"github.com/safing/portbase/updater"
"github.com/safing/portmaster/updates/helper"
)
// database key for update information
// Database key for update information.
const (
versionsDBKey = "core:status/versions"
)
// working vars
var (
versionExport *versions
versionExportDB = database.NewInterface(&database.Options{
@@ -35,6 +35,7 @@ type versions struct {
Core *info.Info
Resources map[string]*updater.Resource
Channel string
Beta bool
Staging bool
@@ -45,8 +46,9 @@ func initVersionExport() (err error) {
// init export struct
versionExport = &versions{
internalSave: true,
Beta: registry.Beta,
Staging: staging,
Channel: initialReleaseChannel,
Beta: initialReleaseChannel == helper.ReleaseChannelBeta,
Staging: initialReleaseChannel == helper.ReleaseChannelStaging,
}
versionExport.SetKey(versionsDBKey)
@@ -68,7 +70,7 @@ func stopVersionExport() error {
return versionExportHook.Cancel()
}
// export is an event hook
// export is an event hook.
func export(_ context.Context, _ interface{}) error {
// populate
versionExport.lock.Lock()

View File

@@ -1,7 +1,6 @@
package helper
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
@@ -54,14 +53,6 @@ func EnsureChromeSandboxPermissions(reg *updater.ResourceRegistry) error {
return nil
}
// PlatformIdentifier converts identifier for the current platform.
func PlatformIdentifier(identifier string) string {
// From https://golang.org/pkg/runtime/#GOARCH
// GOOS is the running program's operating system target: one of darwin, freebsd, linux, and so on.
// GOARCH is the running program's architecture target: one of 386, amd64, arm, s390x, and so on.
return fmt.Sprintf("%s_%s/%s", runtime.GOOS, runtime.GOARCH, identifier)
}
func checkSysctl(setting string, value byte) bool {
c, err := sysctl(setting)
if err != nil {

50
updates/helper/indexes.go Normal file
View File

@@ -0,0 +1,50 @@
package helper
import (
"github.com/safing/portbase/updater"
)
const (
ReleaseChannelKey = "core/releaseChannel"
ReleaseChannelJSONKey = "core.releaseChannel"
ReleaseChannelStable = "stable"
ReleaseChannelBeta = "beta"
ReleaseChannelStaging = "staging"
)
func SetIndexes(registry *updater.ResourceRegistry, releaseChannel string) {
// 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()
// Always add the stable index as a base.
registry.AddIndex(updater.Index{
Path: "stable.json",
})
// Add beta index if in beta or staging channel.
if releaseChannel == ReleaseChannelBeta ||
releaseChannel == ReleaseChannelStaging {
registry.AddIndex(updater.Index{
Path: "beta.json",
PreRelease: true,
})
}
// Add staging index if in staging channel.
if releaseChannel == ReleaseChannelStaging {
registry.AddIndex(updater.Index{
Path: "staging.json",
PreRelease: true,
})
}
// Add the intel index last, as it updates the fastest and should not be
// crippled by other faulty indexes. It can only specify versions for its
// scope anyway.
registry.AddIndex(updater.Index{
Path: "all/intel/intel.json",
})
}

68
updates/helper/updates.go Normal file
View File

@@ -0,0 +1,68 @@
package helper
import (
"fmt"
"runtime"
)
const (
onWindows = runtime.GOOS == "windows"
)
// PlatformIdentifier converts identifier for the current platform.
func PlatformIdentifier(identifier string) string {
// From https://golang.org/pkg/runtime/#GOARCH
// GOOS is the running program's operating system target: one of darwin, freebsd, linux, and so on.
// GOARCH is the running program's architecture target: one of 386, amd64, arm, s390x, and so on.
return fmt.Sprintf("%s_%s/%s", runtime.GOOS, runtime.GOARCH, identifier)
}
// MandatoryUpdates returns mandatory updates that should be loaded on install
// or reset.
func MandatoryUpdates() (identifiers []string) {
// Binaries
if onWindows {
identifiers = []string{
PlatformIdentifier("core/portmaster-core.exe"),
PlatformIdentifier("kext/portmaster-kext.dll"),
PlatformIdentifier("kext/portmaster-kext.sys"),
PlatformIdentifier("start/portmaster-start.exe"),
PlatformIdentifier("notifier/portmaster-notifier.exe"),
PlatformIdentifier("notifier/portmaster-snoretoast.exe"),
}
} else {
identifiers = []string{
PlatformIdentifier("core/portmaster-core"),
PlatformIdentifier("start/portmaster-start"),
PlatformIdentifier("notifier/portmaster-notifier"),
}
}
// Components, Assets and Data
identifiers = append(
identifiers,
// User interface components
PlatformIdentifier("app/portmaster-app.zip"),
"all/ui/modules/portmaster.zip",
"all/ui/modules/assets.zip",
// Filter lists data
"all/intel/lists/base.dsdl",
"all/intel/lists/intermediate.dsdl",
"all/intel/lists/urgent.dsdl",
// Geo IP data
"all/intel/geoip/geoipv4.mmdb.gz",
"all/intel/geoip/geoipv6.mmdb.gz",
)
return identifiers
}
// AutoUnpackUpdates returns assets that need unpacking.
func AutoUnpackUpdates() []string {
return []string{
PlatformIdentifier("app/portmaster-app.zip"),
}
}

View File

@@ -4,11 +4,11 @@ import (
"context"
"flag"
"fmt"
"os"
"path/filepath"
"runtime"
"time"
"github.com/safing/portmaster/updates/helper"
"github.com/safing/portbase/dataroot"
"github.com/safing/portbase/log"
"github.com/safing/portbase/modules"
@@ -19,10 +19,6 @@ import (
const (
onWindows = runtime.GOOS == "windows"
releaseChannelKey = "core/releaseChannel"
releaseChannelStable = "stable"
releaseChannelBeta = "beta"
enableUpdatesKey = "core/automaticUpdates"
// ModuleName is the name of the update module
@@ -48,16 +44,11 @@ var (
module *modules.Module
registry *updater.ResourceRegistry
userAgentFromFlag string
staging bool
updateTask *modules.Task
updateASAP bool
disableTaskSchedule bool
// MandatoryUpdates is a list of full identifiers that
// should always be kept up to date.
MandatoryUpdates []string
// UserAgent is an HTTP User-Agent that is used to add
// more context to requests made by the registry when
// fetching resources from the update server.
@@ -65,9 +56,8 @@ var (
)
const (
updateInProgress = "updates:in-progress"
updateFailed = "updates:failed"
updateSuccess = "updates:success"
updateFailed = "updates:failed"
updateSuccess = "updates:success"
)
func init() {
@@ -76,29 +66,9 @@ func init() {
module.RegisterEvent(ResourceUpdateEvent, true)
flag.StringVar(&userAgentFromFlag, "update-agent", "", "set the user agent for requests to the update server")
flag.BoolVar(&staging, "staging", false, "use staging update channel; for testing only")
// initialize mandatory updates
if onWindows {
MandatoryUpdates = []string{
platform("core/portmaster-core.exe"),
platform("start/portmaster-start.exe"),
platform("notifier/portmaster-notifier.exe"),
platform("notifier/portmaster-snoretoast.exe"),
}
} else {
MandatoryUpdates = []string{
platform("core/portmaster-core"),
platform("start/portmaster-start"),
platform("notifier/portmaster-notifier"),
}
}
MandatoryUpdates = append(
MandatoryUpdates,
platform("app/portmaster-app.zip"),
"all/ui/modules/portmaster.zip",
)
var dummy bool
flag.BoolVar(&dummy, "staging", false, "deprecated, configure in settings instead")
}
func prep() error {
@@ -107,8 +77,6 @@ func prep() error {
}
return registerAPIEndpoints()
return nil
}
func start() error {
@@ -131,13 +99,11 @@ func start() error {
"https://updates.safing.io",
},
UserAgent: UserAgent,
MandatoryUpdates: MandatoryUpdates,
AutoUnpack: []string{
platform("app/portmaster-app.zip"),
},
Beta: releaseChannel() == releaseChannelBeta,
DevMode: devMode(),
Online: true,
MandatoryUpdates: helper.MandatoryUpdates(),
AutoUnpack: helper.AutoUnpackUpdates(),
UsePreReleases: initialReleaseChannel != helper.ReleaseChannelStable,
DevMode: devMode(),
Online: true,
}
if userAgentFromFlag != "" {
// override with flag value
@@ -149,38 +115,8 @@ func start() error {
return err
}
registry.AddIndex(updater.Index{
Path: "stable.json",
Stable: true,
Beta: false,
})
if registry.Beta {
registry.AddIndex(updater.Index{
Path: "beta.json",
Stable: false,
Beta: true,
})
}
registry.AddIndex(updater.Index{
Path: "all/intel/intel.json",
Stable: true,
Beta: true,
})
if stagingActive() {
// Set flag no matter how staging was activated.
staging = true
log.Warning("updates: staging environment is active")
registry.AddIndex(updater.Index{
Path: "staging.json",
Stable: true,
Beta: true,
})
}
// Set indexes based on the release channel.
helper.SetIndexes(registry, initialReleaseChannel)
err = registry.LoadIndexes(module.Ctx)
if err != nil {
@@ -342,21 +278,6 @@ func stop() error {
return stopVersionExport()
}
func platform(identifier string) string {
return fmt.Sprintf("%s_%s/%s", runtime.GOOS, runtime.GOARCH, identifier)
}
func stagingActive() bool {
// Check flag and env variable.
if staging || os.Getenv("PORTMASTER_STAGING") == "enabled" {
return true
}
// Check if staging index is present and acessible.
_, err := os.Stat(filepath.Join(registry.StorageDir().Path, "staging.json"))
return err == nil
}
// RootPath returns the root path used for storing updates.
func RootPath() string {
if !module.Online() {

View File

@@ -351,10 +351,9 @@ func upgradeFile(fileToUpgrade string, file *updater.File) error {
}
// CopyFile atomically copies a file using the update registry's tmp dir.
func CopyFile(srcPath, dstPath string) (err error) {
func CopyFile(srcPath, dstPath string) error {
// check tmp dir
err = registry.TmpDir().Ensure()
err := registry.TmpDir().Ensure()
if err != nil {
return fmt.Errorf("could not prepare tmp directory for copying file: %w", err)
}
@@ -369,14 +368,14 @@ func CopyFile(srcPath, dstPath string) (err error) {
// open source
srcFile, err := os.Open(srcPath)
if err != nil {
return
return err
}
defer srcFile.Close()
// copy data
_, err = io.Copy(atomicDstFile, srcFile)
if err != nil {
return
return err
}
// finalize file