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.
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:
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
return new_contents
class NewDirectoryNode:
- implements(IDirectoryNode, ICheckable)
+ implements(IDirectoryNode, ICheckable, IDeepCheckable)
filenode_class = MutableFileNode
def __init__(self, client):
from allmydata import uri
from allmydata.immutable.checker import SimpleCHKFileChecker, \
SimpleCHKFileVerifier
-from allmydata.checker_results import DeepCheckResults, \
- DeepCheckAndRepairResults
class FileNode:
implements(IFileNode, ICheckable)
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)
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
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.
"""
"""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.
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
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
# 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):
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):
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:
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
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")