Two quick comments
1)API.md doc is missing in the patch for new api addition.
2)Can we have test cases?
Please, don't forget to include test cases to cover this scenario. Do it
in the V2.
On Tue, 2015-11-03 at 12:15 +0530, chandra(a)linux.vnet.ibm.com wrote:
> From: chandrureddy <chandra(a)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
> +
> +
> +@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
_______________________________________________
Kimchi-devel mailing list
Kimchi-devel(a)ovirt.org
http://lists.ovirt.org/mailman/listinfo/kimchi-devel