18947: Refactor keep-web as arvados-server command.
[arvados.git] / lib / service / cmd.go
index b7decd88a4bbc5a6cfad8d9373bd5894105a37af..43357998d8b6c79cbb065f82e4ce92f71c080d54 100644 (file)
@@ -20,20 +20,20 @@ import (
        "git.arvados.org/arvados.git/lib/cmd"
        "git.arvados.org/arvados.git/lib/config"
        "git.arvados.org/arvados.git/sdk/go/arvados"
-       "git.arvados.org/arvados.git/sdk/go/auth"
        "git.arvados.org/arvados.git/sdk/go/ctxlog"
        "git.arvados.org/arvados.git/sdk/go/health"
        "git.arvados.org/arvados.git/sdk/go/httpserver"
        "github.com/coreos/go-systemd/daemon"
        "github.com/julienschmidt/httprouter"
        "github.com/prometheus/client_golang/prometheus"
-       "github.com/prometheus/client_golang/prometheus/promhttp"
        "github.com/sirupsen/logrus"
 )
 
 type Handler interface {
        http.Handler
        CheckHealth() error
+       // Done returns a channel that closes when the handler shuts
+       // itself down, or nil if this never happens.
        Done() <-chan struct{}
 }
 
@@ -74,6 +74,13 @@ func (c *command) RunCommand(prog string, args []string, stdin io.Reader, stdout
 
        loader := config.NewLoader(stdin, log)
        loader.SetupFlags(flags)
+
+       // prog is [keepstore, keep-web, git-httpd, ...]  but the
+       // legacy config flags are [-legacy-keepstore-config,
+       // -legacy-keepweb-config, -legacy-git-httpd-config, ...]
+       legacyFlag := "-legacy-" + strings.Replace(prog, "keep-", "keep", 1) + "-config"
+       args = loader.MungeLegacyConfigArgs(log, args, legacyFlag)
+
        versionFlag := flags.Bool("version", false, "Write version information to stdout and exit 0")
        pprofAddr := flags.String("pprof", "", "Serve Go profile data at `[addr]:port`")
        if ok, code := cmd.ParseFlags(flags, prog, args, "", stderr); !ok {
@@ -131,11 +138,10 @@ func (c *command) RunCommand(prog string, args []string, stdin io.Reader, stdout
                        httpserver.AddRequestIDs(
                                httpserver.LogRequests(
                                        interceptHealthReqs(cluster.ManagementToken, handler.CheckHealth,
-                                               interceptMetricsReqs(cluster.ManagementToken, reg, log,
-                                                       httpserver.NewRequestLimiter(cluster.API.MaxConcurrentRequests, handler, reg)))))))
+                                               httpserver.NewRequestLimiter(cluster.API.MaxConcurrentRequests, handler, reg))))))
        srv := &httpserver.Server{
                Server: http.Server{
-                       Handler:     instrumented.ServeAPI(cluster.ManagementToken, instrumented),
+                       Handler:     ifCollectionInHost(instrumented, instrumented.ServeAPI(cluster.ManagementToken, instrumented)),
                        BaseContext: func(net.Listener) context.Context { return ctx },
                },
                Addr: listenURL.Host,
@@ -178,6 +184,23 @@ func (c *command) RunCommand(prog string, args []string, stdin io.Reader, stdout
        return 0
 }
 
+// If an incoming request's target vhost has an embedded collection
+// UUID or PDH, handle it with hTrue, otherwise handle it with
+// hFalse.
+//
+// Facilitates routing "http://collections.example/metrics" to metrics
+// and "http://{uuid}.collections.example/metrics" to a file in a
+// collection.
+func ifCollectionInHost(hTrue, hFalse http.Handler) http.Handler {
+       return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+               if arvados.CollectionIDFromDNSName(r.Host) != "" {
+                       hTrue.ServeHTTP(w, r)
+               } else {
+                       hFalse.ServeHTTP(w, r)
+               }
+       })
+}
+
 func interceptHealthReqs(mgtToken string, checkHealth func() error, next http.Handler) http.Handler {
        mux := httprouter.New()
        mux.Handler("GET", "/_health/ping", &health.Handler{
@@ -186,19 +209,7 @@ func interceptHealthReqs(mgtToken string, checkHealth func() error, next http.Ha
                Routes: health.Routes{"ping": checkHealth},
        })
        mux.NotFound = next
-       return mux
-}
-
-func interceptMetricsReqs(mgtToken string, reg *prometheus.Registry, log logrus.FieldLogger, next http.Handler) http.Handler {
-       mux := httprouter.New()
-       metricsH := auth.RequireLiteralToken(mgtToken,
-               promhttp.HandlerFor(reg, promhttp.HandlerOpts{
-                       ErrorLog: log,
-               }))
-       mux.Handler("GET", "/metrics", metricsH)
-       mux.Handler("GET", "/metrics.json", metricsH)
-       mux.NotFound = next
-       return mux
+       return ifCollectionInHost(next, mux)
 }
 
 func getListenAddr(svcs arvados.Services, prog arvados.ServiceName, log logrus.FieldLogger) (arvados.URL, error) {