// Package cmd is the AdGuard Home entry point. It assembles the configuration // file manager, sets up signal processing logic, and so on. // // TODO(a.garipov): Move to the upper-level internal/. package cmd import ( "context" "io/fs" "os" "time" "github.com/AdguardTeam/AdGuardHome/internal/next/configmgr" "github.com/AdguardTeam/AdGuardHome/internal/version" "github.com/AdguardTeam/golibs/errors" "github.com/AdguardTeam/golibs/logutil/slogutil" "github.com/AdguardTeam/golibs/service" ) // Main is the entry point of AdGuard Home. func Main(embeddedFrontend fs.FS) { ctx := context.Background() start := time.Now() cmdName := os.Args[0] opts, err := parseOptions(cmdName, os.Args[1:]) exitCode, needExit := processOptions(opts, cmdName, err) if needExit { os.Exit(exitCode) } baseLogger := newBaseLogger(opts) baseLogger.InfoContext( ctx, "starting adguard home", "version", version.Version(), "pid", os.Getpid(), ) if opts.workDir != "" { baseLogger.InfoContext(ctx, "changing working directory", "dir", opts.workDir) err = os.Chdir(opts.workDir) errors.Check(err) } frontend, err := frontendFromOpts(ctx, baseLogger, opts, embeddedFrontend) errors.Check(err) startCtx, startCancel := context.WithTimeout(ctx, defaultTimeoutStart) defer startCancel() confMgrConf := &configmgr.Config{ BaseLogger: baseLogger, Logger: baseLogger.With(slogutil.KeyPrefix, "configmgr"), Frontend: frontend, WebAddr: opts.webAddr, Start: start, FileName: opts.confFile, } confMgr, err := configmgr.New(startCtx, confMgrConf) errors.Check(err) web := confMgr.Web() err = web.Start(startCtx) errors.Check(err) dns := confMgr.DNS() err = dns.Start(startCtx) errors.Check(err) sigHdlr := newSignalHandler( baseLogger.With(slogutil.KeyPrefix, service.SignalHandlerPrefix), confMgrConf, opts.pidFile, web, dns, ) os.Exit(sigHdlr.handle(ctx)) } // Default timeouts. // // TODO(a.garipov): Make configurable. const ( defaultTimeoutStart = 1 * time.Minute defaultTimeoutShutdown = 5 * time.Second ) // newConfigMgr returns a new configuration manager using defaultTimeout as the // context timeout. func newConfigMgr(ctx context.Context, c *configmgr.Config) (m *configmgr.Manager, err error) { return configmgr.New(ctx, c) }