Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-pages.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJaime Martinez <jmartinez@gitlab.com>2021-10-13 08:46:56 +0300
committerJaime Martinez <jmartinez@gitlab.com>2021-10-13 08:46:56 +0300
commitb9e48b62307e7b6ea18949a805bb986deac79032 (patch)
tree56e2b60a92c561aca307aae64f99c3efa08df7ac
parent247bd7ba2fd9139711218c6a42ed03c551f958d9 (diff)
feat: add status-address listener609-listen-status-ready
Changelog: added
-rw-r--r--app.go37
-rw-r--r--internal/config/config.go4
-rw-r--r--internal/config/flags.go1
-rw-r--r--main.go20
-rw-r--r--test/acceptance/healthcheck_test.go44
5 files changed, 102 insertions, 4 deletions
diff --git a/app.go b/app.go
index 23e8a3cd..54b52fc4 100644
--- a/app.go
+++ b/app.go
@@ -76,7 +76,7 @@ func (a *theApp) ServeTLS(ch *cryptotls.ClientHelloInfo) (*cryptotls.Certificate
return nil, nil
}
-func (a *theApp) healthCheck(w http.ResponseWriter, r *http.Request, https bool) {
+func (a *theApp) healthCheck(w http.ResponseWriter, r *http.Request) {
if a.isReady() {
w.Write([]byte("success\n"))
} else {
@@ -150,9 +150,7 @@ func (a *theApp) tryAuxiliaryHandlers(w http.ResponseWriter, r *http.Request, ht
// healthCheckMiddleware is serving the application status check
func (a *theApp) healthCheckMiddleware(handler http.Handler) (http.Handler, error) {
- healthCheck := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- a.healthCheck(w, r, request.IsHTTPS(r))
- })
+ healthCheck := http.HandlerFunc(a.healthCheck)
loggedHealthCheck, err := logging.BasicAccessLogger(healthCheck, a.config.Log.Format, nil)
if err != nil {
@@ -336,6 +334,10 @@ func (a *theApp) Run() {
a.listenMetricsFD(&wg, a.config.ListenMetrics)
}
+ if a.config.ListenStatus != 0 {
+ a.listenStatusFD(&wg, a.config.ListenStatus, limiter)
+ }
+
wg.Wait()
}
@@ -415,6 +417,33 @@ func (a *theApp) listenMetricsFD(wg *sync.WaitGroup, fd uintptr) {
}()
}
+func (a *theApp) listenStatusFD(wg *sync.WaitGroup, fd uintptr, limiter *netutil.Limiter) {
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+
+ healthCheck := http.HandlerFunc(a.healthCheck)
+
+ loggedHealthCheck, err := logging.BasicAccessLogger(healthCheck, a.config.Log.Format, nil)
+ if err != nil {
+ capturingFatal(err, errortracking.WithField("listener", "status"))
+ }
+
+ httpHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ if r.RequestURI == a.config.General.StatusPath {
+ loggedHealthCheck.ServeHTTP(w, r)
+ return
+ }
+
+ httperrors.Serve404(w)
+ })
+
+ if err := a.listenAndServe(listenerConfig{fd: fd, handler: httpHandler, limiter: limiter, tlsConfig: nil, isProxyV2: false}); err != nil {
+ capturingFatal(err, errortracking.WithField("listener", request.SchemeHTTPS))
+ }
+ }()
+}
+
func runApp(config *cfg.Config) {
source, err := gitlab.New(&config.GitLab)
if err != nil {
diff --git a/internal/config/config.go b/internal/config/config.go
index 94c22328..24d8a82c 100644
--- a/internal/config/config.go
+++ b/internal/config/config.go
@@ -30,6 +30,7 @@ type Config struct {
// ListenMetrics points to a file descriptor of a socket, whose address is
// specified by `Config.General.MetricsAddress`.
ListenMetrics uintptr
+ ListenStatus uintptr
// These fields contain the raw strings passed for listen-http,
// listen-https, listen-proxy and listen-https-proxyv2 settings. It is used
@@ -52,6 +53,7 @@ type General struct {
RootDir string
RootKey []byte
StatusPath string
+ StatusAddress string
DisableCrossOriginRequests bool
InsecureCiphers bool
@@ -178,6 +180,7 @@ func loadConfig() (*Config, error) {
RedirectHTTP: *redirectHTTP,
RootDir: *pagesRoot,
StatusPath: *pagesStatus,
+ StatusAddress: *statusAddress,
DisableCrossOriginRequests: *disableCrossOriginRequests,
InsecureCiphers: *insecureCiphers,
PropagateCorrelationID: *propagateCorrelationID,
@@ -288,6 +291,7 @@ func LogConfig(config *Config) {
"root-cert": *pagesRootKey,
"root-key": *pagesRootCert,
"status_path": config.General.StatusPath,
+ "status_address": config.General.StatusAddress,
"tls-min-version": *tlsMinVersion,
"tls-max-version": *tlsMaxVersion,
"gitlab-server": config.GitLab.PublicServer,
diff --git a/internal/config/flags.go b/internal/config/flags.go
index 52b7be18..7e753ee4 100644
--- a/internal/config/flags.go
+++ b/internal/config/flags.go
@@ -18,6 +18,7 @@ var (
artifactsServer = flag.String("artifacts-server", "", "API URL to proxy artifact requests to, e.g.: 'https://gitlab.com/api/v4'")
artifactsServerTimeout = flag.Int("artifacts-server-timeout", 10, "Timeout (in seconds) for a proxied request to the artifacts server")
pagesStatus = flag.String("pages-status", "", "The url path for a status page, e.g., /@status")
+ statusAddress = flag.String("status-address", "", "The address to listen for status requests")
metricsAddress = flag.String("metrics-address", "", "The address to listen on for metrics requests")
sentryDSN = flag.String("sentry-dsn", "", "The address for sending sentry crash reporting to")
sentryEnvironment = flag.String("sentry-environment", "", "The environment for sentry crash reporting")
diff --git a/main.go b/main.go
index 8d7af93a..46ea2408 100644
--- a/main.go
+++ b/main.go
@@ -80,6 +80,7 @@ func appMain() {
for _, cs := range [][]io.Closer{
createAppListeners(config),
createMetricsListener(config),
+ createStatusListener(config),
} {
defer closeAll(cs)
}
@@ -176,6 +177,25 @@ func createMetricsListener(config *cfg.Config) []io.Closer {
return []io.Closer{l, f}
}
+// createStatusListener returns net.Listener and *os.File instances. The
+// caller must ensure they don't get closed or garbage-collected (which
+// implies closing) too soon.
+func createStatusListener(config *cfg.Config) []io.Closer {
+ addr := config.General.StatusAddress
+ if addr == "" {
+ return nil
+ }
+
+ l, f := createSocket(addr)
+ config.ListenStatus = f.Fd()
+
+ log.WithFields(log.Fields{
+ "listener": addr,
+ }).Debug("Set up status listener")
+
+ return []io.Closer{l, f}
+}
+
func printVersion(showVersion bool, version string) {
if showVersion {
fmt.Fprintf(os.Stdout, "%s\n", version)
diff --git a/test/acceptance/healthcheck_test.go b/test/acceptance/healthcheck_test.go
new file mode 100644
index 00000000..fa4b6541
--- /dev/null
+++ b/test/acceptance/healthcheck_test.go
@@ -0,0 +1,44 @@
+package acceptance_test
+
+import (
+ "fmt"
+ "net/http"
+ "testing"
+
+ "github.com/stretchr/testify/require"
+)
+
+func TestHealthCheckListener(t *testing.T) {
+ statusPath := "/-/readiness"
+ statusAddress := "127.0.0.1:4100"
+
+ RunPagesProcess(t,
+ withListeners([]ListenSpec{httpListener}),
+ withExtraArgument("pages-status", statusPath),
+ withExtraArgument("status-address", statusAddress),
+ )
+
+ tcs := map[string]struct {
+ path string
+ expectedStatus int
+ }{
+ "readiness_path": {path: statusPath, expectedStatus: http.StatusOK},
+ "another_path": {path: "/another-path", expectedStatus: http.StatusNotFound},
+ }
+
+ for tn, tc := range tcs {
+ t.Run(tn, func(t *testing.T) {
+ req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("http://%s%s", statusAddress, tc.path), nil)
+ require.NoError(t, err)
+
+ res, err := QuickTimeoutHTTPSClient.Do(req)
+ require.NoError(t, err)
+
+ require.Equal(t, tc.expectedStatus, res.StatusCode)
+
+ res2, err := GetPageFromListener(t, httpListener, "gitlab-example.com", tc.path)
+ require.NoError(t, err)
+ require.Equal(t, tc.expectedStatus, res2.StatusCode, "http listener must match too")
+ })
+ }
+}