black
modified: virt-back
This commit is contained in:
parent
fd1592c3b1
commit
85e1f3b28b
1 changed files with 41 additions and 12 deletions
53
virt-back
53
virt-back
|
|
@ -124,7 +124,9 @@ def backup(doms):
|
||||||
f.write(xml)
|
f.write(xml)
|
||||||
|
|
||||||
# Updated regular expression to match file= and dev= within <disk> elements
|
# Updated regular expression to match file= and dev= within <disk> elements
|
||||||
disklist = re.findall(r"<disk.*?<source (?:file|dev)='(.*?)'.*?</disk>", xml, re.DOTALL)
|
disklist = re.findall(
|
||||||
|
r"<disk.*?<source (?:file|dev)='(.*?)'.*?</disk>", xml, re.DOTALL
|
||||||
|
)
|
||||||
|
|
||||||
logit("backup", "invoking backup for " + dom.name())
|
logit("backup", "invoking backup for " + dom.name())
|
||||||
|
|
||||||
|
|
@ -137,13 +139,24 @@ def backup(doms):
|
||||||
|
|
||||||
if is_zfs_dataset(disk_source):
|
if is_zfs_dataset(disk_source):
|
||||||
# Handle ZFS dataset
|
# Handle ZFS dataset
|
||||||
zfs_dataset = disk_source[len('/dev/zvol/'):] if disk_source.startswith('/dev/zvol/') else disk_source
|
zfs_dataset = (
|
||||||
|
disk_source[len("/dev/zvol/") :]
|
||||||
|
if disk_source.startswith("/dev/zvol/")
|
||||||
|
else disk_source
|
||||||
|
)
|
||||||
zfs_snapshot_base = f"{zfs_dataset}@backup-{TODAY}"
|
zfs_snapshot_base = f"{zfs_dataset}@backup-{TODAY}"
|
||||||
zfs_snapshot = zfs_snapshot_base
|
zfs_snapshot = zfs_snapshot_base
|
||||||
suffix = 1
|
suffix = 1
|
||||||
|
|
||||||
# Increment snapshot name until an available name is found
|
# Increment snapshot name until an available name is found
|
||||||
while subprocess.run(["zfs", "list", zfs_snapshot], stdout=subprocess.PIPE, stderr=subprocess.PIPE).returncode == 0:
|
while (
|
||||||
|
subprocess.run(
|
||||||
|
["zfs", "list", zfs_snapshot],
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.PIPE,
|
||||||
|
).returncode
|
||||||
|
== 0
|
||||||
|
):
|
||||||
zfs_snapshot = f"{zfs_snapshot_base}-{suffix}"
|
zfs_snapshot = f"{zfs_snapshot_base}-{suffix}"
|
||||||
suffix += 1
|
suffix += 1
|
||||||
|
|
||||||
|
|
@ -152,7 +165,9 @@ def backup(doms):
|
||||||
zfs_file += ".gz"
|
zfs_file += ".gz"
|
||||||
|
|
||||||
# Create ZFS snapshot
|
# Create ZFS snapshot
|
||||||
logit("backup", f"creating ZFS snapshot {zfs_snapshot} for {dom.name()}")
|
logit(
|
||||||
|
"backup", f"creating ZFS snapshot {zfs_snapshot} for {dom.name()}"
|
||||||
|
)
|
||||||
try:
|
try:
|
||||||
subprocess.run(["zfs", "snapshot", zfs_snapshot], check=True)
|
subprocess.run(["zfs", "snapshot", zfs_snapshot], check=True)
|
||||||
except subprocess.CalledProcessError as e:
|
except subprocess.CalledProcessError as e:
|
||||||
|
|
@ -160,14 +175,23 @@ def backup(doms):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Send ZFS snapshot to file with optional compression
|
# Send ZFS snapshot to file with optional compression
|
||||||
logit("backup", f"sending ZFS snapshot {zfs_snapshot} to {zfs_file} for {dom.name()}")
|
logit(
|
||||||
|
"backup",
|
||||||
|
f"sending ZFS snapshot {zfs_snapshot} to {zfs_file} for {dom.name()}",
|
||||||
|
)
|
||||||
try:
|
try:
|
||||||
with open(zfs_file, "wb") as f:
|
with open(zfs_file, "wb") as f:
|
||||||
if options.nogzip:
|
if options.nogzip:
|
||||||
subprocess.run(["zfs", "send", zfs_snapshot], stdout=f, check=True)
|
subprocess.run(
|
||||||
|
["zfs", "send", zfs_snapshot], stdout=f, check=True
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
send_proc = subprocess.Popen(["zfs", "send", zfs_snapshot], stdout=subprocess.PIPE)
|
send_proc = subprocess.Popen(
|
||||||
gzip_proc = subprocess.Popen(["gzip"], stdin=send_proc.stdout, stdout=f)
|
["zfs", "send", zfs_snapshot], stdout=subprocess.PIPE
|
||||||
|
)
|
||||||
|
gzip_proc = subprocess.Popen(
|
||||||
|
["gzip"], stdin=send_proc.stdout, stdout=f
|
||||||
|
)
|
||||||
send_proc.stdout.close() # Allow send_proc to receive a SIGPIPE if gzip_proc exits
|
send_proc.stdout.close() # Allow send_proc to receive a SIGPIPE if gzip_proc exits
|
||||||
gzip_proc.communicate()
|
gzip_proc.communicate()
|
||||||
except subprocess.CalledProcessError as e:
|
except subprocess.CalledProcessError as e:
|
||||||
|
|
@ -222,7 +246,10 @@ def backup(doms):
|
||||||
tar.add(zfs_file) # add zfs snapshot to tar
|
tar.add(zfs_file) # add zfs snapshot to tar
|
||||||
remove(zfs_file) # cleanup tmp files
|
remove(zfs_file) # cleanup tmp files
|
||||||
else:
|
else:
|
||||||
logit("error", f"ZFS snapshot file {zfs_file} not found for {dom.name()}")
|
logit(
|
||||||
|
"error",
|
||||||
|
f"ZFS snapshot file {zfs_file} not found for {dom.name()}",
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
disk_file = disk_source.split("/")[-1]
|
disk_file = disk_source.split("/")[-1]
|
||||||
disk_dest = path.join(options.backpath, disk_file)
|
disk_dest = path.join(options.backpath, disk_file)
|
||||||
|
|
@ -240,12 +267,14 @@ def is_zfs_dataset(disk_source):
|
||||||
logit("backup", f"checking if {disk_source} is a ZFS dataset")
|
logit("backup", f"checking if {disk_source} is a ZFS dataset")
|
||||||
try:
|
try:
|
||||||
# Extract the ZFS dataset name from the device path
|
# Extract the ZFS dataset name from the device path
|
||||||
if disk_source.startswith('/dev/zvol/'):
|
if disk_source.startswith("/dev/zvol/"):
|
||||||
zfs_dataset = disk_source[len('/dev/zvol/'):]
|
zfs_dataset = disk_source[len("/dev/zvol/") :]
|
||||||
else:
|
else:
|
||||||
zfs_dataset = disk_source
|
zfs_dataset = disk_source
|
||||||
|
|
||||||
result = subprocess.run(["zfs", "list", zfs_dataset], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
result = subprocess.run(
|
||||||
|
["zfs", "list", zfs_dataset], stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||||
|
)
|
||||||
is_zfs = result.returncode == 0
|
is_zfs = result.returncode == 0
|
||||||
logit("backup", f"{zfs_dataset} is {'a' if is_zfs else 'not a'} ZFS dataset")
|
logit("backup", f"{zfs_dataset} is {'a' if is_zfs else 'not a'} ZFS dataset")
|
||||||
return is_zfs
|
return is_zfs
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue