cherry-pick: all: imp updater

Merge in DNS/adguard-home from imp-updater to master

Squashed commit of the following:

commit 6ed487359e56a35b36f13dcbf2efbf2a7a2d8734
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Thu Jun 9 16:29:35 2022 +0300

    all: imp logs, err handling

commit e930044cb619a43e5a44c230dadbe2228e9a93f5
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Thu Jun 9 15:53:35 2022 +0300

    all: imp updater
This commit is contained in:
Ainar Garipov
2022-06-09 17:47:05 +03:00
committed by Ainar Garipov
parent b3f2e88e9c
commit 7b9cfa94f8
9 changed files with 123 additions and 124 deletions

View File

@@ -5,9 +5,9 @@ import (
"fmt"
"io"
"net/http"
"strings"
"time"
"github.com/AdguardTeam/AdGuardHome/internal/aghalg"
"github.com/AdguardTeam/AdGuardHome/internal/aghio"
"github.com/AdguardTeam/golibs/errors"
)
@@ -17,11 +17,12 @@ const versionCheckPeriod = 8 * time.Hour
// VersionInfo contains information about a new version.
type VersionInfo struct {
CanAutoUpdate *bool `json:"can_autoupdate,omitempty"`
NewVersion string `json:"new_version,omitempty"`
Announcement string `json:"announcement,omitempty"`
AnnouncementURL string `json:"announcement_url,omitempty"`
SelfUpdateMinVersion string `json:"-"`
NewVersion string `json:"new_version,omitempty"`
Announcement string `json:"announcement,omitempty"`
AnnouncementURL string `json:"announcement_url,omitempty"`
// TODO(a.garipov): See if the frontend actually still cares about
// nullability.
CanAutoUpdate aghalg.NullBool `json:"can_autoupdate,omitempty"`
}
// MaxResponseSize is responses on server's requests maximum length in bytes.
@@ -67,15 +68,13 @@ func (u *Updater) VersionInfo(forceRecheck bool) (vi VersionInfo, err error) {
}
func (u *Updater) parseVersionResponse(data []byte) (VersionInfo, error) {
var canAutoUpdate bool
info := VersionInfo{
CanAutoUpdate: &canAutoUpdate,
CanAutoUpdate: aghalg.NBFalse,
}
versionJSON := map[string]string{
"version": "",
"announcement": "",
"announcement_url": "",
"selfupdate_min_version": "",
"version": "",
"announcement": "",
"announcement_url": "",
}
err := json.Unmarshal(data, &versionJSON)
if err != nil {
@@ -91,14 +90,9 @@ func (u *Updater) parseVersionResponse(data []byte) (VersionInfo, error) {
info.NewVersion = versionJSON["version"]
info.Announcement = versionJSON["announcement"]
info.AnnouncementURL = versionJSON["announcement_url"]
info.SelfUpdateMinVersion = versionJSON["selfupdate_min_version"]
packageURL, ok := u.downloadURL(versionJSON)
if ok &&
info.NewVersion != u.version &&
strings.TrimPrefix(u.version, "v") >= strings.TrimPrefix(info.SelfUpdateMinVersion, "v") {
canAutoUpdate = true
}
info.CanAutoUpdate = aghalg.BoolToNullBool(ok && info.NewVersion != u.version)
u.newVersion = info.NewVersion
u.packageURL = packageURL

View File

@@ -104,11 +104,14 @@ func NewUpdater(conf *Config) *Updater {
}
// Update performs the auto-update.
func (u *Updater) Update() error {
func (u *Updater) Update() (err error) {
u.mu.Lock()
defer u.mu.Unlock()
err := u.prepare()
log.Info("updater: updating")
defer func() { log.Info("updater: finished; errors: %v", err) }()
err = u.prepare()
if err != nil {
return err
}
@@ -178,7 +181,12 @@ func (u *Updater) prepare() (err error) {
u.backupExeName = filepath.Join(u.backupDir, exeName)
u.updateExeName = filepath.Join(u.updateDir, exeName)
log.Info("Updating from %s to %s. URL:%s", version.Version(), u.newVersion, u.packageURL)
log.Debug(
"updater: updating from %s to %s using url: %s",
version.Version(),
u.newVersion,
u.packageURL,
)
// TODO(a.garipov): Use os.Args[0] instead?
u.currentExeName = filepath.Join(u.workDir, exeName)
@@ -194,7 +202,7 @@ func (u *Updater) unpack() error {
var err error
_, pkgNameOnly := filepath.Split(u.packageURL)
log.Debug("updater: unpacking the package")
log.Debug("updater: unpacking package")
if strings.HasSuffix(pkgNameOnly, ".zip") {
u.unpackedFiles, err = zipFileUnpack(u.packageName, u.updateDir)
if err != nil {
@@ -229,7 +237,7 @@ func (u *Updater) check() error {
}
func (u *Updater) backup() error {
log.Debug("updater: backing up the current configuration")
log.Debug("updater: backing up current configuration")
_ = os.Mkdir(u.backupDir, 0o755)
err := copyFile(u.confName, filepath.Join(u.backupDir, "AdGuardHome.yaml"))
if err != nil {
@@ -252,7 +260,7 @@ func (u *Updater) replace() error {
return fmt.Errorf("copySupportingFiles(%s, %s) failed: %s", u.updateDir, u.workDir, err)
}
log.Debug("updater: renaming: %s -> %s", u.currentExeName, u.backupExeName)
log.Debug("updater: renaming: %s to %s", u.currentExeName, u.backupExeName)
err = os.Rename(u.currentExeName, u.backupExeName)
if err != nil {
return err
@@ -268,7 +276,7 @@ func (u *Updater) replace() error {
return err
}
log.Debug("updater: renamed: %s -> %s", u.updateExeName, u.currentExeName)
log.Debug("updater: renamed: %s to %s", u.updateExeName, u.currentExeName)
return nil
}
@@ -297,7 +305,7 @@ func (u *Updater) downloadPackageFile(url, filename string) (err error) {
return fmt.Errorf("http request failed: %w", err)
}
log.Debug("updater: reading HTTP body")
log.Debug("updater: reading http body")
// This use of ReadAll is now safe, because we limited body's Reader.
body, err := io.ReadAll(r)
if err != nil {
@@ -343,7 +351,7 @@ func tarGzFileUnpackOne(outDir string, tr *tar.Reader, hdr *tar.Header) (name st
}
if hdr.Typeflag != tar.TypeReg {
log.Debug("updater: %s: unknown file type %d, skipping", name, hdr.Typeflag)
log.Info("updater: %s: unknown file type %d, skipping", name, hdr.Typeflag)
return "", nil
}
@@ -364,7 +372,7 @@ func tarGzFileUnpackOne(outDir string, tr *tar.Reader, hdr *tar.Header) (name st
return "", fmt.Errorf("io.Copy(): %w", err)
}
log.Tracef("updater: created file %s", outputName)
log.Debug("updater: created file %q", outputName)
return name, nil
}
@@ -440,7 +448,7 @@ func zipFileUnpackOne(outDir string, zf *zip.File) (name string, err error) {
return "", fmt.Errorf("os.Mkdir(%q): %w", outputName, err)
}
log.Tracef("created directory %q", outputName)
log.Debug("updater: created directory %q", outputName)
return "", nil
}
@@ -457,7 +465,7 @@ func zipFileUnpackOne(outDir string, zf *zip.File) (name string, err error) {
return "", fmt.Errorf("io.Copy(): %w", err)
}
log.Tracef("created file %s", outputName)
log.Debug("updater: created file %q", outputName)
return name, nil
}
@@ -516,7 +524,7 @@ func copySupportingFiles(files []string, srcdir, dstdir string) error {
return err
}
log.Debug("updater: copied: %q -> %q", src, dst)
log.Debug("updater: copied: %q to %q", src, dst)
}
return nil

View File

@@ -10,6 +10,7 @@ import (
"strconv"
"testing"
"github.com/AdguardTeam/AdGuardHome/internal/aghalg"
"github.com/AdguardTeam/AdGuardHome/internal/aghtest"
"github.com/AdguardTeam/AdGuardHome/internal/version"
"github.com/AdguardTeam/golibs/testutil"
@@ -92,10 +93,7 @@ func TestUpdateGetVersion(t *testing.T) {
assert.Equal(t, "v0.103.0-beta.2", info.NewVersion)
assert.Equal(t, "AdGuard Home v0.103.0-beta.2 is now available!", info.Announcement)
assert.Equal(t, "https://github.com/AdguardTeam/AdGuardHome/internal/releases", info.AnnouncementURL)
assert.Equal(t, "v0.0", info.SelfUpdateMinVersion)
if assert.NotNil(t, info.CanAutoUpdate) {
assert.True(t, *info.CanAutoUpdate)
}
assert.Equal(t, aghalg.NBTrue, info.CanAutoUpdate)
// check cached
_, err = u.VersionInfo(false)
@@ -290,10 +288,7 @@ func TestUpdater_VersionInto_ARM(t *testing.T) {
assert.Equal(t, "v0.103.0-beta.2", info.NewVersion)
assert.Equal(t, "AdGuard Home v0.103.0-beta.2 is now available!", info.Announcement)
assert.Equal(t, "https://github.com/AdguardTeam/AdGuardHome/internal/releases", info.AnnouncementURL)
assert.Equal(t, "v0.0", info.SelfUpdateMinVersion)
if assert.NotNil(t, info.CanAutoUpdate) {
assert.True(t, *info.CanAutoUpdate)
}
assert.Equal(t, aghalg.NBTrue, info.CanAutoUpdate)
}
func TestUpdater_VersionInto_MIPS(t *testing.T) {
@@ -330,8 +325,5 @@ func TestUpdater_VersionInto_MIPS(t *testing.T) {
assert.Equal(t, "v0.103.0-beta.2", info.NewVersion)
assert.Equal(t, "AdGuard Home v0.103.0-beta.2 is now available!", info.Announcement)
assert.Equal(t, "https://github.com/AdguardTeam/AdGuardHome/internal/releases", info.AnnouncementURL)
assert.Equal(t, "v0.0", info.SelfUpdateMinVersion)
if assert.NotNil(t, info.CanAutoUpdate) {
assert.True(t, *info.CanAutoUpdate)
}
assert.Equal(t, aghalg.NBTrue, info.CanAutoUpdate)
}