8624: New behavior for by_tag/ dir. Allow 'cd' into any tag directory that
[arvados.git] / services / fuse / arvados_fuse / fusedir.py
index 15f75645b9730543e372f6464c7dddff0f89672f..399992fad369daacc81491dbf54c63d28c49b2f6 100644 (file)
@@ -1,3 +1,7 @@
+# Copyright (C) The Arvados Authors. All rights reserved.
+#
+# SPDX-License-Identifier: AGPL-3.0
+
 import logging
 import re
 import time
@@ -164,11 +168,11 @@ class Directory(FreshBase):
                 return True
         return False
 
-    def has_ref(self, only_children=False):
-        if not only_children and super(Directory, self).has_ref():
+    def has_ref(self, only_children):
+        if super(Directory, self).has_ref(only_children):
             return True
         for v in self._entries.itervalues():
-            if v.has_ref():
+            if v.has_ref(False):
                 return True
         return False
 
@@ -673,6 +677,7 @@ class TagsDirectory(Directory):
         self.num_retries = num_retries
         self._poll = True
         self._poll_time = poll_time
+        self._extra = set()
 
     def want_event_subscribe(self):
         return True
@@ -681,15 +686,30 @@ class TagsDirectory(Directory):
     def update(self):
         with llfuse.lock_released:
             tags = self.api.links().list(
-                filters=[['link_class', '=', 'tag']],
-                select=['name'], distinct=True
+                filters=[['link_class', '=', 'tag'], ["name", "!=", ""]],
+                select=['name'], distinct=True, limit=1000
                 ).execute(num_retries=self.num_retries)
         if "items" in tags:
-            self.merge(tags['items'],
+            self.merge(tags['items']+[{"name": n} for n in self._extra],
                        lambda i: i['name'],
                        lambda a, i: a.tag == i['name'],
                        lambda i: TagDirectory(self.inode, self.inodes, self.api, self.num_retries, i['name'], poll=self._poll, poll_time=self._poll_time))
 
+    def __contains__(self, k):
+        if super(TagsDirectory, self).__contains__(k):
+            return True
+        else:
+            with llfuse.lock_released:
+                tags = self.api.links().list(
+                    filters=[['link_class', '=', 'tag'], ['name', '=', k]], limit=1
+                ).execute(num_retries=self.num_retries)
+            if tags["items"]:
+                self._extra.add(k)
+                self.invalidate()
+                return True
+            else:
+                return False
+
 
 class TagDirectory(Directory):
     """A special directory that contains as subdirectories all collections visible