From b1db6d9ff2e78765b1a4660ca458537d7630e0c2 Mon Sep 17 00:00:00 2001 From: Brian Warner Date: Wed, 29 Oct 2008 18:09:17 -0700 Subject: [PATCH] web: add 'Repair' button to checker results when they indicate unhealthyness. Also add the object's uri to the CheckerResults instance. --- src/allmydata/checker_results.py | 6 +++++- src/allmydata/immutable/checker.py | 10 ++++++---- src/allmydata/immutable/filenode.py | 7 +++++-- src/allmydata/interfaces.py | 2 ++ src/allmydata/mutable/checker.py | 4 ++-- src/allmydata/test/common.py | 4 ++-- src/allmydata/test/test_dirnode.py | 2 +- src/allmydata/web/checker-results.xhtml | 2 ++ src/allmydata/web/checker_results.py | 12 ++++++++++++ 9 files changed, 37 insertions(+), 12 deletions(-) diff --git a/src/allmydata/checker_results.py b/src/allmydata/checker_results.py index 46da9a24..803b6f82 100644 --- a/src/allmydata/checker_results.py +++ b/src/allmydata/checker_results.py @@ -7,7 +7,9 @@ from allmydata.util import base32 class CheckerResults: implements(ICheckerResults) - def __init__(self, storage_index): + def __init__(self, uri, storage_index): + assert isinstance(uri, str) + self.uri = uri self.storage_index = storage_index self.problems = [] self.data = {"count-corrupt-shares": 0, @@ -38,6 +40,8 @@ class CheckerResults: return self.storage_index def get_storage_index_string(self): return base32.b2a(self.storage_index) + def get_uri(self): + return self.uri def is_healthy(self): return self.healthy diff --git a/src/allmydata/immutable/checker.py b/src/allmydata/immutable/checker.py index 4c3eacaf..c5808007 100644 --- a/src/allmydata/immutable/checker.py +++ b/src/allmydata/immutable/checker.py @@ -17,11 +17,12 @@ class SimpleCHKFileChecker: """Return a list of (needed, total, found, sharemap), where sharemap maps share number to a list of (binary) nodeids of the shareholders.""" - def __init__(self, client, storage_index, needed_shares, total_shares): + def __init__(self, client, uri, storage_index, needed_shares, total_shares): self.peer_getter = client.get_permuted_peers self.needed_shares = needed_shares self.total_shares = total_shares self.found_shares = set() + self.uri = uri self.storage_index = storage_index self.sharemap = {} self.responded = set() @@ -67,7 +68,7 @@ class SimpleCHKFileChecker: pass def _done(self, res): - r = CheckerResults(self.storage_index) + r = CheckerResults(self.uri, self.storage_index) report = [] healthy = bool(len(self.found_shares) >= self.total_shares) r.set_healthy(healthy) @@ -151,9 +152,10 @@ class SimpleCHKFileVerifier(download.FileDownloader): # remaining shareholders, and it cannot verify the plaintext. check_plaintext_hash = False - def __init__(self, client, storage_index, k, N, size, ueb_hash): + def __init__(self, client, uri, storage_index, k, N, size, ueb_hash): self._client = client + self._uri = uri self._storage_index = storage_index self._uri_extension_hash = ueb_hash self._total_shares = N @@ -163,7 +165,7 @@ class SimpleCHKFileVerifier(download.FileDownloader): self._si_s = storage.si_b2a(self._storage_index) self.init_logging() - self._check_results = r = CheckerResults(self._storage_index) + self._check_results = r = CheckerResults(self._uri, self._storage_index) r.set_data({"count-shares-needed": k, "count-shares-expected": N, }) diff --git a/src/allmydata/immutable/filenode.py b/src/allmydata/immutable/filenode.py index 40c98a83..083eb845 100644 --- a/src/allmydata/immutable/filenode.py +++ b/src/allmydata/immutable/filenode.py @@ -196,9 +196,12 @@ class FileNode(_ImmutableFileNodeBase): ueb_hash = self.u.uri_extension_hash if verify: v = self.verifier_class(self._client, - storage_index, k, N, size, ueb_hash) + self.get_uri(), storage_index, + k, N, size, ueb_hash) else: - v = self.checker_class(self._client, storage_index, k, N) + v = self.checker_class(self._client, + self.get_uri(), storage_index, + k, N) return v.start() def check_and_repair(self, monitor, verify=False): diff --git a/src/allmydata/interfaces.py b/src/allmydata/interfaces.py index c624bdfa..ce1adae0 100644 --- a/src/allmydata/interfaces.py +++ b/src/allmydata/interfaces.py @@ -1607,6 +1607,8 @@ class ICheckerResults(Interface): """Return a string with the (binary) storage index.""" def get_storage_index_string(): """Return a string with the (printable) abbreviated storage index.""" + def get_uri(): + """Return the (string) URI of the object that was checked.""" def is_healthy(): """Return a boolean, True if the file/dir is fully healthy, False if diff --git a/src/allmydata/mutable/checker.py b/src/allmydata/mutable/checker.py index e09050eb..8aaaedf9 100644 --- a/src/allmydata/mutable/checker.py +++ b/src/allmydata/mutable/checker.py @@ -16,7 +16,7 @@ class MutableChecker: self._monitor = monitor self.bad_shares = [] # list of (nodeid,shnum,failure) self._storage_index = self._node.get_storage_index() - self.results = CheckerResults(self._storage_index) + self.results = CheckerResults(node.get_uri(), self._storage_index) self.need_repair = False self.responded = set() # set of (binary) nodeids @@ -296,7 +296,7 @@ class MutableCheckAndRepairer(MutableChecker): d = self._node.repair(self.results) def _repair_finished(repair_results): self.cr_results.repair_successful = True - r = CheckerResults(self._storage_index) + r = CheckerResults(self._node.get_uri(), self._storage_index) self.cr_results.post_repair_results = r self._fill_checker_results(repair_results.servermap, r) self.cr_results.repair_results = repair_results # TODO? diff --git a/src/allmydata/test/common.py b/src/allmydata/test/common.py index af86e77a..a7dbacaf 100644 --- a/src/allmydata/test/common.py +++ b/src/allmydata/test/common.py @@ -51,7 +51,7 @@ class FakeCHKFileNode: return self.storage_index def check(self, monitor, verify=False): - r = CheckerResults(self.storage_index) + r = CheckerResults(self.my_uri, self.storage_index) is_bad = self.bad_shares.get(self.storage_index, None) data = {} data["count-shares-needed"] = 3 @@ -183,7 +183,7 @@ class FakeMutableFileNode: return self.storage_index def check(self, monitor, verify=False): - r = CheckerResults(self.storage_index) + r = CheckerResults(self.my_uri.to_string(), self.storage_index) is_bad = self.bad_shares.get(self.storage_index, None) data = {} data["count-shares-needed"] = 3 diff --git a/src/allmydata/test/test_dirnode.py b/src/allmydata/test/test_dirnode.py index e656bad2..42b9b26f 100644 --- a/src/allmydata/test/test_dirnode.py +++ b/src/allmydata/test/test_dirnode.py @@ -37,7 +37,7 @@ class Marker: return self.verifieruri def check(self, monitor, verify=False): - r = CheckerResults(None) + r = CheckerResults("", None) r.set_healthy(True) return defer.succeed(r) diff --git a/src/allmydata/web/checker-results.xhtml b/src/allmydata/web/checker-results.xhtml index a27df0e7..6fef7986 100644 --- a/src/allmydata/web/checker-results.xhtml +++ b/src/allmydata/web/checker-results.xhtml @@ -15,6 +15,8 @@ +
+
diff --git a/src/allmydata/web/checker_results.py b/src/allmydata/web/checker_results.py index d11468d7..a3eabff7 100644 --- a/src/allmydata/web/checker_results.py +++ b/src/allmydata/web/checker_results.py @@ -183,6 +183,18 @@ class CheckerResults(CheckerBase, rend.Page, ResultsBase): return ctx.tag["Healthy!"] return ctx.tag["Not Healthy!: ", self._html(self.r.get_summary())] + def render_repair(self, ctx, data): + if self.r.is_healthy(): + return "" + repair = T.form(action=".", method="post", + enctype="multipart/form-data")[ + T.fieldset[ + T.input(type="hidden", name="t", value="check"), + T.input(type="hidden", name="repair", value="true"), + T.input(type="submit", value="Repair"), + ]] + return ctx.tag[repair] + def render_rebalance(self, ctx, data): if self.r.needs_rebalancing(): return ctx.tag["(needs rebalancing)"] -- 2.45.2