nova-powervm/nova_powervm/virt/powervm/vios.py

140 lines
4.6 KiB
Python

# Copyright 2015 IBM Corp.
#
# All Rights Reserved.
#
# 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 abc
from oslo.config import cfg
from oslo_log import log as logging
import six
from nova.i18n import _LE
from pypowervm import exceptions as pvm_exc
from pypowervm.wrappers import constants as pvm_consts
from pypowervm.wrappers import logical_partition as pvm_lpar
from pypowervm.wrappers import virtual_io_server as pvm_vios
vios_opts = [
cfg.StrOpt('vios_name',
default='',
help='VIOS to use for I/O operations.')
]
LOG = logging.getLogger(__name__)
CONF = cfg.CONF
CONF.register_opts(vios_opts)
@six.add_metaclass(abc.ABCMeta)
class AbstractVIOSException(Exception):
def __init__(self, **kwds):
msg = self.msg_fmt % kwds
super(AbstractVIOSException, self).__init__(msg)
class VIOSNotFound(AbstractVIOSException):
msg_fmt = _LE('Unable to locate the Virtual I/O Server \'%(vios_name)s\''
' for this operation.')
def get_vios_uuid(adapter, name):
searchstring = "(PartitionName=='%s')" % name
try:
resp = adapter.read(pvm_consts.VIOS,
suffix_type='search',
suffix_parm=searchstring)
except pvm_exc.Error as e:
if e.response.status == 404:
raise VIOSNotFound(vios_name=name)
else:
LOG.exception(e)
raise
except Exception as e:
LOG.exception(e)
raise
entry = resp.feed.entries[0]
uuid = entry.properties['id']
return uuid
def get_vios_entry(adapter, vios_uuid, vios_name):
try:
resp = adapter.read(pvm_consts.VIOS, root_id=vios_uuid)
except pvm_exc.Error as e:
if e.response.status == 404:
raise VIOSNotFound(vios_name=vios_name)
else:
LOG.exception(e)
raise
except Exception as e:
LOG.exception(e)
raise
return resp.entry, resp.headers['etag']
def get_vscsi_mappings(adapter, lpar_uuid, vio_wrapper, mapping_type):
"""Returns a list of VirtualSCSIMaps that pair to the instance.
:param adapter: The pypowervm API Adapter.
:param lpar_uuid: The lpar UUID that identifies which system to get the
storage mappings for.
:param vio_wrapper: The VIOS pypowervm wrapper for the VIOS. Should have
the mappings within it.
:param mapping_type: The type of mapping to look for. Typically
VirtualOpticalMedia or VirtualDisk
:returns: A list of vSCSI Mappings (pypowervm wrapper) from the VIOS
that are tied to the lpar, for the mapping type.
"""
# Quick read of the partition ID. Identifier between LPAR and VIOS
partition_id = adapter.read(pvm_lpar.LPAR_ROOT, root_id=lpar_uuid,
suffix_type='quick',
suffix_parm='PartitionID').body
# The return list is the Virtual SCSI Mapping wrappers
vscsi_maps = []
# Find all of the maps that match up to our partition
for scsi_map in vio_wrapper.scsi_mappings:
# If no client, it can't match us...
if scsi_map.client_adapter is None:
continue
# If the ID doesn't match up, not a valid one.
if scsi_map.client_adapter.lpar_id != partition_id:
continue
# Check to see if the mapping is to a vopt
if (scsi_map.backing_storage is None or
not isinstance(scsi_map.backing_storage, mapping_type)):
continue
vscsi_maps.append(scsi_map)
return vscsi_maps
def add_vscsi_mapping(adapter, vios_uuid, vios_name, scsi_map):
# Get the VIOS Entry
vios_entry, etag = get_vios_entry(adapter, vios_uuid, vios_name)
# Wrap the entry
vios_wrap = pvm_vios.VirtualIOServer(vios_entry)
# Add the new mapping to the end
vios_wrap.scsi_mappings.append(pvm_vios.VirtualSCSIMapping(scsi_map))
# Write it back to the VIOS
adapter.update(vios_wrap._entry.element, etag,
pvm_consts.VIOS, vios_uuid, xag=None)