]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/blob - src/allmydata/nodemaker.py
tests: double the timeout on test_runner.RunNode.test_introducer since feisty hit...
[tahoe-lafs/tahoe-lafs.git] / src / allmydata / nodemaker.py
1 import weakref
2 from allmydata.immutable.filenode import FileNode, LiteralFileNode
3 from allmydata.mutable.filenode import MutableFileNode
4 from allmydata.dirnode import DirectoryNode
5 from allmydata.unknown import UnknownNode
6 from allmydata.uri import DirectoryURI, ReadonlyDirectoryURI
7
8 # the "node maker" is a two-argument callable (really a 'create' method on a
9 # NodeMaker instance) which accepts a URI string (and an optional readcap
10 # string, for use by dirnode.copy) and returns an object which (at the very
11 # least) provides IFilesystemNode. That interface has other methods that can
12 # be used to determine if the node represents a file or directory, in which
13 # case other methods are available (like download() or modify()). Each Tahoe
14 # process will typically have a single NodeMaker, but unit tests may create
15 # simplified/mocked forms for test purposes.
16
17 # any authorities which fsnodes will need (like a reference to the
18 # StorageFarmBroker, to access storage servers for publish/retrieve/download)
19 # will be retained as attributes inside the NodeMaker and passed to fsnodes
20 # as necessary.
21
22 class NodeMaker:
23     def __init__(self, storage_broker, secret_holder, history,
24                  uploader, downloader, download_cache_dirman,
25                  default_encoding_parameters, key_generator):
26         self.storage_broker = storage_broker
27         self.secret_holder = secret_holder
28         self.history = history
29         self.uploader = uploader
30         self.downloader = downloader
31         self.download_cache_dirman = download_cache_dirman
32         self.default_encoding_parameters = default_encoding_parameters
33         self.key_generator = key_generator
34
35         self._node_cache = weakref.WeakValueDictionary() # uri -> node
36
37     def _create_lit(self, cap):
38         return LiteralFileNode(cap)
39     def _create_immutable(self, cap):
40         return FileNode(cap, self.storage_broker, self.secret_holder,
41                         self.downloader, self.history,
42                         self.download_cache_dirman)
43     def _create_mutable(self, cap):
44         n = MutableFileNode(self.storage_broker, self.secret_holder,
45                             self.default_encoding_parameters,
46                             self.history)
47         return n.init_from_uri(cap)
48     def _create_dirnode(self, filenode):
49         return DirectoryNode(filenode, self, self.uploader)
50
51     def create_from_cap(self, writecap, readcap=None):
52         # this returns synchronously.
53         assert isinstance(writecap, (str, type(None))), type(writecap)
54         assert isinstance(readcap,  (str, type(None))), type(readcap)
55         cap = writecap or readcap
56         if not cap:
57             # maybe the writecap was hidden because we're in a readonly
58             # directory, and the future cap format doesn't have a readcap, or
59             # something.
60             return UnknownNode(writecap, readcap)
61         if cap in self._node_cache:
62             return self._node_cache[cap]
63         elif cap.startswith("URI:LIT:"):
64             node = self._create_lit(cap)
65         elif cap.startswith("URI:CHK:"):
66             node = self._create_immutable(cap)
67         elif cap.startswith("URI:SSK-RO:") or cap.startswith("URI:SSK:"):
68             node = self._create_mutable(cap)
69         elif cap.startswith("URI:DIR2-RO:") or cap.startswith("URI:DIR2:"):
70             if cap.startswith("URI:DIR2-RO:"):
71                 dircap = ReadonlyDirectoryURI.init_from_string(cap)
72             elif cap.startswith("URI:DIR2:"):
73                 dircap = DirectoryURI.init_from_string(cap)
74             filecap = dircap.get_filenode_uri().to_string()
75             filenode = self.create_from_cap(filecap)
76             node = self._create_dirnode(filenode)
77         else:
78             return UnknownNode(writecap, readcap) # don't cache UnknownNode
79         self._node_cache[cap] = node  # note: WeakValueDictionary
80         return node
81
82
83     def create_mutable_file(self, contents="", keysize=None):
84         n = MutableFileNode(self.storage_broker, self.secret_holder,
85                             self.default_encoding_parameters, self.history)
86         d = self.key_generator.generate(keysize)
87         d.addCallback(n.create_with_keys, contents)
88         d.addCallback(lambda res: n)
89         return d
90
91     def create_new_mutable_directory(self, initial_children={}):
92         if initial_children:
93             raise NotImplementedError("initial_children= not implemented yet")
94         d = self.create_mutable_file()
95         d.addCallback(self._create_dirnode)
96         return d