[ARVADOS] updated: 9e27ddfd2f2538ff2216d75c450aa72dd3bc1cf8

Git user git at public.curoverse.com
Mon Sep 26 13:44:35 EDT 2016


Summary of changes:
 sdk/go/arvadosclient/pool.go                       | 36 +++++++----
 sdk/go/arvadostest/run_servers.go                  |  9 +++
 .../arv-git-httpd.service}                         |  4 +-
 services/arv-git-httpd/auth_handler.go             | 28 +++++---
 services/arv-git-httpd/git_handler.go              |  6 +-
 services/arv-git-httpd/git_handler_test.go         |  2 +-
 services/arv-git-httpd/gitolite_test.go            | 16 ++++-
 services/arv-git-httpd/integration_test.go         | 25 +++++---
 services/arv-git-httpd/main.go                     | 75 +++++++++++++++-------
 services/arv-git-httpd/server.go                   |  4 +-
 services/arv-git-httpd/usage.go                    | 62 ++++++++++++++++++
 11 files changed, 206 insertions(+), 61 deletions(-)
 copy services/{keepproxy/keepproxy.service => arv-git-httpd/arv-git-httpd.service} (69%)
 create mode 100644 services/arv-git-httpd/usage.go

       via  9e27ddfd2f2538ff2216d75c450aa72dd3bc1cf8 (commit)
       via  04cbfda1656d1d6cf3eee2f901c2ee79ab597e59 (commit)
       via  8a704d9628a2731635d0d1cb96a85a83c0f79a13 (commit)
       via  ec8f01cc84b75ab2cb9204cab63636a1a479a893 (commit)
       via  6e1c29f2530ff36892ebe64a81e3d962766763de (commit)
       via  8a286717d5f4f549570d81533f746ba838b73d30 (commit)
      from  c3734153c799a79136683093c21f64a7f1fa4e80 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.


commit 9e27ddfd2f2538ff2216d75c450aa72dd3bc1cf8
Merge: c373415 04cbfda
Author: Tom Clegg <tom at curoverse.com>
Date:   Mon Sep 26 13:44:16 2016 -0400

    Merge branch '9950-arv-git-httpd-config' closes #9950


commit 04cbfda1656d1d6cf3eee2f901c2ee79ab597e59
Author: Tom Clegg <tom at curoverse.com>
Date:   Mon Sep 26 12:24:46 2016 -0400

    9950: Remove uses of environment variables.

diff --git a/sdk/go/arvadosclient/pool.go b/sdk/go/arvadosclient/pool.go
index 87b67c3..26b3518 100644
--- a/sdk/go/arvadosclient/pool.go
+++ b/sdk/go/arvadosclient/pool.go
@@ -10,22 +10,32 @@ import (
 // credentials. See arvados-git-httpd for an example, and sync.Pool
 // for more information about garbage collection.
 type ClientPool struct {
-	sync.Pool
-	lastErr error
+	// Initialize new clients by coping this one.
+	Prototype *ArvadosClient
+
+	pool      *sync.Pool
+	lastErr   error
+	setupOnce sync.Once
 }
 
-// MakeClientPool returns a new empty ClientPool.
+// MakeClientPool returns a new empty ClientPool, using environment
+// variables to initialize the prototype.
 func MakeClientPool() *ClientPool {
-	p := &ClientPool{}
-	p.Pool = sync.Pool{New: func() interface{} {
-		arv, err := MakeArvadosClient()
-		if err != nil {
-			p.lastErr = err
+	proto, err := MakeArvadosClient()
+	return &ClientPool{
+		Prototype: &proto,
+		lastErr:   err,
+	}
+}
+
+func (p *ClientPool) setup() {
+	p.pool = &sync.Pool{New: func() interface{} {
+		if p.lastErr != nil {
 			return nil
 		}
-		return &arv
+		c := *p.Prototype
+		return &c
 	}}
-	return p
 }
 
 // Err returns the error that was encountered last time Get returned
@@ -39,7 +49,8 @@ func (p *ClientPool) Err() error {
 // (including its ApiToken) will be just as it was when it was Put
 // back in the pool.
 func (p *ClientPool) Get() *ArvadosClient {
-	c, ok := p.Pool.Get().(*ArvadosClient)
+	p.setupOnce.Do(p.setup)
+	c, ok := p.pool.Get().(*ArvadosClient)
 	if !ok {
 		return nil
 	}
@@ -48,5 +59,6 @@ func (p *ClientPool) Get() *ArvadosClient {
 
 // Put puts an ArvadosClient back in the pool.
 func (p *ClientPool) Put(c *ArvadosClient) {
-	p.Pool.Put(c)
+	p.setupOnce.Do(p.setup)
+	p.pool.Put(c)
 }
diff --git a/sdk/go/arvadostest/run_servers.go b/sdk/go/arvadostest/run_servers.go
index 7edc482..d3b48ea 100644
--- a/sdk/go/arvadostest/run_servers.go
+++ b/sdk/go/arvadostest/run_servers.go
@@ -22,6 +22,15 @@ func ResetEnv() {
 	}
 }
 
+// APIHost returns the address:port of the current test server.
+func APIHost() string {
+	h := authSettings["ARVADOS_API_HOST"]
+	if h == "" {
+		log.Fatal("arvadostest.APIHost() was called but authSettings is not populated")
+	}
+	return h
+}
+
 // ParseAuthSettings parses auth settings from given input
 func ParseAuthSettings(authScript []byte) {
 	scanner := bufio.NewScanner(bytes.NewReader(authScript))
diff --git a/services/arv-git-httpd/auth_handler.go b/services/arv-git-httpd/auth_handler.go
index bfdb396..9f92cd1 100644
--- a/services/arv-git-httpd/auth_handler.go
+++ b/services/arv-git-httpd/auth_handler.go
@@ -20,13 +20,12 @@ type authHandler struct {
 }
 
 func (h *authHandler) setup() {
-	os.Setenv("ARVADOS_API_HOST", theConfig.Client.APIHost)
-	if theConfig.Client.Insecure {
-		os.Setenv("ARVADOS_API_HOST_INSECURE", "1")
-	} else {
-		os.Setenv("ARVADOS_API_HOST_INSECURE", "")
+	ac, err := arvadosclient.New(&theConfig.Client)
+	if err != nil {
+		log.Fatal(err)
 	}
-	h.clientPool = arvadosclient.MakeClientPool()
+	h.clientPool = &arvadosclient.ClientPool{Prototype: ac}
+	log.Printf("%+v", h.clientPool.Prototype)
 }
 
 func (h *authHandler) ServeHTTP(wOrig http.ResponseWriter, r *http.Request) {
diff --git a/services/arv-git-httpd/gitolite_test.go b/services/arv-git-httpd/gitolite_test.go
index 219eb11..74c2b8c 100644
--- a/services/arv-git-httpd/gitolite_test.go
+++ b/services/arv-git-httpd/gitolite_test.go
@@ -7,6 +7,7 @@ import (
 	"strings"
 
 	"git.curoverse.com/arvados.git/sdk/go/arvados"
+	"git.curoverse.com/arvados.git/sdk/go/arvadostest"
 	check "gopkg.in/check.v1"
 )
 
@@ -44,7 +45,7 @@ func (s *GitoliteSuite) SetUpTest(c *check.C) {
 	s.tmpRepoRoot = s.gitoliteHome + "/repositories"
 	s.Config = &Config{
 		Client: arvados.Client{
-			APIHost:  os.Getenv("ARVADOS_API_HOST"),
+			APIHost:  arvadostest.APIHost(),
 			Insecure: true,
 		},
 		Listen:     ":0",
diff --git a/services/arv-git-httpd/integration_test.go b/services/arv-git-httpd/integration_test.go
index f772b4d..5e55eca 100644
--- a/services/arv-git-httpd/integration_test.go
+++ b/services/arv-git-httpd/integration_test.go
@@ -70,7 +70,7 @@ func (s *IntegrationSuite) SetUpTest(c *check.C) {
 	if s.Config == nil {
 		s.Config = &Config{
 			Client: arvados.Client{
-				APIHost:  os.Getenv("ARVADOS_API_HOST"),
+				APIHost:  arvadostest.APIHost(),
 				Insecure: true,
 			},
 			Listen:     ":0",
@@ -78,13 +78,17 @@ func (s *IntegrationSuite) SetUpTest(c *check.C) {
 			RepoRoot:   s.tmpRepoRoot,
 		}
 	}
+
+	// Clear ARVADOS_API_* env vars before starting up the server,
+	// to make sure arv-git-httpd doesn't use them or complain
+	// about them being missing.
+	os.Unsetenv("ARVADOS_API_HOST")
+	os.Unsetenv("ARVADOS_API_HOST_INSECURE")
+	os.Unsetenv("ARVADOS_API_TOKEN")
+
 	theConfig = s.Config
 	err = s.testServer.Start()
 	c.Assert(err, check.Equals, nil)
-
-	// Clear ARVADOS_API_TOKEN after starting up the server, to
-	// make sure arv-git-httpd doesn't use it.
-	os.Setenv("ARVADOS_API_TOKEN", "unused-token-placates-client-library")
 }
 
 func (s *IntegrationSuite) TearDownTest(c *check.C) {
diff --git a/services/arv-git-httpd/main.go b/services/arv-git-httpd/main.go
index ccee20e..40dcf32 100644
--- a/services/arv-git-httpd/main.go
+++ b/services/arv-git-httpd/main.go
@@ -63,14 +63,6 @@ func init() {
 			log.Print("Current configuration:\n", string(j))
 		}
 	}
-
-	// MakeArvadosClient returns an error if token is unset (even
-	// though we don't need to do anything requiring
-	// authentication yet). We can't do this in newArvadosClient()
-	// just before calling MakeArvadosClient(), though, because
-	// that interferes with the env var needed by "run test
-	// servers".
-	os.Setenv("ARVADOS_API_TOKEN", "xxx")
 }
 
 func main() {

commit 8a704d9628a2731635d0d1cb96a85a83c0f79a13
Author: Tom Clegg <tom at curoverse.com>
Date:   Wed Sep 21 14:34:05 2016 -0400

    9950: Propagate Client.Insecure config to arvadosclient library via ARVADOS_API_HOST_INSECURE env var.

diff --git a/services/arv-git-httpd/auth_handler.go b/services/arv-git-httpd/auth_handler.go
index 3186501..bfdb396 100644
--- a/services/arv-git-httpd/auth_handler.go
+++ b/services/arv-git-httpd/auth_handler.go
@@ -21,6 +21,11 @@ type authHandler struct {
 
 func (h *authHandler) setup() {
 	os.Setenv("ARVADOS_API_HOST", theConfig.Client.APIHost)
+	if theConfig.Client.Insecure {
+		os.Setenv("ARVADOS_API_HOST_INSECURE", "1")
+	} else {
+		os.Setenv("ARVADOS_API_HOST_INSECURE", "")
+	}
 	h.clientPool = arvadosclient.MakeClientPool()
 }
 
diff --git a/services/arv-git-httpd/gitolite_test.go b/services/arv-git-httpd/gitolite_test.go
index d21a814..219eb11 100644
--- a/services/arv-git-httpd/gitolite_test.go
+++ b/services/arv-git-httpd/gitolite_test.go
@@ -44,7 +44,8 @@ func (s *GitoliteSuite) SetUpTest(c *check.C) {
 	s.tmpRepoRoot = s.gitoliteHome + "/repositories"
 	s.Config = &Config{
 		Client: arvados.Client{
-			APIHost: os.Getenv("ARVADOS_API_HOST"),
+			APIHost:  os.Getenv("ARVADOS_API_HOST"),
+			Insecure: true,
 		},
 		Listen:     ":0",
 		GitCommand: "/usr/share/gitolite3/gitolite-shell",
diff --git a/services/arv-git-httpd/integration_test.go b/services/arv-git-httpd/integration_test.go
index 5ec5ccb..f772b4d 100644
--- a/services/arv-git-httpd/integration_test.go
+++ b/services/arv-git-httpd/integration_test.go
@@ -70,7 +70,8 @@ func (s *IntegrationSuite) SetUpTest(c *check.C) {
 	if s.Config == nil {
 		s.Config = &Config{
 			Client: arvados.Client{
-				APIHost: os.Getenv("ARVADOS_API_HOST"),
+				APIHost:  os.Getenv("ARVADOS_API_HOST"),
+				Insecure: true,
 			},
 			Listen:     ":0",
 			GitCommand: "/usr/bin/git",

commit ec8f01cc84b75ab2cb9204cab63636a1a479a893
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 ce18b71..ccee20e 100644
--- a/services/arv-git-httpd/main.go
+++ b/services/arv-git-httpd/main.go
@@ -9,6 +9,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
@@ -77,6 +78,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.RepoRoot)
 	if err := srv.Wait(); err != nil {

commit 6e1c29f2530ff36892ebe64a81e3d962766763de
Author: Tom Clegg <tom at curoverse.com>
Date:   Wed Sep 21 09:35:27 2016 -0400

    9950: Rename Root config to RepoRoot.

diff --git a/services/arv-git-httpd/auth_handler.go b/services/arv-git-httpd/auth_handler.go
index 6ba0f38..3186501 100644
--- a/services/arv-git-httpd/auth_handler.go
+++ b/services/arv-git-httpd/auth_handler.go
@@ -137,7 +137,7 @@ func (h *authHandler) ServeHTTP(wOrig http.ResponseWriter, r *http.Request) {
 		"/" + repoName + "/.git",
 	}
 	for _, dir := range tryDirs {
-		if fileInfo, err := os.Stat(theConfig.Root + dir); err != nil {
+		if fileInfo, err := os.Stat(theConfig.RepoRoot + dir); err != nil {
 			if !os.IsNotExist(err) {
 				statusCode, statusText = http.StatusInternalServerError, err.Error()
 				return
@@ -149,7 +149,7 @@ func (h *authHandler) ServeHTTP(wOrig http.ResponseWriter, r *http.Request) {
 	}
 	if rewrittenPath == "" {
 		log.Println("WARNING:", repoUUID,
-			"git directory not found in", theConfig.Root, tryDirs)
+			"git directory not found in", theConfig.RepoRoot, tryDirs)
 		// We say "content not found" to disambiguate from the
 		// earlier "API says that repo does not exist" error.
 		statusCode, statusText = http.StatusNotFound, "content not found"
diff --git a/services/arv-git-httpd/git_handler.go b/services/arv-git-httpd/git_handler.go
index f4baa72..f0b98fa 100644
--- a/services/arv-git-httpd/git_handler.go
+++ b/services/arv-git-httpd/git_handler.go
@@ -19,9 +19,9 @@ func newGitHandler() http.Handler {
 	return &gitHandler{
 		Handler: cgi.Handler{
 			Path: theConfig.GitCommand,
-			Dir:  theConfig.Root,
+			Dir:  theConfig.RepoRoot,
 			Env: []string{
-				"GIT_PROJECT_ROOT=" + theConfig.Root,
+				"GIT_PROJECT_ROOT=" + theConfig.RepoRoot,
 				"GIT_HTTP_EXPORT_ALL=",
 				"SERVER_ADDR=" + theConfig.Listen,
 			},
diff --git a/services/arv-git-httpd/gitolite_test.go b/services/arv-git-httpd/gitolite_test.go
index 96d9d24..d21a814 100644
--- a/services/arv-git-httpd/gitolite_test.go
+++ b/services/arv-git-httpd/gitolite_test.go
@@ -48,7 +48,7 @@ func (s *GitoliteSuite) SetUpTest(c *check.C) {
 		},
 		Listen:     ":0",
 		GitCommand: "/usr/share/gitolite3/gitolite-shell",
-		Root:       s.tmpRepoRoot,
+		RepoRoot:   s.tmpRepoRoot,
 	}
 	s.IntegrationSuite.SetUpTest(c)
 
diff --git a/services/arv-git-httpd/integration_test.go b/services/arv-git-httpd/integration_test.go
index a548d6d..5ec5ccb 100644
--- a/services/arv-git-httpd/integration_test.go
+++ b/services/arv-git-httpd/integration_test.go
@@ -74,7 +74,7 @@ func (s *IntegrationSuite) SetUpTest(c *check.C) {
 			},
 			Listen:     ":0",
 			GitCommand: "/usr/bin/git",
-			Root:       s.tmpRepoRoot,
+			RepoRoot:   s.tmpRepoRoot,
 		}
 	}
 	theConfig = s.Config
diff --git a/services/arv-git-httpd/main.go b/services/arv-git-httpd/main.go
index 202e0a2..ce18b71 100644
--- a/services/arv-git-httpd/main.go
+++ b/services/arv-git-httpd/main.go
@@ -16,7 +16,7 @@ type Config struct {
 	Client     arvados.Client
 	Listen     string
 	GitCommand string
-	Root       string
+	RepoRoot   string
 }
 
 var theConfig = defaultConfig()
@@ -29,7 +29,7 @@ func defaultConfig() *Config {
 	return &Config{
 		Listen:     ":80",
 		GitCommand: "/usr/bin/git",
-		Root:       cwd,
+		RepoRoot:   cwd,
 	}
 }
 
@@ -40,7 +40,7 @@ func init() {
 		"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,
+	flag.StringVar(&theConfig.RepoRoot, "repo-root", theConfig.RepoRoot,
 		"Path to git repositories."+deprecated)
 
 	cfgPath := flag.String("config", defaultCfgPath, "Configuration file `path`.")
@@ -78,7 +78,7 @@ func main() {
 		log.Fatal(err)
 	}
 	log.Println("Listening at", srv.Addr)
-	log.Println("Repository root", theConfig.Root)
+	log.Println("Repository root", theConfig.RepoRoot)
 	if err := srv.Wait(); err != nil {
 		log.Fatal(err)
 	}
diff --git a/services/arv-git-httpd/usage.go b/services/arv-git-httpd/usage.go
index 649fb10..a4a9900 100644
--- a/services/arv-git-httpd/usage.go
+++ b/services/arv-git-httpd/usage.go
@@ -54,7 +54,7 @@ GitCommand:
     request will execute this program with the single argument
     "http-backend".
 
-Root:
+RepoRoot:
 
     Path to git repositories. Defaults to current working directory.
 

commit 8a286717d5f4f549570d81533f746ba838b73d30
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..202e0a2 100644
--- a/services/arv-git-httpd/main.go
+++ b/services/arv-git-httpd/main.go
@@ -1,31 +1,67 @@
 package main
 
 import (
+	"encoding/json"
 	"flag"
 	"log"
 	"os"
+	"regexp"
+
+	"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() {
+	const defaultCfgPath = "/etc/arvados/arv-git-httpd/config.json"
+	const 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", defaultCfgPath, "Configuration file `path`.")
+	flag.Usage = usage
+	flag.Parse()
+
+	err := config.LoadFile(theConfig, *cfgPath)
+	if err != nil {
+		h := os.Getenv("ARVADOS_API_HOST")
+		if h == "" || !os.IsNotExist(err) || *cfgPath != defaultCfgPath {
+			log.Fatal(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
+		if regexp.MustCompile("^(?i:1|yes|true)$").MatchString(os.Getenv("ARVADOS_API_HOST_INSECURE")) {
+			theConfig.Client.Insecure = true
+		}
+		if j, err := json.MarshalIndent(theConfig, "", "    "); err == nil {
+			log.Print("Current configuration:\n", string(j))
+		}
+	}
 
 	// MakeArvadosClient returns an error if token is unset (even
 	// though we don't need to do anything requiring
@@ -37,7 +73,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