79a3eb3f7b85de9667c04fe1b24f2a5217db5772
[arvados.git] / services / arv-git-httpd / main.go
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 package main
6
7 import (
8         "encoding/json"
9         "flag"
10         "log"
11         "os"
12         "regexp"
13
14         "git.curoverse.com/arvados.git/sdk/go/arvados"
15         "git.curoverse.com/arvados.git/sdk/go/config"
16         "github.com/coreos/go-systemd/daemon"
17 )
18
19 // Server configuration
20 type Config struct {
21         Client          arvados.Client
22         Listen          string
23         GitCommand      string
24         RepoRoot        string
25         GitoliteHome    string
26         ManagementToken string
27 }
28
29 var theConfig = defaultConfig()
30
31 func defaultConfig() *Config {
32         return &Config{
33                 Listen:     ":80",
34                 GitCommand: "/usr/bin/git",
35                 RepoRoot:   "/var/lib/arvados/git/repositories",
36         }
37 }
38
39 func main() {
40         const defaultCfgPath = "/etc/arvados/git-httpd/git-httpd.yml"
41         const deprecated = " (DEPRECATED -- use config file instead)"
42         flag.StringVar(&theConfig.Listen, "address", theConfig.Listen,
43                 "Address to listen on, \"host:port\" or \":port\"."+deprecated)
44         flag.StringVar(&theConfig.GitCommand, "git-command", theConfig.GitCommand,
45                 "Path to git or gitolite-shell executable. Each authenticated request will execute this program with a single argument, \"http-backend\"."+deprecated)
46         flag.StringVar(&theConfig.RepoRoot, "repo-root", theConfig.RepoRoot,
47                 "Path to git repositories."+deprecated)
48         flag.StringVar(&theConfig.GitoliteHome, "gitolite-home", theConfig.GitoliteHome,
49                 "Value for GITOLITE_HTTP_HOME environment variable. If not empty, GL_BYPASS_ACCESS_CHECKS=1 will also be set."+deprecated)
50
51         cfgPath := flag.String("config", defaultCfgPath, "Configuration file `path`.")
52         dumpConfig := flag.Bool("dump-config", false, "write current configuration to stdout and exit (useful for migrating from command line flags to config file)")
53
54         flag.StringVar(&theConfig.ManagementToken, "management-token", theConfig.ManagementToken,
55                 "Authorization token to be included in all health check requests.")
56
57         flag.Usage = usage
58         flag.Parse()
59
60         err := config.LoadFile(theConfig, *cfgPath)
61         if err != nil {
62                 h := os.Getenv("ARVADOS_API_HOST")
63                 if h == "" || !os.IsNotExist(err) || *cfgPath != defaultCfgPath {
64                         log.Fatal(err)
65                 }
66                 log.Print("DEPRECATED: No config file found, but ARVADOS_API_HOST environment variable is set. Please use a config file instead.")
67                 theConfig.Client.APIHost = h
68                 if regexp.MustCompile("^(?i:1|yes|true)$").MatchString(os.Getenv("ARVADOS_API_HOST_INSECURE")) {
69                         theConfig.Client.Insecure = true
70                 }
71                 if j, err := json.MarshalIndent(theConfig, "", "    "); err == nil {
72                         log.Print("Current configuration:\n", string(j))
73                 }
74         }
75
76         if *dumpConfig {
77                 log.Fatal(config.DumpAndExit(theConfig))
78         }
79
80         srv := &server{}
81         if err := srv.Start(); err != nil {
82                 log.Fatal(err)
83         }
84         if _, err := daemon.SdNotify(false, "READY=1"); err != nil {
85                 log.Printf("Error notifying init daemon: %v", err)
86         }
87         log.Println("Listening at", srv.Addr)
88         log.Println("Repository root", theConfig.RepoRoot)
89         if err := srv.Wait(); err != nil {
90                 log.Fatal(err)
91         }
92 }