mirror of
https://github.com/psy0rz/zfs_autobackup.git
synced 2025-04-21 23:00:26 +03:00
Compare commits
No commits in common. "master" and "v3.3-beta2" have entirely different histories.
master
...
v3.3-beta2
2
.github/workflows/python-publish.yml
vendored
2
.github/workflows/python-publish.yml
vendored
@ -5,7 +5,7 @@ name: Upload Python Package
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
types: [created]
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
|
@ -1,4 +1,4 @@
|
||||
import os
|
||||
|
||||
# To run tests as non-root, use this hack:
|
||||
# chmod 4755 /usr/sbin/zpool /usr/sbin/zfs
|
||||
|
||||
@ -51,10 +51,6 @@ if sys.version_info.major==2:
|
||||
else:
|
||||
OutputIO=io.StringIO
|
||||
|
||||
# for when we're using a suid-root python binary during development
|
||||
os.setuid(0)
|
||||
os.setgid(0)
|
||||
|
||||
|
||||
# for python2 compatibility (python 3 has this already)
|
||||
@contextlib.contextmanager
|
||||
|
@ -29,12 +29,6 @@ class TestZfsEncryption(unittest2.TestCase):
|
||||
except:
|
||||
self.skipTest("Encryption not supported on this ZFS version.")
|
||||
|
||||
def load_key(self, key, path):
|
||||
|
||||
shelltest("rm /tmp/zfstest.key 2>/dev/null;true")
|
||||
shelltest("echo {} > /tmp/zfstest.key".format(key))
|
||||
shelltest("zfs load-key {}".format(path))
|
||||
|
||||
def prepare_encrypted_dataset(self, key, path, unload_key=False):
|
||||
|
||||
# create encrypted source dataset
|
||||
@ -267,7 +261,7 @@ test_target1/test_source2/fs2/sub encryptionroot -
|
||||
# #unload key
|
||||
shelltest("zfs unload-key test_target1/encryptedtarget")
|
||||
|
||||
# resume should fail
|
||||
# resume
|
||||
with mocktime("20101111000001"):
|
||||
self.assertEqual(ZfsAutobackup(
|
||||
"test test_target1/encryptedtarget --verbose --no-progress --encrypt --exclude-received --allow-empty --no-snapshot --clear-mountpoint".split(
|
||||
@ -275,39 +269,21 @@ test_target1/test_source2/fs2/sub encryptionroot -
|
||||
|
||||
|
||||
|
||||
#NOTE: On some versions this leaves 2 weird sub-datasets that should'nt be there (its probably a zfs bug?)
|
||||
#so we ignore this, and just make sure the backup resumes correctly after reloading the key.
|
||||
# r = shelltest("zfs get -r -t all encryptionroot test_target1")
|
||||
# self.assertEqual(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_target1/encryptedtarget/test_source1/fs1@test-20101111000000 encryptionroot test_target1/encryptedtarget -
|
||||
# test_target1/encryptedtarget/test_source1/fs1/encryptedsource encryptionroot test_target1/encryptedtarget/test_source1/fs1/encryptedsource -
|
||||
# test_target1/encryptedtarget/test_source1/fs1/encryptedsource@test-20101111000000 encryptionroot test_target1/encryptedtarget/test_source1/fs1/encryptedsource -
|
||||
# test_target1/encryptedtarget/test_source1/fs1/encryptedsource@test-20101111000001 encryptionroot test_target1/encryptedtarget/test_source1/fs1/encryptedsource -
|
||||
# test_target1/encryptedtarget/test_source1/fs1/sub encryptionroot test_target1/encryptedtarget -
|
||||
# test_target1/encryptedtarget/test_source1/fs1/sub@test-20101111000000 encryptionroot test_target1/encryptedtarget -
|
||||
# test_target1/encryptedtarget/test_source1/fs1/sub/sub encryptionroot - -
|
||||
# test_target1/encryptedtarget/test_source1/fs1/sub/sub@test-20101111000001 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/encryptedtarget -
|
||||
# test_target1/encryptedtarget/test_source2/fs2/sub@test-20101111000000 encryptionroot test_target1/encryptedtarget -
|
||||
# test_target1/encryptedtarget/test_source2/fs2/sub/sub encryptionroot - -
|
||||
# test_target1/encryptedtarget/test_source2/fs2/sub/sub@test-20101111000001 encryptionroot - -
|
||||
# """)
|
||||
|
||||
|
||||
|
||||
#reload key and resume correctly.
|
||||
self.load_key("22222222", "test_target1/encryptedtarget")
|
||||
|
||||
# resume should complete
|
||||
with mocktime("20101111000001"):
|
||||
self.assertEqual(ZfsAutobackup(
|
||||
"test test_target1/encryptedtarget --verbose --no-progress --encrypt --exclude-received --allow-empty --no-snapshot --clear-mountpoint".split(
|
||||
" ")).run(),0)
|
||||
|
||||
r = shelltest("zfs get -r -t all encryptionroot test_target1")
|
||||
self.assertEqual(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_target1/encryptedtarget/test_source1/fs1@test-20101111000000 encryptionroot test_target1/encryptedtarget -
|
||||
test_target1/encryptedtarget/test_source1/fs1/encryptedsource encryptionroot test_target1/encryptedtarget/test_source1/fs1/encryptedsource -
|
||||
test_target1/encryptedtarget/test_source1/fs1/encryptedsource@test-20101111000000 encryptionroot test_target1/encryptedtarget/test_source1/fs1/encryptedsource -
|
||||
test_target1/encryptedtarget/test_source1/fs1/encryptedsource@test-20101111000001 encryptionroot test_target1/encryptedtarget/test_source1/fs1/encryptedsource -
|
||||
test_target1/encryptedtarget/test_source1/fs1/sub encryptionroot test_target1/encryptedtarget -
|
||||
test_target1/encryptedtarget/test_source1/fs1/sub@test-20101111000000 encryptionroot test_target1/encryptedtarget -
|
||||
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/encryptedtarget -
|
||||
test_target1/encryptedtarget/test_source2/fs2/sub@test-20101111000000 encryptionroot test_target1/encryptedtarget -
|
||||
""")
|
||||
|
@ -883,28 +883,23 @@ test_target1/test_source2/fs2/sub@test-20101111000003
|
||||
|
||||
def test_progress(self):
|
||||
|
||||
r=shelltest("dd if=/dev/urandom of=/test_source1/data.txt bs=5M count=1")
|
||||
r=shelltest("dd if=/dev/zero of=/test_source1/data.txt bs=200000 count=1")
|
||||
r = shelltest("zfs snapshot test_source1@test")
|
||||
|
||||
l=LogConsole(show_verbose=True, show_debug=True, color=False)
|
||||
l=LogConsole(show_verbose=True, show_debug=False, color=False)
|
||||
n=ZfsNode(utc=False, snapshot_time_format="bla", hold_name="bla", logger=l)
|
||||
d=ZfsDataset(n,"test_source1@test")
|
||||
|
||||
sp=d.send_pipe([], prev_snapshot=None, resume_token=None, show_progress=True, raw=False, send_pipes=[], send_properties=True, write_embedded=True, zfs_compressed=True)
|
||||
|
||||
|
||||
|
||||
|
||||
with OutputIO() as buf:
|
||||
with redirect_stderr(buf):
|
||||
try:
|
||||
|
||||
p=n.run(["mbuffer", "-R1M", "-m4096", "-o" ,"/dev/null"], inp=sp)
|
||||
# p=n.run(["dd", "of=/dev/null"], inp=sp)
|
||||
|
||||
n.run(["sleep", "2"], inp=sp)
|
||||
except:
|
||||
pass
|
||||
|
||||
print(list(buf.getvalue()))
|
||||
print(buf.getvalue())
|
||||
# correct message?
|
||||
self.assertRegex(buf.getvalue(),".*>>> .*minutes left.*")
|
||||
|
@ -1 +0,0 @@
|
||||
.
|
@ -10,7 +10,7 @@ class CliBase(object):
|
||||
Overridden in subclasses that add stuff for the specific programs."""
|
||||
|
||||
# also used by setup.py
|
||||
VERSION = "3.3"
|
||||
VERSION = "3.3-beta.2"
|
||||
HEADER = "{} v{} - (c)2022 E.H.Eefting (edwin@datux.nl)".format(os.path.basename(sys.argv[0]), VERSION)
|
||||
|
||||
def __init__(self, argv, print_arguments=True):
|
||||
|
@ -1,5 +1,4 @@
|
||||
import argparse
|
||||
import re
|
||||
import sys
|
||||
|
||||
from .CliBase import CliBase
|
||||
@ -113,14 +112,6 @@ class ZfsAuto(CliBase):
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
|
||||
def regex_argument_type(input_line):
|
||||
"""Parses regex arguments into re.Pattern objects"""
|
||||
try:
|
||||
return re.compile(input_line)
|
||||
except:
|
||||
raise ValueError("Could not parse argument '{}' as a regular expression".format(input_line))
|
||||
group.add_argument('--exclude-snapshot-pattern', action='append', default=[], type=regex_argument_type, help="Regular expression to match snapshots that will be ignored.")
|
||||
|
||||
return parser
|
||||
|
||||
def print_error_sources(self):
|
||||
|
@ -472,8 +472,7 @@ class ZfsAutobackup(ZfsAuto):
|
||||
snapshot_time_format=self.snapshot_time_format, hold_name=self.hold_name, logger=self,
|
||||
ssh_config=self.args.ssh_config,
|
||||
ssh_to=self.args.ssh_source, readonly=self.args.test,
|
||||
debug_output=self.args.debug_output, description=description, thinner=source_thinner,
|
||||
exclude_snapshot_patterns=self.args.exclude_snapshot_pattern)
|
||||
debug_output=self.args.debug_output, description=description, thinner=source_thinner)
|
||||
|
||||
################# select source datasets
|
||||
self.set_title("Selecting")
|
||||
|
@ -235,8 +235,7 @@ class ZfsAutoverify(ZfsAuto):
|
||||
snapshot_time_format=self.snapshot_time_format, hold_name=self.hold_name, logger=self,
|
||||
ssh_config=self.args.ssh_config,
|
||||
ssh_to=self.args.ssh_source, readonly=self.args.test,
|
||||
debug_output=self.args.debug_output, description=description,
|
||||
exclude_snapshot_patterns=self.args.exclude_snapshot_pattern)
|
||||
debug_output=self.args.debug_output, description=description)
|
||||
|
||||
################# select source datasets
|
||||
self.set_title("Selecting")
|
||||
|
@ -124,20 +124,6 @@ class ZfsDataset:
|
||||
def is_snapshot(self):
|
||||
"""true if this dataset is a snapshot"""
|
||||
return self.name.find("@") != -1
|
||||
|
||||
@property
|
||||
def is_excluded(self):
|
||||
"""true if this dataset is a snapshot and matches the exclude pattern"""
|
||||
if not self.is_snapshot:
|
||||
return False
|
||||
|
||||
|
||||
for pattern in self.zfs_node.exclude_snapshot_patterns:
|
||||
if pattern.search(self.name) is not None:
|
||||
self.debug("Excluded (path matches snapshot exclude pattern)")
|
||||
return True
|
||||
|
||||
|
||||
|
||||
def is_selected(self, value, source, inherited, exclude_received, exclude_paths, exclude_unchanged):
|
||||
"""determine if dataset should be selected for backup (called from
|
||||
@ -1185,7 +1171,7 @@ class ZfsDataset:
|
||||
target_snapshot = target_dataset.find_snapshot(source_snapshot) # still virtual
|
||||
|
||||
# does target actually want it?
|
||||
if target_snapshot not in target_obsoletes and not source_snapshot.is_excluded:
|
||||
if target_snapshot not in target_obsoletes:
|
||||
|
||||
# do the rollback, one time at first transfer
|
||||
if do_rollback:
|
||||
|
@ -20,7 +20,7 @@ class ZfsNode(ExecuteNode):
|
||||
|
||||
def __init__(self, logger, utc=False, snapshot_time_format="", hold_name="", ssh_config=None, ssh_to=None, readonly=False,
|
||||
description="",
|
||||
debug_output=False, thinner=None, exclude_snapshot_patterns=[]):
|
||||
debug_output=False, thinner=None):
|
||||
|
||||
self.utc = utc
|
||||
self.snapshot_time_format = snapshot_time_format
|
||||
@ -30,8 +30,6 @@ class ZfsNode(ExecuteNode):
|
||||
|
||||
self.logger = logger
|
||||
|
||||
self.exclude_snapshot_patterns = exclude_snapshot_patterns
|
||||
|
||||
if ssh_config:
|
||||
self.verbose("Using custom SSH config: {}".format(ssh_config))
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user