[ARVADOS] created: 2dec430e80dee042f985e151e3e5870dd1dae82b
Git user
git at public.curoverse.com
Tue Sep 20 22:35:02 EDT 2016
at 2dec430e80dee042f985e151e3e5870dd1dae82b (commit)
commit 2dec430e80dee042f985e151e3e5870dd1dae82b
Author: Tom Clegg <tom at curoverse.com>
Date: Tue Sep 20 21:28:00 2016 -0400
9950: Add systemd unit file arv-git-httpd.service.
diff --git a/services/arv-git-httpd/arv-git-httpd.service b/services/arv-git-httpd/arv-git-httpd.service
new file mode 100644
index 0000000..1182a0e
--- /dev/null
+++ b/services/arv-git-httpd/arv-git-httpd.service
@@ -0,0 +1,12 @@
+[Unit]
+Description=Arvados git server
+Documentation=https://doc.arvados.org/
+After=network.target
+
+[Service]
+Type=notify
+ExecStart=/usr/bin/arv-git-httpd
+Restart=always
+
+[Install]
+WantedBy=multi-user.target
diff --git a/services/arv-git-httpd/main.go b/services/arv-git-httpd/main.go
index 3dc8c6f..72d84fe 100644
--- a/services/arv-git-httpd/main.go
+++ b/services/arv-git-httpd/main.go
@@ -7,6 +7,7 @@ import (
"git.curoverse.com/arvados.git/sdk/go/arvados"
"git.curoverse.com/arvados.git/sdk/go/config"
+ "github.com/coreos/go-systemd/daemon"
)
// Server configuration
@@ -69,6 +70,9 @@ func main() {
if err := srv.Start(); err != nil {
log.Fatal(err)
}
+ if _, err := daemon.SdNotify("READY=1"); err != nil {
+ log.Printf("Error notifying init daemon: %v", err)
+ }
log.Println("Listening at", srv.Addr)
log.Println("Repository root", theConfig.Root)
if err := srv.Wait(); err != nil {
commit 766ee8c620a6c1d8b79d9ca1e5443feb4c16c4d0
Author: Tom Clegg <tom at curoverse.com>
Date: Tue Sep 20 21:27:32 2016 -0400
9950: Load config from /etc/arvados/arv-git-httpd/config.json.
diff --git a/services/arv-git-httpd/auth_handler.go b/services/arv-git-httpd/auth_handler.go
index fccb0c9..6ba0f38 100644
--- a/services/arv-git-httpd/auth_handler.go
+++ b/services/arv-git-httpd/auth_handler.go
@@ -5,6 +5,7 @@ import (
"net/http"
"os"
"strings"
+ "sync"
"time"
"git.curoverse.com/arvados.git/sdk/go/arvadosclient"
@@ -12,13 +13,20 @@ import (
"git.curoverse.com/arvados.git/sdk/go/httpserver"
)
-var clientPool = arvadosclient.MakeClientPool()
-
type authHandler struct {
- handler http.Handler
+ handler http.Handler
+ clientPool *arvadosclient.ClientPool
+ setupOnce sync.Once
+}
+
+func (h *authHandler) setup() {
+ os.Setenv("ARVADOS_API_HOST", theConfig.Client.APIHost)
+ h.clientPool = arvadosclient.MakeClientPool()
}
func (h *authHandler) ServeHTTP(wOrig http.ResponseWriter, r *http.Request) {
+ h.setupOnce.Do(h.setup)
+
var statusCode int
var statusText string
var apiToken string
@@ -68,12 +76,12 @@ func (h *authHandler) ServeHTTP(wOrig http.ResponseWriter, r *http.Request) {
repoName = pathParts[0]
repoName = strings.TrimRight(repoName, "/")
- arv := clientPool.Get()
+ arv := h.clientPool.Get()
if arv == nil {
- statusCode, statusText = http.StatusInternalServerError, "connection pool failed: "+clientPool.Err().Error()
+ statusCode, statusText = http.StatusInternalServerError, "connection pool failed: "+h.clientPool.Err().Error()
return
}
- defer clientPool.Put(arv)
+ defer h.clientPool.Put(arv)
// Ask API server whether the repository is readable using
// this token (by trying to read it!)
diff --git a/services/arv-git-httpd/git_handler.go b/services/arv-git-httpd/git_handler.go
index 0312b29..f4baa72 100644
--- a/services/arv-git-httpd/git_handler.go
+++ b/services/arv-git-httpd/git_handler.go
@@ -23,7 +23,7 @@ func newGitHandler() http.Handler {
Env: []string{
"GIT_PROJECT_ROOT=" + theConfig.Root,
"GIT_HTTP_EXPORT_ALL=",
- "SERVER_ADDR=" + theConfig.Addr,
+ "SERVER_ADDR=" + theConfig.Listen,
},
InheritEnv: []string{
"PATH",
diff --git a/services/arv-git-httpd/git_handler_test.go b/services/arv-git-httpd/git_handler_test.go
index 35c2f48..d87162d 100644
--- a/services/arv-git-httpd/git_handler_test.go
+++ b/services/arv-git-httpd/git_handler_test.go
@@ -37,7 +37,7 @@ func (s *GitHandlerSuite) TestEnvVars(c *check.C) {
c.Check(body, check.Matches, `(?ms).*^GL_BYPASS_ACCESS_CHECKS=yesplease$.*`)
c.Check(body, check.Matches, `(?ms).*^REMOTE_HOST=::1$.*`)
c.Check(body, check.Matches, `(?ms).*^REMOTE_PORT=12345$.*`)
- c.Check(body, check.Matches, `(?ms).*^SERVER_ADDR=`+regexp.QuoteMeta(theConfig.Addr)+`$.*`)
+ c.Check(body, check.Matches, `(?ms).*^SERVER_ADDR=`+regexp.QuoteMeta(theConfig.Listen)+`$.*`)
}
func (s *GitHandlerSuite) TestCGIErrorOnSplitHostPortError(c *check.C) {
diff --git a/services/arv-git-httpd/gitolite_test.go b/services/arv-git-httpd/gitolite_test.go
index 20bdae7..96d9d24 100644
--- a/services/arv-git-httpd/gitolite_test.go
+++ b/services/arv-git-httpd/gitolite_test.go
@@ -6,6 +6,7 @@ import (
"os/exec"
"strings"
+ "git.curoverse.com/arvados.git/sdk/go/arvados"
check "gopkg.in/check.v1"
)
@@ -41,8 +42,11 @@ func (s *GitoliteSuite) SetUpTest(c *check.C) {
runGitolite("gitolite", "setup", "--admin", "root")
s.tmpRepoRoot = s.gitoliteHome + "/repositories"
- s.Config = &config{
- Addr: ":0",
+ s.Config = &Config{
+ Client: arvados.Client{
+ APIHost: os.Getenv("ARVADOS_API_HOST"),
+ },
+ Listen: ":0",
GitCommand: "/usr/share/gitolite3/gitolite-shell",
Root: s.tmpRepoRoot,
}
@@ -62,6 +66,10 @@ func (s *GitoliteSuite) TearDownTest(c *check.C) {
// upgrade to Go 1.4.
os.Setenv("GITOLITE_HTTP_HOME", "")
os.Setenv("GL_BYPASS_ACCESS_CHECKS", "")
+ if s.gitoliteHome != "" {
+ err := os.RemoveAll(s.gitoliteHome)
+ c.Check(err, check.Equals, nil)
+ }
s.IntegrationSuite.TearDownTest(c)
}
diff --git a/services/arv-git-httpd/integration_test.go b/services/arv-git-httpd/integration_test.go
index 61d83ff..a548d6d 100644
--- a/services/arv-git-httpd/integration_test.go
+++ b/services/arv-git-httpd/integration_test.go
@@ -8,6 +8,7 @@ import (
"strings"
"testing"
+ "git.curoverse.com/arvados.git/sdk/go/arvados"
"git.curoverse.com/arvados.git/sdk/go/arvadostest"
check "gopkg.in/check.v1"
)
@@ -23,7 +24,7 @@ type IntegrationSuite struct {
tmpRepoRoot string
tmpWorkdir string
testServer *server
- Config *config
+ Config *Config
}
func (s *IntegrationSuite) SetUpSuite(c *check.C) {
@@ -67,8 +68,11 @@ func (s *IntegrationSuite) SetUpTest(c *check.C) {
c.Assert(err, check.Equals, nil)
if s.Config == nil {
- s.Config = &config{
- Addr: ":0",
+ s.Config = &Config{
+ Client: arvados.Client{
+ APIHost: os.Getenv("ARVADOS_API_HOST"),
+ },
+ Listen: ":0",
GitCommand: "/usr/bin/git",
Root: s.tmpRepoRoot,
}
diff --git a/services/arv-git-httpd/main.go b/services/arv-git-httpd/main.go
index 98695c9..3dc8c6f 100644
--- a/services/arv-git-httpd/main.go
+++ b/services/arv-git-httpd/main.go
@@ -4,28 +4,56 @@ import (
"flag"
"log"
"os"
+
+ "git.curoverse.com/arvados.git/sdk/go/arvados"
+ "git.curoverse.com/arvados.git/sdk/go/config"
)
-type config struct {
- Addr string
+// Server configuration
+type Config struct {
+ Client arvados.Client
+ Listen string
GitCommand string
Root string
}
-var theConfig *config
+var theConfig = defaultConfig()
-func init() {
- theConfig = &config{}
- flag.StringVar(&theConfig.Addr, "address", "0.0.0.0:80",
- "Address to listen on, \"host:port\".")
- flag.StringVar(&theConfig.GitCommand, "git-command", "/usr/bin/git",
- "Path to git or gitolite-shell executable. Each authenticated request will execute this program with a single argument, \"http-backend\".")
+func defaultConfig() *Config {
cwd, err := os.Getwd()
if err != nil {
log.Fatalln("Getwd():", err)
}
- flag.StringVar(&theConfig.Root, "repo-root", cwd,
- "Path to git repositories.")
+ return &Config{
+ Listen: ":80",
+ GitCommand: "/usr/bin/git",
+ Root: cwd,
+ }
+}
+
+func init() {
+ deprecated := " (DEPRECATED -- use config file instead)"
+ flag.StringVar(&theConfig.Listen, "address", theConfig.Listen,
+ "Address to listen on, \"host:port\" or \":port\"."+deprecated)
+ flag.StringVar(&theConfig.GitCommand, "git-command", theConfig.GitCommand,
+ "Path to git or gitolite-shell executable. Each authenticated request will execute this program with a single argument, \"http-backend\"."+deprecated)
+ flag.StringVar(&theConfig.Root, "repo-root", theConfig.Root,
+ "Path to git repositories."+deprecated)
+
+ cfgPath := flag.String("config", "/etc/arvados/arv-git-httpd/config.json",
+ "Configuration file `path`.")
+ flag.Usage = usage
+ flag.Parse()
+
+ err := config.LoadFile(theConfig, *cfgPath)
+ if err != nil {
+ if h := os.Getenv("ARVADOS_API_HOST"); h != "" && os.IsNotExist(err) {
+ log.Print("DEPRECATED: No config file found, but ARVADOS_API_HOST environment variable is set. Please use a config file instead.")
+ theConfig.Client.APIHost = h
+ } else {
+ log.Fatal(err)
+ }
+ }
// MakeArvadosClient returns an error if token is unset (even
// though we don't need to do anything requiring
@@ -37,7 +65,6 @@ func init() {
}
func main() {
- flag.Parse()
srv := &server{}
if err := srv.Start(); err != nil {
log.Fatal(err)
diff --git a/services/arv-git-httpd/server.go b/services/arv-git-httpd/server.go
index 40e77a8..e2311d2 100644
--- a/services/arv-git-httpd/server.go
+++ b/services/arv-git-httpd/server.go
@@ -12,8 +12,8 @@ type server struct {
func (srv *server) Start() error {
mux := http.NewServeMux()
- mux.Handle("/", &authHandler{newGitHandler()})
+ mux.Handle("/", &authHandler{handler: newGitHandler()})
srv.Handler = mux
- srv.Addr = theConfig.Addr
+ srv.Addr = theConfig.Listen
return srv.Server.Start()
}
diff --git a/services/arv-git-httpd/usage.go b/services/arv-git-httpd/usage.go
new file mode 100644
index 0000000..649fb10
--- /dev/null
+++ b/services/arv-git-httpd/usage.go
@@ -0,0 +1,62 @@
+package main
+
+import (
+ "encoding/json"
+ "flag"
+ "fmt"
+ "os"
+)
+
+func usage() {
+ c := defaultConfig()
+ c.Client.APIHost = "zzzzz.arvadosapi.com:443"
+ exampleConfigFile, err := json.MarshalIndent(c, " ", " ")
+ if err != nil {
+ panic(err)
+ }
+ fmt.Fprintf(os.Stderr, `
+
+arv-git-httpd provides authenticated access to Arvados-hosted git repositories.
+
+See http://doc.arvados.org/install/install-arv-git-httpd.html.
+
+Usage: arv-git-httpd [-config path/to/config.json]
+
+Options:
+`)
+ flag.PrintDefaults()
+ fmt.Fprintf(os.Stderr, `
+Example config file:
+ %s
+
+Client.APIHost:
+
+ Address (or address:port) of the Arvados API endpoint.
+
+Client.AuthToken:
+
+ Unused. Normally empty, or omitted entirely.
+
+Client.Insecure:
+
+ True if your Arvados API endpoint uses an unverifiable SSL/TLS
+ certificate.
+
+Listen:
+
+ Local port to listen on. Can be "address:port" or ":port", where
+ "address" is a host IP address or name and "port" is a port number
+ or name.
+
+GitCommand:
+
+ Path to git or gitolite-shell executable. Each authenticated
+ request will execute this program with the single argument
+ "http-backend".
+
+Root:
+
+ Path to git repositories. Defaults to current working directory.
+
+`, exampleConfigFile)
+}
-----------------------------------------------------------------------
hooks/post-receive
--
More information about the arvados-commits
mailing list