diff --git a/tests/basetest.py b/tests/basetest.py index 49124e1..b090e9b 100644 --- a/tests/basetest.py +++ b/tests/basetest.py @@ -11,6 +11,7 @@ import subprocess import time from pprint import * from zfs_autobackup.ZfsAutobackup import * +from zfs_autobackup.ZfsAutoverify import * from mock import * import contextlib import sys diff --git a/tests/test_verify.py b/tests/test_verify.py index 345df72..0d95b44 100644 --- a/tests/test_verify.py +++ b/tests/test_verify.py @@ -1,17 +1,16 @@ -from zfs_autobackup.CmdPipe import CmdPipe + from basetest import * -import time + # test zfs-verify: # - when there is no common snapshot at all # - when encryption key not loaded -# - on datasets: +# - test mode +# - on snapshots of datasets: # - that are correct # - that are different -# - that are not mounted -# - that are mounted -# - that are mounted on the "wrong" place -# - on zvols +# - because of rsync: test local/local, local remote etc +# - on snapshots of zvols # - that are correct # - that are different # @@ -36,28 +35,7 @@ class TestZfsEncryption(unittest2.TestCase): def test_verify(self): - return + self.assertFalse(ZfsAutoverify("test test_target1 --verbose --test".split(" ")).run()) - r = shelltest("zfs get -r -t filesystem encryptionroot test_target1") - self.assertMultiLineEqual(r,""" -NAME PROPERTY VALUE SOURCE -test_target1 encryptionroot - - -test_target1/encryptedtarget encryptionroot test_target1/encryptedtarget - -test_target1/encryptedtarget/test_source1 encryptionroot test_target1/encryptedtarget - -test_target1/encryptedtarget/test_source1/fs1 encryptionroot - - -test_target1/encryptedtarget/test_source1/fs1/encryptedsource encryptionroot test_target1/encryptedtarget/test_source1/fs1/encryptedsource - -test_target1/encryptedtarget/test_source1/fs1/encryptedsourcekeyless encryptionroot test_target1/encryptedtarget/test_source1/fs1/encryptedsourcekeyless - -test_target1/encryptedtarget/test_source1/fs1/sub encryptionroot - - -test_target1/encryptedtarget/test_source2 encryptionroot test_target1/encryptedtarget - -test_target1/encryptedtarget/test_source2/fs2 encryptionroot test_target1/encryptedtarget - -test_target1/encryptedtarget/test_source2/fs2/sub encryptionroot - - -test_target1/test_source1 encryptionroot - - -test_target1/test_source1/fs1 encryptionroot - - -test_target1/test_source1/fs1/encryptedsource encryptionroot test_target1/test_source1/fs1/encryptedsource - -test_target1/test_source1/fs1/encryptedsourcekeyless encryptionroot test_target1/test_source1/fs1/encryptedsourcekeyless - -test_target1/test_source1/fs1/sub encryptionroot - - -test_target1/test_source2 encryptionroot - - -test_target1/test_source2/fs2 encryptionroot - - -test_target1/test_source2/fs2/sub encryptionroot - - -""") + self.assertFalse(ZfsAutoverify("test test_target1 --verbose --debug".split(" ")).run()) diff --git a/zfs_autobackup/ZfsAutoverify.py b/zfs_autobackup/ZfsAutoverify.py index 0abce71..33c7650 100644 --- a/zfs_autobackup/ZfsAutoverify.py +++ b/zfs_autobackup/ZfsAutoverify.py @@ -1,7 +1,11 @@ +import os + from .ZfsAuto import ZfsAuto from .ZfsDataset import ZfsDataset from .ZfsNode import ZfsNode import sys +import platform + class ZfsAutoverify(ZfsAuto): """The zfs-autoverify class, default agruments and stuff come from ZfsAuto""" @@ -30,7 +34,16 @@ class ZfsAutoverify(ZfsAuto): return (parser) - def verify_datasets(self, source_node, source_datasets, target_node): + + def verify_filesystem(self, source_dataset, source_mnt, target_dataset, target_mnt): + + + pass + + def verify_volume(self, source_dataset, target_dataset): + pass + + def verify_datasets(self, source_node, source_mnt, source_datasets, target_node, target_mnt): fail_count=0 count = 0 @@ -47,7 +60,12 @@ class ZfsAutoverify(ZfsAuto): target_dataset = ZfsDataset(target_node, target_name) if source_dataset.properties['type']=="filesystem": - print("JOOO") + self.verify_filesystem(source_dataset, source_mnt, target_dataset, target_mnt) + elif source_dataset.properties['type']=="volume": + self.verify_volume(source_dataset, target_dataset) + else: + raise(Exception("{} has unknown type {}".format(source_dataset, source_dataset.properties['type']))) + except Exception as e: fail_count = fail_count + 1 @@ -55,10 +73,31 @@ class ZfsAutoverify(ZfsAuto): if self.args.debug: raise + def create_mountpoints(self, source_node, target_node): + + # prepare mount points + + source_mnt = "/tmp/zfs-autoverify_source_{}_{}".format(platform.node(), os.getpid()) + source_node.run(["mkdir", source_mnt]) + + target_mnt = "/tmp/zfs-autoverify_target_{}_{}".format(platform.node(), os.getpid()) + target_node.run(["mkdir", target_mnt]) + + return source_mnt, target_mnt + + def cleanup_mountpoint(self, node, mnt): + node.run([ "umount", mnt ], hide_errors=True, valid_exitcodes=[] ) + node.run([ "rmdir", mnt ], hide_errors=True, valid_exitcodes=[] ) def run(self): + source_node=None + source_mnt=None + target_node=None + target_mnt=None + + try: ################ create source zfsNode @@ -90,11 +129,32 @@ class ZfsAutoverify(ZfsAuto): description="[Target]") target_node.verbose("Verify datasets under: {}".format(self.args.target_path)) + + source_mnt, target_mnt=self.create_mountpoints(source_node, target_node) + fail_count = self.verify_datasets( source_node=source_node, + source_mnt=source_mnt, source_datasets=source_datasets, + target_mnt=target_mnt, target_node=target_node) + if not fail_count: + if self.args.test: + self.set_title("All tests successful.") + else: + self.set_title("All datasets verified ok") + + else: + if fail_count != 255: + self.error("{} dataset(s) failed!".format(fail_count)) + + if self.args.test: + self.verbose("") + self.warning("TEST MODE - DID NOT VERIFY ANYTHING!") + + return fail_count + except Exception as e: self.error("Exception: " + str(e)) if self.args.debug: @@ -103,6 +163,17 @@ class ZfsAutoverify(ZfsAuto): except KeyboardInterrupt: self.error("Aborted") return 255 + finally: + + # cleanup + if source_mnt is not None: + self.cleanup_mountpoint(source_node, source_mnt) + + if target_mnt is not None: + self.cleanup_mountpoint(target_node, target_mnt) + + + def cli(): import sys