
There's no performance data return from zvm management tool if the virtual machine in shutdown stat. In current implementation, InstanceNotFoundException would be raised in this case. With this change integrated, zvm inspector will check instance's power_state at first, then try to get the data. Also did some change to ignore invalid data format exception that in case of all virtual machines on the compute node are in shutdow state. Change-Id: I02b69adc6e818a69d1e6887a3344f6bf0b344aa7
190 lines
7.6 KiB
Python
190 lines
7.6 KiB
Python
# Copyright 2015 IBM Corp.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
|
|
from ceilometer.compute.virt import inspector as virt_inspector
|
|
from ceilometer.i18n import _
|
|
from oslo_config import cfg
|
|
from oslo_log import log
|
|
from oslo_utils import timeutils
|
|
from oslo_utils import units
|
|
|
|
from ceilometer_zvm.compute.virt.zvm import utils as zvmutils
|
|
|
|
|
|
zvm_ops = [
|
|
cfg.StrOpt('zvm_xcat_server',
|
|
default=None,
|
|
help='Host name or IP address of xCAT management_node'),
|
|
cfg.StrOpt('zvm_xcat_username',
|
|
default=None,
|
|
help='xCAT username'),
|
|
cfg.StrOpt('zvm_xcat_password',
|
|
default=None,
|
|
secret=True,
|
|
help='Password of the xCAT user'),
|
|
cfg.IntOpt('zvm_xcat_connection_timeout',
|
|
default=600,
|
|
help="The number of seconds wait for xCAT MN response"),
|
|
cfg.StrOpt('xcat_zhcp_nodename',
|
|
default='zhcp',
|
|
help='xCat zHCP nodename in xCAT '),
|
|
cfg.StrOpt('zvm_host',
|
|
default=None,
|
|
help='z/VM host that managed by xCAT MN.'),
|
|
cfg.StrOpt('zvm_xcat_master',
|
|
default='xcat',
|
|
help='The xCAT MM node name'),
|
|
cfg.IntOpt('cache_update_interval',
|
|
default=600,
|
|
help="Cached data update interval"),
|
|
]
|
|
|
|
|
|
CONF = cfg.CONF
|
|
CONF.register_opts(zvm_ops, group='zvm')
|
|
|
|
LOG = log.getLogger(__name__)
|
|
|
|
|
|
class ZVMInspector(virt_inspector.Inspector):
|
|
|
|
def __init__(self):
|
|
self.cache = zvmutils.CacheData()
|
|
self.cache_expiration = timeutils.utcnow_ts()
|
|
|
|
self.instances = {}
|
|
self.zhcp_info = {
|
|
'nodename': CONF.zvm.xcat_zhcp_nodename,
|
|
'hostname': zvmutils.get_node_hostname(
|
|
CONF.zvm.xcat_zhcp_nodename),
|
|
'userid': zvmutils.get_userid(CONF.zvm.xcat_zhcp_nodename)
|
|
}
|
|
|
|
def _update_inst_cpu_mem_stat(self, instances):
|
|
inst_pis = zvmutils.image_performance_query(
|
|
self.zhcp_info['nodename'], instances.values())
|
|
|
|
for inst_name, userid in instances.items():
|
|
if userid not in inst_pis.keys():
|
|
# Not performance data returned for this virtual machine
|
|
continue
|
|
|
|
with zvmutils.expect_invalid_xcat_resp_data():
|
|
guest_cpus = int(inst_pis[userid]['guest_cpus'])
|
|
used_cpu_time = inst_pis[userid]['used_cpu_time']
|
|
used_cpu_time = int(used_cpu_time.partition(' ')[0]) * units.k
|
|
used_memory = inst_pis[userid]['used_memory']
|
|
used_memory = int(used_memory.partition(' ')[0]) / units.Ki
|
|
|
|
inst_stat = {'nodename': inst_name,
|
|
'userid': userid,
|
|
'guest_cpus': guest_cpus,
|
|
'used_cpu_time': used_cpu_time,
|
|
'used_memory': used_memory}
|
|
|
|
self.cache.set('cpumem', inst_stat)
|
|
|
|
def _update_inst_nic_stat(self, instances):
|
|
vsw_dict = zvmutils.virutal_network_vswitch_query_iuo_stats(
|
|
self.zhcp_info['nodename'])
|
|
with zvmutils.expect_invalid_xcat_resp_data():
|
|
for vsw in vsw_dict['vswitches']:
|
|
for nic in vsw['nics']:
|
|
for inst_name, userid in instances.items():
|
|
if nic['userid'].upper() == userid.upper():
|
|
nic_entry = {'vswitch_name': vsw['vswitch_name'],
|
|
'nic_vdev': nic['vdev'],
|
|
'nic_fr_rx': int(nic['nic_fr_rx']),
|
|
'nic_fr_tx': int(nic['nic_fr_tx']),
|
|
'nic_rx': int(nic['nic_rx']),
|
|
'nic_tx': int(nic['nic_tx'])}
|
|
inst_stat = self.cache.get('vnics', inst_name)
|
|
if inst_stat is None:
|
|
inst_stat = {
|
|
'nodename': inst_name,
|
|
'userid': userid,
|
|
'nics': [nic_entry]
|
|
}
|
|
else:
|
|
inst_stat['nics'].append(nic_entry)
|
|
self.cache.set('vnics', inst_stat)
|
|
|
|
def _update_cache(self, meter, instances={}):
|
|
if instances == {}:
|
|
self.cache.clear()
|
|
self.cache_expiration = (timeutils.utcnow_ts() +
|
|
CONF.zvm.cache_update_interval)
|
|
instances = self.instances = zvmutils.list_instances(
|
|
self.zhcp_info)
|
|
if meter == 'cpumem':
|
|
self._update_inst_cpu_mem_stat(instances)
|
|
if meter == 'vnics':
|
|
self._update_inst_nic_stat(instances)
|
|
|
|
def _check_expiration_and_update_cache(self, meter):
|
|
now = timeutils.utcnow_ts()
|
|
if now >= self.cache_expiration:
|
|
self._update_cache(meter)
|
|
|
|
def _get_inst_stat(self, meter, instance):
|
|
inst_name = zvmutils.get_inst_name(instance)
|
|
# zvm inspector can not get instance info in shutdown stat
|
|
if zvmutils.get_inst_power_state(instance) == 0x04:
|
|
msg = _("Can not get vm info in shutdown state "
|
|
"for %s") % inst_name
|
|
raise virt_inspector.InstanceShutOffException(msg)
|
|
|
|
self._check_expiration_and_update_cache(meter)
|
|
|
|
inst_stat = self.cache.get(meter, inst_name)
|
|
|
|
if inst_stat is None:
|
|
userid = (self.instances.get(inst_name) or
|
|
zvmutils.get_userid(inst_name))
|
|
self._update_cache(meter, {inst_name: userid})
|
|
inst_stat = self.cache.get(meter, inst_name)
|
|
|
|
if inst_stat is None:
|
|
msg = _("Can not get vm info for %s") % inst_name
|
|
raise virt_inspector.InstanceNotFoundException(msg)
|
|
else:
|
|
return inst_stat
|
|
|
|
def inspect_cpus(self, instance):
|
|
inst_stat = self._get_inst_stat('cpumem', instance)
|
|
return virt_inspector.CPUStats(number=inst_stat['guest_cpus'],
|
|
time=inst_stat['used_cpu_time'])
|
|
|
|
def inspect_memory_usage(self, instance, duration=None):
|
|
inst_stat = self._get_inst_stat('cpumem', instance)
|
|
return virt_inspector.MemoryUsageStats(usage=inst_stat['used_memory'])
|
|
|
|
def inspect_vnics(self, instance):
|
|
inst_stat = self._get_inst_stat('vnics', instance)
|
|
for nic in inst_stat['nics']:
|
|
nic_id = '_'.join((nic['vswitch_name'], inst_stat['userid'],
|
|
nic['nic_vdev']))
|
|
interface = virt_inspector.Interface(
|
|
name=nic_id,
|
|
mac=None,
|
|
fref=None,
|
|
parameters=None)
|
|
stats = virt_inspector.InterfaceStats(
|
|
rx_bytes=nic['nic_rx'],
|
|
rx_packets=nic['nic_fr_rx'],
|
|
tx_bytes=nic['nic_tx'],
|
|
tx_packets=nic['nic_fr_tx'])
|
|
yield (interface, stats)
|