[PATCH] [Kimchi 0/3] Issue #201: Handling libvirt connection failures.

From: Paulo Vital <pvital@linux.vnet.ibm.com> This is the backend part of the solution to solve issue #201. Frontend still needs some updates to provide more information to user. Paulo Vital (3): Update Kimchi config file for Systemd service Make Cheerypy up if not able to connect to libvirt Add support to check if libvirtd is running. contrib/kimchid.service.fedora | 3 ++- contrib/kimchid.service.ubuntu | 3 ++- i18n.py | 3 +++ model/config.py | 29 +++++++++++++++++++++-------- model/libvirtconnection.py | 13 +++++++++++-- model/templates.py | 5 ++++- utils.py | 16 +++++++++++++++- 7 files changed, 58 insertions(+), 14 deletions(-) -- 2.5.5

From: Paulo Vital <pvital@linux.vnet.ibm.com> Modify kimchid.service for Fedora and Ubuntu to update how Kimchi dependencies must be loaded by Systemd. Now, when libvirtd.service stops wokd.service will not shutdown in sequence, still running. However, when wokd.service starts it still needs libvirtd.service be started before. This patch is part of the solution for Issue #201 Signed-off-by: Paulo Vital <pvital@linux.vnet.ibm.com> --- contrib/kimchid.service.fedora | 3 ++- contrib/kimchid.service.ubuntu | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/contrib/kimchid.service.fedora b/contrib/kimchid.service.fedora index d7b10d2..87a5866 100644 --- a/contrib/kimchid.service.fedora +++ b/contrib/kimchid.service.fedora @@ -1,5 +1,6 @@ [Unit] -Requires=libvirtd.service wokd.service +Requires=wokd.service +Wants=libvirtd.service After=libvirtd.service wokd.service [Service] diff --git a/contrib/kimchid.service.ubuntu b/contrib/kimchid.service.ubuntu index f865987..e52db66 100644 --- a/contrib/kimchid.service.ubuntu +++ b/contrib/kimchid.service.ubuntu @@ -1,5 +1,6 @@ [Unit] -Requires=libvirt-bin.service wokd.service +Requires=wokd.service +Wants=libvirt-bin.service After=libvirt-bin.service wokd.service [Service] -- 2.5.5

From: Paulo Vital <pvital@linux.vnet.ibm.com> Modified libvirtconnection.py to not stop Cherrypy server when not able to connect to libvirt. Now, a notification message is displayed in UI to warn user about libvirtd missing connection, making the web server available to provide the other plugins from wok. This patch is part of the solution for Issue #201 Signed-off-by: Paulo Vital <pvital@linux.vnet.ibm.com> --- i18n.py | 2 ++ model/libvirtconnection.py | 6 ++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/i18n.py b/i18n.py index db245c0..157f820 100644 --- a/i18n.py +++ b/i18n.py @@ -331,4 +331,6 @@ messages = { "KCHLVMS0001E": _("Invalid volume group name parameter: %(name)s."), + "KCHCONN0001E": _("Unable to establish connection with libvirt. Please check your libvirt URI which is often defined in /etc/libvirt/libvirt.conf"), + } diff --git a/model/libvirtconnection.py b/model/libvirtconnection.py index e899a33..113378e 100644 --- a/model/libvirtconnection.py +++ b/model/libvirtconnection.py @@ -22,6 +22,7 @@ import libvirt import threading import time +from wok.objectstore import add_notification from wok.utils import wok_log @@ -101,8 +102,9 @@ class LibvirtConnection(object): "your libvirt URI which is often " "defined in " "/etc/libvirt/libvirt.conf") - cherrypy.engine.stop() - exit(1) + add_notification("KCHCONN0001E", + plugin_name="/plugins/kimchi") + return None time.sleep(2) for name in dir(libvirt.virConnect): -- 2.5.5

On 09-05-2016 09:56, pvital@linux.vnet.ibm.com wrote:
From: Paulo Vital <pvital@linux.vnet.ibm.com>
Modified libvirtconnection.py to not stop Cherrypy server when not able to connect to libvirt. Now, a notification message is displayed in UI to warn user about libvirtd missing connection, making the web server available to provide the other plugins from wok.
This patch is part of the solution for Issue #201
Signed-off-by: Paulo Vital <pvital@linux.vnet.ibm.com> --- i18n.py | 2 ++ model/libvirtconnection.py | 6 ++++-- 2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/i18n.py b/i18n.py index db245c0..157f820 100644 --- a/i18n.py +++ b/i18n.py @@ -331,4 +331,6 @@ messages = {
"KCHLVMS0001E": _("Invalid volume group name parameter: %(name)s."),
+ "KCHCONN0001E": _("Unable to establish connection with libvirt. Please check your libvirt URI which is often defined in /etc/libvirt/libvirt.conf"), + } diff --git a/model/libvirtconnection.py b/model/libvirtconnection.py index e899a33..113378e 100644 --- a/model/libvirtconnection.py +++ b/model/libvirtconnection.py @@ -22,6 +22,7 @@ import libvirt import threading import time
+from wok.objectstore import add_notification
Paulo, I have a patch moving add_notification from objectstore to model.notifications.
from wok.utils import wok_log
@@ -101,8 +102,9 @@ class LibvirtConnection(object): "your libvirt URI which is often " "defined in " "/etc/libvirt/libvirt.conf") - cherrypy.engine.stop() - exit(1) + add_notification("KCHCONN0001E", + plugin_name="/plugins/kimchi") + return None time.sleep(2)
for name in dir(libvirt.virConnect):
-- Lucio Correia Software Engineer IBM LTC Brazil

On May 09 10:38AM, Lucio Correia wrote:
On 09-05-2016 09:56, pvital@linux.vnet.ibm.com wrote:
From: Paulo Vital <pvital@linux.vnet.ibm.com>
Modified libvirtconnection.py to not stop Cherrypy server when not able to connect to libvirt. Now, a notification message is displayed in UI to warn user about libvirtd missing connection, making the web server available to provide the other plugins from wok.
This patch is part of the solution for Issue #201
Signed-off-by: Paulo Vital <pvital@linux.vnet.ibm.com> --- i18n.py | 2 ++ model/libvirtconnection.py | 6 ++++-- 2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/i18n.py b/i18n.py index db245c0..157f820 100644 --- a/i18n.py +++ b/i18n.py @@ -331,4 +331,6 @@ messages = {
"KCHLVMS0001E": _("Invalid volume group name parameter: %(name)s."),
+ "KCHCONN0001E": _("Unable to establish connection with libvirt. Please check your libvirt URI which is often defined in /etc/libvirt/libvirt.conf"), + } diff --git a/model/libvirtconnection.py b/model/libvirtconnection.py index e899a33..113378e 100644 --- a/model/libvirtconnection.py +++ b/model/libvirtconnection.py @@ -22,6 +22,7 @@ import libvirt import threading import time
+from wok.objectstore import add_notification
Paulo, I have a patch moving add_notification from objectstore to model.notifications.
Yeap! I saw and reviewed it :-) Will wait your patch be committed upstream then I send a V2 with the new import.
from wok.utils import wok_log
@@ -101,8 +102,9 @@ class LibvirtConnection(object): "your libvirt URI which is often " "defined in " "/etc/libvirt/libvirt.conf") - cherrypy.engine.stop() - exit(1) + add_notification("KCHCONN0001E", + plugin_name="/plugins/kimchi") + return None time.sleep(2)
for name in dir(libvirt.virConnect):
-- Lucio Correia Software Engineer IBM LTC Brazil
_______________________________________________ Kimchi-devel mailing list Kimchi-devel@ovirt.org http://lists.ovirt.org/mailman/listinfo/kimchi-devel
-- Paulo Ricardo Paz Vital Linux Technology Center, IBM Systems http://www.ibm.com/linux/ltc/

From: Paulo Vital <pvital@linux.vnet.ibm.com> Created method check if libvirtd is running to notify user in UI about the not availability of the server and update CapabilitiesModel to provide the same information to UI/user. This patch is part of the solution for Issue #201 Signed-off-by: Paulo Vital <pvital@linux.vnet.ibm.com> --- i18n.py | 1 + model/config.py | 29 +++++++++++++++++++++-------- model/libvirtconnection.py | 7 +++++++ model/templates.py | 5 ++++- utils.py | 16 +++++++++++++++- 5 files changed, 48 insertions(+), 10 deletions(-) diff --git a/i18n.py b/i18n.py index 157f820..2301e60 100644 --- a/i18n.py +++ b/i18n.py @@ -332,5 +332,6 @@ messages = { "KCHLVMS0001E": _("Invalid volume group name parameter: %(name)s."), "KCHCONN0001E": _("Unable to establish connection with libvirt. Please check your libvirt URI which is often defined in /etc/libvirt/libvirt.conf"), + "KCHCONN0002E": _("Libvirt service is not active. Please start the libvirt service in your host system."), } diff --git a/model/config.py b/model/config.py index 39e4efa..58a82df 100644 --- a/model/config.py +++ b/model/config.py @@ -31,7 +31,7 @@ from wok.plugins.kimchi.model.featuretests import FeatureTests from wok.plugins.kimchi.model.featuretests import FEATURETEST_POOL_NAME from wok.plugins.kimchi.model.featuretests import FEATURETEST_VM_NAME from wok.plugins.kimchi.screenshot import VMScreenshot -from wok.plugins.kimchi.utils import check_url_path +from wok.plugins.kimchi.utils import check_url_path, is_libvirtd_up class ConfigModel(object): @@ -55,6 +55,7 @@ class CapabilitiesModel(object): self.kernel_vfio = False self.nm_running = False self.mem_hotplug_support = False + self.libvirtd_running = False # run feature tests self._set_capabilities() @@ -106,6 +107,7 @@ class CapabilitiesModel(object): self.kernel_vfio = FeatureTests.kernel_support_vfio() self.nm_running = FeatureTests.is_nm_running() self.mem_hotplug_support = FeatureTests.has_mem_hotplug_support(conn) + self.libvirtd_running = is_libvirtd_up() wok_log.info("*** Feature tests completed ***") _set_capabilities.priority = 90 @@ -122,13 +124,24 @@ class CapabilitiesModel(object): return False def lookup(self, *ident): - return {'libvirt_stream_protocols': self.libvirt_stream_protocols, - 'qemu_spice': self._qemu_support_spice(), - 'qemu_stream': self.qemu_stream, - 'screenshot': VMScreenshot.get_stream_test_result(), - 'kernel_vfio': self.kernel_vfio, - 'nm_running': FeatureTests.is_nm_running(), - 'mem_hotplug_support': self.mem_hotplug_support} + if not is_libvirtd_up(): + return {'libvirt_stream_protocols': [], + 'qemu_spice': False, + 'qemu_stream': False, + 'screenshot': None, + 'kernel_vfio': self.kernel_vfio, + 'nm_running': FeatureTests.is_nm_running(), + 'mem_hotplug_support': False, + 'libvirtd_running': False} + else: + return {'libvirt_stream_protocols': self.libvirt_stream_protocols, + 'qemu_spice': self._qemu_support_spice(), + 'qemu_stream': self.qemu_stream, + 'screenshot': VMScreenshot.get_stream_test_result(), + 'kernel_vfio': self.kernel_vfio, + 'nm_running': FeatureTests.is_nm_running(), + 'mem_hotplug_support': self.mem_hotplug_support, + 'libvirtd_running': True} class DistrosModel(object): diff --git a/model/libvirtconnection.py b/model/libvirtconnection.py index 113378e..89d5475 100644 --- a/model/libvirtconnection.py +++ b/model/libvirtconnection.py @@ -25,6 +25,8 @@ import time from wok.objectstore import add_notification from wok.utils import wok_log +from wok.plugins.kimchi.utils import is_libvirtd_up + class LibvirtConnection(object): _connections = {} @@ -85,6 +87,11 @@ class LibvirtConnection(object): wrapper.__doc__ = f.__doc__ return wrapper + if not is_libvirtd_up(): + wok_log.error('Libvirt service is not active.') + add_notification('KCHCONN0002E', plugin_name='/plugins/kimchi') + return None + with LibvirtConnection._connectionLock: conn = self._connections.get(conn_id) if not conn: diff --git a/model/templates.py b/model/templates.py index 5cdac00..25bc017 100644 --- a/model/templates.py +++ b/model/templates.py @@ -34,7 +34,7 @@ from wok.xmlutils.utils import xpath_get_text from wok.plugins.kimchi.config import get_kimchi_version from wok.plugins.kimchi.kvmusertests import UserTests from wok.plugins.kimchi.model.cpuinfo import CPUInfoModel -from wok.plugins.kimchi.utils import pool_name_from_uri +from wok.plugins.kimchi.utils import is_libvirtd_up, pool_name_from_uri from wok.plugins.kimchi.vmtemplate import VMTemplate ISO_TYPE = "ISO 9660 CD-ROM" @@ -148,6 +148,9 @@ class TemplatesModel(object): return name def get_list(self): + if not is_libvirtd_up(): + return [] + with self.objstore as session: return session.get_list('template') diff --git a/utils.py b/utils.py index c4cd07d..1f2a575 100644 --- a/utils.py +++ b/utils.py @@ -20,6 +20,7 @@ import contextlib import json +import platform import re import sqlite3 import time @@ -30,7 +31,7 @@ from urlparse import urlparse from wok.exception import InvalidParameter, OperationFailed from wok.plugins.kimchi import config from wok.plugins.kimchi.osinfo import get_template_default -from wok.utils import wok_log +from wok.utils import run_command, wok_log from wok.xmlutils.utils import xpath_get_text MAX_REDIRECTION_ALLOWED = 5 @@ -257,3 +258,16 @@ def get_next_clone_name(all_names, basename, name_suffix='', ts=False): new_name = new_name + name_suffix return new_name + +def is_libvirtd_up(): + """ + Checks if libvirtd.service is up. + """ + distro, _, _ = platform.linux_distribution() + if distro == 'Ubuntu': + cmd = ['systemctl', 'is-active', 'libvirt-bin.service'] + else: + cmd = ['systemctl', 'is-active', 'libvirtd.service'] + + output, error, rc = run_command(cmd, silent=True) + return True if output == 'active\n' else False -- 2.5.5

On 05/09/2016 09:56 AM, pvital@linux.vnet.ibm.com wrote:
From: Paulo Vital <pvital@linux.vnet.ibm.com>
Created method check if libvirtd is running to notify user in UI about the not availability of the server and update CapabilitiesModel to provide the same information to UI/user.
This patch is part of the solution for Issue #201
Signed-off-by: Paulo Vital <pvital@linux.vnet.ibm.com> --- i18n.py | 1 + model/config.py | 29 +++++++++++++++++++++-------- model/libvirtconnection.py | 7 +++++++ model/templates.py | 5 ++++- utils.py | 16 +++++++++++++++- 5 files changed, 48 insertions(+), 10 deletions(-)
diff --git a/i18n.py b/i18n.py index 157f820..2301e60 100644 --- a/i18n.py +++ b/i18n.py @@ -332,5 +332,6 @@ messages = { "KCHLVMS0001E": _("Invalid volume group name parameter: %(name)s."),
"KCHCONN0001E": _("Unable to establish connection with libvirt. Please check your libvirt URI which is often defined in /etc/libvirt/libvirt.conf"), + "KCHCONN0002E": _("Libvirt service is not active. Please start the libvirt service in your host system."),
} diff --git a/model/config.py b/model/config.py index 39e4efa..58a82df 100644 --- a/model/config.py +++ b/model/config.py @@ -31,7 +31,7 @@ from wok.plugins.kimchi.model.featuretests import FeatureTests from wok.plugins.kimchi.model.featuretests import FEATURETEST_POOL_NAME from wok.plugins.kimchi.model.featuretests import FEATURETEST_VM_NAME from wok.plugins.kimchi.screenshot import VMScreenshot -from wok.plugins.kimchi.utils import check_url_path +from wok.plugins.kimchi.utils import check_url_path, is_libvirtd_up
class ConfigModel(object): @@ -55,6 +55,7 @@ class CapabilitiesModel(object): self.kernel_vfio = False self.nm_running = False self.mem_hotplug_support = False + self.libvirtd_running = False
# run feature tests self._set_capabilities() @@ -106,6 +107,7 @@ class CapabilitiesModel(object): self.kernel_vfio = FeatureTests.kernel_support_vfio() self.nm_running = FeatureTests.is_nm_running() self.mem_hotplug_support = FeatureTests.has_mem_hotplug_support(conn) + self.libvirtd_running = is_libvirtd_up() wok_log.info("*** Feature tests completed ***") _set_capabilities.priority = 90
@@ -122,13 +124,24 @@ class CapabilitiesModel(object): return False
def lookup(self, *ident): - return {'libvirt_stream_protocols': self.libvirt_stream_protocols, - 'qemu_spice': self._qemu_support_spice(), - 'qemu_stream': self.qemu_stream, - 'screenshot': VMScreenshot.get_stream_test_result(), - 'kernel_vfio': self.kernel_vfio, - 'nm_running': FeatureTests.is_nm_running(), - 'mem_hotplug_support': self.mem_hotplug_support} + if not is_libvirtd_up(): + return {'libvirt_stream_protocols': [], + 'qemu_spice': False, + 'qemu_stream': False, + 'screenshot': None, + 'kernel_vfio': self.kernel_vfio, + 'nm_running': FeatureTests.is_nm_running(), + 'mem_hotplug_support': False, + 'libvirtd_running': False}
+ else:
You don't need the else statement when you have return right before.
+ return {'libvirt_stream_protocols': self.libvirt_stream_protocols, + 'qemu_spice': self._qemu_support_spice(), + 'qemu_stream': self.qemu_stream, + 'screenshot': VMScreenshot.get_stream_test_result(), + 'kernel_vfio': self.kernel_vfio, + 'nm_running': FeatureTests.is_nm_running(), + 'mem_hotplug_support': self.mem_hotplug_support, + 'libvirtd_running': True}
class DistrosModel(object): diff --git a/model/libvirtconnection.py b/model/libvirtconnection.py index 113378e..89d5475 100644 --- a/model/libvirtconnection.py +++ b/model/libvirtconnection.py @@ -25,6 +25,8 @@ import time from wok.objectstore import add_notification from wok.utils import wok_log
+from wok.plugins.kimchi.utils import is_libvirtd_up +
class LibvirtConnection(object): _connections = {} @@ -85,6 +87,11 @@ class LibvirtConnection(object): wrapper.__doc__ = f.__doc__ return wrapper
+ if not is_libvirtd_up(): + wok_log.error('Libvirt service is not active.') + add_notification('KCHCONN0002E', plugin_name='/plugins/kimchi') + return None + with LibvirtConnection._connectionLock: conn = self._connections.get(conn_id) if not conn: diff --git a/model/templates.py b/model/templates.py index 5cdac00..25bc017 100644 --- a/model/templates.py +++ b/model/templates.py @@ -34,7 +34,7 @@ from wok.xmlutils.utils import xpath_get_text from wok.plugins.kimchi.config import get_kimchi_version from wok.plugins.kimchi.kvmusertests import UserTests from wok.plugins.kimchi.model.cpuinfo import CPUInfoModel -from wok.plugins.kimchi.utils import pool_name_from_uri +from wok.plugins.kimchi.utils import is_libvirtd_up, pool_name_from_uri from wok.plugins.kimchi.vmtemplate import VMTemplate
ISO_TYPE = "ISO 9660 CD-ROM" @@ -148,6 +148,9 @@ class TemplatesModel(object): return name
def get_list(self): + if not is_libvirtd_up(): + return [] + with self.objstore as session: return session.get_list('template')
diff --git a/utils.py b/utils.py index c4cd07d..1f2a575 100644 --- a/utils.py +++ b/utils.py @@ -20,6 +20,7 @@
import contextlib import json +import platform import re import sqlite3 import time @@ -30,7 +31,7 @@ from urlparse import urlparse from wok.exception import InvalidParameter, OperationFailed from wok.plugins.kimchi import config from wok.plugins.kimchi.osinfo import get_template_default -from wok.utils import wok_log +from wok.utils import run_command, wok_log from wok.xmlutils.utils import xpath_get_text
MAX_REDIRECTION_ALLOWED = 5 @@ -257,3 +258,16 @@ def get_next_clone_name(all_names, basename, name_suffix='', ts=False): new_name = new_name + name_suffix
return new_name + +def is_libvirtd_up(): + """ + Checks if libvirtd.service is up. + """ + distro, _, _ = platform.linux_distribution() + if distro == 'Ubuntu':
It is better to use .lower() to avoid issues with case sensitive.
+ cmd = ['systemctl', 'is-active', 'libvirt-bin.service'] + else: + cmd = ['systemctl', 'is-active', 'libvirtd.service'] + + output, error, rc = run_command(cmd, silent=True) + return True if output == 'active\n' else False
participants (4)
-
Aline Manera
-
Lucio Correia
-
Paulo Ricardo Paz Vital
-
pvital@linux.vnet.ibm.com