From: Brian Warner Date: Thu, 13 Oct 2011 16:32:29 +0000 (-0700) Subject: misc mutable-type fixes: X-Git-Url: https://git.rkrishnan.org/?p=tahoe-lafs%2Ftahoe-lafs.git;a=commitdiff_plain;h=210761cd49f9ba68522991c6c5f8addd05b3fd2c misc mutable-type fixes: * fix tahoe.cfg control of default mutable type * tolerate arbitrary case in [client]mutable.format value * small docs improvements * use get_mutable_type() as a format-is-mutable predicate * tighten up error message --- diff --git a/docs/frontends/webapi.rst b/docs/frontends/webapi.rst index 6365f441..49e8b1f1 100644 --- a/docs/frontends/webapi.rst +++ b/docs/frontends/webapi.rst @@ -379,15 +379,20 @@ Writing/Uploading A File immutable file, the "offset" parameter is not valid. When creating a new file, you can control the type of file created by - specifying a format= argument in the query string. format=MDMF creates an MDMF - mutable file. format=SDMF creates an SDMF mutable file. format=CHK creates an - immutable file. The value of the format argument is case-insensitive. For - compatibility with previous versions of Tahoe-LAFS, the webapi will also - accept a mutable=true argument in the query string. If mutable=true is given, - then the new file will be mutable, and its format will be the default mutable - file format, as configured on the Tahoe-LAFS node hosting the webapi server. - Use of mutable=true is discouraged; new code should use format= instead of - mutable=true. If neither format= nor mutable=true are given, the + specifying a format= argument in the query string. format=MDMF creates an + MDMF mutable file. format=SDMF creates an SDMF mutable file. format=CHK + creates an immutable file. The value of the format argument is + case-insensitive. If no format is specified, the newly-created file will be + immutable (but see below). + + For compatibility with previous versions of Tahoe-LAFS, the web-API will + also accept a mutable=true argument in the query string. If mutable=true is + given, then the new file will be mutable, and its format will be the default + mutable file format, as configured by the [client]mutable.format option of + tahoe.cfg on the Tahoe-LAFS node hosting the webapi server. Use of + mutable=true is discouraged; new code should use format= instead of + mutable=true (unless it needs to be compatible with web-API servers older + than v1.9.0). If neither format= nor mutable=true are given, the newly-created file will be immutable. This returns the file-cap of the resulting file. If a new file was created diff --git a/src/allmydata/client.py b/src/allmydata/client.py index aa55da7a..813ee395 100644 --- a/src/allmydata/client.py +++ b/src/allmydata/client.py @@ -339,19 +339,20 @@ class Client(node.Node, pollmixin.PollMixin): self.blacklist = Blacklist(fn) def init_nodemaker(self): + default = self.get_config("client", "mutable.format", default="SDMF") + if default.upper() == "MDMF": + self.mutable_file_default = MDMF_VERSION + else: + self.mutable_file_default = SDMF_VERSION self.nodemaker = NodeMaker(self.storage_broker, self._secret_holder, self.get_history(), self.getServiceNamed("uploader"), self.terminator, self.get_encoding_parameters(), + self.mutable_file_default, self._key_generator, self.blacklist) - default = self.get_config("client", "mutable.format", default="sdmf") - if default == "mdmf": - self.mutable_file_default = MDMF_VERSION - else: - self.mutable_file_default = SDMF_VERSION def get_history(self): return self.history @@ -507,8 +508,6 @@ class Client(node.Node, pollmixin.PollMixin): return self.nodemaker.create_immutable_directory(children, convergence) def create_mutable_file(self, contents=None, keysize=None, version=None): - if not version: - version = self.mutable_file_default return self.nodemaker.create_mutable_file(contents, keysize, version=version) diff --git a/src/allmydata/nodemaker.py b/src/allmydata/nodemaker.py index 6fdaf479..d0c9b4b6 100644 --- a/src/allmydata/nodemaker.py +++ b/src/allmydata/nodemaker.py @@ -1,7 +1,7 @@ import weakref from zope.interface import implements from allmydata.util.assertutil import precondition -from allmydata.interfaces import INodeMaker, SDMF_VERSION +from allmydata.interfaces import INodeMaker from allmydata.immutable.literal import LiteralFileNode from allmydata.immutable.filenode import ImmutableFileNode, CiphertextFileNode from allmydata.immutable.upload import Data @@ -18,14 +18,15 @@ class NodeMaker: def __init__(self, storage_broker, secret_holder, history, uploader, terminator, - default_encoding_parameters, key_generator, - blacklist=None): + default_encoding_parameters, mutable_file_default, + key_generator, blacklist=None): self.storage_broker = storage_broker self.secret_holder = secret_holder self.history = history self.uploader = uploader self.terminator = terminator self.default_encoding_parameters = default_encoding_parameters + self.mutable_file_default = mutable_file_default self.key_generator = key_generator self.blacklist = blacklist @@ -111,7 +112,7 @@ class NodeMaker: def create_mutable_file(self, contents=None, keysize=None, version=None): if version is None: - version = SDMF_VERSION + version = self.mutable_file_default n = MutableFileNode(self.storage_broker, self.secret_holder, self.default_encoding_parameters, self.history) d = self.key_generator.generate(keysize) diff --git a/src/allmydata/test/test_dirnode.py b/src/allmydata/test/test_dirnode.py index 145419be..8bea7d05 100644 --- a/src/allmydata/test/test_dirnode.py +++ b/src/allmydata/test/test_dirnode.py @@ -1376,7 +1376,7 @@ class Packing(testutil.ReallyEqualMixin, unittest.TestCase): known_tree = b32decode(self.known_tree) nodemaker = NodeMaker(None, None, None, None, None, - {"k": 3, "n": 10}, None) + {"k": 3, "n": 10}, None, None) write_uri = "URI:SSK-RO:e3mdrzfwhoq42hy5ubcz6rp3o4:ybyibhnp3vvwuq2vaw2ckjmesgkklfs6ghxleztqidihjyofgw7q" filenode = nodemaker.create_from_cap(write_uri) node = dirnode.DirectoryNode(filenode, nodemaker, None) @@ -1437,7 +1437,7 @@ class Packing(testutil.ReallyEqualMixin, unittest.TestCase): return kids def test_deep_immutable(self): - nm = NodeMaker(None, None, None, None, None, {"k": 3, "n": 10}, None) + nm = NodeMaker(None, None, None, None, None, {"k": 3, "n": 10}, None, None) fn = MinimalFakeMutableFile() kids = self._make_kids(nm, ["imm", "lit", "write", "read", @@ -1536,7 +1536,7 @@ class FakeClient2(Client): def __init__(self): self.nodemaker = FakeNodeMaker(None, None, None, None, None, - {"k":3,"n":10}, None) + {"k":3,"n":10}, None, None) def create_node_from_uri(self, rwcap, rocap): return self.nodemaker.create_from_cap(rwcap, rocap) @@ -1825,6 +1825,7 @@ class Deleter(GridTestMixin, testutil.ReallyEqualMixin, unittest.TestCase): c0.get_history(), c0.getServiceNamed("uploader"), c0.terminator, c0.get_encoding_parameters(), + c0.mutable_file_default, c0._key_generator) n = nm.create_from_cap(self.root_uri) assert n._node.please_ucwe_after_next_upload == False diff --git a/src/allmydata/test/test_mutable.py b/src/allmydata/test/test_mutable.py index 3c39ae51..e273448a 100644 --- a/src/allmydata/test/test_mutable.py +++ b/src/allmydata/test/test_mutable.py @@ -239,7 +239,7 @@ def make_nodemaker(s=None, num_peers=10): keygen.set_default_keysize(TEST_RSA_KEY_SIZE) nodemaker = NodeMaker(storage_broker, sh, None, None, None, - {"k": 3, "n": 10}, keygen) + {"k": 3, "n": 10}, SDMF_VERSION, keygen) return nodemaker class Filenode(unittest.TestCase, testutil.ShouldFailMixin): diff --git a/src/allmydata/web/common.py b/src/allmydata/web/common.py index 9bfed072..13385c5f 100644 --- a/src/allmydata/web/common.py +++ b/src/allmydata/web/common.py @@ -56,6 +56,11 @@ def get_mutable_type(file_format): # accepts result of get_format() elif file_format == "MDMF": return MDMF_VERSION else: + # this is also used to identify which formats are mutable. Use + # if get_mutable_type(file_format) is not None: + # do_mutable() + # else: + # do_immutable() return None diff --git a/src/allmydata/web/filenode.py b/src/allmydata/web/filenode.py index 28913170..3e4abf13 100644 --- a/src/allmydata/web/filenode.py +++ b/src/allmydata/web/filenode.py @@ -27,8 +27,8 @@ class ReplaceMeMixin: def replace_me_with_a_child(self, req, client, replace): # a new file is being uploaded in our place. file_format = get_format(req, "CHK") - if file_format in ("SDMF", "MDMF"): - mutable_type = get_mutable_type(file_format) + mutable_type = get_mutable_type(file_format) + if mutable_type is not None: data = MutableFileHandle(req.content) d = client.create_mutable_file(data, version=mutable_type) def _uploaded(newnode): diff --git a/src/allmydata/web/root.py b/src/allmydata/web/root.py index 47a6e9bf..2b9ea204 100644 --- a/src/allmydata/web/root.py +++ b/src/allmydata/web/root.py @@ -46,9 +46,9 @@ class URIHandler(RenderMixin, rend.Page): t = get_arg(req, "t", "").strip() if t == "": file_format = get_format(req, "CHK") - if file_format in ("SDMF", "MDMF"): - version = get_mutable_type(file_format) - return unlinked.PUTUnlinkedSSK(req, self.client, version) + mutable_type = get_mutable_type(file_format) + if mutable_type is not None: + return unlinked.PUTUnlinkedSSK(req, self.client, mutable_type) else: return unlinked.PUTUnlinkedCHK(req, self.client) if t == "mkdir": @@ -65,9 +65,9 @@ class URIHandler(RenderMixin, rend.Page): t = get_arg(req, "t", "").strip() if t in ("", "upload"): file_format = get_format(req) - if file_format in ("SDMF", "MDMF"): - version = get_mutable_type(file_format) - return unlinked.POSTUnlinkedSSK(req, self.client, version) + mutable_type = get_mutable_type(file_format) + if mutable_type is not None: + return unlinked.POSTUnlinkedSSK(req, self.client, mutable_type) else: return unlinked.POSTUnlinkedCHK(req, self.client) if t == "mkdir": diff --git a/src/allmydata/web/unlinked.py b/src/allmydata/web/unlinked.py index 94dd0621..8fa88479 100644 --- a/src/allmydata/web/unlinked.py +++ b/src/allmydata/web/unlinked.py @@ -29,7 +29,7 @@ def PUTUnlinkedCreateDirectory(req, client): # "PUT /uri?t=mkdir", to create an unlinked directory. file_format = get_format(req, None) if file_format == "CHK": - raise WebError("format=CHK not currently accepted for PUT /uri?t=mkdir", + raise WebError("format=CHK not accepted for PUT /uri?t=mkdir", http.BAD_REQUEST) mt = None if file_format: