Compare commits
4 Commits
c87736eb0a
...
v0.9.79
Author | SHA1 | Date | |
---|---|---|---|
221af3f241 | |||
35f80e544c | |||
83b937654c | |||
714bde89e6 |
10
CHANGELOG.md
10
CHANGELOG.md
@ -1,5 +1,15 @@
|
||||
## PVC Changelog
|
||||
|
||||
###### [v0.9.79](https://github.com/parallelvirtualcluster/pvc/releases/tag/v0.9.79)
|
||||
|
||||
**API Changes**: New endpoints /vm/{vm}/backup, /vm/{vm}/restore
|
||||
|
||||
* [CLI Client] Fixes some storage pool help text messages
|
||||
* [Node Daemon] Increases the IPMI monitoring plugin timeout
|
||||
* [All] Adds support for VM backups, including creation, removal, and restore
|
||||
* [Repository] Fixes shebangs in scripts to be consistent
|
||||
* [Daemon Library] Improves the handling of VM list arguments (default None)
|
||||
|
||||
###### [v0.9.78](https://github.com/parallelvirtualcluster/pvc/releases/tag/v0.9.78)
|
||||
|
||||
* [API, Client CLI] Fixes several bugs around image uploads; adds a new query parameter for non-raw images
|
||||
|
@ -27,7 +27,7 @@ from ssl import SSLContext, TLSVersion
|
||||
from distutils.util import strtobool as dustrtobool
|
||||
|
||||
# Daemon version
|
||||
version = "0.9.78"
|
||||
version = "0.9.79"
|
||||
|
||||
# API version
|
||||
API_VERSION = 1.0
|
||||
|
@ -2,7 +2,7 @@ from setuptools import setup
|
||||
|
||||
setup(
|
||||
name="pvc",
|
||||
version="0.9.78",
|
||||
version="0.9.79",
|
||||
packages=["pvc.cli", "pvc.lib"],
|
||||
install_requires=[
|
||||
"Click",
|
||||
|
@ -30,7 +30,6 @@ from datetime import datetime
|
||||
from distutils.util import strtobool
|
||||
from json import dump as jdump
|
||||
from json import load as jload
|
||||
from os import remove
|
||||
from shutil import rmtree
|
||||
from socket import gethostname
|
||||
from uuid import UUID
|
||||
@ -1403,7 +1402,7 @@ def backup_vm(
|
||||
|
||||
# 4. Create destination directory
|
||||
vm_target_root = f"{backup_path}/{domain}"
|
||||
vm_target_backup = f"{backup_path}/{domain}/{domain}.{datestring}.pvcdisks"
|
||||
vm_target_backup = f"{backup_path}/{domain}/{datestring}/pvcdisks"
|
||||
if not os.path.isdir(vm_target_backup):
|
||||
try:
|
||||
os.makedirs(vm_target_backup)
|
||||
@ -1468,13 +1467,13 @@ def backup_vm(
|
||||
"type": backup_type,
|
||||
"datestring": datestring,
|
||||
"incremental_parent": incremental_parent,
|
||||
"retained_snapshot": retain_snapshot,
|
||||
"vm_detail": vm_detail,
|
||||
"backup_files": [
|
||||
(f"{domain}.{datestring}.pvcdisks/{p}.{v}.{export_fileext}", s)
|
||||
for p, v, s in vm_volumes
|
||||
(f"pvcdisks/{p}.{v}.{export_fileext}", s) for p, v, s in vm_volumes
|
||||
],
|
||||
}
|
||||
with open(f"{vm_target_root}/{domain}.{datestring}.pvcbackup", "w") as fh:
|
||||
with open(f"{vm_target_root}/{datestring}/pvcbackup.json", "w") as fh:
|
||||
jdump(vm_backup, fh)
|
||||
|
||||
# 8. Remove snapshots if retain_snapshot is False
|
||||
@ -1535,18 +1534,16 @@ def remove_backup(zkhandler, domain, backup_path, datestring):
|
||||
return False, f"ERROR: Source path {backup_path} does not exist!"
|
||||
|
||||
# Ensure that domain path (on this node) exists
|
||||
backup_backup_path = f"{backup_path}/{domain}"
|
||||
if not os.path.isdir(backup_backup_path):
|
||||
return False, f"ERROR: Source VM path {backup_backup_path} does not exist!"
|
||||
vm_backup_path = f"{backup_path}/{domain}"
|
||||
if not os.path.isdir(vm_backup_path):
|
||||
return False, f"ERROR: Source VM path {vm_backup_path} does not exist!"
|
||||
|
||||
# Ensure that the archives are present
|
||||
backup_source_pvcbackup_file = (
|
||||
f"{backup_backup_path}/{domain}.{datestring}.pvcbackup"
|
||||
)
|
||||
backup_source_pvcbackup_file = f"{vm_backup_path}/{datestring}/pvcbackup.json"
|
||||
if not os.path.isfile(backup_source_pvcbackup_file):
|
||||
return False, "ERROR: The specified source backup files do not exist!"
|
||||
|
||||
backup_source_pvcdisks_path = f"{backup_backup_path}/{domain}.{datestring}.pvcdisks"
|
||||
backup_source_pvcdisks_path = f"{vm_backup_path}/{datestring}/pvcdisks"
|
||||
if not os.path.isdir(backup_source_pvcdisks_path):
|
||||
return False, "ERROR: The specified source backup files do not exist!"
|
||||
|
||||
@ -1561,6 +1558,7 @@ def remove_backup(zkhandler, domain, backup_path, datestring):
|
||||
is_snapshot_remove_failed = False
|
||||
which_snapshot_remove_failed = list()
|
||||
msg_snapshot_remove_failed = list()
|
||||
if backup_source_details["retained_snapshot"]:
|
||||
for volume_file, _ in backup_source_details.get("backup_files"):
|
||||
pool, volume, _ = volume_file.split("/")[-1].split(".")
|
||||
snapshot = f"backup_{datestring}"
|
||||
@ -1574,8 +1572,7 @@ def remove_backup(zkhandler, domain, backup_path, datestring):
|
||||
is_files_remove_failed = False
|
||||
msg_files_remove_failed = None
|
||||
try:
|
||||
remove(backup_source_pvcbackup_file)
|
||||
rmtree(backup_source_pvcdisks_path)
|
||||
rmtree(f"{vm_backup_path}/{datestring}")
|
||||
except Exception as e:
|
||||
is_files_remove_failed = True
|
||||
msg_files_remove_failed = e
|
||||
@ -1626,14 +1623,12 @@ def restore_vm(zkhandler, domain, backup_path, datestring, retain_snapshot=False
|
||||
return False, f"ERROR: Source path {backup_path} does not exist!"
|
||||
|
||||
# Ensure that domain path (on this node) exists
|
||||
backup_backup_path = f"{backup_path}/{domain}"
|
||||
if not os.path.isdir(backup_backup_path):
|
||||
return False, f"ERROR: Source VM path {backup_backup_path} does not exist!"
|
||||
vm_backup_path = f"{backup_path}/{domain}"
|
||||
if not os.path.isdir(vm_backup_path):
|
||||
return False, f"ERROR: Source VM path {vm_backup_path} does not exist!"
|
||||
|
||||
# Ensure that the archives are present
|
||||
backup_source_pvcbackup_file = (
|
||||
f"{backup_backup_path}/{domain}.{datestring}.pvcbackup"
|
||||
)
|
||||
backup_source_pvcbackup_file = f"{vm_backup_path}/{datestring}/pvcbackup.json"
|
||||
if not os.path.isfile(backup_source_pvcbackup_file):
|
||||
return False, "ERROR: The specified source backup files do not exist!"
|
||||
|
||||
@ -1648,7 +1643,7 @@ def restore_vm(zkhandler, domain, backup_path, datestring, retain_snapshot=False
|
||||
incremental_parent = backup_source_details.get("incremental_parent", None)
|
||||
if incremental_parent is not None:
|
||||
backup_source_parent_pvcbackup_file = (
|
||||
f"{backup_backup_path}/{domain}.{incremental_parent}.pvcbackup"
|
||||
f"{vm_backup_path}/{incremental_parent}/pvcbackup.json"
|
||||
)
|
||||
if not os.path.isfile(backup_source_parent_pvcbackup_file):
|
||||
return (
|
||||
@ -1724,7 +1719,7 @@ def restore_vm(zkhandler, domain, backup_path, datestring, retain_snapshot=False
|
||||
|
||||
# Next we import the parent images
|
||||
retcode, stdout, stderr = common.run_os_command(
|
||||
f"rbd import --export-format 2 --dest-pool {pool} {backup_path}/{domain}/{parent_volume_file} {volume}"
|
||||
f"rbd import --export-format 2 --dest-pool {pool} {backup_path}/{domain}/{incremental_parent}/{parent_volume_file} {volume}"
|
||||
)
|
||||
if retcode:
|
||||
return (
|
||||
@ -1734,7 +1729,7 @@ def restore_vm(zkhandler, domain, backup_path, datestring, retain_snapshot=False
|
||||
|
||||
# Then we import the incremental diffs
|
||||
retcode, stdout, stderr = common.run_os_command(
|
||||
f"rbd import-diff {backup_path}/{domain}/{volume_file} {pool}/{volume}"
|
||||
f"rbd import-diff {backup_path}/{domain}/{datestring}/{volume_file} {pool}/{volume}"
|
||||
)
|
||||
if retcode:
|
||||
return (
|
||||
@ -1796,7 +1791,7 @@ def restore_vm(zkhandler, domain, backup_path, datestring, retain_snapshot=False
|
||||
|
||||
# Then we perform the actual import
|
||||
retcode, stdout, stderr = common.run_os_command(
|
||||
f"rbd import --export-format 2 --dest-pool {pool} {backup_path}/{domain}/{volume_file} {volume}"
|
||||
f"rbd import --export-format 2 --dest-pool {pool} {backup_path}/{domain}/{datestring}/{volume_file} {volume}"
|
||||
)
|
||||
if retcode:
|
||||
return (
|
||||
@ -1810,7 +1805,7 @@ def restore_vm(zkhandler, domain, backup_path, datestring, retain_snapshot=False
|
||||
zkhandler,
|
||||
pool,
|
||||
volume,
|
||||
f"backup_{incremental_parent}",
|
||||
f"backup_{datestring}",
|
||||
zk_only=True,
|
||||
)
|
||||
if not retcode:
|
||||
|
12
debian/changelog
vendored
12
debian/changelog
vendored
@ -1,3 +1,15 @@
|
||||
pvc (0.9.79-0) unstable; urgency=high
|
||||
|
||||
**API Changes**: New endpoints /vm/{vm}/backup, /vm/{vm}/restore
|
||||
|
||||
* [CLI Client] Fixes some storage pool help text messages
|
||||
* [Node Daemon] Increases the IPMI monitoring plugin timeout
|
||||
* [All] Adds support for VM backups, including creation, removal, and restore
|
||||
* [Repository] Fixes shebangs in scripts to be consistent
|
||||
* [Daemon Library] Improves the handling of VM list arguments (default None)
|
||||
|
||||
-- Joshua M. Boniface <joshua@boniface.me> Tue, 24 Oct 2023 02:10:24 -0400
|
||||
|
||||
pvc (0.9.78-0) unstable; urgency=high
|
||||
|
||||
* [API, Client CLI] Fixes several bugs around image uploads; adds a new query parameter for non-raw images
|
||||
|
@ -49,7 +49,7 @@ import re
|
||||
import json
|
||||
|
||||
# Daemon version
|
||||
version = "0.9.78"
|
||||
version = "0.9.79"
|
||||
|
||||
|
||||
##########################################################
|
||||
|
Reference in New Issue
Block a user