Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add --restore-root option to specify target for misc vm files #214

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions libvirtnbdbackup/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,9 @@ def copy(args: Namespace, source: str, target: str) -> None:
if args.sshClient:
args.sshClient.copy(source, target)
else:
if hasattr(args, "restore_root") and args.restore_root is not None:
dir, _ = os.path.split(target)
os.makedirs(dir, exist_ok=True)
shutil.copyfile(source, target)
except OSError as e:
log.warning("Failed to copy [%s] to [%s]: [%s]", source, target, e)
Expand Down
13 changes: 12 additions & 1 deletion libvirtnbdbackup/restore/files.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,20 @@
from libvirtnbdbackup.exceptions import RestoreError


def restore(args: Namespace, vmConfig: str, virtClient: virt.client) -> None:
def restore(
args: Namespace, vmConfig: str, virtClient: virt.client, restConfig: bytes
) -> bytes:
"""Notice user if backed up vm had loader / nvram"""
config = vmconfig.read(vmConfig)
info = virtClient.getDomainInfo(config)
restored_files = {}

for setting, val in info.items():
f = lib.getLatest(args.input, f"*{os.path.basename(val)}*", -1)
if args.restore_root is not None:
_, _, val_as_relative = os.path.splitroot(val)
val = os.path.join(args.restore_root, val_as_relative)
restored_files[setting] = os.path.abspath(val)
if lib.exists(args, val):
logging.info(
"File [%s]: for boot option [%s] already exists, skipping.",
Expand All @@ -50,6 +57,10 @@ def restore(args: Namespace, vmConfig: str, virtClient: virt.client) -> None:
"Restoring configured file [%s] for boot option [%s]", val, setting
)
lib.copy(args, f[0], val)
if restConfig != b"" and args.adjust_config is True:
return vmconfig.apply_paths(restConfig, restored_files)
else:
return restConfig


def verify(args: Namespace, dataFiles: List[str]) -> bool:
Expand Down
10 changes: 10 additions & 0 deletions libvirtnbdbackup/restore/vmconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
from libvirtnbdbackup.virt import xml
from libvirtnbdbackup.virt import disktype

from typing import Dict


def read(ConfigFile: str) -> str:
"""Read saved virtual machine config'"""
Expand Down Expand Up @@ -138,3 +140,11 @@ def restore(
lib.copy(args, vmConfig, targetFile)
logging.info("Copied original vm config to [%s]", targetFile)
logging.info("Note: virtual machine config must be adjusted manually.")


def apply_paths(config: bytes, restored_files: Dict[str, str]):
tree = xml.asTree(config)
os_config = tree.find("os")
for flag, val in restored_files.items():
os_config.find(flag).text = val
return xml.ElementTree.tostring(tree, encoding="utf8", method="xml")
9 changes: 8 additions & 1 deletion virtnbdrestore
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,13 @@ def main() -> None:
action="store_true",
help="Preallocate restored qcow images. (default: %(default)s)",
)
opt.add_argument(
"-R",
"--restore-root",
default=None,
type=str,
help="Store restored misc VM files (loader, firmware vars, etc) under alternative root directory (default /)",
)

remopt = parser.add_argument_group("Remote Restore options")
argopt.addRemoteArgs(remopt)
Expand Down Expand Up @@ -271,7 +278,7 @@ def main() -> None:
logging.error("Disk restore failed: [%s]", errmsg)
sys.exit(1)

files.restore(args, ConfigFile, virtClient)
restConfig = files.restore(args, ConfigFile, virtClient, restConfig)
vmconfig.restore(args, ConfigFile, restConfig, args.config_file)
virtClient.refreshPool(args.output)
if args.define is True:
Expand Down