X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/df591042778408d03d410d5c22a669d85652d1ea..3e1c43866e5b523c3f1d273c25942ad56dc66d3f:/sdk/go/arvados/fs_site.go diff --git a/sdk/go/arvados/fs_site.go b/sdk/go/arvados/fs_site.go index cdcf40e114..82114e2ea9 100644 --- a/sdk/go/arvados/fs_site.go +++ b/sdk/go/arvados/fs_site.go @@ -6,26 +6,30 @@ package arvados import ( "os" + "strings" "sync" "time" ) -type siteFileSystem struct { +type CustomFileSystem interface { + FileSystem + MountByID(mount string) + MountProject(mount, uuid string) + MountUsers(mount string) +} + +type customFileSystem struct { fileSystem + root *vdirnode 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{ + root: root, fileSystem: fileSystem{ fsBackend: keepBackend{apiClient: c, keepClient: kc}, root: root, @@ -41,28 +45,67 @@ 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.inode.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, }, }, - create: fs.mountCollection, + create: fs.mountByID, }, 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.inode.Child(mount, func(inode) (inode, error) { + return fs.newProjectNode(fs.root, mount, uuid), nil + }) +} + +func (fs *customFileSystem) MountUsers(mount string) { + fs.root.inode.Child(mount, func(inode) (inode, error) { + return &lookupnode{ + stale: fs.Stale, + loadOne: fs.usersLoadOne, + loadAll: fs.usersLoadAll, + 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 +114,27 @@ 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) mountByID(parent inode, id string) inode { + if strings.Contains(id, "-4zz18-") || pdhRegexp.MatchString(id) { + return fs.mountCollection(parent, id) + } else if strings.Contains(id, "-j7d0g-") { + return fs.newProjectNode(fs.root, id, id) + } else { + return nil + } +} + +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,9 +149,11 @@ func (fs *siteFileSystem) mountCollection(parent inode, id string) inode { return root } -func (fs *siteFileSystem) newProjectNode(root inode, name, uuid string) inode { - return &projectnode{ - uuid: uuid, +func (fs *customFileSystem) newProjectNode(root inode, name, uuid string) inode { + return &lookupnode{ + stale: fs.Stale, + loadOne: func(parent inode, name string) (inode, error) { return fs.projectsLoadOne(parent, uuid, name) }, + loadAll: func(parent inode) ([]inode, error) { return fs.projectsLoadAll(parent, uuid) }, inode: &treenode{ fs: fs, parent: root,