13111: Save on sync().
[arvados.git] / sdk / go / arvados / fs_site.go
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: Apache-2.0
4
5 package arvados
6
7 import (
8         "os"
9         "time"
10 )
11
12 // SiteFileSystem returns a FileSystem that maps collections and other
13 // Arvados objects onto a filesystem layout.
14 //
15 // This is experimental: the filesystem layout is not stable, and
16 // there are significant known bugs and shortcomings. For example,
17 // although the FileSystem allows files to be added and modified in
18 // collections, these changes are not persistent or visible to other
19 // Arvados clients.
20 func (c *Client) SiteFileSystem(kc keepClient) FileSystem {
21         fs := &fileSystem{
22                 fsBackend: keepBackend{apiClient: c, keepClient: kc},
23         }
24         root := &treenode{
25                 fs: fs,
26                 fileinfo: fileinfo{
27                         name:    "/",
28                         mode:    os.ModeDir | 0755,
29                         modTime: time.Now(),
30                 },
31                 inodes: make(map[string]inode),
32         }
33         root.parent = root
34         root.Child("by_id", func(inode) inode {
35                 var vn inode
36                 vn = &vdirnode{
37                         treenode: treenode{
38                                 fs:     fs,
39                                 parent: root,
40                                 inodes: make(map[string]inode),
41                                 fileinfo: fileinfo{
42                                         name:    "by_id",
43                                         modTime: time.Now(),
44                                         mode:    0755 | os.ModeDir,
45                                 },
46                         },
47                         create: func(name string) inode {
48                                 return newEntByID(vn, name)
49                         },
50                 }
51                 return vn
52         })
53         fs.root = root
54         return fs
55 }
56
57 func newEntByID(parent inode, id string) inode {
58         var coll Collection
59         err := parent.FS().RequestAndDecode(&coll, "GET", "arvados/v1/collections/"+id, nil, nil)
60         if err != nil {
61                 return nil
62         }
63         fs, err := coll.FileSystem(parent.FS(), parent.FS())
64         if err != nil {
65                 return nil
66         }
67         root := fs.(*collectionFileSystem).root.(*dirnode)
68         root.fileinfo.name = id
69         root.parent = parent
70         return root
71 }
72
73 type vdirnode struct {
74         treenode
75         create func(string) inode
76 }
77
78 func (vn *vdirnode) Child(name string, _ func(inode) inode) inode {
79         return vn.treenode.Child(name, func(existing inode) inode {
80                 if existing != nil {
81                         return existing
82                 } else {
83                         return vn.create(name)
84                 }
85         })
86 }