144 lines
5.7 KiB
Python
144 lines
5.7 KiB
Python
# Copyright 2015, 2020 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.
|
|
|
|
|
|
import six
|
|
|
|
from ceilometer.compute.virt import inspector as virt_inspector
|
|
from ceilometer.i18n import _
|
|
from ceilometer_zvm.compute.virt.zvm import exception
|
|
from ceilometer_zvm.compute.virt.zvm import utils as zvmutils
|
|
from oslo_config import cfg
|
|
from oslo_log import log
|
|
from oslo_utils import units
|
|
|
|
LOG = log.getLogger(__name__)
|
|
|
|
zvm_opts = [
|
|
cfg.URIOpt('zvm_cloud_connector_url',
|
|
help="""
|
|
URL to be used to communicate with z/VM Cloud Connector.
|
|
Example: https://10.10.10.1:8080.
|
|
"""),
|
|
cfg.StrOpt('zvm_cloud_connector_token_file',
|
|
default=None,
|
|
help="""
|
|
Token file that contains the admin token to be used when sending
|
|
request to z/VM Cloud Connector.
|
|
"""),
|
|
cfg.StrOpt('zvm_cloud_connector_ca_file',
|
|
default=None,
|
|
help="""
|
|
CA certificate file to be used to verify z/VM Cloud Connector
|
|
server certificate.
|
|
|
|
A string, it must be a path to a CA bundle to use.
|
|
"""),
|
|
]
|
|
|
|
|
|
class ZVMInspector(virt_inspector.Inspector):
|
|
|
|
def __init__(self, conf):
|
|
super(ZVMInspector, self).__init__(conf)
|
|
self.cache = {}
|
|
self.conf.register_opts(zvm_opts)
|
|
self._reqh = zvmutils.zVMConnectorRequestHandler(
|
|
self.conf)
|
|
|
|
def inspect_vnics(self, instance, duration):
|
|
nics_data = self._inspect_inst_data(instance, 'vnics')
|
|
# Construct the final result
|
|
for nic in nics_data:
|
|
yield virt_inspector.InterfaceStats(
|
|
name=nic['nic_vdev'],
|
|
mac=None,
|
|
fref=None,
|
|
parameters=None,
|
|
rx_bytes=nic['nic_rx'],
|
|
rx_packets=nic['nic_fr_rx'],
|
|
# rx_bytes_delta was taken out from zcc
|
|
rx_bytes_delta=None,
|
|
rx_errors=nic['nic_fr_rx_err'],
|
|
rx_drop=None,
|
|
tx_bytes=nic['nic_tx'],
|
|
tx_packets=nic['nic_fr_tx'],
|
|
# tx_bytes_delta was taken out from zcc
|
|
tx_bytes_delta=None,
|
|
tx_errors=nic['nic_fr_tx_err'],
|
|
tx_drop=None
|
|
)
|
|
|
|
def inspect_instance(self, instance, duration):
|
|
inst_stats = self._inspect_inst_data(instance, 'stats')
|
|
LOG.debug("instance stats:%s", str(inst_stats))
|
|
cpu_number = inst_stats['guest_cpus']
|
|
used_cpu_time = (inst_stats['used_cpu_time_us'] * units.k)
|
|
used_mem_mb = inst_stats['used_mem_kb'] / units.Ki
|
|
# Construct the final result
|
|
return virt_inspector.InstanceStats(cpu_number=cpu_number,
|
|
cpu_time=used_cpu_time,
|
|
memory_usage=used_mem_mb
|
|
)
|
|
|
|
def _inspect_inst_data(self, instance, inspect_type):
|
|
inspect_data = {}
|
|
# Make sure the inst name in upper case
|
|
inst_name = zvmutils.get_inst_name(instance).upper()
|
|
msg_shutdown = _("Can not get vm info in shutdown state "
|
|
"for %s") % inst_name
|
|
msg_notexist = _("Can not get vm info for %s, vm not exist"
|
|
) % inst_name
|
|
msg_nodata = _("Failed to get vm info for %s") % inst_name
|
|
# zvm inspector can not get instance info in shutdown stat
|
|
if zvmutils.get_inst_power_state(instance) == 0x04:
|
|
raise virt_inspector.InstanceShutOffException(msg_shutdown)
|
|
try:
|
|
if inspect_type == 'stats':
|
|
inspect_data = self._reqh.call('guest_inspect_stats',
|
|
inst_name)
|
|
elif inspect_type == 'vnics':
|
|
inspect_data = self._reqh.call('guest_inspect_vnics',
|
|
inst_name)
|
|
except Exception as err:
|
|
msg_nodata += _(". Error: %s") % six.text_type(err)
|
|
raise virt_inspector.NoDataException(msg_nodata)
|
|
|
|
# Check the inst data is in the returned result
|
|
index_key = inst_name
|
|
if index_key not in inspect_data:
|
|
# Check the reason: shutdown or not exist or other error
|
|
power_stat = ''
|
|
try:
|
|
power_stat = self._reqh.call('guest_get_power_state',
|
|
inst_name)
|
|
except exception.ZVMConnectorRequestFailed as err:
|
|
if err.results['overallRC'] == 404:
|
|
# instance not exists
|
|
raise virt_inspector.InstanceNotFoundException(msg_notexist
|
|
)
|
|
else:
|
|
msg_nodata += _(". Error: %s") % six.text_type(err)
|
|
raise virt_inspector.NoDataException(msg_nodata)
|
|
except Exception as err:
|
|
msg_nodata += _(". Error: %s") % six.text_type(err)
|
|
raise virt_inspector.NoDataException(msg_nodata)
|
|
|
|
if power_stat == 'off':
|
|
raise virt_inspector.InstanceShutOffException(msg_shutdown)
|
|
else:
|
|
raise virt_inspector.NoDataException(msg_nodata)
|
|
else:
|
|
return inspect_data[index_key]
|