Merge branch 'master' into 13804-no-shutdown-wanted-nodes
[arvados.git] / sdk / go / arvados / fs_project.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         "log"
9         "os"
10         "strings"
11 )
12
13 func (fs *customFileSystem) defaultUUID(uuid string) (string, error) {
14         if uuid != "" {
15                 return uuid, nil
16         }
17         var resp User
18         err := fs.RequestAndDecode(&resp, "GET", "arvados/v1/users/current", nil, nil)
19         if err != nil {
20                 return "", err
21         }
22         return resp.UUID, nil
23 }
24
25 // loadOneChild loads only the named child, if it exists.
26 func (fs *customFileSystem) projectsLoadOne(parent inode, uuid, name string) (inode, error) {
27         uuid, err := fs.defaultUUID(uuid)
28         if err != nil {
29                 return nil, err
30         }
31
32         var contents CollectionList
33         err = fs.RequestAndDecode(&contents, "GET", "arvados/v1/groups/"+uuid+"/contents", nil, ResourceListParams{
34                 Count: "none",
35                 Filters: []Filter{
36                         {"name", "=", name},
37                         {"uuid", "is_a", []string{"arvados#collection", "arvados#group"}},
38                         {"groups.group_class", "=", "project"},
39                 },
40         })
41         if err != nil {
42                 return nil, err
43         }
44         if len(contents.Items) == 0 {
45                 return nil, os.ErrNotExist
46         }
47         coll := contents.Items[0]
48
49         if strings.Contains(coll.UUID, "-j7d0g-") {
50                 // Group item was loaded into a Collection var -- but
51                 // we only need the Name and UUID anyway, so it's OK.
52                 return fs.newProjectNode(parent, coll.Name, coll.UUID), nil
53         } else if strings.Contains(coll.UUID, "-4zz18-") {
54                 return deferredCollectionFS(fs, parent, coll), nil
55         } else {
56                 log.Printf("projectnode: unrecognized UUID in response: %q", coll.UUID)
57                 return nil, ErrInvalidArgument
58         }
59 }
60
61 func (fs *customFileSystem) projectsLoadAll(parent inode, uuid string) ([]inode, error) {
62         uuid, err := fs.defaultUUID(uuid)
63         if err != nil {
64                 return nil, err
65         }
66
67         var inodes []inode
68
69         // Note: the "filters" slice's backing array might be reused
70         // by append(filters,...) below. This isn't goroutine safe,
71         // but all accesses are in the same goroutine, so it's OK.
72         filters := []Filter{{"owner_uuid", "=", uuid}}
73         params := ResourceListParams{
74                 Count:   "none",
75                 Filters: filters,
76                 Order:   "uuid",
77         }
78         for {
79                 var resp CollectionList
80                 err = fs.RequestAndDecode(&resp, "GET", "arvados/v1/collections", nil, params)
81                 if err != nil {
82                         return nil, err
83                 }
84                 if len(resp.Items) == 0 {
85                         break
86                 }
87                 for _, i := range resp.Items {
88                         coll := i
89                         if !permittedName(coll.Name) {
90                                 continue
91                         }
92                         inodes = append(inodes, deferredCollectionFS(fs, parent, coll))
93                 }
94                 params.Filters = append(filters, Filter{"uuid", ">", resp.Items[len(resp.Items)-1].UUID})
95         }
96
97         filters = append(filters, Filter{"group_class", "=", "project"})
98         params.Filters = filters
99         for {
100                 var resp GroupList
101                 err = fs.RequestAndDecode(&resp, "GET", "arvados/v1/groups", nil, params)
102                 if err != nil {
103                         return nil, err
104                 }
105                 if len(resp.Items) == 0 {
106                         break
107                 }
108                 for _, group := range resp.Items {
109                         if !permittedName(group.Name) {
110                                 continue
111                         }
112                         inodes = append(inodes, fs.newProjectNode(parent, group.Name, group.UUID))
113                 }
114                 params.Filters = append(filters, Filter{"uuid", ">", resp.Items[len(resp.Items)-1].UUID})
115         }
116         return inodes, nil
117 }