[ARVADOS] created: 1.1.3-264-g7633b94

Git user git at public.curoverse.com
Tue Mar 20 16:58:04 EDT 2018


        at  7633b9438d0c75693eb167c146b26764dd7161ed (commit)


commit 7633b9438d0c75693eb167c146b26764dd7161ed
Author: Tom Clegg <tclegg at veritasgenetics.com>
Date:   Tue Mar 20 16:56:16 2018 -0400

    13111: Add /users virtual dir to siteFS.
    
    Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tclegg at veritasgenetics.com>

diff --git a/lib/mount/fs.go b/lib/mount/fs.go
index d269779..1633296 100644
--- a/lib/mount/fs.go
+++ b/lib/mount/fs.go
@@ -33,7 +33,7 @@ type keepFS struct {
 	Uid        int
 	Gid        int
 
-	root   arvados.FileSystem
+	root   arvados.CustomFileSystem
 	open   map[uint64]*sharedFile
 	lastFH uint64
 	sync.Mutex
@@ -70,6 +70,7 @@ func (fs *keepFS) lookupFH(fh uint64) *sharedFile {
 func (fs *keepFS) Init() {
 	defer fs.debugPanics()
 	fs.root = fs.Client.SiteFileSystem(fs.KeepClient)
+	fs.root.MountProject("home", "")
 	if fs.ready != nil {
 		close(fs.ready)
 	}
diff --git a/sdk/go/arvados/fs_project.go b/sdk/go/arvados/fs_project.go
index 776c8a3..7f34a42 100644
--- a/sdk/go/arvados/fs_project.go
+++ b/sdk/go/arvados/fs_project.go
@@ -10,25 +10,31 @@ import (
 	"time"
 )
 
+type staleChecker struct {
+	mtx  sync.Mutex
+	last time.Time
+}
+
+func (sc *staleChecker) DoIfStale(fn func(), staleFunc func(time.Time) bool) {
+	sc.mtx.Lock()
+	defer sc.mtx.Unlock()
+	if !staleFunc(sc.last) {
+		return
+	}
+	sc.last = time.Now()
+	fn()
+}
+
 // projectnode exposes an Arvados project as a filesystem directory.
 type projectnode struct {
 	inode
+	staleChecker
 	uuid string
 	err  error
-
-	loadLock  sync.Mutex
-	loadStart time.Time
 }
 
 func (pn *projectnode) load() {
-	fs := pn.FS().(*siteFileSystem)
-
-	pn.loadLock.Lock()
-	defer pn.loadLock.Unlock()
-	if !fs.Stale(pn.loadStart) {
-		return
-	}
-	pn.loadStart = time.Now()
+	fs := pn.FS().(*customFileSystem)
 
 	if pn.uuid == "" {
 		var resp User
@@ -89,7 +95,7 @@ func (pn *projectnode) load() {
 }
 
 func (pn *projectnode) Readdir() ([]os.FileInfo, error) {
-	pn.load()
+	pn.staleChecker.DoIfStale(pn.load, pn.FS().(*customFileSystem).Stale)
 	if pn.err != nil {
 		return nil, pn.err
 	}
@@ -97,7 +103,7 @@ func (pn *projectnode) Readdir() ([]os.FileInfo, error) {
 }
 
 func (pn *projectnode) Child(name string, replace func(inode) (inode, error)) (inode, error) {
-	pn.load()
+	pn.staleChecker.DoIfStale(pn.load, pn.FS().(*customFileSystem).Stale)
 	if pn.err != nil {
 		return nil, pn.err
 	}
diff --git a/sdk/go/arvados/fs_site.go b/sdk/go/arvados/fs_site.go
index cdcf40e..b52a83e 100644
--- a/sdk/go/arvados/fs_site.go
+++ b/sdk/go/arvados/fs_site.go
@@ -10,22 +10,23 @@ import (
 	"time"
 )
 
-type siteFileSystem struct {
+type CustomFileSystem interface {
+	FileSystem
+	MountByID(mount string)
+	MountProject(mount, uuid string)
+	MountUsers(mount string)
+}
+
+type customFileSystem struct {
 	fileSystem
 
 	staleThreshold time.Time
 	staleLock      sync.Mutex
 }
 
-// SiteFileSystem returns a FileSystem that maps collections and other
-// Arvados objects onto a filesystem layout.
-//
-// This is experimental: the filesystem layout is not stable, and
-// there are significant known bugs and shortcomings. For example,
-// writes are not persisted until Sync() is called.
-func (c *Client) SiteFileSystem(kc keepClient) FileSystem {
+func (c *Client) CustomFileSystem(kc keepClient) CustomFileSystem {
 	root := &vdirnode{}
-	fs := &siteFileSystem{
+	fs := &customFileSystem{
 		fileSystem: fileSystem{
 			fsBackend: keepBackend{apiClient: c, keepClient: kc},
 			root:      root,
@@ -41,14 +42,18 @@ func (c *Client) SiteFileSystem(kc keepClient) FileSystem {
 		},
 		inodes: make(map[string]inode),
 	}
-	root.inode.Child("by_id", func(inode) (inode, error) {
+	return fs
+}
+
+func (fs *customFileSystem) MountByID(mount string) {
+	fs.root.Child(mount, func(inode) (inode, error) {
 		return &vdirnode{
 			inode: &treenode{
 				fs:     fs,
 				parent: fs.root,
 				inodes: make(map[string]inode),
 				fileinfo: fileinfo{
-					name:    "by_id",
+					name:    mount,
 					modTime: time.Now(),
 					mode:    0755 | os.ModeDir,
 				},
@@ -56,13 +61,45 @@ func (c *Client) SiteFileSystem(kc keepClient) FileSystem {
 			create: fs.mountCollection,
 		}, nil
 	})
-	root.inode.Child("home", func(inode) (inode, error) {
-		return fs.newProjectNode(fs.root, "home", ""), nil
+}
+
+func (fs *customFileSystem) MountProject(mount, uuid string) {
+	fs.root.Child(mount, func(inode) (inode, error) {
+		return fs.newProjectNode(fs.root, mount, uuid), nil
 	})
+}
+
+func (fs *customFileSystem) MountUsers(mount string) {
+	fs.root.Child(mount, func(inode) (inode, error) {
+		return &usersnode{
+			inode: &treenode{
+				fs:     fs,
+				parent: fs.root,
+				inodes: make(map[string]inode),
+				fileinfo: fileinfo{
+					name:    mount,
+					modTime: time.Now(),
+					mode:    0755 | os.ModeDir,
+				},
+			},
+		}, nil
+	})
+}
+
+// SiteFileSystem returns a FileSystem that maps collections and other
+// Arvados objects onto a filesystem layout.
+//
+// This is experimental: the filesystem layout is not stable, and
+// there are significant known bugs and shortcomings. For example,
+// writes are not persisted until Sync() is called.
+func (c *Client) SiteFileSystem(kc keepClient) CustomFileSystem {
+	fs := c.CustomFileSystem(kc)
+	fs.MountByID("by_id")
+	fs.MountUsers("users")
 	return fs
 }
 
-func (fs *siteFileSystem) Sync() error {
+func (fs *customFileSystem) Sync() error {
 	fs.staleLock.Lock()
 	defer fs.staleLock.Unlock()
 	fs.staleThreshold = time.Now()
@@ -71,17 +108,17 @@ func (fs *siteFileSystem) Sync() error {
 
 // Stale returns true if information obtained at time t should be
 // considered stale.
-func (fs *siteFileSystem) Stale(t time.Time) bool {
+func (fs *customFileSystem) Stale(t time.Time) bool {
 	fs.staleLock.Lock()
 	defer fs.staleLock.Unlock()
 	return !fs.staleThreshold.Before(t)
 }
 
-func (fs *siteFileSystem) newNode(name string, perm os.FileMode, modTime time.Time) (node inode, err error) {
+func (fs *customFileSystem) newNode(name string, perm os.FileMode, modTime time.Time) (node inode, err error) {
 	return nil, ErrInvalidOperation
 }
 
-func (fs *siteFileSystem) mountCollection(parent inode, id string) inode {
+func (fs *customFileSystem) mountCollection(parent inode, id string) inode {
 	var coll Collection
 	err := fs.RequestAndDecode(&coll, "GET", "arvados/v1/collections/"+id, nil, nil)
 	if err != nil {
@@ -96,7 +133,23 @@ func (fs *siteFileSystem) mountCollection(parent inode, id string) inode {
 	return root
 }
 
-func (fs *siteFileSystem) newProjectNode(root inode, name, uuid string) inode {
+func (fs *customFileSystem) newProjectNode(root inode, name, uuid string) inode {
+	return &projectnode{
+		uuid: uuid,
+		inode: &treenode{
+			fs:     fs,
+			parent: root,
+			inodes: make(map[string]inode),
+			fileinfo: fileinfo{
+				name:    name,
+				modTime: time.Now(),
+				mode:    0755 | os.ModeDir,
+			},
+		},
+	}
+}
+
+func (fs *customFileSystem) newUserNode(root inode, name, uuid string) inode {
 	return &projectnode{
 		uuid: uuid,
 		inode: &treenode{
diff --git a/sdk/go/arvados/fs_users.go b/sdk/go/arvados/fs_users.go
new file mode 100644
index 0000000..ccfe2c5
--- /dev/null
+++ b/sdk/go/arvados/fs_users.go
@@ -0,0 +1,62 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+package arvados
+
+import (
+	"os"
+)
+
+// usersnode is a virtual directory with an entry for each visible
+// Arvados username, each showing the respective user's "home
+// projects".
+type usersnode struct {
+	inode
+	staleChecker
+	err error
+}
+
+func (un *usersnode) load() {
+	fs := un.FS().(*customFileSystem)
+
+	params := ResourceListParams{
+		Order: "uuid",
+	}
+	for {
+		var resp UserList
+		un.err = fs.RequestAndDecode(&resp, "GET", "arvados/v1/users", nil, params)
+		if un.err != nil {
+			return
+		}
+		if len(resp.Items) == 0 {
+			break
+		}
+		for _, user := range resp.Items {
+			if user.Username == "" {
+				continue
+			}
+			un.inode.Child(user.Username, func(inode) (inode, error) {
+				return fs.newProjectNode(un, user.Username, user.UUID), nil
+			})
+		}
+		params.Filters = []Filter{{"uuid", ">", resp.Items[len(resp.Items)-1].UUID}}
+	}
+	un.err = nil
+}
+
+func (un *usersnode) Readdir() ([]os.FileInfo, error) {
+	un.staleChecker.DoIfStale(un.load, un.FS().(*customFileSystem).Stale)
+	if un.err != nil {
+		return nil, un.err
+	}
+	return un.inode.Readdir()
+}
+
+func (un *usersnode) Child(name string, _ func(inode) (inode, error)) (inode, error) {
+	un.staleChecker.DoIfStale(un.load, un.FS().(*customFileSystem).Stale)
+	if un.err != nil {
+		return nil, un.err
+	}
+	return un.inode.Child(name, nil)
+}
diff --git a/services/keep-web/handler.go b/services/keep-web/handler.go
index 19a2040..5ab4f70 100644
--- a/services/keep-web/handler.go
+++ b/services/keep-web/handler.go
@@ -236,7 +236,7 @@ func (h *handler) ServeHTTP(wOrig http.ResponseWriter, r *http.Request) {
 	pathParts := strings.Split(r.URL.Path[1:], "/")
 
 	var stripParts int
-	var targetID string
+	var collectionID string
 	var tokens []string
 	var reqTokens []string
 	var pathToken bool
@@ -250,7 +250,7 @@ func (h *handler) ServeHTTP(wOrig http.ResponseWriter, r *http.Request) {
 		attachment = true
 	}
 
-	if targetID = parseCollectionIDFromDNSName(r.Host); targetID != "" {
+	if collectionID = parseCollectionIDFromDNSName(r.Host); collectionID != "" {
 		// http://ID.collections.example/PATH...
 		credentialsOK = true
 	} else if r.URL.Path == "/status.json" {
@@ -258,28 +258,23 @@ func (h *handler) ServeHTTP(wOrig http.ResponseWriter, r *http.Request) {
 		return
 	} else if len(pathParts) >= 1 && strings.HasPrefix(pathParts[0], "c=") {
 		// /c=ID[/PATH...]
-		targetID = parseCollectionIDFromURL(pathParts[0][2:])
+		collectionID = parseCollectionIDFromURL(pathParts[0][2:])
 		stripParts = 1
 	} else if len(pathParts) >= 2 && pathParts[0] == "collections" {
 		if len(pathParts) >= 4 && pathParts[1] == "download" {
 			// /collections/download/ID/TOKEN/PATH...
-			targetID = parseCollectionIDFromURL(pathParts[2])
+			collectionID = parseCollectionIDFromURL(pathParts[2])
 			tokens = []string{pathParts[3]}
 			stripParts = 4
 			pathToken = true
 		} else {
 			// /collections/ID/PATH...
-			targetID = parseCollectionIDFromURL(pathParts[1])
+			collectionID = parseCollectionIDFromURL(pathParts[1])
 			tokens = h.Config.AnonymousTokens
 			stripParts = 2
 		}
 	}
 
-	if targetID == "" {
-		statusCode = http.StatusNotFound
-		return
-	}
-
 	formToken := r.FormValue("api_token")
 	if formToken != "" && r.Header.Get("Origin") != "" && attachment && r.URL.Query().Get("api_token") == "" {
 		// The client provided an explicit token in the POST
@@ -347,7 +342,7 @@ func (h *handler) ServeHTTP(wOrig http.ResponseWriter, r *http.Request) {
 	tokenResult := make(map[string]int)
 	for _, arv.ApiToken = range tokens {
 		var err error
-		collection, err = h.Config.Cache.Get(arv, targetID, forceReload)
+		collection, err = h.Config.Cache.Get(arv, collectionID, forceReload)
 		if err == nil {
 			// Success
 			break
@@ -414,14 +409,21 @@ func (h *handler) ServeHTTP(wOrig http.ResponseWriter, r *http.Request) {
 		AuthToken: arv.ApiToken,
 		Insecure:  arv.ApiInsecure,
 	}
-	fs, err := collection.FileSystem(client, kc)
+
+	var fs arvados.FileSystem
+	if collectionID == "" {
+		fs = client.SiteFileSystem(kc)
+	} else {
+		fs, err = collection.FileSystem(client, kc)
+	}
 	if err != nil {
 		statusCode, statusText = http.StatusInternalServerError, err.Error()
 		return
 	}
 
-	targetIsPDH := arvadosclient.PDHMatch(targetID)
-	if targetIsPDH && writeMethod[r.Method] {
+	writefs, writeOK := fs.(arvados.CollectionFileSystem)
+	targetIsPDH := arvadosclient.PDHMatch(collectionID)
+	if (targetIsPDH || !writeOK) && writeMethod[r.Method] {
 		statusCode, statusText = http.StatusMethodNotAllowed, errReadOnly.Error()
 		return
 	}
@@ -435,7 +437,7 @@ func (h *handler) ServeHTTP(wOrig http.ResponseWriter, r *http.Request) {
 			w = &updateOnSuccess{
 				ResponseWriter: w,
 				update: func() error {
-					return h.Config.Cache.Update(client, *collection, fs)
+					return h.Config.Cache.Update(client, *collection, writefs)
 				}}
 		}
 		h := webdav.Handler{
diff --git a/services/keep-web/webdav.go b/services/keep-web/webdav.go
index af83681..941090a 100644
--- a/services/keep-web/webdav.go
+++ b/services/keep-web/webdav.go
@@ -36,7 +36,7 @@ var (
 // existence automatically so sequences like "mkcol foo; put foo/bar"
 // work as expected.
 type webdavFS struct {
-	collfs  arvados.CollectionFileSystem
+	collfs  arvados.FileSystem
 	writing bool
 	// webdav PROPFIND reads the first few bytes of each file
 	// whose filename extension isn't recognized, which is

commit 161de9f7fe71e328837df5c053f3663bc59245f3
Author: Tom Clegg <tclegg at veritasgenetics.com>
Date:   Tue Mar 20 10:52:09 2018 -0400

    13111: Add tests for /users/ paths.
    
    Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tclegg at veritasgenetics.com>

diff --git a/services/keep-web/cadaver_test.go b/services/keep-web/cadaver_test.go
index b7ec1de..5f5f69a 100644
--- a/services/keep-web/cadaver_test.go
+++ b/services/keep-web/cadaver_test.go
@@ -22,24 +22,33 @@ import (
 )
 
 func (s *IntegrationSuite) TestCadaverHTTPAuth(c *check.C) {
-	s.testCadaver(c, arvadostest.ActiveToken, func(newUUID string) (string, string, string) {
+	s.testCadaver(c, arvadostest.ActiveToken, func(newCollection arvados.Collection) (string, string, string) {
 		r := "/c=" + arvadostest.FooAndBarFilesInDirUUID + "/"
-		w := "/c=" + newUUID + "/"
+		w := "/c=" + newCollection.UUID + "/"
 		pdh := "/c=" + strings.Replace(arvadostest.FooAndBarFilesInDirPDH, "+", "-", -1) + "/"
 		return r, w, pdh
 	})
 }
 
 func (s *IntegrationSuite) TestCadaverPathAuth(c *check.C) {
-	s.testCadaver(c, "", func(newUUID string) (string, string, string) {
+	s.testCadaver(c, "", func(newCollection arvados.Collection) (string, string, string) {
 		r := "/c=" + arvadostest.FooAndBarFilesInDirUUID + "/t=" + arvadostest.ActiveToken + "/"
-		w := "/c=" + newUUID + "/t=" + arvadostest.ActiveToken + "/"
+		w := "/c=" + newCollection.UUID + "/t=" + arvadostest.ActiveToken + "/"
 		pdh := "/c=" + strings.Replace(arvadostest.FooAndBarFilesInDirPDH, "+", "-", -1) + "/t=" + arvadostest.ActiveToken + "/"
 		return r, w, pdh
 	})
 }
 
-func (s *IntegrationSuite) testCadaver(c *check.C, password string, pathFunc func(string) (string, string, string)) {
+func (s *IntegrationSuite) TestCadaverUserProject(c *check.C) {
+	s.testCadaver(c, arvadostest.ActiveToken, func(newCollection arvados.Collection) (string, string, string) {
+		r := "/users/active/foo_file_in_dir/"
+		w := "/users/active/" + newCollection.Name
+		pdh := "/c=" + strings.Replace(arvadostest.FooAndBarFilesInDirPDH, "+", "-", -1) + "/"
+		return r, w, pdh
+	})
+}
+
+func (s *IntegrationSuite) testCadaver(c *check.C, password string, pathFunc func(arvados.Collection) (string, string, string)) {
 	testdata := []byte("the human tragedy consists in the necessity of living with the consequences of actions performed under the pressure of compulsions we do not understand")
 
 	tempdir, err := ioutil.TempDir("", "keep-web-test-")
@@ -62,7 +71,7 @@ func (s *IntegrationSuite) testCadaver(c *check.C, password string, pathFunc fun
 	err = arv.RequestAndDecode(&newCollection, "POST", "/arvados/v1/collections", bytes.NewBufferString(url.Values{"collection": {"{}"}}.Encode()), nil)
 	c.Assert(err, check.IsNil)
 
-	readPath, writePath, pdhPath := pathFunc(newCollection.UUID)
+	readPath, writePath, pdhPath := pathFunc(newCollection)
 
 	matchToday := time.Now().Format("Jan +2")
 
diff --git a/services/keep-web/handler_test.go b/services/keep-web/handler_test.go
index 21e47c8..a8f8c83 100644
--- a/services/keep-web/handler_test.go
+++ b/services/keep-web/handler_test.go
@@ -62,6 +62,7 @@ func (s *UnitSuite) TestInvalidUUID(c *check.C) {
 	for _, trial := range []string{
 		"http://keep-web/c=" + bogusID + "/foo",
 		"http://keep-web/c=" + bogusID + "/t=" + token + "/foo",
+		"http://keep-web/users/active/" + bogusID + "/foo",
 		"http://keep-web/collections/download/" + bogusID + "/" + token + "/foo",
 		"http://keep-web/collections/" + bogusID + "/foo",
 		"http://" + bogusID + ".keep-web/" + bogusID + "/foo",
@@ -517,6 +518,12 @@ func (s *IntegrationSuite) TestDirectoryListing(c *check.C) {
 			cutDirs: 2,
 		},
 		{
+			uri:     "download.example.com/users/active/" + arvadostest.FooAndBarFilesInDirUUID + "/",
+			header:  authHeader,
+			expect:  []string{"dir1/foo", "dir1/bar"},
+			cutDirs: 3,
+		},
+		{
 			uri:     "collections.example.com/collections/download/" + arvadostest.FooAndBarFilesInDirUUID + "/" + arvadostest.ActiveToken + "/",
 			header:  nil,
 			expect:  []string{"dir1/foo", "dir1/bar"},

commit 0d5f2f7c474724871f05bad1308c66e68c9d7473
Author: Tom Clegg <tclegg at veritasgenetics.com>
Date:   Tue Mar 20 10:00:36 2018 -0400

    13111: Test webdav with http basic authentication.
    
    Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tclegg at veritasgenetics.com>

diff --git a/services/keep-web/cadaver_test.go b/services/keep-web/cadaver_test.go
index eb32367..b7ec1de 100644
--- a/services/keep-web/cadaver_test.go
+++ b/services/keep-web/cadaver_test.go
@@ -6,11 +6,13 @@ package main
 
 import (
 	"bytes"
+	"fmt"
 	"io"
 	"io/ioutil"
 	"net/url"
 	"os"
 	"os/exec"
+	"path/filepath"
 	"strings"
 	"time"
 
@@ -19,34 +21,51 @@ import (
 	check "gopkg.in/check.v1"
 )
 
-func (s *IntegrationSuite) TestWebdavWithCadaver(c *check.C) {
+func (s *IntegrationSuite) TestCadaverHTTPAuth(c *check.C) {
+	s.testCadaver(c, arvadostest.ActiveToken, func(newUUID string) (string, string, string) {
+		r := "/c=" + arvadostest.FooAndBarFilesInDirUUID + "/"
+		w := "/c=" + newUUID + "/"
+		pdh := "/c=" + strings.Replace(arvadostest.FooAndBarFilesInDirPDH, "+", "-", -1) + "/"
+		return r, w, pdh
+	})
+}
+
+func (s *IntegrationSuite) TestCadaverPathAuth(c *check.C) {
+	s.testCadaver(c, "", func(newUUID string) (string, string, string) {
+		r := "/c=" + arvadostest.FooAndBarFilesInDirUUID + "/t=" + arvadostest.ActiveToken + "/"
+		w := "/c=" + newUUID + "/t=" + arvadostest.ActiveToken + "/"
+		pdh := "/c=" + strings.Replace(arvadostest.FooAndBarFilesInDirPDH, "+", "-", -1) + "/t=" + arvadostest.ActiveToken + "/"
+		return r, w, pdh
+	})
+}
+
+func (s *IntegrationSuite) testCadaver(c *check.C, password string, pathFunc func(string) (string, string, string)) {
 	testdata := []byte("the human tragedy consists in the necessity of living with the consequences of actions performed under the pressure of compulsions we do not understand")
 
-	localfile, err := ioutil.TempFile("", "localfile")
+	tempdir, err := ioutil.TempDir("", "keep-web-test-")
+	c.Assert(err, check.IsNil)
+	defer os.RemoveAll(tempdir)
+
+	localfile, err := ioutil.TempFile(tempdir, "localfile")
 	c.Assert(err, check.IsNil)
-	defer os.Remove(localfile.Name())
 	localfile.Write(testdata)
 
-	emptyfile, err := ioutil.TempFile("", "emptyfile")
+	emptyfile, err := ioutil.TempFile(tempdir, "emptyfile")
 	c.Assert(err, check.IsNil)
-	defer os.Remove(emptyfile.Name())
 
-	checkfile, err := ioutil.TempFile("", "checkfile")
+	checkfile, err := ioutil.TempFile(tempdir, "checkfile")
 	c.Assert(err, check.IsNil)
-	defer os.Remove(checkfile.Name())
 
 	var newCollection arvados.Collection
 	arv := arvados.NewClientFromEnv()
 	arv.AuthToken = arvadostest.ActiveToken
 	err = arv.RequestAndDecode(&newCollection, "POST", "/arvados/v1/collections", bytes.NewBufferString(url.Values{"collection": {"{}"}}.Encode()), nil)
 	c.Assert(err, check.IsNil)
-	writePath := "/c=" + newCollection.UUID + "/t=" + arv.AuthToken + "/"
 
-	pdhPath := "/c=" + strings.Replace(arvadostest.FooAndBarFilesInDirPDH, "+", "-", -1) + "/t=" + arv.AuthToken + "/"
+	readPath, writePath, pdhPath := pathFunc(newCollection.UUID)
 
 	matchToday := time.Now().Format("Jan +2")
 
-	readPath := "/c=" + arvadostest.FooAndBarFilesInDirUUID + "/t=" + arvadostest.ActiveToken + "/"
 	type testcase struct {
 		path  string
 		cmd   string
@@ -215,6 +234,22 @@ func (s *IntegrationSuite) TestWebdavWithCadaver(c *check.C) {
 		os.Remove(checkfile.Name())
 
 		cmd := exec.Command("cadaver", "http://"+s.testServer.Addr+trial.path)
+		if password != "" {
+			// cadaver won't try username/password
+			// authentication unless the server responds
+			// 401 to an unauthenticated request, which it
+			// only does in AttachmentOnlyHost,
+			// TrustAllContent, and per-collection vhost
+			// cases.
+			s.testServer.Config.AttachmentOnlyHost = s.testServer.Addr
+
+			cmd.Env = append(os.Environ(), "HOME="+tempdir)
+			f, err := os.OpenFile(filepath.Join(tempdir, ".netrc"), os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0600)
+			c.Assert(err, check.IsNil)
+			_, err = fmt.Fprintf(f, "default login none password %s\n", password)
+			c.Assert(err, check.IsNil)
+			c.Assert(f.Close(), check.IsNil)
+		}
 		cmd.Stdin = bytes.NewBufferString(trial.cmd)
 		stdout, err := cmd.StdoutPipe()
 		c.Assert(err, check.Equals, nil)

-----------------------------------------------------------------------


hooks/post-receive
-- 




More information about the arvados-commits mailing list