[Kimchi-devel] [PATCH] Take off libvirt to get vms info used before any shutdown and reboot actions
Chandra Shehkhar Reddy Potula
chandra at linux.vnet.ibm.com
Tue Nov 3 08:59:32 UTC 2015
Will be send a separate patch to take care of your comments.
On 11/03/2015 12:35 PM, Abhiram wrote:
> Two quick comments
> 1)API.md doc is missing in the patch for new api addition.
> 2)Can we have test cases?
>
> On Tue, 2015-11-03 at 12:15 +0530, chandra at linux.vnet.ibm.com wrote:
>> From: chandrureddy <chandra at linux.vnet.ibm.com>
>>
>> Earlier been used libvirt to fetch the vms information in the back end code
>> UI was using REST API 'plugins/kimchi/vms' to get the vms info.
>> Ginger Base not have this functionality and will not work on plain linux.
>> Ginger Base should handle well on both plain linux with out KVM and with KVM
>>
>> New code provides REST API 'plugins/gingerbase/vms'
>> 1. to get the vms information on KVM mahcine (virsh way)
>> 2. return empty json in case of plain linux machine
>> ---
>> src/wok/plugins/gingerbase/control/vmsinfo.py | 34 +++++++++++++
>> src/wok/plugins/gingerbase/i18n.py | 1 +
>> src/wok/plugins/gingerbase/model/host.py | 23 +++------
>> src/wok/plugins/gingerbase/model/vmsinfo.py | 32 ++++++++++++
>> .../plugins/gingerbase/ui/js/src/gingerbase.api.js | 12 +++++
>> .../gingerbase/ui/js/src/gingerbase.host.js | 23 ++++-----
>> src/wok/plugins/gingerbase/ui/pages/i18n.json.tmpl | 2 +
>> src/wok/plugins/gingerbase/utils.py | 59 +++++++++++++++++++++-
>> 8 files changed, 157 insertions(+), 29 deletions(-)
>> create mode 100644 src/wok/plugins/gingerbase/control/vmsinfo.py
>> create mode 100644 src/wok/plugins/gingerbase/model/vmsinfo.py
>>
>> diff --git a/src/wok/plugins/gingerbase/control/vmsinfo.py b/src/wok/plugins/gingerbase/control/vmsinfo.py
>> new file mode 100644
>> index 0000000..e9bddea
>> --- /dev/null
>> +++ b/src/wok/plugins/gingerbase/control/vmsinfo.py
>> @@ -0,0 +1,34 @@
>> +#
>> +# Project Ginger Base
>> +#
>> +# Copyright IBM, Corp. 2015
>> +#
>> +# This library is free software; you can redistribute it and/or
>> +# modify it under the terms of the GNU Lesser General Public
>> +# License as published by the Free Software Foundation; either
>> +# version 2.1 of the License, or (at your option) any later version.
>> +#
>> +# This library is distributed in the hope that it will be useful,
>> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
>> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
>> +# Lesser General Public License for more details.
>> +#
>> +# You should have received a copy of the GNU Lesser General Public
>> +# License along with this library; if not, write to the Free Software
>> +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
>> +
>> +from wok.control.utils import UrlSubNode
>> +from wok.control.base import SimpleCollection
>> +
>> +
>> + at UrlSubNode('vms', True)
>> +class VMs(SimpleCollection):
>> + def __init__(self, model):
>> + super(VMs, self).__init__(model)
>> + self.role_key = 'host'
>> + self.admin_methods = ['GET']
>> + self.uri_fmt = '/vms/%s'
>> +
>> + @property
>> + def data(self):
>> + return self.info
>> diff --git a/src/wok/plugins/gingerbase/i18n.py b/src/wok/plugins/gingerbase/i18n.py
>> index 8596f17..d477b20 100644
>> --- a/src/wok/plugins/gingerbase/i18n.py
>> +++ b/src/wok/plugins/gingerbase/i18n.py
>> @@ -40,6 +40,7 @@ messages = {
>> "GGBHOST0001E": _("Unable to shutdown host machine as there are running virtual machines"),
>> "GGBHOST0002E": _("Unable to reboot host machine as there are running virtual machines"),
>> "GGBHOST0005E": _("When specifying CPU topology, each element must be an integer greater than zero."),
>> + "GGBHOST0006E": _("Failed to execute virsh command"),
>>
>> "GGBPKGUPD0001E": _("No packages marked for update"),
>> "GGBPKGUPD0002E": _("Package %(name)s is not marked to be updated."),
>> diff --git a/src/wok/plugins/gingerbase/model/host.py b/src/wok/plugins/gingerbase/model/host.py
>> index 670fec5..307f26a 100644
>> --- a/src/wok/plugins/gingerbase/model/host.py
>> +++ b/src/wok/plugins/gingerbase/model/host.py
>> @@ -37,6 +37,7 @@ from wok.model.tasks import TaskModel
>> from wok.plugins.gingerbase.model.debugreports import DebugReportsModel
>> from wok.plugins.gingerbase.repositories import Repositories
>> from wok.plugins.gingerbase.swupdate import SoftwareUpdate
>> +from wok.plugins.gingerbase.utils import get_vms_by_state
>>
>> HOST_STATS_INTERVAL = 1
>>
>> @@ -142,30 +143,22 @@ class HostModel(object):
>>
>> def shutdown(self, args=None):
>> # Check for running vms before shutdown
>> - # FIXME : Find alternative way to figure out if any vms running
>> - # running_vms = self._get_vms_list_by_state('running')
>> - # if len(running_vms) > 0:
>> - # raise OperationFailed("GGBHOST0001E")
>> + running_vms = get_vms_by_state('running')
>> + if len(running_vms) > 0:
>> + raise OperationFailed("GGBHOST0001E")
>>
>> wok_log.info('Host is going to shutdown.')
>> os.system('shutdown -h now')
>>
>> def reboot(self, args=None):
>> - # Find running VMs
>> - # FIXME : Find alternative way to figure out if any vms running
>> - # running_vms = self._get_vms_list_by_state('running')
>> - # if len(running_vms) > 0:
>> - # raise OperationFailed("GGBHOST0002E")
>> + # Check for running vms before reboot
>> + running_vms = get_vms_by_state('running')
>> + if len(running_vms) > 0:
>> + raise OperationFailed("GGBHOST0002E")
>>
>> wok_log.info('Host is going to reboot.')
>> os.system('reboot')
>>
>> - # def _get_vms_list_by_state(self, state):
>> - # conn = self.conn.get()
>> - # return [dom.name().decode('utf-8')
>> - # for dom in conn.listAllDomains(0)
>> - # if (DOM_STATE_MAP[dom.info()[0]]) == state]
>> -
>>
>> class SoftwareUpdateProgressModel(object):
>> def __init__(self, **kargs):
>> diff --git a/src/wok/plugins/gingerbase/model/vmsinfo.py b/src/wok/plugins/gingerbase/model/vmsinfo.py
>> new file mode 100644
>> index 0000000..a9895df
>> --- /dev/null
>> +++ b/src/wok/plugins/gingerbase/model/vmsinfo.py
>> @@ -0,0 +1,32 @@
>> +#
>> +# Project Ginger Base
>> +#
>> +# Copyright IBM, Corp. 2015
>> +#
>> +# This library is free software; you can redistribute it and/or
>> +# modify it under the terms of the GNU Lesser General Public
>> +# License as published by the Free Software Foundation; either
>> +# version 2.1 of the License, or (at your option) any later version.
>> +#
>> +# This library is distributed in the hope that it will be useful,
>> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
>> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
>> +# Lesser General Public License for more details.
>> +#
>> +# You should have received a copy of the GNU Lesser General Public
>> +# License along with this library; if not, write to the Free Software
>> +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
>> +
>> +from wok.model.tasks import TaskModel
>> +from wok.plugins.gingerbase.utils import get_vms
>> +
>> +
>> +class VMsModel(object):
>> + def __init__(self, **kargs):
>> + self.objstore = kargs['objstore']
>> + self.task = TaskModel(**kargs)
>> + self.vms_info = get_vms()
>> +
>> + def get_list(self, *name):
>> + self.vms_info = get_vms()
>> + return self.vms_info
>> diff --git a/src/wok/plugins/gingerbase/ui/js/src/gingerbase.api.js b/src/wok/plugins/gingerbase/ui/js/src/gingerbase.api.js
>> index db6543f..9cd3b4a 100644
>> --- a/src/wok/plugins/gingerbase/ui/js/src/gingerbase.api.js
>> +++ b/src/wok/plugins/gingerbase/ui/js/src/gingerbase.api.js
>> @@ -358,5 +358,17 @@ var kimchi = {
>> wok.message.error(data.responseJSON.reason);
>> }
>> });
>> + },
>> +
>> + listVMs : function(suc, err) {
>> + wok.requestJSON({
>> + url : 'plugins/gingerbase/vms',
>> + type : 'GET',
>> + contentType : 'application/json',
>> + dataType : 'json',
>> + resend: true,
>> + success : suc,
>> + error : err
>> + });
>> }
>> };
>> diff --git a/src/wok/plugins/gingerbase/ui/js/src/gingerbase.host.js b/src/wok/plugins/gingerbase/ui/js/src/gingerbase.host.js
>> index 0d52b92..ea64dad 100644
>> --- a/src/wok/plugins/gingerbase/ui/js/src/gingerbase.host.js
>> +++ b/src/wok/plugins/gingerbase/ui/js/src/gingerbase.host.js
>> @@ -500,18 +500,17 @@ kimchi.host_main = function() {
>> $(shutdownButtonID).prop('disabled', true);
>> $(restartButtonID).prop('disabled', true);
>> // Check if there is any VM is running.
>> - // FIXME : Find alternative way to figure out if any vms running
>> - // kimchi.listVMs(function(vms) {
>> - // for(var i = 0; i < vms.length; i++) {
>> - // if(vms[i]['state'] === 'running') {
>> - // wok.message.error.code('GGBHOST6001E');
>> - // $(shutdownButtonID).prop('disabled', false);
>> - // $(restartButtonID).prop('disabled', false);
>> - // return;
>> - // }
>> - // }
>> - //
>> - // });
>> + kimchi.listVMs(function(vms) {
>> + for(var i = 0; i < vms.length; i++) {
>> + if(vms[i]['state'] === 'running') {
>> + wok.message.error.code('GGBHOST6001E');
>> + $(shutdownButtonID).prop('disabled', false);
>> + $(restartButtonID).prop('disabled', false);
>> + return;
>> + }
>> + }
>> +
>> + });
>> }, function() {
>> });
>> };
>> diff --git a/src/wok/plugins/gingerbase/ui/pages/i18n.json.tmpl b/src/wok/plugins/gingerbase/ui/pages/i18n.json.tmpl
>> index f6228ab..346e76f 100644
>> --- a/src/wok/plugins/gingerbase/ui/pages/i18n.json.tmpl
>> +++ b/src/wok/plugins/gingerbase/ui/pages/i18n.json.tmpl
>> @@ -113,6 +113,8 @@
>> "GGBDR6012M": "$_("Pending...")",
>> "GGBDR6013M": "$_("Report name is the same as the original one.")",
>>
>> + "GGBHOST6001E": "$_("Unable to shut down system as there are some virtual machines running!")",
>> +
>> "GGBVM6001M": "$_("This will delete the virtual machine and its virtual disks. This operation cannot be undone. Would you like to continue?")",
>> "GGBVM6002M": "$_("Power off Confirmation")",
>> "GGBVM6003M": "$_("This action may produce undesirable results, "
>> diff --git a/src/wok/plugins/gingerbase/utils.py b/src/wok/plugins/gingerbase/utils.py
>> index 9f41967..b606438 100644
>> --- a/src/wok/plugins/gingerbase/utils.py
>> +++ b/src/wok/plugins/gingerbase/utils.py
>> @@ -22,12 +22,13 @@
>>
>> import contextlib
>> import os
>> +import re
>> import urllib2
>> from httplib import HTTPConnection, HTTPException
>> from urlparse import urlparse
>>
>> -from wok.exception import InvalidParameter
>> -
>> +from wok.exception import InvalidParameter, OperationFailed
>> +from wok.utils import run_command, wok_log
>>
>> MAX_REDIRECTION_ALLOWED = 5
>>
>> @@ -80,3 +81,57 @@ def validate_repo_url(url):
>> raise InvalidParameter("WOKUTILS0001E", {'url': url})
>> else:
>> raise InvalidParameter("KCHREPOS0002E")
>> +
>> +
>> +def get_vms():
>> + # Check for vms running on the machine
>> + # virsh -r -c 'qemu:///system' list --all
>> + # Id Name State
>> + # ----------------------------------------------------
>> + # 3 Fedora21 running
>> + # - a8Sr0LzRgWjEqy3iiKjQvA shut off
>> + # - kimchi-cdrom shut off
>> + # - kimchi-ifaces shut off
>> + vms = []
>> + try:
>> + __import__('libvirt')
>> + vms_running = ["virsh", "-r", "-c", "qemu:///system", "list", "--all"]
>> + (std_out, std_err, rc) = run_command(vms_running)
>> +
>> + if rc == 0:
>> + header_pattern = r'('+re.escape('Id') + r')\s+' \
>> + r'('+re.escape('Name') + r')\s+' \
>> + r'('+re.escape('State') + r')$'
>> +
>> + vm_pattern = r'([-]|[0-9]+)\s+' \
>> + r'([0-9a-zA-Z-_]*)\s+' \
>> + r'([a-zA-Z-_]+[\s]?[a-zA-Z-_]+)'
>> + command_out = std_out.strip().split("\n")
>> + header = re.search(header_pattern, command_out[0], re.M | re.I)
>> +
>> + value_pattern = re.compile(vm_pattern, re.M | re.I)
>> + for line in command_out[2:]:
>> + value = re.search(value_pattern, line)
>> + vm_data = {}
>> + if value:
>> + if (header.group() != value.group()) and \
>> + (len(header.groups()) == len(value.groups())):
>> + for cnt in range(1, len(header.groups())+1):
>> + vm_data[header.group(cnt).lower()] = \
>> + value.group(cnt)
>> + vms.append(vm_data)
>> + else:
>> + raise OperationFailed('GGBHOST0006E')
>> + except ImportError, err:
>> + wok_log.info('Host is running linux with out KVM. %s' % err.message)
>> + return []
>> + return vms
>> +
>> +
>> +def get_vms_by_state(state='running'):
>> + vms_running = []
>> + vms = get_vms()
>> + for vm in vms:
>> + if vm['state'] == state:
>> + vms_running.append(vm)
>> + return vms_running
>
More information about the Kimchi-devel
mailing list