WIP
This commit is contained in:
176
service/core/update_versions.go
Normal file
176
service/core/update_versions.go
Normal file
@@ -0,0 +1,176 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"sync"
|
||||
"text/tabwriter"
|
||||
|
||||
"github.com/safing/portmaster/base/database/record"
|
||||
"github.com/safing/portmaster/base/info"
|
||||
"github.com/safing/portmaster/base/utils/debug"
|
||||
"github.com/safing/portmaster/service/mgr"
|
||||
"github.com/safing/portmaster/service/updates"
|
||||
)
|
||||
|
||||
const (
|
||||
// versionsDBKey is the database key for update version information.
|
||||
versionsDBKey = "core:status/versions"
|
||||
|
||||
// versionsDBKey is the database key for simple update version information.
|
||||
simpleVersionsDBKey = "core:status/simple-versions"
|
||||
)
|
||||
|
||||
// Versions holds update versions and status information.
|
||||
type Versions struct {
|
||||
record.Base
|
||||
sync.Mutex
|
||||
|
||||
Core *info.Info
|
||||
Resources map[string]*updates.Artifact
|
||||
Channel string
|
||||
Beta bool
|
||||
Staging bool
|
||||
}
|
||||
|
||||
// SimpleVersions holds simplified update versions and status information.
|
||||
type SimpleVersions struct {
|
||||
record.Base
|
||||
sync.Mutex
|
||||
|
||||
Build *info.Info
|
||||
Resources map[string]*SimplifiedResourceVersion
|
||||
Channel string
|
||||
}
|
||||
|
||||
// SimplifiedResourceVersion holds version information about one resource.
|
||||
type SimplifiedResourceVersion struct {
|
||||
Version string
|
||||
}
|
||||
|
||||
// GetVersions returns the update versions and status information.
|
||||
// Resources must be locked when accessed.
|
||||
func GetVersions() *Versions {
|
||||
// Get all artifacts.
|
||||
resources := make(map[string]*updates.Artifact)
|
||||
if artifacts, err := module.instance.BinaryUpdates().GetFiles(); err == nil {
|
||||
for _, artifact := range artifacts {
|
||||
resources[artifact.Filename] = artifact
|
||||
}
|
||||
}
|
||||
if artifacts, err := module.instance.IntelUpdates().GetFiles(); err == nil {
|
||||
for _, artifact := range artifacts {
|
||||
resources[artifact.Filename] = artifact
|
||||
}
|
||||
}
|
||||
|
||||
return &Versions{
|
||||
Core: info.GetInfo(),
|
||||
Resources: resources,
|
||||
Channel: initialReleaseChannel,
|
||||
Beta: initialReleaseChannel == ReleaseChannelBeta,
|
||||
Staging: initialReleaseChannel == ReleaseChannelStaging,
|
||||
}
|
||||
}
|
||||
|
||||
// GetSimpleVersions returns the simplified update versions and status information.
|
||||
func GetSimpleVersions() *SimpleVersions {
|
||||
// Get all artifacts, simply map.
|
||||
resources := make(map[string]*SimplifiedResourceVersion)
|
||||
if artifacts, err := module.instance.BinaryUpdates().GetFiles(); err == nil {
|
||||
for _, artifact := range artifacts {
|
||||
resources[artifact.Filename] = &SimplifiedResourceVersion{
|
||||
Version: artifact.Version,
|
||||
}
|
||||
}
|
||||
}
|
||||
if artifacts, err := module.instance.IntelUpdates().GetFiles(); err == nil {
|
||||
for _, artifact := range artifacts {
|
||||
resources[artifact.Filename] = &SimplifiedResourceVersion{
|
||||
Version: artifact.Version,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fill base info.
|
||||
return &SimpleVersions{
|
||||
Build: info.GetInfo(),
|
||||
Resources: resources,
|
||||
Channel: initialReleaseChannel,
|
||||
}
|
||||
}
|
||||
|
||||
func initVersionExport() {
|
||||
module.instance.BinaryUpdates().EventResourcesUpdated.AddCallback("export version status", export)
|
||||
module.instance.IntelUpdates().EventResourcesUpdated.AddCallback("export version status", export)
|
||||
|
||||
_, _ = export(nil, struct{}{})
|
||||
}
|
||||
|
||||
func (v *Versions) save() error {
|
||||
if !v.KeyIsSet() {
|
||||
v.SetKey(versionsDBKey)
|
||||
}
|
||||
return db.Put(v)
|
||||
}
|
||||
|
||||
func (v *SimpleVersions) save() error {
|
||||
if !v.KeyIsSet() {
|
||||
v.SetKey(simpleVersionsDBKey)
|
||||
}
|
||||
return db.Put(v)
|
||||
}
|
||||
|
||||
// export is an event hook.
|
||||
func export(_ *mgr.WorkerCtx, _ struct{}) (cancel bool, err error) {
|
||||
// Export versions.
|
||||
if err := GetVersions().save(); err != nil {
|
||||
return false, err
|
||||
}
|
||||
if err := GetSimpleVersions().save(); err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// AddVersionsToDebugInfo adds the update system status to the given debug.Info.
|
||||
func AddVersionsToDebugInfo(di *debug.Info) {
|
||||
overviewBuf := bytes.NewBuffer(nil)
|
||||
tableBuf := bytes.NewBuffer(nil)
|
||||
tabWriter := tabwriter.NewWriter(tableBuf, 8, 4, 3, ' ', 0)
|
||||
fmt.Fprint(tabWriter, "\nFile\tVersion\tIndex\tSHA256\n")
|
||||
|
||||
// Collect data for debug info.
|
||||
var cnt int
|
||||
if index, err := module.instance.BinaryUpdates().GetIndex(); err == nil {
|
||||
fmt.Fprintf(overviewBuf, "Binaries Index: v%s from %s\n", index.Version, index.Published)
|
||||
for _, artifact := range index.Artifacts {
|
||||
fmt.Fprintf(tabWriter, "\n%s\t%s\t%s\t%s", artifact.Filename, vStr(artifact.Version), "binaries", artifact.SHA256)
|
||||
cnt++
|
||||
}
|
||||
}
|
||||
if index, err := module.instance.IntelUpdates().GetIndex(); err == nil {
|
||||
fmt.Fprintf(overviewBuf, "Intel Index: v%s from %s\n", index.Version, index.Published)
|
||||
for _, artifact := range index.Artifacts {
|
||||
fmt.Fprintf(tabWriter, "\n%s\t%s\t%s\t%s", artifact.Filename, vStr(artifact.Version), "intel", artifact.SHA256)
|
||||
cnt++
|
||||
}
|
||||
}
|
||||
_ = tabWriter.Flush()
|
||||
|
||||
// Add section.
|
||||
di.AddSection(
|
||||
fmt.Sprintf("Updates: %s (%d)", initialReleaseChannel, cnt),
|
||||
debug.UseCodeSection,
|
||||
overviewBuf.String(),
|
||||
tableBuf.String(),
|
||||
)
|
||||
}
|
||||
|
||||
func vStr(v string) string {
|
||||
if v != "" {
|
||||
return v
|
||||
}
|
||||
return "unknown"
|
||||
}
|
||||
Reference in New Issue
Block a user