1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
18 "git.arvados.org/arvados.git/lib/boot"
19 "git.arvados.org/arvados.git/lib/cloud/cloudtest"
20 "git.arvados.org/arvados.git/lib/cmd"
21 "git.arvados.org/arvados.git/lib/config"
22 "git.arvados.org/arvados.git/lib/controller"
23 "git.arvados.org/arvados.git/lib/crunchrun"
24 "git.arvados.org/arvados.git/lib/crunchstat"
25 "git.arvados.org/arvados.git/lib/dispatchcloud"
26 "git.arvados.org/arvados.git/lib/install"
27 "git.arvados.org/arvados.git/lib/lsf"
28 "git.arvados.org/arvados.git/lib/recovercollection"
29 "git.arvados.org/arvados.git/lib/service"
30 "git.arvados.org/arvados.git/sdk/go/arvados"
31 "git.arvados.org/arvados.git/sdk/go/health"
32 dispatchslurm "git.arvados.org/arvados.git/services/crunch-dispatch-slurm"
33 "git.arvados.org/arvados.git/services/githttpd"
34 keepbalance "git.arvados.org/arvados.git/services/keep-balance"
35 keepweb "git.arvados.org/arvados.git/services/keep-web"
36 "git.arvados.org/arvados.git/services/keepproxy"
37 "git.arvados.org/arvados.git/services/keepstore"
38 "git.arvados.org/arvados.git/services/ws"
39 "github.com/prometheus/client_golang/prometheus"
43 handler = cmd.Multi(map[string]cmd.Handler{
44 "version": cmd.Version,
45 "-version": cmd.Version,
46 "--version": cmd.Version,
49 "check": health.CheckCommand,
50 "cloudtest": cloudtest.Command,
51 "config-check": config.CheckCommand,
52 "config-defaults": config.DumpDefaultsCommand,
53 "config-dump": config.DumpCommand,
54 "controller": controller.Command,
55 "crunch-run": crunchrun.Command,
56 "crunchstat": crunchstat.Command,
57 "dispatch-cloud": dispatchcloud.Command,
58 "dispatch-lsf": lsf.DispatchCommand,
59 "dispatch-slurm": dispatchslurm.Command,
60 "git-httpd": githttpd.Command,
61 "health": healthCommand,
62 "install": install.Command,
63 "init": install.InitCommand,
64 "keep-balance": keepbalance.Command,
65 "keep-web": keepweb.Command,
66 "keepproxy": keepproxy.Command,
67 "keepstore": keepstore.Command,
68 "recover-collection": recovercollection.Command,
69 "workbench2": wb2command{},
75 os.Exit(handler.RunCommand(os.Args[0], os.Args[1:], os.Stdin, os.Stdout, os.Stderr))
78 type wb2command struct{}
80 func (wb2command) RunCommand(prog string, args []string, stdin io.Reader, stdout, stderr io.Writer) int {
82 fmt.Fprintf(stderr, "usage: %s api-host listen-addr app-dir\n", prog)
85 configJSON, err := json.Marshal(map[string]string{"API_HOST": args[0]})
87 fmt.Fprintf(stderr, "json.Marshal: %s\n", err)
90 servefs := http.FileServer(http.Dir(args[2]))
91 mux := http.NewServeMux()
92 mux.Handle("/", http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
93 for _, ent := range strings.Split(req.URL.Path, "/") {
95 http.Error(w, "invalid URL path", http.StatusBadRequest)
99 fnm := filepath.Join(args[2], filepath.FromSlash(path.Clean("/"+req.URL.Path)))
100 if _, err := os.Stat(fnm); os.IsNotExist(err) {
103 servefs.ServeHTTP(w, req)
105 mux.HandleFunc("/config.json", func(w http.ResponseWriter, _ *http.Request) {
108 mux.HandleFunc("/_health/ping", func(w http.ResponseWriter, _ *http.Request) {
109 io.WriteString(w, `{"health":"OK"}`)
111 err = http.ListenAndServe(args[1], mux)
113 fmt.Fprintln(stderr, err.Error())
119 var healthCommand cmd.Handler = service.Command(arvados.ServiceNameHealth, func(ctx context.Context, cluster *arvados.Cluster, _ string, reg *prometheus.Registry) service.Handler {
120 mClockSkew := prometheus.NewGauge(prometheus.GaugeOpts{
121 Namespace: "arvados",
123 Name: "clock_skew_seconds",
124 Help: "Clock skew observed in most recent health check",
126 reg.MustRegister(mClockSkew)
127 return &health.Aggregator{
129 MetricClockSkew: mClockSkew,