mirror of
https://github.com/tahoe-lafs/tahoe-lafs.git
synced 2025-04-08 11:24:25 +00:00
disallow deep-check on non-directories, simplifies the code a bit
This commit is contained in:
parent
4bb88fd2ee
commit
f570ad7ba5
@ -729,9 +729,9 @@ POST $URL?t=deep-check
|
||||
page will contain a summary of the results, including details on any
|
||||
file/directory that was not fully healthy.
|
||||
|
||||
t=deep-check is most useful to invoke on a directory. If invoked on a file,
|
||||
it will just check that single object. The recursive walker will deal with
|
||||
loops safely.
|
||||
t=deep-check can only be invoked on a directory. An error (400 BAD_REQUEST)
|
||||
will be signalled if it is invoked on a file. The recursive walker will
|
||||
deal with loops safely.
|
||||
|
||||
This accepts the same verify=, when_done=, and return_to= arguments as
|
||||
t=check.
|
||||
@ -801,6 +801,10 @@ POST $URL?t=deep-check&repair=true
|
||||
This triggers a recursive walk of all files and directories, performing a
|
||||
t=check&repair=true on each one.
|
||||
|
||||
Like t=deep-check without the repair= argument, this can only be invoked on
|
||||
a directory. An error (400 BAD_REQUEST) will be signalled if it is invoked
|
||||
on a file. The recursive walker will deal with loops safely.
|
||||
|
||||
This accepts the same when_done=URL, return_to=URL, and verify=true
|
||||
arguments as t=deep-check. When an output=JSON argument is provided, the
|
||||
response will contain the following keys:
|
||||
|
@ -8,7 +8,7 @@ from allmydata.mutable.common import NotMutableError
|
||||
from allmydata.mutable.node import MutableFileNode
|
||||
from allmydata.interfaces import IMutableFileNode, IDirectoryNode,\
|
||||
IURI, IFileNode, IMutableFileURI, IFilesystemNode, \
|
||||
ExistingChildError, ICheckable
|
||||
ExistingChildError, ICheckable, IDeepCheckable
|
||||
from allmydata.checker_results import DeepCheckResults, \
|
||||
DeepCheckAndRepairResults
|
||||
from allmydata.util import hashutil, mathutil, base32, log
|
||||
@ -114,7 +114,7 @@ class Adder:
|
||||
return new_contents
|
||||
|
||||
class NewDirectoryNode:
|
||||
implements(IDirectoryNode, ICheckable)
|
||||
implements(IDirectoryNode, ICheckable, IDeepCheckable)
|
||||
filenode_class = MutableFileNode
|
||||
|
||||
def __init__(self, client):
|
||||
|
@ -5,8 +5,6 @@ from allmydata.interfaces import IFileNode, IFileURI, IURI, ICheckable
|
||||
from allmydata import uri
|
||||
from allmydata.immutable.checker import SimpleCHKFileChecker, \
|
||||
SimpleCHKFileVerifier
|
||||
from allmydata.checker_results import DeepCheckResults, \
|
||||
DeepCheckAndRepairResults
|
||||
|
||||
class FileNode:
|
||||
implements(IFileNode, ICheckable)
|
||||
@ -75,24 +73,6 @@ class FileNode:
|
||||
d.addCallback(_done)
|
||||
return d
|
||||
|
||||
def deep_check(self, verify=False):
|
||||
d = self.check(verify)
|
||||
def _done(r):
|
||||
dr = DeepCheckResults(self.get_verifier().storage_index)
|
||||
dr.add_check(r, [])
|
||||
return dr
|
||||
d.addCallback(_done)
|
||||
return d
|
||||
|
||||
def deep_check_and_repair(self, verify=False):
|
||||
d = self.check_and_repair(verify)
|
||||
def _done(r):
|
||||
dr = DeepCheckAndRepairResults(self.get_verifier().storage_index)
|
||||
dr.add_check_and_repair(r, [])
|
||||
return dr
|
||||
d.addCallback(_done)
|
||||
return d
|
||||
|
||||
def download(self, target):
|
||||
downloader = self._client.getServiceNamed("downloader")
|
||||
return downloader.download(self.uri, target)
|
||||
@ -150,14 +130,6 @@ class LiteralFileNode:
|
||||
def check_and_repair(self, verify=False):
|
||||
return defer.succeed(None)
|
||||
|
||||
def deep_check(self, verify=False):
|
||||
dr = DeepCheckResults(None)
|
||||
return defer.succeed(dr)
|
||||
|
||||
def deep_check_and_repair(self, verify=False):
|
||||
dr = DeepCheckAndRepairResults(None)
|
||||
return defer.succeed(dr)
|
||||
|
||||
def download(self, target):
|
||||
# note that this does not update the stats_provider
|
||||
data = IURI(self.uri).data
|
||||
|
@ -1485,11 +1485,11 @@ class ICheckable(Interface):
|
||||
attempted, 'post' will be another ICheckerResults instance with the
|
||||
state of the object after repair."""
|
||||
|
||||
class IDeepCheckable(Interface):
|
||||
def deep_check(verify=False):
|
||||
"""Check upon the health of me and everything I can reach.
|
||||
|
||||
This is a recursive form of check(), useable on dirnodes. (it can be
|
||||
called safely on filenodes too, but only checks the one object).
|
||||
This is a recursive form of check(), useable only on dirnodes.
|
||||
|
||||
I return a Deferred that fires with an IDeepCheckResults object.
|
||||
"""
|
||||
@ -1498,9 +1498,8 @@ class ICheckable(Interface):
|
||||
"""Check upon the health of me and everything I can reach. Repair
|
||||
anything that isn't healthy.
|
||||
|
||||
This is a recursive form of check_and_repair(), useable on dirnodes.
|
||||
(it can be called safely on filenodes too, but only checks/repairs
|
||||
the one object).
|
||||
This is a recursive form of check_and_repair(), useable only on
|
||||
dirnodes.
|
||||
|
||||
I return a Deferred that fires with an IDeepCheckAndRepairResults
|
||||
object.
|
||||
|
@ -12,8 +12,6 @@ from allmydata.util import hashutil
|
||||
from allmydata.util.assertutil import precondition
|
||||
from allmydata.uri import WriteableSSKFileURI
|
||||
from allmydata.immutable.encode import NotEnoughSharesError
|
||||
from allmydata.checker_results import DeepCheckResults, \
|
||||
DeepCheckAndRepairResults
|
||||
from pycryptopp.publickey import rsa
|
||||
from pycryptopp.cipher.aes import AES
|
||||
|
||||
@ -253,25 +251,6 @@ class MutableFileNode:
|
||||
checker = self.check_and_repairer_class(self)
|
||||
return checker.check(verify)
|
||||
|
||||
def deep_check(self, verify=False):
|
||||
# deep-check on a filenode only gets one result
|
||||
d = self.check(verify)
|
||||
def _done(r):
|
||||
dr = DeepCheckResults(self.get_storage_index())
|
||||
dr.add_check(r, [])
|
||||
return dr
|
||||
d.addCallback(_done)
|
||||
return d
|
||||
|
||||
def deep_check_and_repair(self, verify=False):
|
||||
d = self.check_and_repair(verify)
|
||||
def _done(r):
|
||||
dr = DeepCheckAndRepairResults(self.get_storage_index())
|
||||
dr.add_check_and_repair(r, [])
|
||||
return dr
|
||||
d.addCallback(_done)
|
||||
return d
|
||||
|
||||
#################################
|
||||
# IRepairable
|
||||
|
||||
|
@ -134,19 +134,6 @@ class Checker(unittest.TestCase):
|
||||
|
||||
# TODO: check-and-repair
|
||||
|
||||
d.addCallback(lambda res: fn1.deep_check())
|
||||
def _check_deepcheck_results(dcr):
|
||||
c = dcr.get_counters()
|
||||
self.failUnlessEqual(c["count-objects-checked"], 1)
|
||||
self.failUnlessEqual(c["count-objects-healthy"], 1)
|
||||
self.failUnlessEqual(c["count-objects-unhealthy"], 0)
|
||||
self.failUnlessEqual(c["count-corrupt-shares"], 0)
|
||||
self.failIf(dcr.get_corrupt_shares())
|
||||
d.addCallback(_check_deepcheck_results)
|
||||
|
||||
d.addCallback(lambda res: fn1.deep_check(verify=True))
|
||||
d.addCallback(_check_deepcheck_results)
|
||||
|
||||
return d
|
||||
|
||||
def test_literal_filenode(self):
|
||||
@ -163,19 +150,6 @@ class Checker(unittest.TestCase):
|
||||
d.addCallback(lambda res: fn1.check(verify=True))
|
||||
d.addCallback(_check_checker_results)
|
||||
|
||||
d.addCallback(lambda res: fn1.deep_check())
|
||||
def _check_deepcheck_results(dcr):
|
||||
c = dcr.get_counters()
|
||||
self.failUnlessEqual(c["count-objects-checked"], 0)
|
||||
self.failUnlessEqual(c["count-objects-healthy"], 0)
|
||||
self.failUnlessEqual(c["count-objects-unhealthy"], 0)
|
||||
self.failUnlessEqual(c["count-corrupt-shares"], 0)
|
||||
self.failIf(dcr.get_corrupt_shares())
|
||||
d.addCallback(_check_deepcheck_results)
|
||||
|
||||
d.addCallback(lambda res: fn1.deep_check(verify=True))
|
||||
d.addCallback(_check_deepcheck_results)
|
||||
|
||||
return d
|
||||
|
||||
def test_mutable_filenode(self):
|
||||
@ -199,19 +173,6 @@ class Checker(unittest.TestCase):
|
||||
d.addCallback(lambda res: n.check(verify=True))
|
||||
d.addCallback(_check_checker_results)
|
||||
|
||||
d.addCallback(lambda res: n.deep_check())
|
||||
def _check_deepcheck_results(dcr):
|
||||
c = dcr.get_counters()
|
||||
self.failUnlessEqual(c["count-objects-checked"], 1)
|
||||
self.failUnlessEqual(c["count-objects-healthy"], 1)
|
||||
self.failUnlessEqual(c["count-objects-unhealthy"], 0)
|
||||
self.failUnlessEqual(c["count-corrupt-shares"], 0)
|
||||
self.failIf(dcr.get_corrupt_shares())
|
||||
d.addCallback(_check_deepcheck_results)
|
||||
|
||||
d.addCallback(lambda res: n.deep_check(verify=True))
|
||||
d.addCallback(_check_deepcheck_results)
|
||||
|
||||
return d
|
||||
|
||||
class FakeMutableChecker:
|
||||
|
@ -2162,46 +2162,15 @@ class DeepCheck(SystemTestMixin, unittest.TestCase):
|
||||
d.addCallback(self.failUnlessEqual, None, "small")
|
||||
|
||||
|
||||
# now deep-check on everything. It should be safe to use deep-check
|
||||
# on anything, even a regular file.
|
||||
# now deep-check the root, with various verify= and repair= options
|
||||
d.addCallback(lambda ign: self.root.deep_check())
|
||||
d.addCallback(self.deep_check_is_healthy, 3, "root")
|
||||
d.addCallback(lambda ign: self.mutable.deep_check())
|
||||
d.addCallback(self.deep_check_is_healthy, 1, "mutable")
|
||||
d.addCallback(lambda ign: self.large.deep_check())
|
||||
d.addCallback(self.deep_check_is_healthy, 1, "large")
|
||||
d.addCallback(lambda ign: self.small.deep_check())
|
||||
d.addCallback(self.deep_check_is_healthy, 0, "small")
|
||||
|
||||
# deep-check verify=True
|
||||
d.addCallback(lambda ign: self.root.deep_check(verify=True))
|
||||
d.addCallback(self.deep_check_is_healthy, 3, "root")
|
||||
d.addCallback(lambda ign: self.mutable.deep_check(verify=True))
|
||||
d.addCallback(self.deep_check_is_healthy, 1, "mutable")
|
||||
d.addCallback(lambda ign: self.large.deep_check(verify=True))
|
||||
d.addCallback(self.deep_check_is_healthy, 1, "large")
|
||||
d.addCallback(lambda ign: self.small.deep_check(verify=True))
|
||||
d.addCallback(self.deep_check_is_healthy, 0, "small")
|
||||
|
||||
# deep-check-and-repair
|
||||
d.addCallback(lambda ign: self.root.deep_check_and_repair())
|
||||
d.addCallback(self.deep_check_and_repair_is_healthy, 3, "root")
|
||||
d.addCallback(lambda ign: self.mutable.deep_check_and_repair())
|
||||
d.addCallback(self.deep_check_and_repair_is_healthy, 1, "mutable")
|
||||
d.addCallback(lambda ign: self.large.deep_check_and_repair())
|
||||
d.addCallback(self.deep_check_and_repair_is_healthy, 1, "large")
|
||||
d.addCallback(lambda ign: self.small.deep_check_and_repair())
|
||||
d.addCallback(self.deep_check_and_repair_is_healthy, 0, "small")
|
||||
|
||||
# deep-check-and-repair, verify=True
|
||||
d.addCallback(lambda ign: self.root.deep_check_and_repair(verify=True))
|
||||
d.addCallback(self.deep_check_and_repair_is_healthy, 3, "root")
|
||||
d.addCallback(lambda ign: self.mutable.deep_check_and_repair(verify=True))
|
||||
d.addCallback(self.deep_check_and_repair_is_healthy, 1, "mutable")
|
||||
d.addCallback(lambda ign: self.large.deep_check_and_repair(verify=True))
|
||||
d.addCallback(self.deep_check_and_repair_is_healthy, 1, "large")
|
||||
d.addCallback(lambda ign: self.small.deep_check_and_repair(verify=True))
|
||||
d.addCallback(self.deep_check_and_repair_is_healthy, 0, "small")
|
||||
|
||||
return d
|
||||
|
||||
@ -2361,8 +2330,7 @@ class DeepCheck(SystemTestMixin, unittest.TestCase):
|
||||
self.web_json(self.small, t="check", repair="true", verify="true"))
|
||||
d.addCallback(self.json_check_lit, self.small, "small")
|
||||
|
||||
# now run a deep-check. When done through the web, this can only be
|
||||
# run on a directory.
|
||||
# now run a deep-check, with various verify= and repair= flags
|
||||
d.addCallback(lambda ign:
|
||||
self.web_json(self.root, t="deep-check"))
|
||||
d.addCallback(self.json_full_deepcheck_is_healthy, self.root, "root")
|
||||
|
Loading…
x
Reference in New Issue
Block a user