From: ShaoHe Feng <shaohef(a)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(a)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