From fc2807cccc773386b83e53d7eb02ee02ef326ba9 Mon Sep 17 00:00:00 2001 From: Itamar Turner-Trauring Date: Fri, 15 Apr 2022 09:08:16 -0400 Subject: [PATCH] Sketch of server-side read-test-write endpoint. --- src/allmydata/storage/http_common.py | 1 + src/allmydata/storage/http_server.py | 60 ++++++++++++++++++++++++---- 2 files changed, 54 insertions(+), 7 deletions(-) diff --git a/src/allmydata/storage/http_common.py b/src/allmydata/storage/http_common.py index addd926d1..123ce403b 100644 --- a/src/allmydata/storage/http_common.py +++ b/src/allmydata/storage/http_common.py @@ -38,6 +38,7 @@ class Secrets(Enum): LEASE_RENEW = "lease-renew-secret" LEASE_CANCEL = "lease-cancel-secret" UPLOAD = "upload-secret" + WRITE_ENABLER = "write-enabler" def get_spki_hash(certificate: Certificate) -> bytes: diff --git a/src/allmydata/storage/http_server.py b/src/allmydata/storage/http_server.py index 7c4860d57..bcb4b22c9 100644 --- a/src/allmydata/storage/http_server.py +++ b/src/allmydata/storage/http_server.py @@ -239,19 +239,39 @@ class _HTTPError(Exception): # https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml. Notably, #6.258 # indicates a set. _SCHEMAS = { - "allocate_buckets": Schema(""" - message = { + "allocate_buckets": Schema( + """ + request = { share-numbers: #6.258([* uint]) allocated-size: uint } - """), - "advise_corrupt_share": Schema(""" - message = { + """ + ), + "advise_corrupt_share": Schema( + """ + request = { reason: tstr } - """) + """ + ), + "mutable_read_test_write": Schema( + """ + request = { + "test-write-vectors": { + * share_number: { + "test": [* {"offset": uint, "size": uint, "specimen": bstr}] + "write": [* {"offset": uint, "data": bstr}] + "new-length": uint + } + } + "read-vector": [* {"offset": uint, "size": uint}] + } + share_number = uint + """ + ), } + class HTTPServer(object): """ A HTTP interface to the storage server. @@ -537,7 +557,9 @@ class HTTPServer(object): "/v1/immutable///corrupt", methods=["POST"], ) - def advise_corrupt_share(self, request, authorization, storage_index, share_number): + def advise_corrupt_share_immutable( + self, request, authorization, storage_index, share_number + ): """Indicate that given share is corrupt, with a text reason.""" try: bucket = self._storage_server.get_buckets(storage_index)[share_number] @@ -548,6 +570,30 @@ class HTTPServer(object): bucket.advise_corrupt_share(info["reason"].encode("utf-8")) return b"" + ##### Immutable APIs ##### + + @_authorized_route( + _app, + {Secrets.LEASE_RENEW, Secrets.LEASE_CANCEL, Secrets.WRITE_ENABLER}, + "/v1/mutable//read-test-write", + methods=["POST"], + ) + def mutable_read_test_write(self, request, authorization, storage_index): + """Read/test/write combined operation for mutables.""" + rtw_request = self._read_encoded(request, _SCHEMAS["mutable_read_test_write"]) + secrets = ( + authorization[Secrets.WRITE_ENABLER], + authorization[Secrets.LEASE_RENEW], + authorization[Secrets.LEASE_CANCEL], + ) + success, read_data = self._storage_server.slot_testv_and_readv_and_writev( + storage_index, + secrets, + rtw_request["test-write-vectors"], + rtw_request["read-vectors"], + ) + return self._send_encoded(request, {"success": success, "data": read_data}) + @implementer(IStreamServerEndpoint) @attr.s