import (
"os"
"sync"
+ "time"
)
// projectnode exposes an Arvados project as a filesystem directory.
type projectnode struct {
inode
- uuid string
- setupOnce sync.Once
- err error
+ uuid string
+ err error
+
+ loadLock sync.Mutex
+ loadStart time.Time
}
-func (pn *projectnode) setup() {
+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()
+
if pn.uuid == "" {
var resp User
pn.err = fs.RequestAndDecode(&resp, "GET", "arvados/v1/users/current", nil, nil)
var resp CollectionList
pn.err = fs.RequestAndDecode(&resp, "GET", "arvados/v1/collections", nil, params)
if pn.err != nil {
- // TODO: retry on next access, instead of returning the same error forever
return
}
if len(resp.Items) == 0 {
var resp GroupList
pn.err = fs.RequestAndDecode(&resp, "GET", "arvados/v1/groups", nil, params)
if pn.err != nil {
- // TODO: retry on next access, instead of returning the same error forever
return
}
if len(resp.Items) == 0 {
}
params.Filters = append(filters, Filter{"uuid", ">", resp.Items[len(resp.Items)-1].UUID})
}
+ pn.err = nil
}
func (pn *projectnode) Readdir() ([]os.FileInfo, error) {
- pn.setupOnce.Do(pn.setup)
+ pn.load()
if pn.err != nil {
return nil, pn.err
}
}
func (pn *projectnode) Child(name string, replace func(inode) (inode, error)) (inode, error) {
- pn.setupOnce.Do(pn.setup)
+ pn.load()
if pn.err != nil {
return nil, pn.err
}
"io"
"os"
+ "git.curoverse.com/arvados.git/sdk/go/arvadostest"
check "gopkg.in/check.v1"
)
ok := false
for _, fi := range fis {
c.Check(fi.Name(), check.Not(check.Equals), "")
- if fi.Name() == "Unrestricted public data" {
+ if fi.Name() == "A Project" {
ok = true
}
}
c.Check(ok, check.Equals, true)
- f, err = s.fs.Open("/home/Unrestricted public data/..")
+ f, err = s.fs.Open("/home/A Project/..")
c.Assert(err, check.IsNil)
fi, err := f.Stat()
c.Check(err, check.IsNil)
c.Check(fi.IsDir(), check.Equals, true)
c.Check(fi.Name(), check.Equals, "home")
- f, err = s.fs.Open("/home/Unrestricted public data/Subproject in anonymous accessible project")
+ f, err = s.fs.Open("/home/A Project/A Subproject")
c.Check(err, check.IsNil)
fi, err = f.Stat()
c.Check(err, check.IsNil)
c.Check(fi.IsDir(), check.Equals, true)
for _, nx := range []string{
- "/home/A Project",
- "/home/A Project/does not exist",
+ "/home/Unrestricted public data",
"/home/Unrestricted public data/does not exist",
+ "/home/A Project/does not exist",
} {
c.Log(nx)
f, err = s.fs.Open(nx)
c.Check(os.IsNotExist(err), check.Equals, true)
}
}
+
+func (s *SiteFSSuite) TestProjectUpdatedByOther(c *check.C) {
+ project, err := s.fs.OpenFile("/home/A Project", 0, 0)
+ c.Check(err, check.IsNil)
+
+ _, err = s.fs.Open("/home/A Project/oob")
+ c.Check(err, check.NotNil)
+
+ oob := Collection{
+ Name: "oob",
+ OwnerUUID: arvadostest.AProjectUUID,
+ }
+ err = s.client.RequestAndDecode(&oob, "POST", "arvados/v1/collections", s.client.UpdateBody(&oob), nil)
+ c.Assert(err, check.IsNil)
+ defer s.client.RequestAndDecode(nil, "DELETE", "arvados/v1/collections/"+oob.UUID, nil, nil)
+
+ err = project.Sync()
+ c.Check(err, check.IsNil)
+ f, err := s.fs.Open("/home/A Project/oob")
+ c.Assert(err, check.IsNil)
+ fi, err := f.Stat()
+ c.Check(fi.IsDir(), check.Equals, true)
+ f.Close()
+
+ wf, err := s.fs.OpenFile("/home/A Project/oob/test.txt", os.O_CREATE|os.O_RDWR, 0700)
+ c.Assert(err, check.IsNil)
+ _, err = wf.Write([]byte("hello oob\n"))
+ c.Check(err, check.IsNil)
+ err = wf.Close()
+ c.Check(err, check.IsNil)
+
+ // Delete test.txt behind s.fs's back by updating the
+ // collection record with the old (empty) ManifestText.
+ err = s.client.RequestAndDecode(nil, "PATCH", "arvados/v1/collections/"+oob.UUID, s.client.UpdateBody(&oob), nil)
+ c.Assert(err, check.IsNil)
+
+ err = project.Sync()
+ c.Check(err, check.IsNil)
+ _, err = s.fs.Open("/home/A Project/oob/test.txt")
+ c.Check(err, check.NotNil)
+ _, err = s.fs.Open("/home/A Project/oob")
+ c.Check(err, check.IsNil)
+
+ err = s.client.RequestAndDecode(nil, "DELETE", "arvados/v1/collections/"+oob.UUID, nil, nil)
+ c.Assert(err, check.IsNil)
+
+ err = project.Sync()
+ c.Check(err, check.IsNil)
+ _, err = s.fs.Open("/home/A Project/oob")
+ c.Check(err, check.NotNil)
+}