diff --git a/workhorse/_support/lint_last_known_acceptable.txt b/workhorse/_support/lint_last_known_acceptable.txt index a8e25ca00c55e64ed6d8d19d539238af4801842d..36d9ef59575fb3f92b0e2850e903fcb8be7eb925 100644 --- a/workhorse/_support/lint_last_known_acceptable.txt +++ b/workhorse/_support/lint_last_known_acceptable.txt @@ -1,13 +1,8 @@ cmd/gitlab-workhorse/config_test.go:191: cmd/gitlab-workhorse/config_test.go:191: Line contains TODO/BUG/FIXME/NOTE/OPTIMIZE/HACK: "TODO this is meant to be 50*time.Second ..." (godox) cmd/gitlab-workhorse/listener.go:26:16: G402: TLS MinVersion too low. (gosec) -cmd/gitlab-workhorse/main.go:9:2: G108: Profiling endpoint is automatically exposed on /debug/pprof (gosec) cmd/gitlab-workhorse/main.go:73: Function 'buildConfig' has too many statements (63 > 40) (funlen) -cmd/gitlab-workhorse/main.go:79:14: Error return value of `fmt.Fprintf` is not checked (errcheck) -cmd/gitlab-workhorse/main.go:80:14: Error return value of `fmt.Fprintf` is not checked (errcheck) -cmd/gitlab-workhorse/main.go:168: Function 'run' has too many statements (62 > 40) (funlen) -cmd/gitlab-workhorse/main.go:200:30: G114: Use of net/http serve function that has no support for setting timeouts (gosec) -cmd/gitlab-workhorse/main.go:268:10: G112: Potential Slowloris Attack because ReadHeaderTimeout is not configured in the http.Server (gosec) -cmd/gitlab-workhorse/main_test.go:60:2: exitAfterDefer: os.Exit will exit, and `defer gitaly.CloseConnections()` will not run (gocritic) +cmd/gitlab-workhorse/main.go:193: Function 'run' has too many statements (59 > 40) (funlen) +cmd/gitlab-workhorse/main.go:289:10: G112: Potential Slowloris Attack because ReadHeaderTimeout is not configured in the http.Server (gosec) internal/api/channel_settings.go:57:28: G402: TLS MinVersion too low. (gosec) internal/channel/channel.go:128:31: response body must be closed (bodyclose) internal/config/config.go:247:18: G204: Subprocess launched with variable (gosec) diff --git a/workhorse/cmd/gitlab-workhorse/main.go b/workhorse/cmd/gitlab-workhorse/main.go index ecc5c5d5d7a4f0449c1b78749d5b069d11332a26..c69710d813fa188441db00b9089cab47884338b8 100644 --- a/workhorse/cmd/gitlab-workhorse/main.go +++ b/workhorse/cmd/gitlab-workhorse/main.go @@ -6,7 +6,7 @@ import ( "fmt" "net" "net/http" - _ "net/http/pprof" + _ "net/http/pprof" // nolint:gosec "os" "os/signal" "syscall" @@ -51,7 +51,7 @@ func main() { } if err != nil { if _, alreadyPrinted := err.(alreadyPrintedError); !alreadyPrinted { - fmt.Fprintln(os.Stderr, err) + _, _ = fmt.Fprintln(os.Stderr, err) } os.Exit(2) } @@ -76,8 +76,8 @@ func buildConfig(arg0 string, args []string) (*bootConfig, *config.Config, error cfg.Version = Version fset := flag.NewFlagSet(arg0, flag.ContinueOnError) fset.Usage = func() { - fmt.Fprintf(fset.Output(), "Usage of %s:\n", arg0) - fmt.Fprintf(fset.Output(), "\n %s [OPTIONS]\n\nOptions:\n", arg0) + _, _ = fmt.Fprintf(fset.Output(), "Usage of %s:\n", arg0) + _, _ = fmt.Fprintf(fset.Output(), "\n %s [OPTIONS]\n\nOptions:\n", arg0) fset.PrintDefaults() } @@ -164,6 +164,31 @@ func buildConfig(arg0 string, args []string) (*bootConfig, *config.Config, error return boot, cfg, nil } +func initializePprof(listenerAddress string, errors chan error) (*http.Server, error) { + if listenerAddress != "" { + return nil, nil + } + + l, err := net.Listen("tcp", listenerAddress) + if err != nil { + return nil, fmt.Errorf("pprofListenAddr: %v", err) + } + + server := &http.Server{ + Addr: listenerAddress, + Handler: nil, + ReadTimeout: 10 * time.Second, + WriteTimeout: 10 * time.Second, + IdleTimeout: 10 * time.Second, + } + + go func() { + errors <- server.Serve(l) + }() + + return server, nil +} + // run() lets us use normal Go error handling; there is no log.Fatal in run(). func run(boot bootConfig, cfg config.Config) error { closer, err := startLogging(boot.logFile, boot.logFormat) @@ -189,17 +214,13 @@ func run(boot bootConfig, cfg config.Config) error { // requests can only reach the profiler if we start a listener. So by // having no profiler HTTP listener by default, the profiler is // effectively disabled by default. - var l net.Listener - - if boot.pprofListenAddr != "" { - l, err = net.Listen("tcp", boot.pprofListenAddr) - if err != nil { - return fmt.Errorf("pprofListenAddr: %v", err) - } - - go func() { finalErrors <- http.Serve(l, nil) }() + _, err = initializePprof(boot.pprofListenAddr, finalErrors) + if err != nil { + return err } + var l net.Listener + monitoringOpts := []monitoring.Option{monitoring.WithBuildInformation(Version, BuildTime)} if cfg.MetricsListener != nil { l, err = newListener("metrics", *cfg.MetricsListener) @@ -266,6 +287,7 @@ func run(boot bootConfig, cfg config.Config) error { syscall.Umask(oldUmask) srv := &http.Server{Handler: up} + for _, l := range listeners { go func(l net.Listener) { finalErrors <- srv.Serve(l) }(l) } diff --git a/workhorse/cmd/gitlab-workhorse/main_test.go b/workhorse/cmd/gitlab-workhorse/main_test.go index f61413fc85b9b739fd62282dfccdc0e33f798fe3..832e7436cdde3e4234ff028aee7d8060f0195395 100644 --- a/workhorse/cmd/gitlab-workhorse/main_test.go +++ b/workhorse/cmd/gitlab-workhorse/main_test.go @@ -54,10 +54,13 @@ func TestMain(m *testing.M) { log.WithError(err).Fatal() } - defer gitaly.CloseConnections() gitaly.InitializeSidechannelRegistry(logrus.StandardLogger()) - os.Exit(m.Run()) + code := m.Run() + + gitaly.CloseConnections() + + os.Exit(code) } func TestDeniedClone(t *testing.T) {