[Kimchi-devel] [PATCH] [Kimchi 8/9] Virt-Viewer launcher: libvirt events to control firewall

dhbarboza82 at gmail.com dhbarboza82 at gmail.com
Thu Jul 7 12:57:47 UTC 2016


From: Daniel Henrique Barboza <danielhb at linux.vnet.ibm.com>

In this patch, the FirewallManager class is used together
with libvirt events to:

- open the firewall port to the graphics server when a call
to lookup() is made;

- close the firewall port when the virtual machine is turned
off.

A cleanup() method was also added to the cherrypy 'exit'
engine to ensure that no firewall port previously opened by
the virtviewerfile module will be left opened when Kimchi/WoK
exits.

Signed-off-by: Daniel Henrique Barboza <danielhb at linux.vnet.ibm.com>
---
 model/virtviewerfile.py | 40 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/model/virtviewerfile.py b/model/virtviewerfile.py
index 398b8a3..e3f60e6 100644
--- a/model/virtviewerfile.py
+++ b/model/virtviewerfile.py
@@ -85,6 +85,16 @@ def create_virt_viewer_file(vm_name, graphics_info):
 class VMVirtViewerFileModel(object):
     def __init__(self, **kargs):
         self.conn = kargs['conn']
+        self.firewall_mngr = FirewallManager()
+        self.vm_event_callbacks = {}
+        cherrypy.engine.subscribe('exit', self.cleanup)
+
+    def cleanup(self):
+        wok_log.info('Closing any VNC/SPICE firewall ports '
+                     'opened by Kimchi ...')
+        self.firewall_mngr.remove_all_vms_ports()
+        for cb_id in self.vm_event_callbacks.values():
+            self.conn.get().domainEventDeregisterAny(cb_id)
 
     def _check_if_vm_running(self, name):
         dom = VMModel.get_vm(name, self.conn)
@@ -92,11 +102,41 @@ class VMVirtViewerFileModel(object):
         if d_info[0] != libvirt.VIR_DOMAIN_RUNNING:
             raise NotFoundError("KCHVM0083E", {'name': name})
 
+    def event_vmshutdown_cb(self, conn, dom, event, detail, *args):
+        if event == libvirt.VIR_DOMAIN_EVENT_STOPPED:
+            vm_name = dom.name()
+            self.firewall_mngr.remove_vm_graphics_port(vm_name)
+            cb_id = self.vm_event_callbacks.pop(vm_name, None)
+            self.conn.get().domainEventDeregisterAny(cb_id)
+
+    def handleVMShutdownPowerOff(self, vm_name):
+        try:
+            dom = VMModel.get_vm(vm_name, self.conn)
+            cb_id = self.conn.get().domainEventRegisterAny(
+                dom,
+                libvirt.VIR_DOMAIN_EVENT_ID_LIFECYCLE,
+                self.event_vmshutdown_cb,
+                None
+            )
+            self.vm_event_callbacks[vm_name] = cb_id
+
+        except (libvirt.libvirtError, AttributeError) as e:
+            if type(e) == AttributeError:
+                reason = 'Libvirt service is not running'
+            else:
+                reason = e.message
+            wok_log.error("Register of LIFECYCLE event failed: %s" % reason)
+
     def lookup(self, name):
         self._check_if_vm_running(name)
         graphics_info = VMModel.get_graphics(name, self.conn)
         file_path = create_virt_viewer_file(name, graphics_info)
 
+        if not self.vm_event_callbacks.get(name, None):
+            graphics_port = graphics_info[2]
+            self.firewall_mngr.add_vm_graphics_port(name, graphics_port)
+            self.handleVMShutdownPowerOff(name)
+
         return 'plugins/kimchi/data/virtviewerfiles/%s' %\
                os.path.basename(file_path)
 
-- 
2.5.5




More information about the Kimchi-devel mailing list