Pull request 2307: AGDNS-2556 Custom updater URL

Squashed commit of the following:

commit 73f946138ccb4f89141f192b6cb1a21887604ab4
Merge: c58847bfb d578c713f
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Tue Nov 26 17:42:29 2024 +0300

    Merge branch 'master' into AGDNS-2556-custom-update-url

commit c58847bfb08131263e1cff4813eb4a466f613d91
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Tue Nov 26 17:34:11 2024 +0300

    home: imp logging

commit 0d451621d76fdf2c363d223eb29c4442d8f36dc8
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Tue Nov 26 15:12:04 2024 +0300

    home: rename config field

commit c7f3822929e9199f8f411f1a0ad072c643feb42f
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Tue Nov 26 15:07:09 2024 +0300

    all: enable updater for some cases

commit 872cd3a18c876076ea643624336cfc0a4296a81d
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Fri Nov 22 19:09:18 2024 +0300

    updater: imp test

commit c9efb412e7411b769df54b7247fe168047fb9799
Merge: c989eef71 abb738013
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Fri Nov 22 17:51:46 2024 +0300

    Merge branch 'master' into AGDNS-2556-custom-update-url

commit c989eef715ae7edd98d7b2d5df06fd3d04153209
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Fri Nov 22 17:46:34 2024 +0300

    all: imp code

commit 0452d8b356e6d0b73b097d43b97b7027fcca752d
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Fri Nov 22 15:37:21 2024 +0300

    all: add custom url to updater
This commit is contained in:
Eugene Burkov
2024-11-26 20:35:16 +03:00
parent d578c713ff
commit 4a49c4db96
9 changed files with 183 additions and 102 deletions

View File

@@ -13,6 +13,7 @@ import (
"github.com/AdguardTeam/golibs/errors"
"github.com/AdguardTeam/golibs/ioutil"
"github.com/AdguardTeam/golibs/log"
"github.com/c2h5oh/datasize"
)
// TODO(a.garipov): Make configurable.
@@ -28,8 +29,9 @@ type VersionInfo struct {
CanAutoUpdate aghalg.NullBool `json:"can_autoupdate,omitempty"`
}
// MaxResponseSize is responses on server's requests maximum length in bytes.
const MaxResponseSize = 64 * 1024
// maxVersionRespSize is the maximum length in bytes for version information
// response.
const maxVersionRespSize datasize.ByteSize = 64 * datasize.KB
// VersionInfo downloads the latest version information. If forceRecheck is
// false and there are cached results, those results are returned.
@@ -51,7 +53,7 @@ func (u *Updater) VersionInfo(forceRecheck bool) (vi VersionInfo, err error) {
}
defer func() { err = errors.WithDeferred(err, resp.Body.Close()) }()
r := ioutil.LimitReader(resp.Body, MaxResponseSize)
r := ioutil.LimitReader(resp.Body, maxVersionRespSize.Bytes())
// This use of ReadAll is safe, because we just limited the appropriate
// ReadCloser.

View File

@@ -51,9 +51,11 @@ func TestUpdater_VersionInfo(t *testing.T) {
}))
t.Cleanup(srv.Close)
fakeURL, err := url.JoinPath(srv.URL, "adguardhome", version.ChannelBeta, "version.json")
srvURL, err := url.Parse(srv.URL)
require.NoError(t, err)
fakeURL := srvURL.JoinPath("adguardhome", version.ChannelBeta, "version.json")
u := updater.NewUpdater(&updater.Config{
Client: srv.Client(),
Version: "v0.103.0-beta.1",
@@ -134,7 +136,7 @@ func TestUpdater_VersionInfo_others(t *testing.T) {
GOARCH: tc.arch,
GOARM: tc.arm,
GOMIPS: tc.mips,
VersionCheckURL: fakeURL.String(),
VersionCheckURL: fakeURL,
})
info, err := u.VersionInfo(false)

View File

@@ -9,8 +9,10 @@ import (
"io"
"io/fs"
"net/http"
"net/url"
"os"
"os/exec"
"path"
"path/filepath"
"strings"
"sync"
@@ -21,6 +23,7 @@ import (
"github.com/AdguardTeam/golibs/errors"
"github.com/AdguardTeam/golibs/ioutil"
"github.com/AdguardTeam/golibs/log"
"github.com/AdguardTeam/golibs/netutil/urlutil"
)
// Updater is the AdGuard Home updater.
@@ -61,10 +64,23 @@ type Updater struct {
prevCheckResult VersionInfo
}
// DefaultVersionURL returns the default URL for the version announcement.
func DefaultVersionURL() *url.URL {
return &url.URL{
Scheme: urlutil.SchemeHTTPS,
Host: "static.adtidy.org",
Path: path.Join("adguardhome", version.Channel(), "version.json"),
}
}
// Config is the AdGuard Home updater configuration.
type Config struct {
Client *http.Client
// VersionCheckURL is URL to the latest version announcement. It must not
// be nil, see [DefaultVersionURL].
VersionCheckURL *url.URL
Version string
Channel string
GOARCH string
@@ -81,12 +97,9 @@ type Config struct {
// ExecPath is path to the executable file.
ExecPath string
// VersionCheckURL is url to the latest version announcement.
VersionCheckURL string
}
// NewUpdater creates a new Updater.
// NewUpdater creates a new Updater. conf must not be nil.
func NewUpdater(conf *Config) *Updater {
return &Updater{
client: conf.Client,
@@ -101,7 +114,7 @@ func NewUpdater(conf *Config) *Updater {
confName: conf.ConfName,
workDir: conf.WorkDir,
execPath: conf.ExecPath,
versionCheckURL: conf.VersionCheckURL,
versionCheckURL: conf.VersionCheckURL.String(),
mu: &sync.RWMutex{},
}
@@ -167,14 +180,6 @@ func (u *Updater) NewVersion() (nv string) {
return u.newVersion
}
// VersionCheckURL returns the version check URL.
func (u *Updater) VersionCheckURL() (vcu string) {
u.mu.RLock()
defer u.mu.RUnlock()
return u.versionCheckURL
}
// prepare fills all necessary fields in Updater object.
func (u *Updater) prepare() (err error) {
u.updateDir = filepath.Join(u.workDir, fmt.Sprintf("agh-update-%s", u.newVersion))

View File

@@ -1,6 +1,7 @@
package updater
import (
"net/url"
"os"
"path/filepath"
"testing"
@@ -45,7 +46,7 @@ func TestUpdater_internal(t *testing.T) {
for _, tc := range testCases {
exePath := filepath.Join(wd, tc.exeName)
// start server for returning package file
// Start server for returning package file.
pkgData, err := os.ReadFile(filepath.Join("testdata", tc.archiveName))
require.NoError(t, err)
@@ -59,6 +60,9 @@ func TestUpdater_internal(t *testing.T) {
ExecPath: exePath,
WorkDir: wd,
ConfName: yamlPath,
// TODO(e.burkov): Rewrite the test to use a fake version check
// URL with a fake URLs for the package files.
VersionCheckURL: &url.URL{},
})
u.newVersion = "v0.103.1"
@@ -72,36 +76,40 @@ func TestUpdater_internal(t *testing.T) {
u.clean()
// check backup files
d, err := os.ReadFile(filepath.Join(wd, "agh-backup", "AdGuardHome.yaml"))
require.NoError(t, err)
require.True(t, t.Run("backup", func(t *testing.T) {
var d []byte
d, err = os.ReadFile(filepath.Join(wd, "agh-backup", "AdGuardHome.yaml"))
require.NoError(t, err)
assert.Equal(t, "AdGuardHome.yaml", string(d))
assert.Equal(t, "AdGuardHome.yaml", string(d))
d, err = os.ReadFile(filepath.Join(wd, "agh-backup", tc.exeName))
require.NoError(t, err)
d, err = os.ReadFile(filepath.Join(wd, "agh-backup", tc.exeName))
require.NoError(t, err)
assert.Equal(t, tc.exeName, string(d))
assert.Equal(t, tc.exeName, string(d))
}))
// check updated files
d, err = os.ReadFile(exePath)
require.NoError(t, err)
require.True(t, t.Run("updated", func(t *testing.T) {
var d []byte
d, err = os.ReadFile(exePath)
require.NoError(t, err)
assert.Equal(t, "1", string(d))
assert.Equal(t, "1", string(d))
d, err = os.ReadFile(readmePath)
require.NoError(t, err)
d, err = os.ReadFile(readmePath)
require.NoError(t, err)
assert.Equal(t, "2", string(d))
assert.Equal(t, "2", string(d))
d, err = os.ReadFile(licensePath)
require.NoError(t, err)
d, err = os.ReadFile(licensePath)
require.NoError(t, err)
assert.Equal(t, "3", string(d))
assert.Equal(t, "3", string(d))
d, err = os.ReadFile(yamlPath)
require.NoError(t, err)
d, err = os.ReadFile(yamlPath)
require.NoError(t, err)
assert.Equal(t, "AdGuardHome.yaml", string(d))
assert.Equal(t, "AdGuardHome.yaml", string(d))
}))
}
}

View File

@@ -65,7 +65,10 @@ func TestUpdater_Update(t *testing.T) {
srv := httptest.NewServer(mux)
t.Cleanup(srv.Close)
versionCheckURL, err := url.JoinPath(srv.URL, versionPath)
srvURL, err := url.Parse(srv.URL)
require.NoError(t, err)
versionCheckURL := srvURL.JoinPath(versionPath)
require.NoError(t, err)
u := updater.NewUpdater(&updater.Config{