Pull request 2738: AGDNS-4352-rm-global-context-web

Squashed commit of the following:

commit 281b1ceb1c231ad981eba23c457318c79417da72
Merge: 18b2dbf91 369d47616
Author: Maksim Kazantsev <m.kazantsev@adguard.com>
Date:   Wed Aug 5 14:10:55 2026 +0400

    Merge branch 'master' into AGDNS-4352-rm-global-context-web

commit 18b2dbf91fca5ec60f9c6bff7683eb6f22b8d14a
Author: Maksim Kazantsev <m.kazantsev@adguard.com>
Date:   Mon Aug 3 13:54:47 2026 +0300

    home: imp docs; imp code;

commit 5cb7cd485c7d40b0843720aed94b4c393b3ccfb0
Author: Maksim Kazantsev <m.kazantsev@adguard.com>
Date:   Mon Aug 3 13:05:32 2026 +0300

    home: imp code;

commit 9b06e321e0326a74ab257bc544f927ef32a2b432
Author: Maksim Kazantsev <m.kazantsev@adguard.com>
Date:   Fri Jul 31 19:06:09 2026 +0300

    home: imp docs;

commit 978b9a96b5f91ba70aa513e56f215f47f6b1c41e
Author: Maksim Kazantsev <m.kazantsev@adguard.com>
Date:   Fri Jul 31 18:58:23 2026 +0300

    home: imp code;

commit fc66f47f2ec0011aea9730e96e0021571ab3066a
Author: Maksim Kazantsev <m.kazantsev@adguard.com>
Date:   Fri Jul 31 18:08:16 2026 +0300

    home: remove web from homeContext;
This commit is contained in:
Maksim Kazantsev committed 2026-08-05 10:16:55 +00:00
1 parent 369d476163
commit e17bc9d8e5
9 files changed
+58 -32

No files matched your search

-3
View File
@@ -407,7 +407,6 @@ func TestAuth_ServeHTTP_firstRun(t *testing.T) {
isFirstRun: true,
})
globalContext.web = web
mw.set(web)
testCases := []struct {
@@ -560,7 +559,6 @@ func TestAuth_ServeHTTP_auth(t *testing.T) {
})
require.NoError(t, err)
globalContext.web = web
mw.set(web)
mux := auth.middleware().Wrap(baseMux)
@@ -722,7 +720,6 @@ func TestAuth_ServeHTTP_logout(t *testing.T) {
})
require.NoError(t, err)
globalContext.web = web
mw.set(web)
mux := auth.middleware().Wrap(baseMux)
+4 -2
View File
@@ -537,6 +537,7 @@ func (web *webAPI) finalizeInstall(
web.httpReg,
web.conf.workDir,
web.hostsContainer,
web.conf.mux,
)
if err != nil {
aghhttp.ErrorAndLog(ctx, l, r, w, http.StatusInternalServerError, "%s", err)
@@ -633,7 +634,7 @@ func decodeApplyConfigReq(r io.Reader) (req *applyConfigReq, restartHTTP bool, e
}
// startMods initializes and starts the DNS server after installation.
// baseLogger, tlsMgr, confModifier, and httpReg must not be nil.
// baseLogger, tlsMgr, confModifier, httpReg, and mux must not be nil.
func startMods(
ctx context.Context,
baseLogger *slog.Logger,
@@ -642,13 +643,14 @@ func startMods(
httpReg aghhttp.Registrar,
workDir string,
hc *aghnet.HostsContainer,
mux *http.ServeMux,
) (err error) {
statsDir, querylogDir, err := checkStatsAndQuerylogDirs(config, workDir)
if err != nil {
return err
}
err = initDNS(ctx, baseLogger, tlsMgr, confModifier, httpReg, statsDir, querylogDir, hc)
err = initDNS(ctx, baseLogger, tlsMgr, confModifier, httpReg, statsDir, querylogDir, hc, mux)
if err != nil {
return err
}
+8 -1
View File
@@ -223,6 +223,14 @@ func (web *webAPI) finishUpdate(
web.logger.InfoContext(ctx, "stopping all tasks")
// Ignore the error because, according to the documentation, this method
// always returns nil error.
err := web.Shutdown(ctx)
if err != nil {
// Should never happen.
web.logger.WarnContext(ctx, "shutting down web", slogutil.KeyError, err)
}
cleanup(ctx, web.logger, web.hostsContainer)
cleanupAlways(ctx, web.logger, web.pidFilePath)
@@ -232,7 +240,6 @@ func (web *webAPI) finishUpdate(
os.Exit(osutil.ExitCodeSuccess)
}
var err error
web.logger.InfoContext(ctx, "restarting", "exec_path", execPath, "args", os.Args[1:])
err = syscall.Exec(execPath, os.Args, os.Environ())
if err != nil {
+6 -9
View File
@@ -26,6 +26,7 @@ import (
"github.com/AdguardTeam/golibs/log"
"github.com/AdguardTeam/golibs/logutil/slogutil"
"github.com/AdguardTeam/golibs/netutil"
"github.com/AdguardTeam/golibs/netutil/httputil"
"github.com/AdguardTeam/golibs/netutil/urlutil"
yaml "go.yaml.in/yaml/v4"
)
@@ -42,7 +43,7 @@ const (
// initDNS updates all the fields of the [globalContext] needed to initialize
// the DNS server and initializes it at last. It also must not be called unless
// [config] and [globalContext] are initialized. baseLogger, tlsMgr,
// confModifier, and httpReg must not be nil.
// confModifier, httpReg, and mux must not be nil.
func initDNS(
ctx context.Context,
baseLogger *slog.Logger,
@@ -52,6 +53,7 @@ func initDNS(
statsDir string,
querylogDir string,
hc *aghnet.HostsContainer,
mux httputil.Router,
) (err error) {
anonymizer := config.anonymizer()
@@ -129,7 +131,9 @@ func initDNS(
return fmt.Errorf("creating dns server: %w", err)
}
registerDoHHandlers(config.HTTPConfig.DoH.Routes)
for _, route := range config.HTTPConfig.DoH.Routes {
mux.Handle(route, globalContext.dnsServer)
}
return nil
}
@@ -570,10 +574,3 @@ func checkDir(path string) (err error) {
return nil
}
// registerDoHHandlers registers DoH handlers on the given routes.
func registerDoHHandlers(routes []string) {
for _, route := range routes {
globalContext.web.conf.mux.Handle(route, globalContext.dnsServer)
}
}
+9 -10
View File
@@ -43,6 +43,7 @@ import (
"github.com/AdguardTeam/golibs/log"
"github.com/AdguardTeam/golibs/logutil/slogutil"
"github.com/AdguardTeam/golibs/netutil"
"github.com/AdguardTeam/golibs/netutil/httputil"
"github.com/AdguardTeam/golibs/netutil/urlutil"
"github.com/AdguardTeam/golibs/osutil"
"github.com/AdguardTeam/golibs/osutil/executil"
@@ -61,7 +62,6 @@ type homeContext struct {
dhcpServer dhcpd.Interface // DHCP module
filters *filtering.DNSFilter // DNS filtering module
web *webAPI // Web (HTTP, HTTPS) module
controlLock sync.Mutex
}
@@ -860,7 +860,7 @@ func run(
mw.set(web)
globalContext.web = web
sigHdlr.addWeb(web)
tlsMgr.setWebAPI(web)
@@ -868,7 +868,7 @@ func run(
fatalOnError(err)
if !isFirstRun {
runDNSServer(ctx, baseLogger, tlsMgr, confModifier, statsDir, querylogDir, httpReg, hc)
runDNSServer(ctx, baseLogger, tlsMgr, confModifier, statsDir, querylogDir, httpReg, hc, web.conf.mux)
}
if !opts.noPermCheck {
@@ -882,7 +882,8 @@ func run(
}
// runDNSServer initializes and starts DNS and DHCP servers if this is not the
// first run. httpReg, slogLogger, tlsMgr and confModifier must not be nil.
// first run. httpReg, slogLogger, tlsMgr, confModifier, and mux must not be
// nil.
func runDNSServer(
ctx context.Context,
slogLogger *slog.Logger,
@@ -892,8 +893,9 @@ func runDNSServer(
querylogDir string,
httpReg *aghhttp.DefaultRegistrar,
hc *aghnet.HostsContainer,
mux httputil.Router,
) {
err := initDNS(ctx, slogLogger, tlsMgr, confModifier, httpReg, statsDir, querylogDir, hc)
err := initDNS(ctx, slogLogger, tlsMgr, confModifier, httpReg, statsDir, querylogDir, hc, mux)
fatalOnError(err)
tlsMgr.start(ctx)
@@ -1231,14 +1233,11 @@ func initWorkingDir(opts options) (workDir string, err error) {
}
// cleanup stops and resets all the modules. l must not be nil.
//
// TODO(m.kazantsev): Consider making it a method of [signalHandler].
func cleanup(ctx context.Context, l *slog.Logger, hc *aghnet.HostsContainer) {
l.InfoContext(ctx, "stopping adguard home")
if globalContext.web != nil {
globalContext.web.close(ctx)
globalContext.web = nil
}
err := stopDNSServer(ctx)
if err != nil {
l.ErrorContext(ctx, "stopping dns server", slogutil.KeyError, err)
-3
View File
@@ -63,7 +63,6 @@ func newTestWeb(
// - [config]
// - [globalContext.clients.storage]
// - [globalContext.dnsServer]
// - [globalContext.web]
//
// TODO(s.chzhen): Remove this once the TLS manager no longer accesses global
// variables. Make tests that use this helper concurrent.
@@ -73,13 +72,11 @@ func storeGlobals(tb testing.TB) {
prevConfig := config
storage := globalContext.clients.storage
dnsServer := globalContext.dnsServer
web := globalContext.web
tb.Cleanup(func() {
config = prevConfig
globalContext.clients.storage = storage
globalContext.dnsServer = dnsServer
globalContext.web = web
})
}
@@ -77,8 +77,6 @@ func TestWeb_HandleGetProfile(t *testing.T) {
})
require.NoError(t, err)
globalContext.web = web
mux := auth.middleware().Wrap(baseMux)
require.True(t, t.Run("userless", func(t *testing.T) {
@@ -129,7 +127,6 @@ func TestWeb_HandlePutProfile(t *testing.T) {
httpReg: httpReg,
})
globalContext.web = web
mw.set(web)
var (
+19 -1
View File
@@ -23,7 +23,7 @@ type signalHandler struct {
// logger is used to log the operation of the signal handler.
logger *slog.Logger
// mu protects clientStorage and tlsManager.
// mu protects clientStorage, tlsManager, and web.
mu *sync.Mutex
// clientStorage is used to reload information about runtime clients with an
@@ -33,6 +33,9 @@ type signalHandler struct {
// tlsManager is used to reload the TLS configuration.
tlsManager aghtls.Manager
// web is the web API server.
web service.Shutdowner
// signals receives incoming signals.
signals <-chan os.Signal
@@ -71,6 +74,14 @@ func (h *signalHandler) addTLSManager(m aghtls.Manager) {
h.tlsManager = m
}
// addWeb stores the web API server.
func (h *signalHandler) addWeb(w *webAPI) {
h.mu.Lock()
defer h.mu.Unlock()
h.web = w
}
// handle processes incoming signals. It blocks until a signal is received. It
// reloads configurations of stored entities on SIGHUP, or performs cleanup on
// all other signals. It is intended to be used as a goroutine.
@@ -112,6 +123,13 @@ func (h *signalHandler) shutdown(ctx context.Context) {
}
}
if h.web != nil {
err := h.web.Shutdown(ctx)
if err != nil {
h.logger.ErrorContext(ctx, "shutting down web", slogutil.KeyError, err)
}
}
h.cleanup(ctx)
}
+12
View File
@@ -24,6 +24,7 @@ import (
"github.com/AdguardTeam/golibs/netutil/urlutil"
"github.com/AdguardTeam/golibs/osutil"
"github.com/AdguardTeam/golibs/osutil/executil"
"github.com/AdguardTeam/golibs/service"
"github.com/NYTimes/gziphandler"
"github.com/quic-go/quic-go/http3"
)
@@ -874,3 +875,14 @@ func (web *webAPI) reconfigureDNSServer(
return nil
}
// type check
var _ service.Shutdowner = (*webAPI)(nil)
// Shutdown implements the [service.Shutdowner] interface. It gracefully shuts
// down the web API server. It always returns nil error.
func (web *webAPI) Shutdown(ctx context.Context) (err error) {
web.close(ctx)
return nil
}