
On 07/15/2014 12:45 PM, shaohef@linux.vnet.ibm.com wrote:
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)))
Maybe splitting this code into variables make it easier to read expire_time = time.gmtime(time.time() + float(expire)) valid_to = time.strftime('%Y-%m-%dT%H:%M:%S', expire_time)
+ 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)))
Same I commented above
+ 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']