Pull request 2728: AGDNS-4289-rm-global-context-etc-hosts

Squashed commit of the following:

commit 0f8fa0222cf4896edcb369a40012a1aec0fb725a
Merge: 18d615e13 f115af2f6
Author: f.setrakov <f.setrakov@adguard.com>
Date:   Thu Jul 30 15:28:58 2026 +0300

    Merge branch 'master' into AGDNS-4289-rm-global-context-etc-hosts

commit 18d615e13f
Author: f.setrakov <f.setrakov@adguard.com>
Date:   Tue Jul 28 18:51:37 2026 +0300

    home: imp code

commit e0e1768df0
Author: f.setrakov <f.setrakov@adguard.com>
Date:   Tue Jul 28 17:12:41 2026 +0300

    home: fix panic, imp code

commit e8028e5162
Merge: 2d4d93f91 8e56afa92
Author: f.setrakov <f.setrakov@adguard.com>
Date:   Tue Jul 28 14:18:31 2026 +0300

    Merge branch 'master' into AGDNS-4289-rm-global-context-etc-hosts

commit 2d4d93f912
Author: f.setrakov <f.setrakov@adguard.com>
Date:   Tue Jul 28 13:55:04 2026 +0300

    home: imp code

commit 64fc6ced97
Author: f.setrakov <f.setrakov@adguard.com>
Date:   Fri Jul 24 10:54:46 2026 +0300

    home: imp code

commit 790084a3e6
Author: f.setrakov <f.setrakov@adguard.com>
Date:   Tue Jul 21 18:50:51 2026 +0300

    home: rm etc hosts from global context
This commit is contained in:
Fedor Setrakov 2026-07-30 12:42:46 +00:00
parent f115af2f65
commit 66360530c3
7 changed files with 186 additions and 131 deletions

View file

@ -536,6 +536,7 @@ func (web *webAPI) finalizeInstall(
web.confModifier,
web.httpReg,
web.conf.workDir,
web.hostsContainer,
)
if err != nil {
aghhttp.ErrorAndLog(ctx, l, r, w, http.StatusInternalServerError, "%s", err)
@ -641,13 +642,14 @@ func startMods(
confModifier agh.ConfigModifier,
httpReg aghhttp.Registrar,
workDir string,
hc *aghnet.HostsContainer,
) (err error) {
statsDir, querylogDir, err := checkStatsAndQuerylogDirs(config, workDir)
if err != nil {
return err
}
err = initDNS(ctx, baseLogger, tlsMgr, confModifier, httpReg, statsDir, querylogDir)
err = initDNS(ctx, baseLogger, tlsMgr, confModifier, httpReg, statsDir, querylogDir, hc)
if err != nil {
return err
}

View file

@ -165,14 +165,7 @@ func (web *webAPI) handleUpdate(w http.ResponseWriter, r *http.Request) {
// The background context is used because the underlying functions wrap it
// with timeout and shut down the server, which handles current request. It
// also should be done in a separate goroutine for the same reason.
go finishUpdate(
context.Background(),
web.logger,
web.cmdCons,
execPath,
web.pidFilePath,
web.conf.runningAsService,
)
go web.finishUpdate(context.Background(), execPath)
}
// versionResponse is the response for /control/version.json endpoint.
@ -221,47 +214,40 @@ func tlsConfUsesPrivilegedPorts(c *tlsConfigSettings) (ok bool) {
}
// finishUpdate completes an update procedure. It is intended to be used as a
// goroutine. l and cmdCons must not be nil.
func finishUpdate(
// goroutine.
func (web *webAPI) finishUpdate(
ctx context.Context,
l *slog.Logger,
cmdCons executil.CommandConstructor,
execPath string,
pidFilePath string,
runningAsService bool,
) {
defer slogutil.RecoverAndExit(ctx, l, osutil.ExitCodeFailure)
defer slogutil.RecoverAndExit(ctx, web.logger, osutil.ExitCodeFailure)
l.InfoContext(ctx, "stopping all tasks")
web.logger.InfoContext(ctx, "stopping all tasks")
cleanup(ctx, l)
cleanupAlways(ctx, l, pidFilePath)
cleanup(ctx, web.logger, web.hostsContainer)
cleanupAlways(ctx, web.logger, web.pidFilePath)
if runtime.GOOS == "windows" {
finalizeWindowsUpdate(ctx, l, cmdCons, execPath, runningAsService)
web.finalizeWindowsUpdate(ctx, execPath)
os.Exit(osutil.ExitCodeSuccess)
}
var err error
l.InfoContext(ctx, "restarting", "exec_path", execPath, "args", os.Args[1:])
web.logger.InfoContext(ctx, "restarting", "exec_path", execPath, "args", os.Args[1:])
err = syscall.Exec(execPath, os.Args, os.Environ())
if err != nil {
panic(fmt.Errorf("restarting: %w", err))
}
}
// finalizeWindowsUpdate completes an update procedure on windows. l and
// cmdCons must not be nil.
func finalizeWindowsUpdate(ctx context.Context,
l *slog.Logger,
cmdCons executil.CommandConstructor,
// finalizeWindowsUpdate completes an update procedure on windows.
func (web *webAPI) finalizeWindowsUpdate(
ctx context.Context,
execPath string,
runningAsService bool,
) {
var commandConf *executil.CommandConfig
if runningAsService {
if web.conf.runningAsService {
// NOTE: We can't restart the service via "kardianos/service" package,
// because it kills the process first we can't start a new instance,
// because Windows doesn't allow it.
@ -281,10 +267,10 @@ func finalizeWindowsUpdate(ctx context.Context,
}
}
l.InfoContext(ctx, "restarting", "exec_path", execPath, "args", os.Args[1:])
web.logger.InfoContext(ctx, "restarting", "exec_path", execPath, "args", os.Args[1:])
var cmd executil.Command
cmd, err := cmdCons.New(ctx, commandConf)
cmd, err := web.cmdCons.New(ctx, commandConf)
if err != nil {
panic(fmt.Errorf("constructing cmd: %w", err))
}

View file

@ -51,6 +51,7 @@ func initDNS(
httpReg aghhttp.Registrar,
statsDir string,
querylogDir string,
hc *aghnet.HostsContainer,
) (err error) {
anonymizer := config.anonymizer()
@ -108,14 +109,21 @@ func initDNS(
err = initDNSServer(
ctx,
globalContext.filters,
globalContext.stats,
globalContext.queryLog,
globalContext.dhcpServer,
anonymizer,
baseLogger,
dnsforward.DNSCreateParams{
Logger: baseLogger,
DNSFilter: globalContext.filters,
Stats: globalContext.stats,
QueryLog: globalContext.queryLog,
PrivateNets: parseSubnetSet(config.DNS.PrivateNets),
Anonymizer: anonymizer,
DHCPServer: globalContext.dhcpServer,
EtcHosts: hc,
LocalDomain: config.DHCP.LocalDomainName,
TLSConfigProvider: tlsMgr,
},
httpReg,
tlsMgr,
baseLogger,
confModifier,
)
if err != nil {
@ -127,36 +135,19 @@ func initDNS(
return nil
}
// initDNSServer initializes the [context.dnsServer]. To only use the internal
// proxy, none of the arguments are required, but tlsMgr and l still must not be
// nil, in other cases all the arguments also must not be nil. It also must not
// be called unless [config] and [globalContext] are initialized.
//
// TODO(e.burkov): Use [dnsforward.DNSCreateParams] as a parameter.
// initDNSServer initializes the [context.dnsServer]. tlsMgr and l must not be
// nil. Other arguments, including params fields, are allowed to be nil if you
// want to use only the internal proxy. It also must not be called unless
// [config] and [globalContext] are initialized.
func initDNSServer(
ctx context.Context,
filters *filtering.DNSFilter,
sts stats.Interface,
qlog querylog.QueryLog,
dhcpSrv dnsforward.DHCP,
anonymizer *aghnet.IPMut,
l *slog.Logger,
params dnsforward.DNSCreateParams,
httpReg aghhttp.Registrar,
tlsMgr *tlsManager,
l *slog.Logger,
confModifier agh.ConfigModifier,
) (err error) {
globalContext.dnsServer, err = dnsforward.NewServer(dnsforward.DNSCreateParams{
Logger: l,
DNSFilter: filters,
Stats: sts,
QueryLog: qlog,
PrivateNets: parseSubnetSet(config.DNS.PrivateNets),
Anonymizer: anonymizer,
DHCPServer: dhcpSrv,
EtcHosts: globalContext.etcHosts,
LocalDomain: config.DHCP.LocalDomainName,
TLSConfigProvider: tlsMgr,
})
globalContext.dnsServer, err = dnsforward.NewServer(params)
defer func() {
if err != nil {
closeDNSServer(ctx)

View file

@ -46,6 +46,7 @@ import (
"github.com/AdguardTeam/golibs/netutil/urlutil"
"github.com/AdguardTeam/golibs/osutil"
"github.com/AdguardTeam/golibs/osutil/executil"
"github.com/AdguardTeam/golibs/service"
)
// Global context
@ -62,10 +63,6 @@ type homeContext struct {
filters *filtering.DNSFilter // DNS filtering module
web *webAPI // Web (HTTP, HTTPS) module
// etcHosts contains IP-hostname mappings taken from the OS-specific hosts
// configuration files, for example /etc/hosts.
etcHosts *aghnet.HostsContainer
controlLock sync.Mutex
}
@ -128,23 +125,27 @@ func Main(clientBuildFS fs.FS) {
pidFilePath := setPIDFilePath(opts)
var (
hc *aghnet.HostsContainer
hcWatcher service.Interface = service.Empty{}
)
if !opts.noEtcHosts {
hc, hcWatcher, err = newHostsContainer(ctx, baseLogger)
fatalOnError(err)
}
sigHdlrLogger := baseLogger.With(slogutil.KeyPrefix, "signalhdlr")
sigHdlr := newSignalHandler(sigHdlrLogger, signals, func(ctx context.Context) {
defer close(done)
sigHdlrCleanup := &signalHandlerCleanup{
logger: sigHdlrLogger,
hostsContainer: hc,
glTokenFileRoot: glTokenFileRoot,
hcWatcher: hcWatcher,
done: done,
pidFilePath: pidFilePath,
glinetMode: opts.glinetMode,
}
cleanup(ctx, sigHdlrLogger)
cleanupAlways(ctx, sigHdlrLogger, pidFilePath)
if !opts.glinetMode {
return
}
closeErr := glTokenFileRoot.Close()
if closeErr != nil {
baseLogger.ErrorContext(ctx, "closing glinet token root", slogutil.KeyError, closeErr)
os.Exit(osutil.ExitCodeFailure)
}
})
sigHdlr := newSignalHandler(sigHdlrLogger, signals, sigHdlrCleanup.cleanup)
go sigHdlr.handle(ctx)
@ -163,6 +164,7 @@ func Main(clientBuildFS fs.FS) {
workDir,
confPath,
pidFilePath,
hc,
)
if err != nil {
svcLogger.ErrorContext(ctx, "action failed", slogutil.KeyError, err)
@ -173,7 +175,19 @@ func Main(clientBuildFS fs.FS) {
}
// run the protection
run(ctx, baseLogger, opts, clientBuildFS, glTokenFileRoot, done, sigHdlr, workDir, confPath, pidFilePath)
run(
ctx,
baseLogger,
opts,
clientBuildFS,
glTokenFileRoot,
done,
sigHdlr,
workDir,
confPath,
pidFilePath,
hc,
)
}
// setupContext initializes [globalContext] fields. It also reads and upgrades
@ -185,24 +199,16 @@ func setupContext(
workDir string,
confPath string,
isFirstRun bool,
) (err error) {
if !opts.noEtcHosts {
err = setupHostsContainer(ctx, baseLogger)
if err != nil {
// Don't wrap the error, because it's informative enough as is.
return err
}
}
) {
if isFirstRun {
baseLogger.InfoContext(ctx, "this is the first time adguard home has been launched")
checkNetworkPermissions(ctx, baseLogger)
return nil
return
}
// TODO(s.chzhen): Consider adding a key prefix.
err = parseConfig(ctx, baseLogger, workDir, confPath)
err := parseConfig(ctx, baseLogger, workDir, confPath)
if err != nil {
baseLogger.ErrorContext(ctx, "failed to parse configuration file", slogutil.KeyError, err)
@ -214,8 +220,6 @@ func setupContext(
os.Exit(osutil.ExitCodeSuccess)
}
return nil
}
// logIfUnsupported logs a formatted warning if the error is one of the
@ -272,13 +276,15 @@ func configureOS(ctx context.Context, l *slog.Logger, conf *configuration) (err
return nil
}
// setupHostsContainer initializes the structures to keep up-to-date the hosts
// newHostsContainer initializes the structures to keep up-to-date the hosts
// provided by the OS. baseLogger must not be nil.
func setupHostsContainer(ctx context.Context, baseLogger *slog.Logger) (err error) {
func newHostsContainer(
ctx context.Context,
baseLogger *slog.Logger,
) (etcHosts *aghnet.HostsContainer, watcher aghos.FSWatcher, err error) {
l := baseLogger.With(slogutil.KeyPrefix, "hosts")
var hostsWatcher aghos.FSWatcher
hostsWatcher, err = aghos.NewOSWatcher(&aghos.OSWatcherConfig{
watcher, err = aghos.NewOSWatcher(&aghos.OSWatcherConfig{
Logger: baseLogger.With(slogutil.KeyPrefix, "hosts_watcher"),
})
if err != nil {
@ -289,37 +295,39 @@ func setupHostsContainer(ctx context.Context, baseLogger *slog.Logger) (err erro
err,
)
hostsWatcher = aghos.EmptyFSWatcher{}
watcher = aghos.EmptyFSWatcher{}
}
paths, err := hostsfile.DefaultHostsPaths()
if err != nil {
return fmt.Errorf("getting default system hosts paths: %w", err)
return nil, nil, fmt.Errorf("getting default system hosts paths: %w", err)
}
globalContext.etcHosts, err = aghnet.NewHostsContainer(
etcHosts, err = aghnet.NewHostsContainer(
ctx,
l,
osutil.RootDirFS(),
hostsWatcher,
watcher,
paths...,
)
if err != nil {
closeErr := hostsWatcher.Shutdown(ctx)
closeErr := watcher.Shutdown(ctx)
if errors.Is(err, aghnet.ErrNoHostsPaths) {
l.WarnContext(ctx, "initializing hosts container", slogutil.KeyError, err)
return closeErr
return nil, nil, closeErr
}
return errors.Join(fmt.Errorf("initializing hosts container: %w", err), closeErr)
err = fmt.Errorf("initializing hosts container: %w", err)
return nil, nil, errors.WithDeferred(err, closeErr)
}
return hostsWatcher.Start(ctx)
return etcHosts, watcher, watcher.Start(ctx)
}
// initContextClients initializes Context clients and related fields. All
// arguments must not be nil.
// arguments except hc must not be nil.
func initContextClients(
ctx context.Context,
logger *slog.Logger,
@ -327,6 +335,7 @@ func initContextClients(
confModifier agh.ConfigModifier,
httpReg aghhttp.Registrar,
workDir string,
hc *aghnet.HostsContainer,
) (err error) {
//lint:ignore SA1019 Migration is not over.
config.DHCP.WorkDir = workDir
@ -355,7 +364,7 @@ func initContextClients(
logger,
config.Clients.Persistent,
globalContext.dhcpServer,
globalContext.etcHosts,
hc,
arpDB,
config.Filtering,
sigHdlr,
@ -415,7 +424,7 @@ func setupBindOpts(opts options) (err error) {
}
// setupDNSFilteringConf sets up DNS filtering configuration settings. All
// arguments must not be nil.
// arguments except hc must not be nil.
func setupDNSFilteringConf(
ctx context.Context,
baseLogger *slog.Logger,
@ -424,6 +433,7 @@ func setupDNSFilteringConf(
confModifier agh.ConfigModifier,
httpReg aghhttp.Registrar,
workDir string,
hc *aghnet.HostsContainer,
) (err error) {
const (
dnsTimeout = 3 * time.Second
@ -439,10 +449,9 @@ func setupDNSFilteringConf(
conf.Logger = baseLogger.With(slogutil.KeyPrefix, "filtering")
conf.EtcHosts = globalContext.etcHosts
// TODO(s.chzhen): Use empty interface.
if globalContext.etcHosts == nil || !config.DNS.HostsFileEnabled {
conf.EtcHosts = nil
if hc != nil && config.DNS.HostsFileEnabled {
conf.EtcHosts = hc
}
conf.ConfModifier = confModifier
@ -631,6 +640,9 @@ type webConfig struct {
// must not be nil.
mux *http.ServeMux
// hostsContainer is used for DNS initialization on updates.
hostsContainer *aghnet.HostsContainer
// configModifier is used to update the global configuration.
configModifier agh.ConfigModifier
@ -683,6 +695,7 @@ func newWeb(ctx context.Context, conf *webConfig) (web *webAPI, err error) {
tlsManager: conf.tlsManager,
auth: conf.auth,
mux: conf.mux,
hostsContainer: conf.hostsContainer,
clientFS: clientFS,
@ -765,6 +778,7 @@ func run(
workDir string,
confPath string,
pidFilePath string,
hc *aghnet.HostsContainer,
) {
aghtls.Init(ctx, baseLogger.With(slogutil.KeyPrefix, "aghtls"))
@ -774,10 +788,9 @@ func run(
mux := http.NewServeMux()
httpReg := aghhttp.NewDefaultRegistrar(mux, mw.wrap)
err := setupContext(ctx, baseLogger, opts, workDir, confPath, isFirstRun)
fatalOnError(err)
setupContext(ctx, baseLogger, opts, workDir, confPath, isFirstRun)
err = configureOS(ctx, baseLogger, config)
err := configureOS(ctx, baseLogger, config)
fatalOnError(err)
// Clients package uses filtering package's static data
@ -792,7 +805,7 @@ func run(
confPath,
)
err = initContextClients(ctx, baseLogger, sigHdlr, confModifier, httpReg, workDir)
err = initContextClients(ctx, baseLogger, sigHdlr, confModifier, httpReg, workDir, hc)
fatalOnError(err)
tlsMgr, err := initTLS(ctx, baseLogger, sigHdlr, confModifier, httpReg)
@ -806,6 +819,7 @@ func run(
confModifier,
httpReg,
workDir,
hc,
)
fatalOnError(err)
@ -831,6 +845,7 @@ func run(
tlsManager: tlsMgr,
auth: auth,
mux: mux,
hostsContainer: hc,
configModifier: confModifier,
httpReg: httpReg,
workDir: workDir,
@ -853,7 +868,7 @@ func run(
fatalOnError(err)
if !isFirstRun {
runDNSServer(ctx, baseLogger, tlsMgr, confModifier, statsDir, querylogDir, httpReg)
runDNSServer(ctx, baseLogger, tlsMgr, confModifier, statsDir, querylogDir, httpReg, hc)
}
if !opts.noPermCheck {
@ -876,8 +891,9 @@ func runDNSServer(
statsDir string,
querylogDir string,
httpReg *aghhttp.DefaultRegistrar,
hc *aghnet.HostsContainer,
) {
err := initDNS(ctx, slogLogger, tlsMgr, confModifier, httpReg, statsDir, querylogDir)
err := initDNS(ctx, slogLogger, tlsMgr, confModifier, httpReg, statsDir, querylogDir, hc)
fatalOnError(err)
tlsMgr.start(ctx)
@ -1215,7 +1231,7 @@ func initWorkingDir(opts options) (workDir string, err error) {
}
// cleanup stops and resets all the modules. l must not be nil.
func cleanup(ctx context.Context, l *slog.Logger) {
func cleanup(ctx context.Context, l *slog.Logger, hc *aghnet.HostsContainer) {
l.InfoContext(ctx, "stopping adguard home")
if globalContext.web != nil {
@ -1235,8 +1251,8 @@ func cleanup(ctx context.Context, l *slog.Logger) {
}
}
if globalContext.etcHosts != nil {
if err = globalContext.etcHosts.Close(); err != nil {
if hc != nil {
if err = hc.Close(); err != nil {
l.ErrorContext(ctx, "closing hosts container", slogutil.KeyError, err)
}
}
@ -1392,7 +1408,12 @@ func cmdlineUpdate(
//
// TODO(e.burkov): We could probably initialize the internal resolver
// separately.
err := initDNSServer(ctx, nil, nil, nil, nil, nil, nil, tlsMgr, l, agh.EmptyConfigModifier{})
params := dnsforward.DNSCreateParams{
Logger: l,
TLSConfigProvider: tlsMgr,
}
err := initDNSServer(ctx, l, params, nil, tlsMgr, agh.EmptyConfigModifier{})
fatalOnError(err)
l.InfoContext(ctx, "performing update via cli")

View file

@ -7,6 +7,7 @@ import (
"log/slog"
"os"
"github.com/AdguardTeam/AdGuardHome/internal/aghnet"
"github.com/AdguardTeam/AdGuardHome/internal/aghos"
"github.com/AdguardTeam/AdGuardHome/internal/ossvc"
"github.com/AdguardTeam/AdGuardHome/internal/version"
@ -41,6 +42,7 @@ type program struct {
baseLogger *slog.Logger
logger *slog.Logger
sigHdlr *signalHandler
hostsContainer *aghnet.HostsContainer
gliNetTokenRoot *os.Root
workDir string
confPath string
@ -67,6 +69,7 @@ func (p *program) Start(_ service.Service) (err error) {
p.workDir,
p.confPath,
p.pidFilePath,
p.hostsContainer,
)
return nil
@ -162,6 +165,7 @@ func handleServiceControlAction(
workDir string,
confPath string,
pidFilePath string,
hc *aghnet.HostsContainer,
) (err error) {
actionName := opts.serviceControlAction
l.InfoContext(ctx, version.Full())
@ -194,6 +198,7 @@ func handleServiceControlAction(
workDir: workDir,
confPath: confPath,
pidFilePath: pidFilePath,
hostsContainer: hc,
}
return p.handleRun(ctx, baseLogger, runOpts)

View file

@ -7,10 +7,12 @@ import (
"sync"
"syscall"
"github.com/AdguardTeam/AdGuardHome/internal/aghnet"
"github.com/AdguardTeam/AdGuardHome/internal/aghtls"
"github.com/AdguardTeam/AdGuardHome/internal/client"
"github.com/AdguardTeam/golibs/logutil/slogutil"
"github.com/AdguardTeam/golibs/osutil"
"github.com/AdguardTeam/golibs/service"
)
// signalHandler processes incoming signals. It reloads configurations of
@ -129,3 +131,44 @@ func (h *signalHandler) reloadConfig(ctx context.Context) {
}
}
}
// signalHandlerCleanup performs application resources cleanup for
// [signalHandler].
type signalHandlerCleanup struct {
logger *slog.Logger
hostsContainer *aghnet.HostsContainer
glTokenFileRoot *os.Root
hcWatcher service.Interface
done chan struct{}
pidFilePath string
glinetMode bool
}
// cleanup performs application cleanup.
func (c *signalHandlerCleanup) cleanup(ctx context.Context) {
defer close(c.done)
cleanup(ctx, c.logger, c.hostsContainer)
cleanupAlways(ctx, c.logger, c.pidFilePath)
if c.glinetMode {
err := c.glTokenFileRoot.Close()
checkCleanupErr(ctx, c.logger, err, "closing glinet token root")
}
if c.hcWatcher != nil {
err := c.hcWatcher.Shutdown(ctx)
checkCleanupErr(ctx, c.logger, err, "shutting down hosts file watcher")
}
}
// checkCleanupErr logs err and exits with [osutil.ExitCodeFailure] if err is
// not nil. l must not be nil.
func checkCleanupErr(ctx context.Context, l *slog.Logger, err error, msg string) {
if err == nil {
return
}
l.ErrorContext(ctx, msg, slogutil.KeyError, err)
os.Exit(osutil.ExitCodeFailure)
}

View file

@ -77,6 +77,9 @@ type webAPIConfig struct {
// must not be nil.
mux *http.ServeMux
// hostsContainer is used for DNS initialization on updates.
hostsContainer *aghnet.HostsContainer
// clientFS is used to initialize file server. It must not be nil.
clientFS fs.FS
@ -231,6 +234,9 @@ type webAPI struct {
// auth stores web user information and handles authentication.
auth *auth
// hostsContainer is used for DNS initialization on updates.
hostsContainer *aghnet.HostsContainer
// httpsServer is the server that handles HTTPS traffic. If it is not nil,
// [Web.http3Server] must also not be nil.
//
@ -252,16 +258,17 @@ func newWebAPI(ctx context.Context, conf *webAPIConfig) (w *webAPI) {
conf.logger.InfoContext(ctx, "initializing")
w = &webAPI{
conf: conf,
confModifier: conf.confModifier,
httpReg: conf.httpReg,
cmdCons: conf.CommandConstructor,
logger: conf.logger,
baseLogger: conf.baseLogger,
tlsManager: conf.tlsManager,
auth: conf.auth,
pidFilePath: conf.pidFilePath,
startTime: time.Now(),
conf: conf,
confModifier: conf.confModifier,
httpReg: conf.httpReg,
cmdCons: conf.CommandConstructor,
logger: conf.logger,
baseLogger: conf.baseLogger,
tlsManager: conf.tlsManager,
auth: conf.auth,
pidFilePath: conf.pidFilePath,
startTime: time.Now(),
hostsContainer: conf.hostsContainer,
}
clientFS := http.FileServer(http.FS(conf.clientFS))