WIP
This commit is contained in:
@@ -10,6 +10,8 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// FIXME: version does not show in portmaster
|
||||||
|
|
||||||
var (
|
var (
|
||||||
name string
|
name string
|
||||||
license string
|
license string
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import (
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
// flag.BoolVar(&updates.RebootOnRestart, "reboot-on-restart", false, "reboot server on auto-upgrade")
|
// flag.BoolVar(&updates.RebootOnRestart, "reboot-on-restart", false, "reboot server on auto-upgrade")
|
||||||
|
// FIXME
|
||||||
}
|
}
|
||||||
|
|
||||||
var sigUSR1 = syscall.Signal(0xa)
|
var sigUSR1 = syscall.Signal(0xa)
|
||||||
@@ -48,6 +49,8 @@ func main() {
|
|||||||
log.SetLogLevel(log.WarningLevel)
|
log.SetLogLevel(log.WarningLevel)
|
||||||
_ = log.Start()
|
_ = log.Start()
|
||||||
|
|
||||||
|
// FIXME: Use service?
|
||||||
|
|
||||||
// Create instance.
|
// Create instance.
|
||||||
var execCmdLine bool
|
var execCmdLine bool
|
||||||
instance, err := spn.New()
|
instance, err := spn.New()
|
||||||
@@ -109,7 +112,7 @@ func main() {
|
|||||||
slog.Warn("program was interrupted, stopping")
|
slog.Warn("program was interrupted, stopping")
|
||||||
}
|
}
|
||||||
|
|
||||||
case <-instance.Stopped():
|
case <-instance.ShutdownComplete():
|
||||||
log.Shutdown()
|
log.Shutdown()
|
||||||
os.Exit(instance.ExitCode())
|
os.Exit(instance.ExitCode())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,6 +78,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
instance.AddModule(observer)
|
instance.AddModule(observer)
|
||||||
|
|
||||||
|
// FIXME: Use service?
|
||||||
|
|
||||||
// Execute command line operation, if requested or available.
|
// Execute command line operation, if requested or available.
|
||||||
switch {
|
switch {
|
||||||
case !execCmdLine:
|
case !execCmdLine:
|
||||||
@@ -126,7 +128,7 @@ func main() {
|
|||||||
slog.Warn("program was interrupted, stopping")
|
slog.Warn("program was interrupted, stopping")
|
||||||
}
|
}
|
||||||
|
|
||||||
case <-instance.Stopped():
|
case <-instance.ShuttingDown():
|
||||||
log.Shutdown()
|
log.Shutdown()
|
||||||
os.Exit(instance.ExitCode())
|
os.Exit(instance.ExitCode())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ func initializeGlobals(cmd *cobra.Command, args []string) {
|
|||||||
svcCfg = &service.ServiceConfig{
|
svcCfg = &service.ServiceConfig{
|
||||||
BinDir: binDir,
|
BinDir: binDir,
|
||||||
DataDir: dataDir,
|
DataDir: dataDir,
|
||||||
BinariesIndexURLs: service.DefaultBinaryIndexURLs,
|
BinariesIndexURLs: service.DefaultStableBinaryIndexURLs,
|
||||||
IntelIndexURLs: service.DefaultIntelIndexURLs,
|
IntelIndexURLs: service.DefaultIntelIndexURLs,
|
||||||
VerifyBinaryUpdates: service.BinarySigningTrustStore,
|
VerifyBinaryUpdates: service.BinarySigningTrustStore,
|
||||||
VerifyIntelUpdates: service.BinarySigningTrustStore,
|
VerifyIntelUpdates: service.BinarySigningTrustStore,
|
||||||
|
|||||||
@@ -60,7 +60,8 @@ func (sc *ServiceConfig) Init() error {
|
|||||||
|
|
||||||
// Apply defaults for required fields.
|
// Apply defaults for required fields.
|
||||||
if len(sc.BinariesIndexURLs) == 0 {
|
if len(sc.BinariesIndexURLs) == 0 {
|
||||||
sc.BinariesIndexURLs = DefaultBinaryIndexURLs
|
// FIXME: Select based on setting.
|
||||||
|
sc.BinariesIndexURLs = DefaultStableBinaryIndexURLs
|
||||||
}
|
}
|
||||||
if len(sc.IntelIndexURLs) == 0 {
|
if len(sc.IntelIndexURLs) == 0 {
|
||||||
sc.IntelIndexURLs = DefaultIntelIndexURLs
|
sc.IntelIndexURLs = DefaultIntelIndexURLs
|
||||||
|
|||||||
@@ -256,7 +256,7 @@ func loadProcess(ctx context.Context, key string, pInfo *processInfo.Process) (*
|
|||||||
// Username
|
// Username
|
||||||
process.UserName, err = pInfo.UsernameWithContext(ctx)
|
process.UserName, err = pInfo.UsernameWithContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("process: failed to get Username for p%d: %w", pInfo.Pid, err)
|
log.Tracer(ctx).Warningf("process: failed to get username (PID %d): %s", pInfo.Pid, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: User Home
|
// TODO: User Home
|
||||||
|
|||||||
@@ -9,9 +9,19 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
DefaultBinaryIndexURLs = []string{
|
DefaultStableBinaryIndexURLs = []string{
|
||||||
"https://updates.safing.io/stable.v3.json",
|
"https://updates.safing.io/stable.v3.json",
|
||||||
}
|
}
|
||||||
|
DefaultBetaBinaryIndexURLs = []string{
|
||||||
|
"https://updates.safing.io/beta.v3.json",
|
||||||
|
}
|
||||||
|
DefaultStagingBinaryIndexURLs = []string{
|
||||||
|
"https://updates.safing.io/staging.v3.json",
|
||||||
|
}
|
||||||
|
DefaultSupportBinaryIndexURLs = []string{
|
||||||
|
"https://updates.safing.io/support.v3.json",
|
||||||
|
}
|
||||||
|
|
||||||
DefaultIntelIndexURLs = []string{
|
DefaultIntelIndexURLs = []string{
|
||||||
"https://updates.safing.io/intel.v3.json",
|
"https://updates.safing.io/intel.v3.json",
|
||||||
}
|
}
|
||||||
@@ -53,6 +63,7 @@ func MakeUpdateConfigs(svcCfg *ServiceConfig) (binaryUpdateConfig, intelUpdateCo
|
|||||||
IndexURLs: svcCfg.BinariesIndexURLs,
|
IndexURLs: svcCfg.BinariesIndexURLs,
|
||||||
IndexFile: "index.json",
|
IndexFile: "index.json",
|
||||||
Verify: svcCfg.VerifyBinaryUpdates,
|
Verify: svcCfg.VerifyBinaryUpdates,
|
||||||
|
AutoCheck: true, // FIXME: Get from setting.
|
||||||
AutoDownload: false,
|
AutoDownload: false,
|
||||||
AutoApply: false,
|
AutoApply: false,
|
||||||
NeedsRestart: true,
|
NeedsRestart: true,
|
||||||
@@ -66,6 +77,7 @@ func MakeUpdateConfigs(svcCfg *ServiceConfig) (binaryUpdateConfig, intelUpdateCo
|
|||||||
IndexURLs: svcCfg.IntelIndexURLs,
|
IndexURLs: svcCfg.IntelIndexURLs,
|
||||||
IndexFile: "index.json",
|
IndexFile: "index.json",
|
||||||
Verify: svcCfg.VerifyIntelUpdates,
|
Verify: svcCfg.VerifyIntelUpdates,
|
||||||
|
AutoCheck: true, // FIXME: Get from setting.
|
||||||
AutoDownload: true,
|
AutoDownload: true,
|
||||||
AutoApply: true,
|
AutoApply: true,
|
||||||
NeedsRestart: false,
|
NeedsRestart: false,
|
||||||
@@ -82,6 +94,7 @@ func MakeUpdateConfigs(svcCfg *ServiceConfig) (binaryUpdateConfig, intelUpdateCo
|
|||||||
IndexURLs: svcCfg.BinariesIndexURLs,
|
IndexURLs: svcCfg.BinariesIndexURLs,
|
||||||
IndexFile: "index.json",
|
IndexFile: "index.json",
|
||||||
Verify: svcCfg.VerifyBinaryUpdates,
|
Verify: svcCfg.VerifyBinaryUpdates,
|
||||||
|
AutoCheck: true, // FIXME: Get from setting.
|
||||||
AutoDownload: false,
|
AutoDownload: false,
|
||||||
AutoApply: false,
|
AutoApply: false,
|
||||||
NeedsRestart: true,
|
NeedsRestart: true,
|
||||||
@@ -95,6 +108,7 @@ func MakeUpdateConfigs(svcCfg *ServiceConfig) (binaryUpdateConfig, intelUpdateCo
|
|||||||
IndexURLs: svcCfg.IntelIndexURLs,
|
IndexURLs: svcCfg.IntelIndexURLs,
|
||||||
IndexFile: "index.json",
|
IndexFile: "index.json",
|
||||||
Verify: svcCfg.VerifyIntelUpdates,
|
Verify: svcCfg.VerifyIntelUpdates,
|
||||||
|
AutoCheck: true, // FIXME: Get from setting.
|
||||||
AutoDownload: true,
|
AutoDownload: true,
|
||||||
AutoApply: true,
|
AutoApply: true,
|
||||||
NeedsRestart: false,
|
NeedsRestart: false,
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ var (
|
|||||||
ErrNotFound = errors.New("file not found")
|
ErrNotFound = errors.New("file not found")
|
||||||
ErrSameIndex = errors.New("same index")
|
ErrSameIndex = errors.New("same index")
|
||||||
|
|
||||||
|
ErrAutoCheckDisabled = errors.New("automatic update checks are disabled")
|
||||||
ErrNoUpdateAvailable = errors.New("no update available")
|
ErrNoUpdateAvailable = errors.New("no update available")
|
||||||
ErrActionRequired = errors.New("action required")
|
ErrActionRequired = errors.New("action required")
|
||||||
)
|
)
|
||||||
@@ -67,6 +68,8 @@ type Config struct {
|
|||||||
// Verify enables and specifies the trust the index signatures will be checked against.
|
// Verify enables and specifies the trust the index signatures will be checked against.
|
||||||
Verify jess.TrustStore
|
Verify jess.TrustStore
|
||||||
|
|
||||||
|
// AutoCheck defines that new indexes may be downloaded automatically without outside trigger.
|
||||||
|
AutoCheck bool
|
||||||
// AutoDownload defines that updates may be downloaded automatically without outside trigger.
|
// AutoDownload defines that updates may be downloaded automatically without outside trigger.
|
||||||
AutoDownload bool
|
AutoDownload bool
|
||||||
// AutoApply defines that updates may be automatically applied without outside trigger.
|
// AutoApply defines that updates may be automatically applied without outside trigger.
|
||||||
@@ -157,8 +160,7 @@ func New(instance instance, name string, cfg Config) (*Updater, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create Workers.
|
// Create Workers.
|
||||||
module.updateCheckWorkerMgr = m.NewWorkerMgr("update checker", module.updateCheckWorker, nil).
|
module.updateCheckWorkerMgr = m.NewWorkerMgr("update checker", module.updateCheckWorker, nil)
|
||||||
Repeat(updateTaskRepeatDuration)
|
|
||||||
module.upgradeWorkerMgr = m.NewWorkerMgr("upgrader", module.upgradeWorker, nil)
|
module.upgradeWorkerMgr = m.NewWorkerMgr("upgrader", module.upgradeWorker, nil)
|
||||||
|
|
||||||
// Load index.
|
// Load index.
|
||||||
@@ -207,12 +209,13 @@ func (u *Updater) updateAndUpgrade(w *mgr.WorkerCtx, indexURLs []string, ignoreV
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get index to check version.
|
||||||
|
u.indexLock.Lock()
|
||||||
|
index := u.index
|
||||||
|
u.indexLock.Unlock()
|
||||||
|
|
||||||
// Check if there is a new version.
|
// Check if there is a new version.
|
||||||
if !ignoreVersion {
|
if !ignoreVersion && index != nil {
|
||||||
// Get index to check version.
|
|
||||||
u.indexLock.Lock()
|
|
||||||
index := u.index
|
|
||||||
u.indexLock.Unlock()
|
|
||||||
// Check with local pointer to index.
|
// Check with local pointer to index.
|
||||||
if err := index.ShouldUpgradeTo(downloader.index); err != nil {
|
if err := index.ShouldUpgradeTo(downloader.index); err != nil {
|
||||||
if errors.Is(err, ErrSameIndex) {
|
if errors.Is(err, ErrSameIndex) {
|
||||||
@@ -351,44 +354,31 @@ func (u *Updater) updateAndUpgrade(w *mgr.WorkerCtx, indexURLs []string, ignoreV
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Notify user that a restart is required.
|
// Notify user that a restart is required.
|
||||||
if u.cfg.Notify && u.instance.Notifications() != nil {
|
if u.cfg.Notify {
|
||||||
|
if u.instance.Notifications() != nil {
|
||||||
u.instance.Notifications().Notify(¬ifications.Notification{
|
u.instance.Notifications().Notify(¬ifications.Notification{
|
||||||
EventID: restartRequiredNotificationID,
|
EventID: restartRequiredNotificationID,
|
||||||
Type: notifications.Info,
|
Type: notifications.Info,
|
||||||
Title: "Restart Required",
|
Title: "Restart Required",
|
||||||
Message: "Portmaster v" + downloader.index.Version + " is installed. Restart to use new version.",
|
Message: "Portmaster v" + downloader.index.Version + " is installed. Restart to use new version.",
|
||||||
AvailableActions: []*notifications.Action{
|
AvailableActions: []*notifications.Action{
|
||||||
{
|
{
|
||||||
ID: "ack",
|
ID: "ack",
|
||||||
Text: "Later",
|
Text: "Later",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ID: "restart",
|
ID: "restart",
|
||||||
Text: "Restart Now",
|
Text: "Restart Now",
|
||||||
Type: notifications.ActionTypeWebhook,
|
Type: notifications.ActionTypeWebhook,
|
||||||
Payload: notifications.ActionTypeWebhookPayload{
|
Payload: notifications.ActionTypeWebhookPayload{
|
||||||
Method: "POST",
|
Method: "POST",
|
||||||
URL: "updates/apply",
|
URL: "updates/apply",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
})
|
||||||
})
|
}
|
||||||
|
|
||||||
u.instance.Notifications().NotifyInfo(
|
|
||||||
updateAvailableNotificationID,
|
|
||||||
"Restart Required",
|
|
||||||
"Portmaster v"+downloader.index.Version+" is installed. Restart to use new version.",
|
|
||||||
notifications.Action{
|
|
||||||
ID: "restart",
|
|
||||||
Text: "Restart Now",
|
|
||||||
Type: notifications.ActionTypeWebhook,
|
|
||||||
Payload: notifications.ActionTypeWebhookPayload{
|
|
||||||
Method: "POST",
|
|
||||||
URL: "core/restart",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
)
|
|
||||||
return fmt.Errorf("%w: restart required", ErrActionRequired)
|
return fmt.Errorf("%w: restart required", ErrActionRequired)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -470,6 +460,7 @@ func (u *Updater) Manager() *mgr.Manager {
|
|||||||
// Start starts the module.
|
// Start starts the module.
|
||||||
func (u *Updater) Start() error {
|
func (u *Updater) Start() error {
|
||||||
if u.corruptedInstallation && u.cfg.Notify && u.instance.Notifications() != nil {
|
if u.corruptedInstallation && u.cfg.Notify && u.instance.Notifications() != nil {
|
||||||
|
// FIXME: this might make sense as a module state
|
||||||
u.instance.Notifications().NotifyError(
|
u.instance.Notifications().NotifyError(
|
||||||
corruptInstallationNotificationID,
|
corruptInstallationNotificationID,
|
||||||
"Install Corruption",
|
"Install Corruption",
|
||||||
@@ -477,7 +468,12 @@ func (u *Updater) Start() error {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
u.updateCheckWorkerMgr.Delay(15 * time.Second)
|
// Check for updates automatically, if enabled.
|
||||||
|
if u.cfg.AutoCheck {
|
||||||
|
u.updateCheckWorkerMgr.
|
||||||
|
Repeat(updateTaskRepeatDuration).
|
||||||
|
Delay(15 * time.Second)
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ import (
|
|||||||
"github.com/safing/portmaster/base/log"
|
"github.com/safing/portmaster/base/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// FIXME: previous update system did in-place service file upgrades. Check if this is still necessary and if changes are in current installers.
|
||||||
|
|
||||||
const (
|
const (
|
||||||
defaultFileMode = os.FileMode(0o0644)
|
defaultFileMode = os.FileMode(0o0644)
|
||||||
executableFileMode = os.FileMode(0o0744)
|
executableFileMode = os.FileMode(0o0744)
|
||||||
@@ -25,7 +27,7 @@ func (u *Updater) upgrade(downloader *Downloader, ignoreVersion bool) error {
|
|||||||
defer u.indexLock.Unlock()
|
defer u.indexLock.Unlock()
|
||||||
|
|
||||||
// Check if we should upgrade at all.
|
// Check if we should upgrade at all.
|
||||||
if !ignoreVersion {
|
if !ignoreVersion && u.index != nil {
|
||||||
if err := u.index.ShouldUpgradeTo(downloader.index); err != nil {
|
if err := u.index.ShouldUpgradeTo(downloader.index); err != nil {
|
||||||
return fmt.Errorf("cannot upgrade: %w", ErrNoUpdateAvailable)
|
return fmt.Errorf("cannot upgrade: %w", ErrNoUpdateAvailable)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user