diff --git a/internal/home/controlupdate.go b/internal/home/controlupdate.go index 2c6f1e60..bdecc4e9 100644 --- a/internal/home/controlupdate.go +++ b/internal/home/controlupdate.go @@ -18,6 +18,7 @@ import ( "github.com/AdguardTeam/AdGuardHome/internal/updater" "github.com/AdguardTeam/golibs/errors" "github.com/AdguardTeam/golibs/logutil/slogutil" + "github.com/AdguardTeam/golibs/osutil" ) // temporaryError is the interface for temporary errors from the Go standard @@ -95,7 +96,7 @@ func (web *webAPI) requestVersionInfo( const sleepTime = 2 * time.Second err = fmt.Errorf("temp net error: %w; sleeping for %s and retrying", err, sleepTime) - web.logger.ErrorContext(ctx, "updating version info", slogutil.KeyError, err) + web.logger.InfoContext(ctx, "updating version info", slogutil.KeyError, err) time.Sleep(sleepTime) @@ -187,22 +188,17 @@ func tlsConfUsesPrivilegedPorts(c *tlsConfigSettings) (ok bool) { return c.Enabled && (c.PortHTTPS < 1024 || c.PortDNSOverTLS < 1024 || c.PortDNSOverQUIC < 1024) } -// finishUpdate completes an update procedure. +// finishUpdate completes an update procedure. It is intended to be used as a +// goroutine. func finishUpdate(ctx context.Context, l *slog.Logger, execPath string, runningAsService bool) { - var err error - defer func() { - if err != nil { - l.ErrorContext(ctx, "restarting", slogutil.KeyError, err) - - os.Exit(1) - } - }() + defer slogutil.RecoverAndExit(ctx, l, osutil.ExitCodeFailure) l.InfoContext(ctx, "stopping all tasks") cleanup(ctx) cleanupAlways() + var err error if runtime.GOOS == "windows" { if runningAsService { // NOTE: We can't restart the service via "kardianos/service" @@ -213,10 +209,10 @@ func finishUpdate(ctx context.Context, l *slog.Logger, execPath string, runningA cmd := exec.Command("cmd", "/c", "net stop AdGuardHome & net start AdGuardHome") err = cmd.Start() if err != nil { - return + panic(fmt.Errorf("restarting service: %w", err)) } - os.Exit(0) + os.Exit(osutil.ExitCodeSuccess) } cmd := exec.Command(execPath, os.Args[1:]...) @@ -226,15 +222,15 @@ func finishUpdate(ctx context.Context, l *slog.Logger, execPath string, runningA cmd.Stderr = os.Stderr err = cmd.Start() if err != nil { - return + panic(fmt.Errorf("restarting: %w", err)) } - os.Exit(0) + os.Exit(osutil.ExitCodeSuccess) } l.InfoContext(ctx, "restarting", "exec_path", execPath, "args", os.Args[1:]) err = syscall.Exec(execPath, os.Args, os.Environ()) if err != nil { - return + panic(fmt.Errorf("restarting: %w", err)) } } diff --git a/internal/home/home.go b/internal/home/home.go index cb9f7fc4..ac41d7f8 100644 --- a/internal/home/home.go +++ b/internal/home/home.go @@ -167,13 +167,13 @@ func setupContext(opts options) (err error) { if err != nil { log.Error("parsing configuration file: %s", err) - os.Exit(1) + os.Exit(osutil.ExitCodeFailure) } if opts.checkConfig { log.Info("configuration file is ok") - os.Exit(0) + os.Exit(osutil.ExitCodeSuccess) } return nil @@ -978,7 +978,7 @@ func loadCmdLineOpts() (opts options) { exitWithError() } - os.Exit(0) + os.Exit(osutil.ExitCodeSuccess) } return opts diff --git a/internal/home/options.go b/internal/home/options.go index dd7e53e4..e0750e3e 100644 --- a/internal/home/options.go +++ b/internal/home/options.go @@ -10,6 +10,7 @@ import ( "github.com/AdguardTeam/AdGuardHome/internal/configmigrate" "github.com/AdguardTeam/AdGuardHome/internal/version" "github.com/AdguardTeam/golibs/log" + "github.com/AdguardTeam/golibs/osutil" "github.com/AdguardTeam/golibs/stringutil" ) @@ -329,7 +330,7 @@ var cmdLineOpts = []cmdLineOpt{{ fmt.Println(version.Full()) } - os.Exit(0) + os.Exit(osutil.ExitCodeSuccess) return nil }, nil diff --git a/internal/home/web.go b/internal/home/web.go index 672b1672..0ea0272b 100644 --- a/internal/home/web.go +++ b/internal/home/web.go @@ -20,6 +20,7 @@ import ( "github.com/AdguardTeam/golibs/netutil" "github.com/AdguardTeam/golibs/netutil/httputil" "github.com/AdguardTeam/golibs/netutil/urlutil" + "github.com/AdguardTeam/golibs/osutil" "github.com/NYTimes/gziphandler" "github.com/quic-go/quic-go/http3" "golang.org/x/net/http2" @@ -112,8 +113,8 @@ type webAPI struct { httpsServer httpsServer } -// newWebAPI creates a new instance of the web UI and API server. conf must not -// be nil and must be valid +// newWebAPI creates a new instance of the web UI and API server. conf must be +// valid. // // TODO(a.garipov): Return a proper error. func newWebAPI(ctx context.Context, conf *webConfig) (w *webAPI) { @@ -172,7 +173,7 @@ func webCheckPortAvailable(port uint16) (ok bool) { // tlsConfigChanged updates the TLS configuration and restarts the HTTPS server // if necessary. func (web *webAPI) tlsConfigChanged(ctx context.Context, tlsConf tlsConfigSettings) { - defer slogutil.RecoverAndLog(ctx, web.logger) + defer slogutil.RecoverAndExit(ctx, web.logger, osutil.ExitCodeFailure) web.logger.DebugContext(ctx, "applying new tls configuration") @@ -210,7 +211,7 @@ const loggerKeyServer = "server" // start - start serving HTTP requests func (web *webAPI) start(ctx context.Context) { - defer slogutil.RecoverAndLog(ctx, web.logger) + defer slogutil.RecoverAndExit(ctx, web.logger, osutil.ExitCodeFailure) web.logger.InfoContext(ctx, "AdGuard Home is available at the following addresses:") @@ -237,6 +238,8 @@ func (web *webAPI) start(ctx context.Context) { ErrorLog: slog.NewLogLogger(logger.Handler(), slog.LevelError), } go func() { + defer slogutil.RecoverAndLog(ctx, web.logger) + errs <- web.httpServer.ListenAndServe() }() @@ -271,7 +274,7 @@ func (web *webAPI) close(ctx context.Context) { } func (web *webAPI) tlsServerLoop(ctx context.Context) { - defer slogutil.RecoverAndLog(ctx, web.logger) + defer slogutil.RecoverAndExit(ctx, web.logger, osutil.ExitCodeFailure) for { web.httpsServer.cond.L.Lock() @@ -333,6 +336,8 @@ func (web *webAPI) tlsServerLoop(ctx context.Context) { } func (web *webAPI) mustStartHTTP3(ctx context.Context, address string) { + defer slogutil.RecoverAndExit(ctx, web.logger, osutil.ExitCodeFailure) + web.httpsServer.server3 = &http3.Server{ // TODO(a.garipov): See if there is a way to use the error log as // well as timeouts here. diff --git a/scripts/translations/main.go b/scripts/translations/main.go index c1f6a3cc..e8dc0473 100644 --- a/scripts/translations/main.go +++ b/scripts/translations/main.go @@ -22,6 +22,7 @@ import ( "github.com/AdguardTeam/AdGuardHome/internal/aghos" "github.com/AdguardTeam/golibs/errors" "github.com/AdguardTeam/golibs/logutil/slogutil" + "github.com/AdguardTeam/golibs/osutil" ) const ( @@ -124,12 +125,12 @@ Commands: if addStr != "" { fmt.Printf("%s\n%s\n", addStr, usageStr) - os.Exit(1) + os.Exit(osutil.ExitCodeFailure) } fmt.Println(usageStr) - os.Exit(0) + os.Exit(osutil.ExitCodeSuccess) } // twoskyConfig is the configuration structure for localization.