Template name change option, reset config files, standalone vm restore (#103)
Recreate config file when requested but also when template name changed. Restore full AppVM dir from backup - not only selected files.
This commit is contained in:
parent
d87265851c
commit
4723b9e2ef
@ -25,12 +25,14 @@ from qubes.qubes import QubesException
|
|||||||
from qubes.qubes import qubes_store_filename
|
from qubes.qubes import qubes_store_filename
|
||||||
from qubes.qubes import qubes_base_dir
|
from qubes.qubes import qubes_base_dir
|
||||||
from qubes.qubes import qubes_templates_dir
|
from qubes.qubes import qubes_templates_dir
|
||||||
|
from qubes.qubes import qubes_appvms_dir
|
||||||
from optparse import OptionParser
|
from optparse import OptionParser
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
import re
|
||||||
|
|
||||||
def size_to_human (size):
|
def size_to_human (size):
|
||||||
if size < 1024:
|
if size < 1024:
|
||||||
@ -58,8 +60,9 @@ fields = {
|
|||||||
|
|
||||||
"updbl" : {"func": "'Yes' if vm.is_updateable() else ''"},
|
"updbl" : {"func": "'Yes' if vm.is_updateable() else ''"},
|
||||||
|
|
||||||
"template": {"func": "'n/a' if vm.is_template() or vm.is_netvm() else\
|
"template": {"func": "'n/a' if vm.is_template() or vm.template_vm is None else\
|
||||||
backup_collection[vm.template_vm.qid].name"},
|
find_template_name(backup_collection[vm.template_vm.qid].name,\
|
||||||
|
options.replace_template)"},
|
||||||
|
|
||||||
"netvm": {"func": "'n/a' if vm.is_netvm() else\
|
"netvm": {"func": "'n/a' if vm.is_netvm() else\
|
||||||
('*' if vm.uses_default_netvm else '') +\
|
('*' if vm.uses_default_netvm else '') +\
|
||||||
@ -102,6 +105,14 @@ def restore_vm_dir (backup_dir, src_dir, dst_dir):
|
|||||||
print "*** Error while copying file {0} to {1}".format(backup_src_dir, dest_dir)
|
print "*** Error while copying file {0} to {1}".format(backup_src_dir, dest_dir)
|
||||||
exit (1)
|
exit (1)
|
||||||
|
|
||||||
|
def find_template_name(template, replaces):
|
||||||
|
rx_replace = re.compile("(.*):(.*)")
|
||||||
|
for r in replaces:
|
||||||
|
m = rx_replace.match(r)
|
||||||
|
if m.group(1) == template:
|
||||||
|
return m.group(2)
|
||||||
|
|
||||||
|
return template
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
usage = "usage: %prog [options] <backup-dir>"
|
usage = "usage: %prog [options] <backup-dir>"
|
||||||
@ -116,6 +127,12 @@ def main():
|
|||||||
parser.add_option ("--skip-conflicting", action="store_true", dest="skip_conflicting", default=False,
|
parser.add_option ("--skip-conflicting", action="store_true", dest="skip_conflicting", default=False,
|
||||||
help="Do not restore VMs that are already present on the host")
|
help="Do not restore VMs that are already present on the host")
|
||||||
|
|
||||||
|
parser.add_option ("--recreate-conf-files", action="store_true", dest="recreate_conf", default=False,
|
||||||
|
help="Recreate conf files after restore")
|
||||||
|
|
||||||
|
parser.add_option ("--replace-template", action="append", dest="replace_template", default=[],
|
||||||
|
help="Restore VMs using another template, syntax: old-template-name:new-template-name (might be repeated)")
|
||||||
|
|
||||||
(options, args) = parser.parse_args ()
|
(options, args) = parser.parse_args ()
|
||||||
|
|
||||||
if (len (args) != 1):
|
if (len (args) != 1):
|
||||||
@ -191,12 +208,12 @@ def main():
|
|||||||
there_are_conflicting_vms = True
|
there_are_conflicting_vms = True
|
||||||
good_to_go = False # Do not overwrite VMs on the host!
|
good_to_go = False # Do not overwrite VMs on the host!
|
||||||
|
|
||||||
if vm.is_appvm():
|
if vm.template_vm is not None:
|
||||||
templatevm_name = vm.template_vm.name
|
templatevm_name = find_template_name(vm.template_vm.name, options.replace_template)
|
||||||
template_vm_on_host = host_collection.get_vm_by_name (templatevm_name)
|
template_vm_on_host = host_collection.get_vm_by_name (templatevm_name)
|
||||||
|
|
||||||
# No template on the host?
|
# No template on the host?
|
||||||
if not ((template_vm_on_host is not None) and template_vm_on_host.is_template):
|
if not ((template_vm_on_host is not None) and template_vm_on_host.is_template()):
|
||||||
|
|
||||||
# Maybe the (custom) template is in the backup?
|
# Maybe the (custom) template is in the backup?
|
||||||
template_vm_on_backup = backup_collection.get_vm_by_name (templatevm_name)
|
template_vm_on_backup = backup_collection.get_vm_by_name (templatevm_name)
|
||||||
@ -279,14 +296,7 @@ def main():
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
if vm.is_appvm():
|
if vm.is_appvm():
|
||||||
|
restore_vm_dir (backup_dir, vm.dir_path, qubes_appvms_dir);
|
||||||
restore_vm_file (backup_dir, vm.private_img)
|
|
||||||
restore_vm_file (backup_dir, vm.icon_path)
|
|
||||||
restore_vm_file (backup_dir, vm.conf_file)
|
|
||||||
|
|
||||||
if vm.is_updateable():
|
|
||||||
restore_vm_file (backup_dir, vm.root_img)
|
|
||||||
|
|
||||||
elif vm.is_template():
|
elif vm.is_template():
|
||||||
restore_vm_dir (backup_dir, vm.dir_path, qubes_templates_dir);
|
restore_vm_dir (backup_dir, vm.dir_path, qubes_templates_dir);
|
||||||
else:
|
else:
|
||||||
@ -323,7 +333,13 @@ def main():
|
|||||||
for vm in [ vm for vm in vms_to_restore if vm.is_appvm()]:
|
for vm in [ vm for vm in vms_to_restore if vm.is_appvm()]:
|
||||||
|
|
||||||
print "-> Adding AppVM {0}...".format(vm.name)
|
print "-> Adding AppVM {0}...".format(vm.name)
|
||||||
template_vm = host_collection.get_vm_by_name(vm.template_vm.name)
|
template_vm = None
|
||||||
|
recreate_conf = options.recreate_conf
|
||||||
|
if vm.template_vm is not None:
|
||||||
|
template_name = find_template_name(vm.template_vm.name, options.replace_template)
|
||||||
|
template_vm = host_collection.get_vm_by_name(template_name)
|
||||||
|
if template_name != vm.template_vm.name:
|
||||||
|
recreate_conf = True
|
||||||
|
|
||||||
if not vm.uses_default_netvm:
|
if not vm.uses_default_netvm:
|
||||||
uses_default_netvm = False
|
uses_default_netvm = False
|
||||||
@ -336,13 +352,16 @@ def main():
|
|||||||
vm = host_collection.add_new_appvm(vm.name, template_vm,
|
vm = host_collection.add_new_appvm(vm.name, template_vm,
|
||||||
conf_file=vm.conf_file,
|
conf_file=vm.conf_file,
|
||||||
dir_path=vm.dir_path,
|
dir_path=vm.dir_path,
|
||||||
|
updateable=updateable,
|
||||||
label=vm.label)
|
label=vm.label)
|
||||||
|
|
||||||
vm.updateable = updateable
|
|
||||||
if not uses_default_netvm:
|
if not uses_default_netvm:
|
||||||
vm.uses_default_netvm = False
|
vm.uses_default_netvm = False
|
||||||
vm.netvm_vm = netvm_vm
|
vm.netvm_vm = netvm_vm
|
||||||
|
|
||||||
|
if template_vm is not None and recreate_conf:
|
||||||
|
print "--> Recreating config file..."
|
||||||
|
vm.create_config_file()
|
||||||
|
|
||||||
vm.create_appmenus(verbose=True)
|
vm.create_appmenus(verbose=True)
|
||||||
try:
|
try:
|
||||||
|
Loading…
Reference in New Issue
Block a user