dom0/core: drop support for non-updateable templates
Implement 'updateable' property as 'template is None'
This commit is contained in:
parent
f143b6c1f2
commit
cdd73f3d14
@ -228,7 +228,6 @@ class QubesVm(object):
|
||||
"volatile_img": { "eval": 'self.absolute_path(value, default_volatile_img)', 'order': 10 },
|
||||
"firewall_conf": { "eval": 'self.absolute_path(value, default_firewall_conf_file)', 'order': 10 },
|
||||
"installed_by_rpm": { "default": False, 'order': 10 },
|
||||
"updateable": { "default": False, 'order': 10 },
|
||||
"template": { "default": None, 'order': 10 },
|
||||
# order >= 20: have template set
|
||||
"uses_default_netvm": { "default": True, 'order': 20 },
|
||||
@ -266,7 +265,7 @@ class QubesVm(object):
|
||||
# Simple string attrs
|
||||
for prop in ['qid', 'name', 'dir_path', 'memory', 'maxmem', 'pcidevs', 'vcpus', 'internal',\
|
||||
'uses_default_kernel', 'kernel', 'uses_default_kernelopts',\
|
||||
'kernelopts', 'services', 'updateable', 'installed_by_rpm',\
|
||||
'kernelopts', 'services', 'installed_by_rpm',\
|
||||
'uses_default_netvm', 'include_in_backups' ]:
|
||||
attrs[prop]['save'] = 'str(self.%s)' % prop
|
||||
# Simple paths
|
||||
@ -279,7 +278,7 @@ class QubesVm(object):
|
||||
|
||||
attrs['netvm']['save'] = 'str(self.netvm.qid) if self.netvm is not None else "none"'
|
||||
attrs['netvm']['save_attr'] = "netvm_qid"
|
||||
attrs['template']['save'] = 'str(self.template.qid) if self.template and not self.is_updateable() else "none"'
|
||||
attrs['template']['save'] = 'str(self.template.qid) if self.template else "none"'
|
||||
attrs['template']['save_attr'] = "template_qid"
|
||||
attrs['label']['save'] = 'self.label.name'
|
||||
|
||||
@ -327,9 +326,6 @@ class QubesVm(object):
|
||||
|
||||
# Some additional checks for template based VM
|
||||
if self.template is not None:
|
||||
if self.updateable:
|
||||
print >> sys.stderr, "ERROR: Template based VM cannot be updateable!"
|
||||
return False
|
||||
if not self.template.is_template():
|
||||
print >> sys.stderr, "ERROR: template_qid={0} doesn't point to a valid TemplateVM".\
|
||||
format(self.template.qid)
|
||||
@ -457,6 +453,11 @@ class QubesVm(object):
|
||||
def mac(self, new_mac):
|
||||
self._mac = new_mac
|
||||
|
||||
@property
|
||||
def updateable(self):
|
||||
return self.template is None
|
||||
|
||||
# Leaved for compatibility
|
||||
def is_updateable(self):
|
||||
return self.updateable
|
||||
|
||||
@ -469,19 +470,6 @@ class QubesVm(object):
|
||||
else:
|
||||
return False
|
||||
|
||||
def set_updateable(self):
|
||||
if self.is_updateable():
|
||||
return
|
||||
|
||||
raise QubesException ("Change 'updateable' flag is not supported. Please use qvm-create.")
|
||||
|
||||
def set_nonupdateable(self):
|
||||
if not self.is_updateable():
|
||||
return
|
||||
|
||||
raise QubesException ("Change 'updateable' flag is not supported. Please use qvm-create.")
|
||||
|
||||
|
||||
def pre_rename(self, new_name):
|
||||
pass
|
||||
|
||||
@ -875,7 +863,7 @@ class QubesVm(object):
|
||||
args['privatedev'] = "'script:file:{dir}/private.img,xvdb,w',".format(dir=self.dir_path)
|
||||
args['volatiledev'] = "'script:file:{dir}/volatile.img,xvdc,w',".format(dir=self.dir_path)
|
||||
modulesmode='r'
|
||||
if self.is_updateable() and self.kernel is None:
|
||||
if self.updateable and self.kernel is None:
|
||||
modulesmode='w'
|
||||
args['otherdevs'] = "'script:file:{dir}/modules.img,xvdd,{mode}',".format(dir=self.kernels_dir, mode=modulesmode)
|
||||
args['kernelopts'] = self.kernelopts
|
||||
@ -937,7 +925,7 @@ class QubesVm(object):
|
||||
shutil.copy(source_template.dir_path + '/vm-' + qubes_whitelisted_appmenus,
|
||||
self.dir_path + '/' + qubes_whitelisted_appmenus)
|
||||
|
||||
if self.is_updateable():
|
||||
if self.updateable:
|
||||
template_root = source_template.root_img
|
||||
if verbose:
|
||||
print >> sys.stderr, "--> Copying the template's root image: {0}".\
|
||||
@ -1067,7 +1055,7 @@ class QubesVm(object):
|
||||
"VM directory doesn't exist: {0}".\
|
||||
format(self.dir_path))
|
||||
|
||||
if self.is_updateable() and not os.path.exists (self.root_img):
|
||||
if self.updateable and not os.path.exists (self.root_img):
|
||||
raise QubesException (
|
||||
"VM root image file doesn't exist: {0}".\
|
||||
format(self.root_img))
|
||||
@ -1483,7 +1471,6 @@ class QubesTemplateVm(QubesVm):
|
||||
def _get_attrs_config(self):
|
||||
attrs_config = super(QubesTemplateVm, self)._get_attrs_config()
|
||||
attrs_config['dir_path']['eval'] = 'value if value is not None else qubes_templates_dir + "/" + self.name'
|
||||
attrs_config['updateable']['default'] = True
|
||||
attrs_config['label']['default'] = default_template_label
|
||||
|
||||
# New attributes
|
||||
@ -1506,18 +1493,9 @@ class QubesTemplateVm(QubesVm):
|
||||
def type(self):
|
||||
return "TemplateVM"
|
||||
|
||||
def set_updateable(self):
|
||||
if self.is_updateable():
|
||||
return
|
||||
|
||||
assert not self.is_running()
|
||||
# Make sure that all the AppVMs are non-updateable...
|
||||
for appvm in self.appvms.values():
|
||||
if appvm.is_updateable():
|
||||
raise QubesException("One of the AppVMs ('{0}')is also 'updateable'\
|
||||
-- cannot make the TemplateVM {'{1}'} 'nonupdatable'".\
|
||||
format (appvm.name, self.name))
|
||||
self.updateable = True
|
||||
@property
|
||||
def updateable(self):
|
||||
return True
|
||||
|
||||
def get_rootdev(self, source_template=None):
|
||||
return "'script:origin:{dir}/root.img:{dir}/root-cow.img,xvda,w',".format(dir=self.dir_path)
|
||||
@ -1633,7 +1611,7 @@ class QubesTemplateVm(QubesVm):
|
||||
|
||||
self.reset_volatile_storage(verbose=verbose)
|
||||
|
||||
if not self.is_updateable():
|
||||
if not self.updateable:
|
||||
raise QubesException ("Cannot start Template VM that is marked \"nonupdatable\"")
|
||||
|
||||
# TODO?: check if none of running appvms are outdated
|
||||
@ -2104,7 +2082,7 @@ class QubesAppVm(QubesVm):
|
||||
|
||||
super(QubesAppVm, self).create_on_disk(verbose, source_template=source_template)
|
||||
|
||||
if self.is_updateable():
|
||||
if self.updateable:
|
||||
if verbose:
|
||||
print >> sys.stderr, "--> Copying the template's appmenus templates dir:\n{0} ==>\n{1}".\
|
||||
format(source_template.appmenus_templates_dir, self.appmenus_templates_dir)
|
||||
@ -2170,7 +2148,6 @@ class QubesVmCollection(dict):
|
||||
def add_new_appvm(self, name, template,
|
||||
dir_path = None, conf_file = None,
|
||||
private_img = None,
|
||||
updateable = False,
|
||||
label = None):
|
||||
|
||||
qid = self.get_new_unused_qid()
|
||||
@ -2180,7 +2157,6 @@ class QubesVmCollection(dict):
|
||||
netvm = self.get_default_netvm(),
|
||||
kernel = self.get_default_kernel(),
|
||||
uses_default_kernel = True,
|
||||
updateable=updateable,
|
||||
label=label)
|
||||
|
||||
if not self.verify_new_vm (vm):
|
||||
@ -2236,14 +2212,13 @@ class QubesVmCollection(dict):
|
||||
def add_new_netvm(self, name, template,
|
||||
dir_path = None, conf_file = None,
|
||||
private_img = None, installed_by_rpm = False,
|
||||
label = None, updateable = False):
|
||||
label = None):
|
||||
|
||||
qid = self.get_new_unused_qid()
|
||||
netid = self.get_new_unused_netid()
|
||||
vm = QubesNetVm (qid=qid, name=name, template=template,
|
||||
netid=netid, label=label,
|
||||
private_img=private_img, installed_by_rpm=installed_by_rpm,
|
||||
updateable=updateable,
|
||||
kernel = self.get_default_kernel(),
|
||||
uses_default_kernel = True,
|
||||
dir_path=dir_path, conf_file=conf_file)
|
||||
@ -2264,7 +2239,7 @@ class QubesVmCollection(dict):
|
||||
def add_new_proxyvm(self, name, template,
|
||||
dir_path = None, conf_file = None,
|
||||
private_img = None, installed_by_rpm = False,
|
||||
label = None, updateable = False):
|
||||
label = None):
|
||||
|
||||
qid = self.get_new_unused_qid()
|
||||
netid = self.get_new_unused_netid()
|
||||
@ -2272,7 +2247,6 @@ class QubesVmCollection(dict):
|
||||
netid=netid, label=label,
|
||||
private_img=private_img, installed_by_rpm=installed_by_rpm,
|
||||
dir_path=dir_path, conf_file=conf_file,
|
||||
updateable=updateable,
|
||||
kernel = self.get_default_kernel(),
|
||||
uses_default_kernel = True,
|
||||
netvm = self.get_default_fw_netvm())
|
||||
@ -2482,7 +2456,7 @@ class QubesVmCollection(dict):
|
||||
kwargs = {}
|
||||
common_attr_list = ("qid", "name", "dir_path", "conf_file",
|
||||
"private_img", "root_img", "template_qid",
|
||||
"installed_by_rpm", "updateable", "internal",
|
||||
"installed_by_rpm", "internal",
|
||||
"uses_default_netvm", "label", "memory", "vcpus", "pcidevs",
|
||||
"maxmem", "kernel", "uses_default_kernel", "kernelopts", "uses_default_kernelopts",
|
||||
"mac", "services", "include_in_backups" )
|
||||
@ -2493,8 +2467,6 @@ class QubesVmCollection(dict):
|
||||
kwargs.pop(attribute)
|
||||
|
||||
kwargs["qid"] = int(kwargs["qid"])
|
||||
if "updateable" in kwargs:
|
||||
kwargs["updateable"] = True if kwargs["updateable"] == "True" else False
|
||||
|
||||
if "include_in_backups" in kwargs:
|
||||
kwargs["include_in_backups"] = True if kwargs["include_in_backups"] == "True" else False
|
||||
|
@ -390,7 +390,7 @@ def backup_prepare(base_backup_dir, vms_list = None, exclude_list = [], print_ca
|
||||
|
||||
if vm.is_appvm():
|
||||
files_to_backup += file_to_backup(vm.icon_path)
|
||||
if vm.is_updateable():
|
||||
if vm.updateable:
|
||||
if os.path.exists(vm.dir_path + "/apps.templates"):
|
||||
# template
|
||||
files_to_backup += file_to_backup(vm.dir_path + "/apps.templates")
|
||||
@ -405,7 +405,7 @@ def backup_prepare(base_backup_dir, vms_list = None, exclude_list = [], print_ca
|
||||
if os.path.exists(vm.dir_path + '/whitelisted-appmenus.list'):
|
||||
files_to_backup += file_to_backup(vm.dir_path + '/whitelisted-appmenus.list')
|
||||
|
||||
if vm.is_updateable():
|
||||
if vm.updateable:
|
||||
sz = vm.get_disk_usage(vm.root_img)
|
||||
files_to_backup += file_to_backup(vm.root_img, sz)
|
||||
vm_sz += sz
|
||||
@ -419,9 +419,9 @@ def backup_prepare(base_backup_dir, vms_list = None, exclude_list = [], print_ca
|
||||
|
||||
fmt="{{0:>{0}}} |".format(fields_to_display[1]["width"] + 1)
|
||||
if vm.is_netvm():
|
||||
s += fmt.format("NetVM" + (" + Sys" if vm.is_updateable() else ""))
|
||||
s += fmt.format("NetVM" + (" + Sys" if vm.updateable else ""))
|
||||
else:
|
||||
s += fmt.format("AppVM" + (" + Sys" if vm.is_updateable() else ""))
|
||||
s += fmt.format("AppVM" + (" + Sys" if vm.updateable else ""))
|
||||
|
||||
fmt="{{0:>{0}}} |".format(fields_to_display[2]["width"] + 1)
|
||||
s += fmt.format(size_to_human(vm_sz))
|
||||
@ -702,7 +702,7 @@ def backup_restore_print_summary(restore_info, print_callback = print_stdout):
|
||||
('Proxy' if vm.is_proxyvm() else \
|
||||
(' Net' if vm.is_netvm() else 'App'))"},
|
||||
|
||||
"updbl" : {"func": "'Yes' if vm.is_updateable() else ''"},
|
||||
"updbl" : {"func": "'Yes' if vm.updateable else ''"},
|
||||
|
||||
"template": {"func": "'n/a' if vm.is_template() or vm.template is None else\
|
||||
vm_info['template']"},
|
||||
@ -834,8 +834,6 @@ def backup_restore_do(backup_dir, restore_info, host_collection = None, print_ca
|
||||
error_callback("Skiping...")
|
||||
continue
|
||||
|
||||
updateable = vm.updateable
|
||||
|
||||
new_vm = None
|
||||
|
||||
try:
|
||||
@ -845,7 +843,6 @@ def backup_restore_do(backup_dir, restore_info, host_collection = None, print_ca
|
||||
dir_path=vm.dir_path,
|
||||
installed_by_rpm=False)
|
||||
|
||||
new_vm.updateable = updateable
|
||||
new_vm.verify_files()
|
||||
except Exception as err:
|
||||
error_callback("ERROR: {0}".format(err))
|
||||
@ -888,8 +885,6 @@ def backup_restore_do(backup_dir, restore_info, host_collection = None, print_ca
|
||||
else:
|
||||
uses_default_netvm = True
|
||||
|
||||
updateable = vm.updateable
|
||||
|
||||
new_vm = None
|
||||
try:
|
||||
restore_vm_dir (backup_dir, vm.dir_path, qubes_servicevms_dir);
|
||||
@ -898,13 +893,11 @@ def backup_restore_do(backup_dir, restore_info, host_collection = None, print_ca
|
||||
new_vm = host_collection.add_new_netvm(vm.name, template,
|
||||
conf_file=vm.conf_file,
|
||||
dir_path=vm.dir_path,
|
||||
updateable=updateable,
|
||||
label=vm.label)
|
||||
elif vm.type == "ProxyVM":
|
||||
new_vm = host_collection.add_new_proxyvm(vm.name, template,
|
||||
conf_file=vm.conf_file,
|
||||
dir_path=vm.dir_path,
|
||||
updateable=updateable,
|
||||
label=vm.label)
|
||||
except Exception as err:
|
||||
error_callback("ERROR: {0}".format(err))
|
||||
@ -953,15 +946,12 @@ def backup_restore_do(backup_dir, restore_info, host_collection = None, print_ca
|
||||
else:
|
||||
uses_default_netvm = True
|
||||
|
||||
updateable = vm.updateable
|
||||
|
||||
new_vm = None
|
||||
try:
|
||||
restore_vm_dir (backup_dir, vm.dir_path, qubes_appvms_dir);
|
||||
new_vm = host_collection.add_new_appvm(vm.name, template,
|
||||
conf_file=vm.conf_file,
|
||||
dir_path=vm.dir_path,
|
||||
updateable=updateable,
|
||||
label=vm.label)
|
||||
except Exception as err:
|
||||
error_callback("ERROR: {0}".format(err))
|
||||
|
@ -60,7 +60,7 @@ def main():
|
||||
dir_path=options.dir_path, installed_by_rpm=False)
|
||||
elif isinstance(src_vm, QubesAppVm):
|
||||
dst_vm = qvm_collection.add_new_appvm(name=dstname, template=src_vm.template,
|
||||
updateable=src_vm.updateable, label=src_vm.label,
|
||||
label=src_vm.label,
|
||||
dir_path=options.dir_path)
|
||||
else:
|
||||
print >> sys.stderr, "ERROR: Clone not supported for this type of VM"
|
||||
|
@ -117,11 +117,11 @@ def main():
|
||||
|
||||
vm = None
|
||||
if options.netvm:
|
||||
vm = qvm_collection.add_new_netvm(vmname, new_vm_template, label = label, updateable = options.standalone)
|
||||
vm = qvm_collection.add_new_netvm(vmname, new_vm_template, label = label)
|
||||
elif options.proxyvm:
|
||||
vm = qvm_collection.add_new_proxyvm(vmname, new_vm_template, label = label, updateable = options.standalone)
|
||||
vm = qvm_collection.add_new_proxyvm(vmname, new_vm_template, label = label)
|
||||
else:
|
||||
vm = qvm_collection.add_new_appvm(vmname, new_vm_template, label = label, updateable = options.standalone)
|
||||
vm = qvm_collection.add_new_appvm(vmname, new_vm_template, label = label)
|
||||
|
||||
if options.internal:
|
||||
vm.internal = True
|
||||
|
@ -44,7 +44,7 @@ fields = {
|
||||
('Proxy' if vm.is_proxyvm() else \
|
||||
(' Net' if vm.is_netvm() else ''))"},
|
||||
|
||||
"updbl" : {"func": "'Yes' if vm.is_updateable() else ''"},
|
||||
"updbl" : {"func": "'Yes' if vm.updateable else ''"},
|
||||
|
||||
"template": {"func": "'n/a' if vm.is_template() else\
|
||||
('None' if vm.template is None else\
|
||||
|
@ -41,7 +41,7 @@ def do_list(vm):
|
||||
print fmt.format ("template", vm.template.name)
|
||||
if vm.netvm is not None:
|
||||
print fmt.format ("netvm", vm.netvm.name)
|
||||
print fmt.format ("updateable?", vm.is_updateable())
|
||||
print fmt.format ("updateable?", vm.updateable)
|
||||
print fmt.format ("installed by RPM?", vm.installed_by_rpm)
|
||||
print fmt.format ("include in backups", vm.include_in_backups)
|
||||
print fmt.format ("dir", vm.dir_path)
|
||||
@ -152,59 +152,6 @@ def set_netvm(vms, vm, args):
|
||||
|
||||
vm.netvm = netvm
|
||||
|
||||
def set_updateable(vms, vm, args):
|
||||
if vm.is_updateable():
|
||||
print >> sys.stderr, "VM '{0}' is already set 'updateable', no action required.".format(vm.name)
|
||||
return True
|
||||
|
||||
if vm.is_running():
|
||||
print >> sys.stderr, "Cannot change 'updateable' attribute of a running VM. Shut it down first."
|
||||
return False
|
||||
|
||||
if vm.is_appvm():
|
||||
# Check if the Template is *non* updateable...
|
||||
if not vm.template.is_updateable():
|
||||
print >> sys.stderr, "VM '{0}': Setting 'updateable' attribute to True.".format(vm.name)
|
||||
vm.set_updateable()
|
||||
else:
|
||||
print >> sys.stderr, "The Template VM ('{0}') is marked as 'updateable' itself!".format(vm.template.name)
|
||||
print >> sys.stderr, "Cannot make the AppVM updateable too, as this might cause COW-backed storage incoherency."
|
||||
print >> sys.stderr, "If you want to make this AppVM updateable, you must first make the Template VM nonupdateable."
|
||||
return False
|
||||
|
||||
if vm.is_template():
|
||||
# Make sure that all the AppVMs are non-updateable...
|
||||
for appvm in vm.appvms.values():
|
||||
if appvm.is_updateable():
|
||||
print >> sys.stderr, "At least one of the AppVMs ('{0}') of this Template VM is also marked 'updateable'.".format(appvm.name)
|
||||
print >> sys.stderr, "Cannot make the Template VM updateable too, as this might cause COW-backed storage incoherency."
|
||||
print >> sys.stderr, "If you want to make this Template VM updateable, you must first make all its decedent AppVMs nonupdateable."
|
||||
return False
|
||||
|
||||
|
||||
print >> sys.stderr, "VM '{0}': Setting 'updateable' attribute to True.".format(vm.name)
|
||||
vm.set_updateable()
|
||||
|
||||
return True
|
||||
|
||||
def set_nonupdateable(vms, vm, args):
|
||||
if not vm.is_updateable():
|
||||
print >> sys.stderr, "VM '{0}' is already set 'nonupdateable', no action required.".format(vm.name)
|
||||
return True
|
||||
|
||||
if vm.is_running():
|
||||
print >> sys.stderr, "Cannot change 'updateable' attribute of a running VM. Shut it down first."
|
||||
return False
|
||||
|
||||
if vm.is_netvm():
|
||||
print >> sys.stderr, "Why, on earth, would you want to make a NetVM 'nonupdateable'?"
|
||||
return False
|
||||
|
||||
|
||||
print >> sys.stderr, "VM '{0}': Setting 'updateable' attribute to False.".format(vm.name)
|
||||
vm.set_nonupdateable()
|
||||
return True
|
||||
|
||||
def set_kernel(vms, vm, args):
|
||||
if vm.template is not None:
|
||||
print >> sys.stderr, "Cannot set kernel for template-based VM. Set it for template instead."
|
||||
@ -310,8 +257,6 @@ def set_include_in_backups(vms, vm, args):
|
||||
|
||||
properties = {
|
||||
"include_in_backups": set_include_in_backups,
|
||||
"updateable": set_updateable,
|
||||
"nonupdateable": set_nonupdateable,
|
||||
"pcidevs": set_pcidevs,
|
||||
"label" : set_label,
|
||||
"netvm" : set_netvm,
|
||||
|
@ -164,8 +164,8 @@ def main():
|
||||
print >>sys.stderr, "ERROR: A VM with the name '{0}' does not exist in the system.".format(vmname)
|
||||
exit(1)
|
||||
|
||||
if not vm.is_updateable():
|
||||
print >>sys.stderr, "ERROR: To sync appmenus for non-updateable VM, do it on template instead"
|
||||
if vm.template is not None:
|
||||
print >>sys.stderr, "ERROR: To sync appmenus for template based VM, do it on template instead"
|
||||
exit(1)
|
||||
|
||||
if not vm.is_running():
|
||||
|
Loading…
Reference in New Issue
Block a user