nova/nova/virt/zvm/hypervisor.py

168 lines
5.7 KiB
Python

# Copyright 2017,2018 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 os
import pwd
from oslo_log import log as logging
from nova.compute import power_state as compute_power_state
from nova import conf
from nova import exception
from nova.virt.zvm import utils as zvmutils
LOG = logging.getLogger(__name__)
CONF = conf.CONF
class Hypervisor(object):
"""z/VM implementation of Hypervisor."""
def __init__(self, zcc_url, ca_file=None):
super(Hypervisor, self).__init__()
self._reqh = zvmutils.ConnectorClient(zcc_url,
ca_file=ca_file)
host_info = self._get_host_info()
# Very very unlikely the hostname will be changed, so when create
# hypervisor object, store the information in the cache and after
# that we can use it directly without query again from connectorclient
self._hypervisor_hostname = host_info['hypervisor_hostname']
self._rhost = ''.join([pwd.getpwuid(os.geteuid()).pw_name, '@',
CONF.my_ip])
def _get_host_info(self):
host_stats = {}
try:
host_stats = self._reqh.call('host_get_info')
except exception.ZVMConnectorError as e:
LOG.warning("Failed to get host stats: %s", e)
return host_stats
def get_available_resource(self):
return self._get_host_info()
def get_available_nodes(self, refresh=False):
# It's not expected that the hostname change, no need to take
# 'refresh' into account.
return [self._hypervisor_hostname]
def list_names(self):
"""list names of the servers in the hypervisor"""
return self._reqh.call('guest_list')
def get_host_uptime(self):
host_info = self._get_host_info()
return host_info['ipl_time']
def guest_exists(self, instance):
return instance.name.upper() in self.list_names()
def guest_get_power_state(self, name):
power_state = compute_power_state.NOSTATE
try:
power_state = self._reqh.call('guest_get_power_state', name)
except exception.ZVMConnectorError as err:
if err.overallRC == 404:
# instance does not exist
LOG.warning("Failed to get power state due to nonexistent "
"instance: %s", name)
raise exception.InstanceNotFound(instance_id=name)
else:
raise
return power_state
def guest_create(self, name, vcpus, memory_mb, disk_list):
self._reqh.call('guest_create', name, vcpus, memory_mb,
disk_list=disk_list)
def guest_deploy(self, name, image_name, transportfiles):
self._reqh.call('guest_deploy', name, image_name,
transportfiles=transportfiles, remotehost=self._rhost)
def guest_delete(self, name):
self._reqh.call('guest_delete', name)
def guest_start(self, name):
self._reqh.call('guest_start', name)
def guest_create_network_interface(self, name, distro, nets):
self._reqh.call('guest_create_network_interface',
name, distro, nets)
def guest_config_minidisks(self, name, disk_list):
self._reqh.call('guest_config_minidisks', name, disk_list)
def guest_capture(self, name, image_id):
self._reqh.call('guest_capture', name, image_id)
def guest_softstop(self, name, timeout=0, retry_interval=0):
self._reqh.call('guest_softstop', name, timeout=timeout,
poll_interval=retry_interval)
def guest_pause(self, name):
self._reqh.call('guest_pause', name)
def guest_unpause(self, name):
self._reqh.call('guest_unpause', name)
def guest_reboot(self, name):
self._reqh.call('guest_reboot', name)
def guest_reset(self, name):
self._reqh.call('guest_reset', name)
def guest_get_console_output(self, name):
"""get console out put of the given instance
:returns: The output of the console of the instace, in string format.
"""
return self._reqh.call('guest_get_console_output', name)
def image_query(self, imagename):
"""Check whether image is there or not
:returns: Query the image and returns a dict of the image info
if the image exists or return {}
"""
return self._reqh.call('image_query', imagename=imagename)
def image_get_root_disk_size(self, imagename):
"""Get the root disk size of image
:returns: return the size (in string) about the root disk of image
"""
return self._reqh.call('image_get_root_disk_size', imagename)
def image_import(self, image_href, image_url, image_meta):
self._reqh.call('image_import', image_href, image_url,
image_meta, remote_host=self._rhost)
def image_export(self, image_id, dest_path):
"""export image to a given place
:returns: a dict which represent the exported image information.
"""
resp = self._reqh.call('image_export', image_id,
dest_path, remote_host=self._rhost)
return resp
def image_delete(self, image_id):
self._reqh.call('image_delete', image_id)