diff --git a/internal/home/home.go b/internal/home/home.go index f457c269..320fb9e1 100644 --- a/internal/home/home.go +++ b/internal/home/home.go @@ -12,7 +12,6 @@ import ( "net/url" "os" "os/signal" - "path" "path/filepath" "runtime" "slices" @@ -495,11 +494,40 @@ func checkPorts() (err error) { return nil } +// isUpdateEnabled returns true if the update is enabled for current +// configuration. It also logs the decision. customURL should be true if the +// updater is using a custom URL. +func isUpdateEnabled(ctx context.Context, l *slog.Logger, opts *options, customURL bool) (ok bool) { + switch ch := version.Channel(); { + case opts.disableUpdate: + l.DebugContext(ctx, "updates are disabled by command-line option") + + return false + case + ch == version.ChannelDevelopment, + ch == version.ChannelCandidate: + if customURL { + l.DebugContext(ctx, "updates are enabled due to custom URL is used") + } else { + l.DebugContext(ctx, "updates are disabled for development and candidate builds") + } + + return customURL + default: + l.DebugContext(ctx, "updates are enabled") + + return true + } +} + +// initWeb initializes the web module. func initWeb( + ctx context.Context, opts options, clientBuildFS fs.FS, upd *updater.Updater, l *slog.Logger, + customURL bool, ) (web *webAPI, err error) { var clientFS fs.FS if opts.localFrontend { @@ -513,17 +541,7 @@ func initWeb( } } - disableUpdate := opts.disableUpdate - switch version.Channel() { - case - version.ChannelDevelopment, - version.ChannelCandidate: - disableUpdate = true - } - - if disableUpdate { - log.Info("AdGuard Home updates are disabled") - } + disableUpdate := !isUpdateEnabled(ctx, l, &opts, customURL) webConf := &webConfig{ updater: upd, @@ -544,7 +562,7 @@ func initWeb( web = newWebAPI(webConf, l) if web == nil { - return nil, fmt.Errorf("initializing web: %w", err) + return nil, errors.Error("can not initialize web") } return web, nil @@ -557,6 +575,8 @@ func fatalOnError(err error) { } // run configures and starts AdGuard Home. +// +// TODO(e.burkov): Make opts a pointer. func run(opts options, clientBuildFS fs.FS, done chan struct{}) { // Configure working dir. err := initWorkingDir(opts) @@ -606,7 +626,7 @@ func run(opts options, clientBuildFS fs.FS, done chan struct{}) { confPath := configFilePath() - upd := newUpdater(ctx, slogLogger, Context.workDir, confPath, execPath, config) + upd, customURL := newUpdater(ctx, slogLogger, Context.workDir, confPath, execPath, config) // TODO(e.burkov): This could be made earlier, probably as the option's // effect. @@ -638,7 +658,7 @@ func run(opts options, clientBuildFS fs.FS, done chan struct{}) { onConfigModified() } - Context.web, err = initWeb(opts, clientBuildFS, upd, slogLogger) + Context.web, err = initWeb(ctx, opts, clientBuildFS, upd, slogLogger, customURL) fatalOnError(err) statsDir, querylogDir, err := checkStatsAndQuerylogDirs(&Context, config) @@ -676,7 +696,8 @@ func run(opts options, clientBuildFS fs.FS, done chan struct{}) { <-done } -// newUpdater creates a new AdGuard Home updater. +// newUpdater creates a new AdGuard Home updater. customURL is true if the user +// has specified a custom version announcement URL. func newUpdater( ctx context.Context, l *slog.Logger, @@ -684,7 +705,7 @@ func newUpdater( confPath string, execPath string, config *configuration, -) (upd *updater.Updater) { +) (upd *updater.Updater, customURL bool) { // envName is the name of the environment variable that can be used to // override the default version check URL. const envName = "ADGUARD_HOME_TEST_UPDATE_VERSION_URL" @@ -693,15 +714,16 @@ func newUpdater( var versionURL *url.URL switch { - case + case version.Channel() == version.ChannelRelease: // Only enable custom update URL for development builds. - version.Channel() == version.ChannelRelease, - !config.UnsafeCustomUpdateIndexURL: + l.DebugContext(ctx, "custom update URL is disabled for release builds") + case !config.UnsafeCustomUpdateIndexURL: // Go on and use the default URL. + l.DebugContext(ctx, "custom update URL is disabled", "env", customURLStr) case customURLStr != "": var err error versionURL, err = url.Parse(customURLStr) - if err != nil { + if customURL = err == nil; !customURL { l.ErrorContext( ctx, "invalid environment variable value", @@ -714,11 +736,7 @@ func newUpdater( } if versionURL == nil { - versionURL = &url.URL{ - Scheme: urlutil.SchemeHTTPS, - Host: "static.adtidy.org", - Path: path.Join("adguardhome", version.Channel(), "version.json"), - } + versionURL = updater.DefaultVersionURL() } l.DebugContext(ctx, "creating updater", "config_path", confPath) @@ -735,7 +753,7 @@ func newUpdater( ConfName: confPath, ExecPath: execPath, VersionCheckURL: versionURL, - }) + }), customURL } // checkPermissions checks and migrates permissions of the files and directories diff --git a/internal/home/web.go b/internal/home/web.go index 099f9aeb..1909720b 100644 --- a/internal/home/web.go +++ b/internal/home/web.go @@ -101,6 +101,8 @@ type webAPI struct { // newWebAPI creates a new instance of the web UI and API server. l must not be // nil. +// +// TODO(a.garipov): Return a proper error. func newWebAPI(conf *webConfig, l *slog.Logger) (w *webAPI) { log.Info("web: initializing") diff --git a/internal/updater/updater.go b/internal/updater/updater.go index 704ba990..fe1e7727 100644 --- a/internal/updater/updater.go +++ b/internal/updater/updater.go @@ -12,6 +12,7 @@ import ( "net/url" "os" "os/exec" + "path" "path/filepath" "strings" "sync" @@ -22,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. @@ -62,11 +64,21 @@ 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. + // VersionCheckURL is URL to the latest version announcement. It must not + // be nil, see [DefaultVersionURL]. VersionCheckURL *url.URL Version string @@ -87,7 +99,7 @@ type Config struct { ExecPath 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,