Merge branch 'master' into hvm

Conflicts:
	dom0/qvm-core/qubes.py
	dom0/qvm-tools/qvm-create
	dom0/qvm-tools/qvm-prefs
This commit is contained in:
Marek Marczykowski 2012-03-09 11:34:13 +01:00
commit 3171cdbdcc
11 changed files with 121 additions and 214 deletions

View File

@ -18,7 +18,7 @@ def main():
print templ, 'is not a template' print templ, 'is not a template'
sys.exit(1) sys.exit(1)
for vm in qvm_collection.values(): for vm in qvm_collection.values():
if vm.template_vm is not None and vm.template_vm.qid == tvm.qid: if vm.template is not None and vm.template.qid == tvm.qid:
vm.create_config_file() vm.create_config_file()
main() main()

View File

@ -235,8 +235,7 @@ class QubesVm(object):
"volatile_img": { "eval": 'self.absolute_path(value, default_volatile_img)', 'order': 10 }, "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 }, "firewall_conf": { "eval": 'self.absolute_path(value, default_firewall_conf_file)', 'order': 10 },
"installed_by_rpm": { "default": False, 'order': 10 }, "installed_by_rpm": { "default": False, 'order': 10 },
"updateable": { "default": False, 'order': 10 }, "template": { "default": None, 'order': 10 },
"template_vm": { "default": None, 'order': 10 },
# order >= 20: have template set # order >= 20: have template set
"uses_default_netvm": { "default": True, 'order': 20 }, "uses_default_netvm": { "default": True, 'order': 20 },
"netvm": { "default": None, "attr": "_netvm", 'order': 20 }, "netvm": { "default": None, "attr": "_netvm", 'order': 20 },
@ -249,7 +248,7 @@ class QubesVm(object):
"internal": { "default": False }, "internal": { "default": False },
"vcpus": { "default": None }, "vcpus": { "default": None },
"kernel": { "default": None, 'eval': \ "kernel": { "default": None, 'eval': \
'self.template_vm.kernel if self.template_vm is not None else value' }, 'self.template.kernel if self.template is not None else value' },
"uses_default_kernel": { "default": True }, "uses_default_kernel": { "default": True },
"uses_default_kernelopts": { "default": True }, "uses_default_kernelopts": { "default": True },
"kernelopts": { "default": "", "eval": \ "kernelopts": { "default": "", "eval": \
@ -260,10 +259,10 @@ class QubesVm(object):
##### Internal attributes - will be overriden in __init__ regardless of args ##### Internal attributes - will be overriden in __init__ regardless of args
"appmenus_templates_dir": { "eval": \ "appmenus_templates_dir": { "eval": \
'self.dir_path + "/" + default_appmenus_templates_subdir if self.updateable else ' + \ 'self.dir_path + "/" + default_appmenus_templates_subdir if self.updateable else ' + \
'self.template_vm.appmenus_templates_dir if self.template_vm is not None else None' }, 'self.template.appmenus_templates_dir if self.template is not None else None' },
"config_file_template": { "eval": "config_template_pv" }, "config_file_template": { "eval": "config_template_pv" },
"icon_path": { "eval": 'self.dir_path + "/icon.png" if self.dir_path is not None else None' }, "icon_path": { "eval": 'self.dir_path + "/icon.png" if self.dir_path is not None else None' },
"kernels_dir": { 'eval': 'self.template_vm.kernels_dir if self.template_vm is not None else ' + \ "kernels_dir": { 'eval': 'self.template.kernels_dir if self.template is not None else ' + \
'qubes_kernels_base_dir + "/" + self.kernel if self.kernel is not None else ' + \ 'qubes_kernels_base_dir + "/" + self.kernel if self.kernel is not None else ' + \
# for backward compatibility (or another rare case): kernel=None -> kernel in VM dir # for backward compatibility (or another rare case): kernel=None -> kernel in VM dir
'self.dir_path + "/" + default_kernels_subdir' }, 'self.dir_path + "/" + default_kernels_subdir' },
@ -273,7 +272,7 @@ class QubesVm(object):
# Simple string attrs # Simple string attrs
for prop in ['qid', 'name', 'dir_path', 'memory', 'maxmem', 'pcidevs', 'vcpus', 'internal',\ for prop in ['qid', 'name', 'dir_path', 'memory', 'maxmem', 'pcidevs', 'vcpus', 'internal',\
'uses_default_kernel', 'kernel', 'uses_default_kernelopts',\ 'uses_default_kernel', 'kernel', 'uses_default_kernelopts',\
'kernelopts', 'services', 'updateable', 'installed_by_rpm',\ 'kernelopts', 'services', 'installed_by_rpm',\
'uses_default_netvm', 'include_in_backups' ]: 'uses_default_netvm', 'include_in_backups' ]:
attrs[prop]['save'] = 'str(self.%s)' % prop attrs[prop]['save'] = 'str(self.%s)' % prop
# Simple paths # Simple paths
@ -286,8 +285,8 @@ class QubesVm(object):
attrs['netvm']['save'] = 'str(self.netvm.qid) if self.netvm is not None else "none"' attrs['netvm']['save'] = 'str(self.netvm.qid) if self.netvm is not None else "none"'
attrs['netvm']['save_attr'] = "netvm_qid" attrs['netvm']['save_attr'] = "netvm_qid"
attrs['template_vm']['save'] = 'str(self.template_vm.qid) if self.template_vm and not self.is_updateable() else "none"' attrs['template']['save'] = 'str(self.template.qid) if self.template else "none"'
attrs['template_vm']['save_attr'] = "template_qid" attrs['template']['save_attr'] = "template_qid"
attrs['label']['save'] = 'self.label.name' attrs['label']['save'] = 'self.label.name'
return attrs return attrs
@ -333,15 +332,12 @@ class QubesVm(object):
self.vcpus = qubes_host.no_cpus self.vcpus = qubes_host.no_cpus
# Some additional checks for template based VM # Some additional checks for template based VM
if self.template_vm is not None: if self.template is not None:
if self.updateable: if not self.template.is_template():
print >> sys.stderr, "ERROR: Template based VM cannot be updateable!"
return False
if not self.template_vm.is_template():
print >> sys.stderr, "ERROR: template_qid={0} doesn't point to a valid TemplateVM".\ print >> sys.stderr, "ERROR: template_qid={0} doesn't point to a valid TemplateVM".\
format(self.template_vm.qid) format(self.template.qid)
return False return False
self.template_vm.appvms[self.qid] = self self.template.appvms[self.qid] = self
else: else:
assert self.root_img is not None, "Missing root_img for standalone VM!" assert self.root_img is not None, "Missing root_img for standalone VM!"
@ -464,6 +460,11 @@ class QubesVm(object):
def mac(self, new_mac): def mac(self, new_mac):
self._mac = new_mac self._mac = new_mac
@property
def updateable(self):
return self.template is None
# Leaved for compatibility
def is_updateable(self): def is_updateable(self):
return self.updateable return self.updateable
@ -476,19 +477,6 @@ class QubesVm(object):
else: else:
return False 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): def pre_rename(self, new_name):
pass pass
@ -683,14 +671,14 @@ class QubesVm(object):
def is_outdated(self): def is_outdated(self):
# Makes sense only on VM based on template # Makes sense only on VM based on template
if self.template_vm is None: if self.template is None:
return False return False
if not self.is_running(): if not self.is_running():
return False return False
rootimg_inode = os.stat(self.template_vm.root_img) rootimg_inode = os.stat(self.template.root_img)
rootcow_inode = os.stat(self.template_vm.rootcow_img) rootcow_inode = os.stat(self.template.rootcow_img)
current_dmdev = "/dev/mapper/snapshot-{0:x}:{1}-{2:x}:{3}".format( current_dmdev = "/dev/mapper/snapshot-{0:x}:{1}-{2:x}:{3}".format(
rootimg_inode[2], rootimg_inode[1], rootimg_inode[2], rootimg_inode[1],
@ -851,8 +839,8 @@ class QubesVm(object):
[{ 'dom': xid }]) [{ 'dom': xid }])
def get_rootdev(self, source_template=None): def get_rootdev(self, source_template=None):
if self.template_vm: if self.template:
return "'script:snapshot:{dir}/root.img:{dir}/root-cow.img,xvda,r',".format(dir=self.template_vm.dir_path) return "'script:snapshot:{dir}/root.img:{dir}/root-cow.img,xvda,r',".format(dir=self.template.dir_path)
else: else:
return "'script:file:{dir}/root.img,xvda,w',".format(dir=self.dir_path) return "'script:file:{dir}/root.img,xvda,w',".format(dir=self.dir_path)
@ -884,7 +872,7 @@ class QubesVm(object):
args['volatiledev'] = "'script:file:{dir}/volatile.img,xvdc,w',".format(dir=self.dir_path) args['volatiledev'] = "'script:file:{dir}/volatile.img,xvdc,w',".format(dir=self.dir_path)
if hasattr(self, 'kernel'): if hasattr(self, 'kernel'):
modulesmode='r' modulesmode='r'
if self.is_updateable() and self.kernel is None: if self.updateable and self.kernel is None:
modulesmode='w' modulesmode='w'
args['otherdevs'] = "'script:file:{dir}/modules.img,xvdd,{mode}',".format(dir=self.kernels_dir, mode=modulesmode) args['otherdevs'] = "'script:file:{dir}/modules.img,xvdd,{mode}',".format(dir=self.kernels_dir, mode=modulesmode)
if hasattr(self, 'kernelopts'): if hasattr(self, 'kernelopts'):
@ -896,7 +884,7 @@ class QubesVm(object):
if file_path is None: if file_path is None:
file_path = self.conf_file file_path = self.conf_file
if source_template is None: if source_template is None:
source_template = self.template_vm source_template = self.template
f_conf_template = open(self.config_file_template, 'r') f_conf_template = open(self.config_file_template, 'r')
conf_template = f_conf_template.read() conf_template = f_conf_template.read()
@ -914,7 +902,7 @@ class QubesVm(object):
def create_on_disk(self, verbose, source_template = None): def create_on_disk(self, verbose, source_template = None):
if source_template is None: if source_template is None:
source_template = self.template_vm source_template = self.template
assert source_template is not None assert source_template is not None
if dry_run: if dry_run:
@ -947,7 +935,7 @@ class QubesVm(object):
shutil.copy(source_template.dir_path + '/vm-' + qubes_whitelisted_appmenus, shutil.copy(source_template.dir_path + '/vm-' + qubes_whitelisted_appmenus,
self.dir_path + '/' + qubes_whitelisted_appmenus) self.dir_path + '/' + qubes_whitelisted_appmenus)
if self.is_updateable(): if self.updateable:
template_root = source_template.root_img template_root = source_template.root_img
if verbose: if verbose:
print >> sys.stderr, "--> Copying the template's root image: {0}".\ print >> sys.stderr, "--> Copying the template's root image: {0}".\
@ -973,7 +961,7 @@ class QubesVm(object):
def create_appmenus(self, verbose, source_template = None): def create_appmenus(self, verbose, source_template = None):
if source_template is None: if source_template is None:
source_template = self.template_vm source_template = self.template
vmtype = None vmtype = None
if self.is_netvm(): if self.is_netvm():
@ -1077,7 +1065,7 @@ class QubesVm(object):
"VM directory doesn't exist: {0}".\ "VM directory doesn't exist: {0}".\
format(self.dir_path)) 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 ( raise QubesException (
"VM root image file doesn't exist: {0}".\ "VM root image file doesn't exist: {0}".\
format(self.root_img)) format(self.root_img))
@ -1107,7 +1095,7 @@ class QubesVm(object):
assert not self.is_running(), "Attempt to clean volatile image of running VM!" assert not self.is_running(), "Attempt to clean volatile image of running VM!"
if source_template is None: if source_template is None:
source_template = self.template_vm source_template = self.template
# Only makes sense on template based VM # Only makes sense on template based VM
if source_template is None: if source_template is None:
@ -1497,7 +1485,6 @@ class QubesTemplateVm(QubesVm):
def _get_attrs_config(self): def _get_attrs_config(self):
attrs_config = super(QubesTemplateVm, self)._get_attrs_config() 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['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 attrs_config['label']['default'] = default_template_label
# New attributes # New attributes
@ -1520,18 +1507,9 @@ class QubesTemplateVm(QubesVm):
def type(self): def type(self):
return "TemplateVM" return "TemplateVM"
def set_updateable(self): @property
if self.is_updateable(): def updateable(self):
return return True
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
def get_rootdev(self, source_template=None): def get_rootdev(self, source_template=None):
return "'script:origin:{dir}/root.img:{dir}/root-cow.img,xvda,w',".format(dir=self.dir_path) return "'script:origin:{dir}/root.img:{dir}/root-cow.img,xvda,w',".format(dir=self.dir_path)
@ -1556,7 +1534,7 @@ class QubesTemplateVm(QubesVm):
retcode = subprocess.call (["cp", src_vm.clean_volatile_img, self.clean_volatile_img]) retcode = subprocess.call (["cp", src_vm.clean_volatile_img, self.clean_volatile_img])
if retcode != 0: if retcode != 0:
raise IOError ("Error while copying {0} to {1}".\ raise IOError ("Error while copying {0} to {1}".\
format(src_template_vm.clean_volatile_img, self.clean_volatile_img)) format(src_vm.clean_volatile_img, self.clean_volatile_img))
if verbose: if verbose:
print >> sys.stderr, "--> Copying the template's volatile image:\n{0} ==>\n{1}".\ print >> sys.stderr, "--> Copying the template's volatile image:\n{0} ==>\n{1}".\
format(self.clean_volatile_img, self.volatile_img) format(self.clean_volatile_img, self.volatile_img)
@ -1577,7 +1555,7 @@ class QubesTemplateVm(QubesVm):
def create_appmenus(self, verbose, source_template = None): def create_appmenus(self, verbose, source_template = None):
if source_template is None: if source_template is None:
source_template = self.template_vm source_template = self.template
try: try:
subprocess.check_call ([qubes_appmenu_create_cmd, self.appmenus_templates_dir, self.name, "vm-templates"]) subprocess.check_call ([qubes_appmenu_create_cmd, self.appmenus_templates_dir, self.name, "vm-templates"])
@ -1647,7 +1625,7 @@ class QubesTemplateVm(QubesVm):
self.reset_volatile_storage(verbose=verbose) 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\"") raise QubesException ("Cannot start Template VM that is marked \"nonupdatable\"")
# TODO?: check if none of running appvms are outdated # TODO?: check if none of running appvms are outdated
@ -1667,7 +1645,7 @@ class QubesTemplateVm(QubesVm):
retcode = subprocess.call (["tar", "xf", self.clean_volatile_img, "-C", self.dir_path]) retcode = subprocess.call (["tar", "xf", self.clean_volatile_img, "-C", self.dir_path])
if retcode != 0: if retcode != 0:
raise IOError ("Error while unpacking {0} to {1}".\ raise IOError ("Error while unpacking {0} to {1}".\
format(self.template_vm.clean_volatile_img, self.volatile_img)) format(self.template.clean_volatile_img, self.volatile_img))
def commit_changes (self, verbose = False): def commit_changes (self, verbose = False):
@ -1992,7 +1970,7 @@ class QubesDom0NetVm(QubesNetVm):
super(QubesDom0NetVm, self).__init__(qid=0, name="dom0", netid=0, super(QubesDom0NetVm, self).__init__(qid=0, name="dom0", netid=0,
dir_path=None, dir_path=None,
private_img = None, private_img = None,
template_vm = None, template = None,
label = default_template_label) label = default_template_label)
self.xid = 0 self.xid = 0
@ -2064,7 +2042,7 @@ class QubesDisposableVm(QubesVm):
super(QubesDisposableVm, self).__init__(dir_path="/nonexistent", **kwargs) super(QubesDisposableVm, self).__init__(dir_path="/nonexistent", **kwargs)
assert self.template_vm is not None, "Missing template_vm for DisposableVM!" assert self.template is not None, "Missing template for DisposableVM!"
# Use DispVM icon with the same color # Use DispVM icon with the same color
if self._label: if self._label:
@ -2089,7 +2067,7 @@ class QubesDisposableVm(QubesVm):
attrs["qid"] = str(self.qid) attrs["qid"] = str(self.qid)
attrs["name"] = self.name attrs["name"] = self.name
attrs["dispid"] = str(self.dispid) attrs["dispid"] = str(self.dispid)
attrs["template_qid"] = str(self.template_vm.qid) attrs["template_qid"] = str(self.template.qid)
attrs["label"] = self.label.name attrs["label"] = self.label.name
attrs["firewall_conf"] = self.relative_path(self.firewall_conf) attrs["firewall_conf"] = self.relative_path(self.firewall_conf)
return attrs return attrs
@ -2118,7 +2096,7 @@ class QubesAppVm(QubesVm):
super(QubesAppVm, self).create_on_disk(verbose, source_template=source_template) super(QubesAppVm, self).create_on_disk(verbose, source_template=source_template)
if self.is_updateable(): if self.updateable:
if verbose: if verbose:
print >> sys.stderr, "--> Copying the template's appmenus templates dir:\n{0} ==>\n{1}".\ print >> sys.stderr, "--> Copying the template's appmenus templates dir:\n{0} ==>\n{1}".\
format(source_template.appmenus_templates_dir, self.appmenus_templates_dir) format(source_template.appmenus_templates_dir, self.appmenus_templates_dir)
@ -2346,20 +2324,18 @@ class QubesVmCollection(dict):
assert False, "Attempt to add VM with qid that already exists in the collection!" assert False, "Attempt to add VM with qid that already exists in the collection!"
def add_new_appvm(self, name, template_vm, def add_new_appvm(self, name, template,
dir_path = None, conf_file = None, dir_path = None, conf_file = None,
private_img = None, private_img = None,
updateable = False,
label = None): label = None):
qid = self.get_new_unused_qid() qid = self.get_new_unused_qid()
vm = QubesAppVm (qid=qid, name=name, template_vm=template_vm, vm = QubesAppVm (qid=qid, name=name, template=template,
dir_path=dir_path, conf_file=conf_file, dir_path=dir_path, conf_file=conf_file,
private_img=private_img, private_img=private_img,
netvm = self.get_default_netvm(), netvm = self.get_default_netvm(),
kernel = self.get_default_kernel(), kernel = self.get_default_kernel(),
uses_default_kernel = True, uses_default_kernel = True,
updateable=updateable,
label=label) label=label)
if not self.verify_new_vm (vm): if not self.verify_new_vm (vm):
@ -2381,11 +2357,11 @@ class QubesVmCollection(dict):
self[vm.qid]=vm self[vm.qid]=vm
return vm return vm
def add_new_disposablevm(self, name, template_vm, dispid, def add_new_disposablevm(self, name, template, dispid,
label = None): label = None):
qid = self.get_new_unused_qid() qid = self.get_new_unused_qid()
vm = QubesDisposableVm (qid=qid, name=name, template_vm=template_vm, vm = QubesDisposableVm (qid=qid, name=name, template=template,
netvm = self.get_default_netvm(), netvm = self.get_default_netvm(),
label=label, dispid=dispid) label=label, dispid=dispid)
@ -2413,30 +2389,29 @@ class QubesVmCollection(dict):
self[vm.qid]=vm self[vm.qid]=vm
if self.default_template_qid is None: if self.default_template_qid is None:
self.set_default_template_vm(vm) self.set_default_template(vm)
return vm return vm
def clone_templatevm(self, src_template_vm, name, dir_path = None, verbose = False): def clone_templatevm(self, src_template, name, dir_path = None, verbose = False):
assert not src_template_vm.is_running(), "Attempt to clone a running Template VM!" assert not src_template.is_running(), "Attempt to clone a running Template VM!"
vm = self.add_new_templatevm (name=name, dir_path=dir_path, installed_by_rpm = False) vm = self.add_new_templatevm (name=name, dir_path=dir_path, installed_by_rpm = False)
return vm return vm
def add_new_netvm(self, name, template_vm, def add_new_netvm(self, name, template,
dir_path = None, conf_file = None, dir_path = None, conf_file = None,
private_img = None, installed_by_rpm = False, private_img = None, installed_by_rpm = False,
label = None, updateable = False): label = None):
qid = self.get_new_unused_qid() qid = self.get_new_unused_qid()
netid = self.get_new_unused_netid() netid = self.get_new_unused_netid()
vm = QubesNetVm (qid=qid, name=name, template_vm=template_vm, vm = QubesNetVm (qid=qid, name=name, template=template,
netid=netid, label=label, netid=netid, label=label,
private_img=private_img, installed_by_rpm=installed_by_rpm, private_img=private_img, installed_by_rpm=installed_by_rpm,
updateable=updateable,
kernel = self.get_default_kernel(), kernel = self.get_default_kernel(),
uses_default_kernel = True, uses_default_kernel = True,
dir_path=dir_path, conf_file=conf_file) dir_path=dir_path, conf_file=conf_file)
@ -2454,18 +2429,17 @@ class QubesVmCollection(dict):
return vm return vm
def add_new_proxyvm(self, name, template_vm, def add_new_proxyvm(self, name, template,
dir_path = None, conf_file = None, dir_path = None, conf_file = None,
private_img = None, installed_by_rpm = False, private_img = None, installed_by_rpm = False,
label = None, updateable = False): label = None):
qid = self.get_new_unused_qid() qid = self.get_new_unused_qid()
netid = self.get_new_unused_netid() netid = self.get_new_unused_netid()
vm = QubesProxyVm (qid=qid, name=name, template_vm=template_vm, vm = QubesProxyVm (qid=qid, name=name, template=template,
netid=netid, label=label, netid=netid, label=label,
private_img=private_img, installed_by_rpm=installed_by_rpm, private_img=private_img, installed_by_rpm=installed_by_rpm,
dir_path=dir_path, conf_file=conf_file, dir_path=dir_path, conf_file=conf_file,
updateable=updateable,
kernel = self.get_default_kernel(), kernel = self.get_default_kernel(),
uses_default_kernel = True, uses_default_kernel = True,
netvm = self.get_default_fw_netvm()) netvm = self.get_default_fw_netvm())
@ -2482,11 +2456,11 @@ class QubesVmCollection(dict):
return vm return vm
def set_default_template_vm(self, vm): def set_default_template(self, vm):
assert vm.is_template(), "VM {0} is not a TemplateVM!".format(vm.name) assert vm.is_template(), "VM {0} is not a TemplateVM!".format(vm.name)
self.default_template_qid = vm.qid self.default_template_qid = vm.qid
def get_default_template_vm(self): def get_default_template(self):
if self.default_template_qid is None: if self.default_template_qid is None:
return None return None
else: else:
@ -2549,7 +2523,7 @@ class QubesVmCollection(dict):
def get_vms_based_on(self, template_qid): def get_vms_based_on(self, template_qid):
vms = set([vm for vm in self.values() vms = set([vm for vm in self.values()
if (vm.template_vm and vm.template_vm.qid == template_qid)]) if (vm.template and vm.template.qid == template_qid)])
return vms return vms
def get_vms_connected_to(self, netvm_qid): def get_vms_connected_to(self, netvm_qid):
@ -2675,7 +2649,7 @@ class QubesVmCollection(dict):
kwargs = {} kwargs = {}
common_attr_list = ("qid", "name", "dir_path", "conf_file", common_attr_list = ("qid", "name", "dir_path", "conf_file",
"private_img", "root_img", "template_qid", "private_img", "root_img", "template_qid",
"installed_by_rpm", "updateable", "internal", "installed_by_rpm", "internal",
"uses_default_netvm", "label", "memory", "vcpus", "pcidevs", "uses_default_netvm", "label", "memory", "vcpus", "pcidevs",
"maxmem", "kernel", "uses_default_kernel", "kernelopts", "uses_default_kernelopts", "maxmem", "kernel", "uses_default_kernel", "kernelopts", "uses_default_kernelopts",
"mac", "services", "include_in_backups" ) "mac", "services", "include_in_backups" )
@ -2686,8 +2660,6 @@ class QubesVmCollection(dict):
kwargs.pop(attribute) kwargs.pop(attribute)
kwargs["qid"] = int(kwargs["qid"]) kwargs["qid"] = int(kwargs["qid"])
if "updateable" in kwargs:
kwargs["updateable"] = True if kwargs["updateable"] == "True" else False
if "include_in_backups" in kwargs: if "include_in_backups" in kwargs:
kwargs["include_in_backups"] = True if kwargs["include_in_backups"] == "True" else False kwargs["include_in_backups"] = True if kwargs["include_in_backups"] == "True" else False
@ -2703,12 +2675,12 @@ class QubesVmCollection(dict):
kwargs.pop("template_qid") kwargs.pop("template_qid")
else: else:
kwargs["template_qid"] = int(kwargs["template_qid"]) kwargs["template_qid"] = int(kwargs["template_qid"])
template_vm = self[kwargs.pop("template_qid")] template = self[kwargs.pop("template_qid")]
if template_vm is None: if template is None:
print >> sys.stderr, "ERROR: VM '{0}' uses unkown template qid='{1}'!".\ print >> sys.stderr, "ERROR: VM '{0}' uses unkown template qid='{1}'!".\
format(kwargs["name"], kwargs["template_qid"]) format(kwargs["name"], kwargs["template_qid"])
else: else:
kwargs["template_vm"] = template_vm kwargs["template"] = template
if "label" in kwargs: if "label" in kwargs:
if kwargs["label"] not in QubesVmLabels: if kwargs["label"] not in QubesVmLabels:
@ -2940,12 +2912,12 @@ class QubesVmCollection(dict):
kwargs["dispid"] = int(kwargs["dispid"]) kwargs["dispid"] = int(kwargs["dispid"])
kwargs["template_qid"] = int(kwargs["template_qid"]) kwargs["template_qid"] = int(kwargs["template_qid"])
template_vm = self[kwargs.pop("template_qid")] template = self[kwargs.pop("template_qid")]
if template_vm is None: if template is None:
print >> sys.stderr, "ERROR: DisposableVM '{0}' uses unkown template qid='{1}'!".\ print >> sys.stderr, "ERROR: DisposableVM '{0}' uses unkown template qid='{1}'!".\
format(kwargs["name"], kwargs["template_qid"]) format(kwargs["name"], kwargs["template_qid"])
else: else:
kwargs["template_vm"] = template_vm kwargs["template"] = template
kwargs["netvm"] = self.get_default_netvm() kwargs["netvm"] = self.get_default_netvm()

View File

@ -390,7 +390,7 @@ def backup_prepare(base_backup_dir, vms_list = None, exclude_list = [], print_ca
if vm.is_appvm(): if vm.is_appvm():
files_to_backup += file_to_backup(vm.icon_path) 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"): if os.path.exists(vm.dir_path + "/apps.templates"):
# template # template
files_to_backup += file_to_backup(vm.dir_path + "/apps.templates") 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'): if os.path.exists(vm.dir_path + '/whitelisted-appmenus.list'):
files_to_backup += file_to_backup(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) sz = vm.get_disk_usage(vm.root_img)
files_to_backup += file_to_backup(vm.root_img, sz) files_to_backup += file_to_backup(vm.root_img, sz)
vm_sz += 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) fmt="{{0:>{0}}} |".format(fields_to_display[1]["width"] + 1)
if vm.is_netvm(): if vm.is_netvm():
s += fmt.format("NetVM" + (" + Sys" if vm.is_updateable() else "")) s += fmt.format("NetVM" + (" + Sys" if vm.updateable else ""))
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) fmt="{{0:>{0}}} |".format(fields_to_display[2]["width"] + 1)
s += fmt.format(size_to_human(vm_sz)) s += fmt.format(size_to_human(vm_sz))
@ -624,10 +624,10 @@ def backup_restore_prepare(backup_dir, options = {}, host_collection = None):
vms_to_restore[vm.name]['already-exists'] = True vms_to_restore[vm.name]['already-exists'] = True
vms_to_restore[vm.name]['good-to-go'] = False vms_to_restore[vm.name]['good-to-go'] = False
if vm.template_vm is None: if vm.template is None:
vms_to_restore[vm.name]['template'] = None vms_to_restore[vm.name]['template'] = None
else: else:
templatevm_name = find_template_name(vm.template_vm.name, options['replace-template']) templatevm_name = find_template_name(vm.template.name, options['replace-template'])
vms_to_restore[vm.name]['template'] = templatevm_name vms_to_restore[vm.name]['template'] = templatevm_name
template_vm_on_host = host_collection.get_vm_by_name (templatevm_name) template_vm_on_host = host_collection.get_vm_by_name (templatevm_name)
@ -638,7 +638,7 @@ def backup_restore_prepare(backup_dir, options = {}, host_collection = None):
if template_vm_on_backup is None or not template_vm_on_backup.is_template(): if template_vm_on_backup is None or not template_vm_on_backup.is_template():
if options['use-default-template']: if options['use-default-template']:
vms_to_restore[vm.name]['orig-template'] = templatevm_name vms_to_restore[vm.name]['orig-template'] = templatevm_name
vms_to_restore[vm.name]['template'] = host_collection.get_default_template_vm().name vms_to_restore[vm.name]['template'] = host_collection.get_default_template().name
else: else:
vms_to_restore[vm.name]['missing-template'] = True vms_to_restore[vm.name]['missing-template'] = True
vms_to_restore[vm.name]['good-to-go'] = False vms_to_restore[vm.name]['good-to-go'] = False
@ -702,9 +702,9 @@ def backup_restore_print_summary(restore_info, print_callback = print_stdout):
('Proxy' if vm.is_proxyvm() else \ ('Proxy' if vm.is_proxyvm() else \
(' Net' if vm.is_netvm() else 'App'))"}, (' 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_vm is None else\ "template": {"func": "'n/a' if vm.is_template() or vm.template is None else\
vm_info['template']"}, vm_info['template']"},
"netvm": {"func": "'n/a' if vm.is_netvm() else\ "netvm": {"func": "'n/a' if vm.is_netvm() else\
@ -834,8 +834,6 @@ def backup_restore_do(backup_dir, restore_info, host_collection = None, print_ca
error_callback("Skiping...") error_callback("Skiping...")
continue continue
updateable = vm.updateable
new_vm = None new_vm = None
try: try:
@ -845,7 +843,6 @@ def backup_restore_do(backup_dir, restore_info, host_collection = None, print_ca
dir_path=vm.dir_path, dir_path=vm.dir_path,
installed_by_rpm=False) installed_by_rpm=False)
new_vm.updateable = updateable
new_vm.verify_files() new_vm.verify_files()
except Exception as err: except Exception as err:
error_callback("ERROR: {0}".format(err)) error_callback("ERROR: {0}".format(err))
@ -877,10 +874,10 @@ def backup_restore_do(backup_dir, restore_info, host_collection = None, print_ca
error_callback("Skiping...") error_callback("Skiping...")
continue continue
template_vm = None template = None
if vm.template_vm is not None: if vm.template is not None:
template_name = vm_info['template'] template_name = vm_info['template']
template_vm = host_collection.get_vm_by_name(template_name) template = host_collection.get_vm_by_name(template_name)
if not vm.uses_default_netvm: if not vm.uses_default_netvm:
uses_default_netvm = False uses_default_netvm = False
@ -888,23 +885,19 @@ def backup_restore_do(backup_dir, restore_info, host_collection = None, print_ca
else: else:
uses_default_netvm = True uses_default_netvm = True
updateable = vm.updateable
new_vm = None new_vm = None
try: try:
restore_vm_dir (backup_dir, vm.dir_path, qubes_servicevms_dir); restore_vm_dir (backup_dir, vm.dir_path, qubes_servicevms_dir);
if vm.type == "NetVM": if vm.type == "NetVM":
new_vm = host_collection.add_new_netvm(vm.name, template_vm, new_vm = host_collection.add_new_netvm(vm.name, template,
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)
elif vm.type == "ProxyVM": elif vm.type == "ProxyVM":
new_vm = host_collection.add_new_proxyvm(vm.name, template_vm, new_vm = host_collection.add_new_proxyvm(vm.name, template,
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)
except Exception as err: except Exception as err:
error_callback("ERROR: {0}".format(err)) error_callback("ERROR: {0}".format(err))
@ -942,10 +935,10 @@ def backup_restore_do(backup_dir, restore_info, host_collection = None, print_ca
error_callback("Skiping...") error_callback("Skiping...")
continue continue
template_vm = None template = None
if vm.template_vm is not None: if vm.template is not None:
template_name = vm_info['template'] template_name = vm_info['template']
template_vm = host_collection.get_vm_by_name(template_name) template = host_collection.get_vm_by_name(template_name)
if not vm.uses_default_netvm: if not vm.uses_default_netvm:
uses_default_netvm = False uses_default_netvm = False
@ -953,15 +946,12 @@ def backup_restore_do(backup_dir, restore_info, host_collection = None, print_ca
else: else:
uses_default_netvm = True uses_default_netvm = True
updateable = vm.updateable
new_vm = None new_vm = None
try: try:
restore_vm_dir (backup_dir, vm.dir_path, qubes_appvms_dir); restore_vm_dir (backup_dir, vm.dir_path, qubes_appvms_dir);
new_vm = host_collection.add_new_appvm(vm.name, template_vm, new_vm = host_collection.add_new_appvm(vm.name, template,
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)
except Exception as err: except Exception as err:
error_callback("ERROR: {0}".format(err)) error_callback("ERROR: {0}".format(err))

View File

@ -32,7 +32,7 @@ def handle_vm(vms, label, new_value = None):
functions = { # label: [ getter, setter ], functions = { # label: [ getter, setter ],
'default-netvm': [ 'get_default_netvm', 'set_default_netvm' ], 'default-netvm': [ 'get_default_netvm', 'set_default_netvm' ],
'default-fw-netvm': [ 'get_default_fw_netvm', 'set_default_fw_netvm' ], 'default-fw-netvm': [ 'get_default_fw_netvm', 'set_default_fw_netvm' ],
'default-template': [ 'get_default_template_vm', 'set_default_template_vm' ], 'default-template': [ 'get_default_template', 'set_default_template' ],
'clockvm': [ 'get_clockvm_vm', 'set_clockvm_vm' ], 'clockvm': [ 'get_clockvm_vm', 'set_clockvm_vm' ],
'updatevm': [ 'get_updatevm_vm', 'set_updatevm_vm' ], 'updatevm': [ 'get_updatevm_vm', 'set_updatevm_vm' ],
} }

View File

@ -52,13 +52,13 @@ def main():
print >> sys.stderr, "ERROR: A VM with the name '{0}' already exists in the system.".format(vmname) print >> sys.stderr, "ERROR: A VM with the name '{0}' already exists in the system.".format(vmname)
exit(1) exit(1)
template_vm = qvm_collection.get_vm_by_name(templatename) template = qvm_collection.get_vm_by_name(templatename)
if template_vm is None: if template is None:
print >> sys.stderr, "ERROR: A Template VM with the name '{0}' does not exist in the system.".format(templatename) print >> sys.stderr, "ERROR: A Template VM with the name '{0}' does not exist in the system.".format(templatename)
exit(1) exit(1)
vm = qvm_collection.add_new_appvm(vmname, template_vm, vm = qvm_collection.add_new_appvm(vmname, template,
conf_file=options.conf_file, conf_file=options.conf_file,
dir_path=options.dir_path) dir_path=options.dir_path)

View File

@ -59,8 +59,8 @@ def main():
dst_vm = qvm_collection.add_new_templatevm(name=dstname, dst_vm = qvm_collection.add_new_templatevm(name=dstname,
dir_path=options.dir_path, installed_by_rpm=False) dir_path=options.dir_path, installed_by_rpm=False)
elif isinstance(src_vm, QubesAppVm): elif isinstance(src_vm, QubesAppVm):
dst_vm = qvm_collection.add_new_appvm(name=dstname, template_vm=src_vm.template_vm, 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) dir_path=options.dir_path)
elif isinstance(src_vm, QubesHVm): elif isinstance(src_vm, QubesHVm):
dst_vm = qvm_collection.add_new_hvm(name=dstname, label=src_vm.label) dst_vm = qvm_collection.add_new_hvm(name=dstname, label=src_vm.label)

View File

@ -108,39 +108,39 @@ def main():
template_vm = None template_vm = None
if options.template is not None: if options.template is not None:
template_vm = qvm_collection.get_vm_by_name(options.template) template = qvm_collection.get_vm_by_name(options.template)
if template_vm is None: if template is None:
print >> sys.stderr, "There is no (Templete)VM with the name '{0}'".format(options.template) print >> sys.stderr, "There is no (Templete)VM with the name '{0}'".format(options.template)
exit (1) exit (1)
if not template_vm.is_template(): if not template.is_template():
print >> sys.stderr, "VM '{0}' is not a TemplateVM".format(options.template) print >> sys.stderr, "VM '{0}' is not a TemplateVM".format(options.template)
exit (1) exit (1)
if (options.verbose): if (options.verbose):
print "--> Using TemplateVM: {0}".format(template_vm.name) print "--> Using TemplateVM: {0}".format(template.name)
elif not options.hvm: elif not options.hvm:
if qvm_collection.get_default_template_vm() is None: if qvm_collection.get_default_template() is None:
print >> sys.stderr, "No default TempleteVM defined!" print >> sys.stderr, "No default TempleteVM defined!"
exit (1) exit (1)
else: else:
template_vm = qvm_collection.get_default_template_vm() template = qvm_collection.get_default_template()
if (options.verbose): if (options.verbose):
print "--> Using default TemplateVM: {0}".format(template_vm.name) print "--> Using default TemplateVM: {0}".format(template.name)
if options.standalone: if options.standalone:
new_vm_template = None new_vm_template = None
else: else:
new_vm_template = template_vm new_vm_template = template
vm = None vm = None
if options.netvm: 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: 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)
elif options.hvm: elif options.hvm:
vm = qvm_collection.add_new_hvm(vmname, label = label) vm = qvm_collection.add_new_hvm(vmname, label = label)
else: 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: if options.internal:
vm.internal = True vm.internal = True
@ -152,7 +152,7 @@ def main():
vm.vcpus = options.vcpus vm.vcpus = options.vcpus
try: try:
vm.create_on_disk(verbose=options.verbose, source_template=template_vm) vm.create_on_disk(verbose=options.verbose, source_template=template)
if options.root: if options.root:
os.unlink(vm.root_img) os.unlink(vm.root_img)
os.rename(options.root, vm.root_img) os.rename(options.root, vm.root_img)

View File

@ -30,8 +30,8 @@ import sys
fields = { fields = {
"qid": {"func": "vm.qid"}, "qid": {"func": "vm.qid"},
"name": {"func": "('=>' if qvm_collection.get_default_template_vm() is not None\ "name": {"func": "('=>' if qvm_collection.get_default_template() is not None\
and vm.qid == qvm_collection.get_default_template_vm().qid else '')\ and vm.qid == qvm_collection.get_default_template().qid else '')\
+ ('[' if vm.is_template() else '')\ + ('[' if vm.is_template() else '')\
+ ('<' if vm.is_disposablevm() else '')\ + ('<' if vm.is_disposablevm() else '')\
+ ('{' if vm.is_netvm() else '')\ + ('{' if vm.is_netvm() else '')\
@ -44,11 +44,11 @@ fields = {
('Proxy' if vm.is_proxyvm() else \ ('Proxy' if vm.is_proxyvm() else \
(' Net' if vm.is_netvm() 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\ "template": {"func": "'n/a' if vm.is_template() else\
('None' if vm.template_vm is None else\ ('None' if vm.template is None else\
qvm_collection[vm.template_vm.qid].name)"}, qvm_collection[vm.template.qid].name)"},
"netvm": {"func": "'n/a' if vm.is_netvm() and not vm.is_proxyvm() else\ "netvm": {"func": "'n/a' if vm.is_netvm() and not vm.is_proxyvm() else\
('*' if vm.uses_default_netvm else '') +\ ('*' if vm.uses_default_netvm else '') +\
@ -149,7 +149,7 @@ def main():
# Now, the AppVMs without template... # Now, the AppVMs without template...
for appvm in vms_list: for appvm in vms_list:
if appvm.is_appvm() and appvm.template_vm is None: if appvm.is_appvm() and appvm.template is None:
vms_to_display.append (appvm) vms_to_display.append (appvm)
# Now, the template, and all its AppVMs... # Now, the template, and all its AppVMs...
@ -158,7 +158,7 @@ def main():
vms_to_display.append (tvm) vms_to_display.append (tvm)
for vm in vms_list: for vm in vms_list:
if (vm.is_appvm() or vm.is_disposablevm()) and \ if (vm.is_appvm() or vm.is_disposablevm()) and \
vm.template_vm and vm.template_vm.qid == tvm.qid: vm.template and vm.template.qid == tvm.qid:
vms_to_display.append(vm) vms_to_display.append(vm)
assert len(vms_to_display) == no_vms assert len(vms_to_display) == no_vms

View File

@ -37,22 +37,22 @@ def do_list(vm):
print fmt.format ("name", vm.name) print fmt.format ("name", vm.name)
print fmt.format ("label", vm.label.name) print fmt.format ("label", vm.label.name)
print fmt.format ("type", vm.type) print fmt.format ("type", vm.type)
if vm.template_vm is not None: if vm.template is not None:
print fmt.format ("template", vm.template_vm.name) print fmt.format ("template", vm.template.name)
if vm.netvm is not None: if vm.netvm is not None:
print fmt.format ("netvm", vm.netvm.name) 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 ("installed by RPM?", vm.installed_by_rpm)
print fmt.format ("include in backups", vm.include_in_backups) print fmt.format ("include in backups", vm.include_in_backups)
print fmt.format ("dir", vm.dir_path) print fmt.format ("dir", vm.dir_path)
print fmt.format ("config", vm.conf_file) print fmt.format ("config", vm.conf_file)
print fmt.format ("pcidevs", vm.pcidevs) print fmt.format ("pcidevs", vm.pcidevs)
if vm.template_vm is None: if vm.template is None:
print fmt.format ("root img", vm.root_img) print fmt.format ("root img", vm.root_img)
if vm.is_template(): if vm.is_template():
print fmt.format ("root COW img", vm.rootcow_img) print fmt.format ("root COW img", vm.rootcow_img)
if vm.template_vm is not None: if vm.template is not None:
print fmt.format ("root img", vm.template_vm.root_img) print fmt.format ("root img", vm.template.root_img)
if hasattr(vm, 'volatile_img') and vm.volatile_img is not None: if hasattr(vm, 'volatile_img') and vm.volatile_img is not None:
print fmt.format ("root volatile img", vm.volatile_img) print fmt.format ("root volatile img", vm.volatile_img)
@ -65,7 +65,7 @@ def do_list(vm):
print fmt.format ("MAC", "%s%s" % (vm.mac, " (auto)" if vm._mac is None else "")) print fmt.format ("MAC", "%s%s" % (vm.mac, " (auto)" if vm._mac is None else ""))
if hasattr(vm, 'kernel'): if hasattr(vm, 'kernel'):
if vm.template_vm is not None: if vm.template is not None:
print fmt.format ("kernel", "%s (from template)" % vm.kernel) print fmt.format ("kernel", "%s (from template)" % vm.kernel)
elif vm.uses_default_kernel: elif vm.uses_default_kernel:
print fmt.format ("kernel", "%s (default)" % vm.kernel) print fmt.format ("kernel", "%s (default)" % vm.kernel)
@ -161,61 +161,8 @@ def set_netvm(vms, vm, args):
vm.netvm = netvm 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_vm.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_vm.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): def set_kernel(vms, vm, args):
if vm.template_vm is not None: if vm.template is not None:
print >> sys.stderr, "Cannot set kernel for template-based VM. Set it for template instead." print >> sys.stderr, "Cannot set kernel for template-based VM. Set it for template instead."
return False return False
@ -250,17 +197,17 @@ def set_template(vms, vm, args):
return False return False
template_name = args[0]; template_name = args[0];
template_vm = vms.get_vm_by_name(template_name) template = vms.get_vm_by_name(template_name)
if template_vm is None or template_vm.qid not in vms: if template is None or template.qid not in vms:
print >> sys.stderr, "A VM with the name '{0}' does not exist in the system.".format(template_name) print >> sys.stderr, "A VM with the name '{0}' does not exist in the system.".format(template_name)
return False return False
if not template_vm.is_template(): if not template.is_template():
print >> sys.stderr, "VM '{0}' is not a TemplateVM".format(template_name) print >> sys.stderr, "VM '{0}' is not a TemplateVM".format(template_name)
return False return False
print >> sys.stderr, "Setting template for VM '{0}' to '{1}'...".format (vm.name, template_name) print >> sys.stderr, "Setting template for VM '{0}' to '{1}'...".format (vm.name, template_name)
vm.template_vm = template_vm vm.template = template
return True return True
def set_vcpus(vms, vm, args): def set_vcpus(vms, vm, args):
@ -334,8 +281,6 @@ def set_include_in_backups(vms, vm, args):
properties = { properties = {
"include_in_backups": set_include_in_backups, "include_in_backups": set_include_in_backups,
"updateable": set_updateable,
"nonupdateable": set_nonupdateable,
"pcidevs": set_pcidevs, "pcidevs": set_pcidevs,
"label" : set_label, "label" : set_label,
"netvm" : set_netvm, "netvm" : set_netvm,

View File

@ -164,8 +164,8 @@ def main():
print >>sys.stderr, "ERROR: A VM with the name '{0}' does not exist in the system.".format(vmname) print >>sys.stderr, "ERROR: A VM with the name '{0}' does not exist in the system.".format(vmname)
exit(1) exit(1)
if not vm.is_updateable(): if vm.template is not None:
print >>sys.stderr, "ERROR: To sync appmenus for non-updateable VM, do it on template instead" print >>sys.stderr, "ERROR: To sync appmenus for template based VM, do it on template instead"
exit(1) exit(1)
if not vm.is_running(): if not vm.is_running():

View File

@ -80,7 +80,7 @@ class QfileDaemonDvm:
qvm_collection.unlock_db() qvm_collection.unlock_db()
return None return None
dispid=int(disp_name[4:]) dispid=int(disp_name[4:])
dispvm=qvm_collection.add_new_disposablevm(disp_name, vm_disptempl.template_vm, label=vm.label, dispid=dispid) dispvm=qvm_collection.add_new_disposablevm(disp_name, vm_disptempl.template, label=vm.label, dispid=dispid)
# By default inherit firewall rules from calling VM # By default inherit firewall rules from calling VM
if os.path.exists(vm.firewall_conf): if os.path.exists(vm.firewall_conf):
disp_firewall_conf = '/var/run/qubes/%s-firewall.xml' % disp_name disp_firewall_conf = '/var/run/qubes/%s-firewall.xml' % disp_name