backup: simplify ordering of restoring VMs
No other change than reducing two nested loops into one.
This commit is contained in:
parent
20d53fbf69
commit
71a7730168
192
qubes/backup.py
192
qubes/backup.py
@ -2110,113 +2110,109 @@ class BackupRestore(object):
|
|||||||
return
|
return
|
||||||
|
|
||||||
# First load templates, then other VMs
|
# First load templates, then other VMs
|
||||||
for do_templates in (True, False):
|
for vm in sorted(vms.values(), key=lambda x: x.is_template(),
|
||||||
|
reverse=True):
|
||||||
if self.canceled:
|
if self.canceled:
|
||||||
|
# only break the loop to save qubes.xml
|
||||||
|
# with already restored VMs
|
||||||
break
|
break
|
||||||
for vm in vms.values():
|
self.log.info("-> Restoring {0}...".format(vm.name))
|
||||||
if self.canceled:
|
retcode = subprocess.call(
|
||||||
# only break the loop to save qubes.xml
|
["mkdir", "-p", os.path.dirname(vm.dir_path)])
|
||||||
# with already restored VMs
|
if retcode != 0:
|
||||||
break
|
self.log.error("*** Cannot create directory: {0}?!".format(
|
||||||
if vm.is_template() != do_templates:
|
vm.dir_path))
|
||||||
continue
|
self.log.warning("Skipping VM {}...".format(vm.name))
|
||||||
self.log.info("-> Restoring {0}...".format(vm.name))
|
continue
|
||||||
retcode = subprocess.call(
|
|
||||||
["mkdir", "-p", os.path.dirname(vm.dir_path)])
|
|
||||||
if retcode != 0:
|
|
||||||
self.log.error("*** Cannot create directory: {0}?!".format(
|
|
||||||
vm.dir_path))
|
|
||||||
self.log.warning("Skipping VM {}...".format(vm.name))
|
|
||||||
continue
|
|
||||||
|
|
||||||
kwargs = {}
|
kwargs = {}
|
||||||
if hasattr(vm, 'template'):
|
if hasattr(vm, 'template'):
|
||||||
if vm.template is not None:
|
if vm.template is not None:
|
||||||
kwargs['template'] = restore_info[vm.name].template
|
kwargs['template'] = restore_info[vm.name].template
|
||||||
else:
|
else:
|
||||||
kwargs['template'] = None
|
kwargs['template'] = None
|
||||||
|
|
||||||
new_vm = None
|
new_vm = None
|
||||||
vm_name = vm.name
|
vm_name = vm.name
|
||||||
if restore_info[vm.name].rename_to:
|
if restore_info[vm.name].rename_to:
|
||||||
vm_name = restore_info[vm.name].rename_to
|
vm_name = restore_info[vm.name].rename_to
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# first only minimal set, later clone_properties
|
# first only minimal set, later clone_properties
|
||||||
# will be called
|
# will be called
|
||||||
new_vm = self.app.add_new_vm(
|
new_vm = self.app.add_new_vm(
|
||||||
vm.__class__,
|
vm.__class__,
|
||||||
name=vm_name,
|
name=vm_name,
|
||||||
label=vm.label,
|
label=vm.label,
|
||||||
installed_by_rpm=False,
|
installed_by_rpm=False,
|
||||||
**kwargs)
|
**kwargs)
|
||||||
if os.path.exists(new_vm.dir_path):
|
if os.path.exists(new_vm.dir_path):
|
||||||
move_to_path = tempfile.mkdtemp('', os.path.basename(
|
move_to_path = tempfile.mkdtemp('', os.path.basename(
|
||||||
new_vm.dir_path), os.path.dirname(new_vm.dir_path))
|
new_vm.dir_path), os.path.dirname(new_vm.dir_path))
|
||||||
try:
|
try:
|
||||||
os.rename(new_vm.dir_path, move_to_path)
|
os.rename(new_vm.dir_path, move_to_path)
|
||||||
self.log.warning(
|
self.log.warning(
|
||||||
"*** Directory {} already exists! It has "
|
"*** Directory {} already exists! It has "
|
||||||
"been moved to {}".format(new_vm.dir_path,
|
"been moved to {}".format(new_vm.dir_path,
|
||||||
move_to_path))
|
move_to_path))
|
||||||
except OSError:
|
except OSError:
|
||||||
self.log.error(
|
self.log.error(
|
||||||
"*** Directory {} already exists and "
|
"*** Directory {} already exists and "
|
||||||
"cannot be moved!".format(new_vm.dir_path))
|
"cannot be moved!".format(new_vm.dir_path))
|
||||||
self.log.warning("Skipping VM {}...".format(
|
self.log.warning("Skipping VM {}...".format(
|
||||||
vm.name))
|
vm.name))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if self.header_data.version == 1:
|
if self.header_data.version == 1:
|
||||||
self._restore_vm_dir_v1(vm.dir_path,
|
self._restore_vm_dir_v1(vm.dir_path,
|
||||||
os.path.dirname(new_vm.dir_path))
|
os.path.dirname(new_vm.dir_path))
|
||||||
else:
|
else:
|
||||||
shutil.move(os.path.join(self.tmpdir,
|
shutil.move(os.path.join(self.tmpdir,
|
||||||
vm.features['backup-path']),
|
vm.features['backup-path']),
|
||||||
new_vm.dir_path)
|
new_vm.dir_path)
|
||||||
|
|
||||||
new_vm.verify_files()
|
new_vm.verify_files()
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
self.log.error("ERROR: {0}".format(err))
|
self.log.error("ERROR: {0}".format(err))
|
||||||
self.log.warning("*** Skipping VM: {0}".format(vm.name))
|
self.log.warning("*** Skipping VM: {0}".format(vm.name))
|
||||||
if new_vm:
|
if new_vm:
|
||||||
del self.app.domains[new_vm.qid]
|
del self.app.domains[new_vm.qid]
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if hasattr(vm, 'kernel'):
|
if hasattr(vm, 'kernel'):
|
||||||
# TODO: add a setting for this?
|
# TODO: add a setting for this?
|
||||||
if not vm.property_is_default('kernel') and vm.kernel and \
|
if not vm.property_is_default('kernel') and vm.kernel and \
|
||||||
vm.kernel not in \
|
vm.kernel not in \
|
||||||
os.listdir(os.path.join(qubes.config.qubes_base_dir,
|
os.listdir(os.path.join(qubes.config.qubes_base_dir,
|
||||||
qubes.config.system_path[
|
qubes.config.system_path[
|
||||||
'qubes_kernels_base_dir'])):
|
'qubes_kernels_base_dir'])):
|
||||||
self.log.warning("Kernel %s not installed, "
|
self.log.warning("Kernel %s not installed, "
|
||||||
"using default one" % vm.kernel)
|
"using default one" % vm.kernel)
|
||||||
vm.kernel = qubes.property.DEFAULT
|
vm.kernel = qubes.property.DEFAULT
|
||||||
# remove no longer needed backup metadata
|
# remove no longer needed backup metadata
|
||||||
if 'backup-content' in vm.features:
|
if 'backup-content' in vm.features:
|
||||||
del vm.features['backup-content']
|
del vm.features['backup-content']
|
||||||
del vm.features['backup-size']
|
del vm.features['backup-size']
|
||||||
del vm.features['backup-path']
|
del vm.features['backup-path']
|
||||||
try:
|
try:
|
||||||
# exclude VM references - handled manually according to
|
# exclude VM references - handled manually according to
|
||||||
# restore options
|
# restore options
|
||||||
proplist = [prop for prop in new_vm.property_list()
|
proplist = [prop for prop in new_vm.property_list()
|
||||||
if prop.clone and prop.__name__ not in
|
if prop.clone and prop.__name__ not in
|
||||||
['template', 'netvm', 'dispvm_netvm']]
|
['template', 'netvm', 'dispvm_netvm']]
|
||||||
new_vm.clone_properties(vm, proplist=proplist)
|
new_vm.clone_properties(vm, proplist=proplist)
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
self.log.error("ERROR: {0}".format(err))
|
self.log.error("ERROR: {0}".format(err))
|
||||||
self.log.warning("*** Some VM property will not be "
|
self.log.warning("*** Some VM property will not be "
|
||||||
"restored")
|
"restored")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
new_vm.fire_event('domain-restore')
|
new_vm.fire_event('domain-restore')
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
self.log.error("ERROR during appmenu restore: "
|
self.log.error("ERROR during appmenu restore: "
|
||||||
"{0}".format(err))
|
"{0}".format(err))
|
||||||
self.log.warning(
|
self.log.warning(
|
||||||
"*** VM '{0}' will not have appmenus".format(vm.name))
|
"*** VM '{0}' will not have appmenus".format(vm.name))
|
||||||
|
|
||||||
# Set network dependencies - only non-default netvm setting
|
# Set network dependencies - only non-default netvm setting
|
||||||
for vm in vms.values():
|
for vm in vms.values():
|
||||||
|
Loading…
Reference in New Issue
Block a user