
From: ShaoHe Feng <shaohef@linux.vnet.ibm.com> Support lookup and update method for ticket. when set a ticket, it will take effect on both persistent and live configure. raise an exception if ticket expires when lookup it. Signed-off-by: ShaoHe Feng <shaohef@linux.vnet.ibm.com> --- src/kimchi/i18n.py | 1 + src/kimchi/model/vms.py | 65 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/src/kimchi/i18n.py b/src/kimchi/i18n.py index 0c76145..a35bfde 100644 --- a/src/kimchi/i18n.py +++ b/src/kimchi/i18n.py @@ -89,6 +89,7 @@ "KCHVM0028E": _("Group(s) '%(groups)s' do not exist"), "KCHVM0029E": _("Unable to shutdown virtual machine %(name)s. Details: %(err)s"), "KCHVM0030E": _("Unable to get access metadata of virtual machine %(name)s. Details: %(err)s"), + "KCHVM0031E": _("The password of virtual machine %(name)s is invalid, please reset it."), "KCHVMIF0001E": _("Interface %(iface)s does not exist in virtual machine %(name)s"), "KCHVMIF0002E": _("Network %(network)s specified for virtual machine %(name)s does not exist"), diff --git a/src/kimchi/model/vms.py b/src/kimchi/model/vms.py index 17bda04..2b919ad 100644 --- a/src/kimchi/model/vms.py +++ b/src/kimchi/model/vms.py @@ -19,7 +19,10 @@ from lxml.builder import E import lxml.etree as ET +from lxml import etree, objectify import os +import random +import string import time import uuid from xml.etree import ElementTree @@ -527,6 +530,68 @@ def _vmscreenshot_delete(self, vm_uuid): 'database due error: %s', e.message) +class VMTicketModel(object): + def __init__(self, **kargs): + self.objstore = kargs['objstore'] + self.conn = kargs['conn'] + + def lookup(self, name): + dom = VMModel.get_vm(name, self.conn) + xml = dom.XMLDesc(libvirt.VIR_DOMAIN_XML_SECURE) + root = objectify.fromstring(xml) + graphic = root.devices.find("graphics") + passwd = graphic.attrib.get('passwd') + valid_to = graphic.attrib.get('passwdValidTo') + if valid_to is not None: + to = time.mktime(time.strptime(valid_to, '%Y-%m-%dT%H:%M:%S')) + if to - time.time() <= 0: + raise OperationFailed("KCHVM0031E", {'name': name}) + return {"passwd": passwd} + + def _libvirt_set_ticket(self, dom, password, expire, flag=0): + DEFAULT_VALID_TO = 30 + xml = dom.XMLDesc(flag) + root = objectify.fromstring(xml) + graphic = root.devices.find("graphics") + graphic.attrib['passwd'] = password + to = graphic.attrib.get('passwdValidTo') + valid_to = None + # will not set the passwdValidTo of persistent configure + if expire is not None: + valid_to = time.strftime( + '%Y-%m-%dT%H:%M:%S', + time.gmtime(time.time() + float(expire))) + if to is not None: + if (time.mktime(time.strptime(to, '%Y-%m-%dT%H:%M:%S')) + - time.time() <= 0): + valid_to = time.strftime( + '%Y-%m-%dT%H:%M:%S', + time.gmtime(time.time() + float(DEFAULT_VALID_TO))) + if valid_to is not None: + graphic.attrib['passwdValidTo'] = valid_to + + return root if flag == 0 else graphic + + def update(self, name, params): + dom = VMModel.get_vm(name, self.conn) + + password = params.get("passwd") + password = password if password is not None else "".join( + random.sample(string.ascii_letters + string.digits, 8)) + expire = params.get("expire") + + # for libvirt updateDeviceFlags do not support update persistent ticket + if dom.isPersistent(): + node = self._libvirt_set_ticket(dom, password, None) + conn = self.conn.get() + conn.defineXML(ET.tostring(node, encoding="utf-8")) + if dom.isActive(): + flag = libvirt.VIR_DOMAIN_XML_SECURE + node = self._libvirt_set_ticket(dom, password, expire, flag) + dom.updateDeviceFlags(etree.tostring(node), + libvirt.VIR_DOMAIN_AFFECT_LIVE) + + class VMScreenshotModel(object): def __init__(self, **kargs): self.objstore = kargs['objstore'] -- 1.9.3