Source code for openlmi.storage.LMI_LVStorageCapabilities

# Copyright (C) 2012 Red Hat, Inc.  All rights reserved.
#
# 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
#
# Authors: Jan Safranek <jsafrane@redhat.com>
# -*- coding: utf-8 -*-
""""
Module for LMI_LVStorageCapabilities class.

LMI_LVStorageCapabilities
-------------------------

.. autoclass:: LMI_LVStorageCapabilities
    :members:

LMI_LVElementCapabilities
-------------------------

.. autoclass:: LMI_LVElementCapabilities
    :members:

"""

from openlmi.storage.CapabilitiesProvider import CapabilitiesProvider
import openlmi.common.cmpi_logging as cmpi_logging
from openlmi.storage.SettingManager import StorageSetting
import pywbem
import blivet.devices
from openlmi.storage.BaseProvider import BaseProvider
from openlmi.storage.util import storage

[docs]class LMI_LVStorageCapabilities(CapabilitiesProvider): """ Provider of LMI_LVStorageCapabilities class.""" @cmpi_logging.trace_method
[docs] def __init__(self, *args, **kwargs): super(LMI_LVStorageCapabilities, self).__init__( classname='LMI_LVStorageCapabilities', *args, **kwargs) self.pool_provider = None
@cmpi_logging.trace_method
[docs] def get_pool_name_for_capabilities(self, instance_id): """ Return CIMInstanceName of storage pool associated with capabilities with given id. """ path = self.parse_instance_id(instance_id) if not path: return None device = storage.get_device_for_persistent_name(self.storage, path) if not device: return None if not isinstance(device, blivet.devices.LVMVolumeGroupDevice): cmpi_logging.logger.trace_warn( "InstanceID %s is not LVMVolumeGroupDevice" % instance_id) return None if not self.pool_provider: self.pool_provider = self.provider_manager.get_provider_for_device( device) return self.pool_provider.get_name_for_device(device)
@cmpi_logging.trace_method def _get_capabilities_for_device(self, device): """ Return capabilities fir given device. """ if not self.pool_provider: self.pool_provider = self.provider_manager.get_provider_for_device( device) redundancy = self.pool_provider.get_redundancy(device) caps = {} _id = storage.get_persistent_name(device) caps['InstanceID'] = self.create_capabilities_id(_id) caps['ElementName'] = device.path caps['DataRedundancyDefault'] = \ pywbem.Uint16(redundancy.data_redundancy) caps['DataRedundancyMax'] = pywbem.Uint16(redundancy.data_redundancy) caps['DataRedundancyMin'] = pywbem.Uint16(redundancy.data_redundancy) caps['NoSinglePointOfFailure'] = redundancy.no_single_point_of_failure caps['NoSinglePointOfFailureDefault'] = \ redundancy.no_single_point_of_failure caps['ExtentStripeLengthDefault'] = \ pywbem.Uint16(redundancy.stripe_length) caps['PackageRedundancyDefault'] = \ pywbem.Uint16(redundancy.package_redundancy) caps['PackageRedundancyMax'] = pywbem.Uint16( redundancy.package_redundancy) caps['PackageRedundancyMin'] = pywbem.Uint16( redundancy.package_redundancy) if redundancy.parity_layout: caps['ParityLayoutDefault'] = pywbem.Uint16( redundancy.parity_layout + 1) else: caps['ParityLayoutDefault'] = None return caps @cmpi_logging.trace_method
[docs] def enumerate_capabilities(self): """ Return an iterable with all capabilities instances, i.e. dictionaries property_name -> value. If the capabilities are the default ones, it must have '_default' as a property name. Subclasses must override this method. """ for vg in self.storage.vgs: yield self._get_capabilities_for_device(vg)
@cmpi_logging.trace_method
[docs] def create_setting_for_capabilities(self, capabilities): """ Create LMI_*Setting for given capabilities. Return CIMInstanceName of the setting or raise CIMError on error. """ setting_id = self.setting_manager.allocate_id( 'LMI_LVStorageSetting') if not setting_id: raise pywbem.CIMError(pywbem.CIM_ERR_FAILED, "Failed to allocate setting InstanceID") setting = self.setting_manager.create_setting( 'LMI_LVStorageSetting', StorageSetting.TYPE_TRANSIENT, setting_id, class_to_create=StorageSetting) setting['DataRedundancyGoal'] = capabilities['DataRedundancyDefault'] setting['DataRedundancyMax'] = capabilities['DataRedundancyDefault'] setting['DataRedundancyMin'] = capabilities['DataRedundancyDefault'] setting['ExtentStripeLength'] = \ capabilities['ExtentStripeLengthDefault'] setting['ExtentStripeLengthMax'] = \ capabilities['ExtentStripeLengthDefault'] setting['ExtentStripeLengthMin'] = \ capabilities['ExtentStripeLengthDefault'] setting['NoSinglePointOfFailure'] = \ capabilities['NoSinglePointOfFailure'] setting['PackageRedundancyGoal'] = \ capabilities['PackageRedundancyDefault'] setting['PackageRedundancyMax'] = \ capabilities['PackageRedundancyDefault'] setting['PackageRedundancyMin'] = \ capabilities['PackageRedundancyDefault'] setting['ElementName'] = 'CreatedFrom' + capabilities['InstanceID'] if capabilities['ParityLayoutDefault']: setting['ParityLayout'] = capabilities['ParityLayoutDefault'] - 1 else: setting['ParityLayout'] = None self.setting_manager.set_setting('LMI_LVStorageSetting', setting) return pywbem.CIMInstanceName( classname='LMI_LVStorageSetting', namespace=self.config.namespace, keybindings={'InstanceID': setting_id})
@cmpi_logging.trace_method
[docs] def get_capabilities_for_id(self, instance_id): """ Return dictionary property_name -> value. If the capabilities are the default ones, it must have '_default' as a property name. Return None if there is no such Capabilities instance. Subclasses can override this method. """ path = self.parse_instance_id(instance_id) if not path: return None device = storage.get_device_for_persistent_name(self.storage, path) if not device: return None if not isinstance(device, blivet.devices.LVMVolumeGroupDevice): cmpi_logging.logger.trace_warn( "InstanceID %s is not LVMVolumeGroupDevice" % instance_id) return None return self._get_capabilities_for_device(device)
@cmpi_logging.trace_method # pylint: disable-msg=W0221
[docs] def cim_method_createsetting(self, env, object_name, param_settingtype=None): """ Implements LMI_LVStorageCapabilities.CreateSetting() Create LMI_LVStorageSetting applicable to this VG All properties its will have default values. """ # just check param_settingtype if param_settingtype: setting_type = self.Values.CreateSetting.SettingType if (param_settingtype != setting_type.Default and param_settingtype != setting_type.Goal): raise pywbem.CIMError(pywbem.CIM_ERR_FAILED, "Wrong value of SettingType parameter.") (retval, outvars) = super(LMI_LVStorageCapabilities, self)\ .cim_method_createsetting(env, object_name) # rename output param from 'setting' to 'newsetting' if outvars and outvars[0].name == "setting": outvars = [pywbem.CIMParameter('newsetting', type='reference', value=outvars[0].value)] return (retval, outvars)
@cmpi_logging.trace_method
[docs] def cim_method_createlvstoragesetting(self, env, object_name): """ Implements LMI_LVStorageCapabilities.CreateLVStorageSetting() This method creates new instance of LMI_LVStorageSetting. Applications then do not need to calculate DataRedundancy, PackageRedundancy and ExtentStripeLength. Because only basic Logical Volumes without any additional stripping or mirroring are supported, this method basically clones LMI_VGStorageSetting to LMI_LVStorageSetting. """ return super(LMI_LVStorageCapabilities, self).cim_method_createsetting( env, object_name)
class Values(CapabilitiesProvider.Values): class CreateSetting(object): Success = pywbem.Uint32(0) Not_Supported = pywbem.Uint32(1) Unspecified_Error = pywbem.Uint32(2) Timeout = pywbem.Uint32(3) Failed = pywbem.Uint32(4) Invalid_Parameter = pywbem.Uint32(5) # DMTF_Reserved = .. # Vendor_Specific = 32768..65535 class SettingType(object): Default = pywbem.Uint16(2) Goal = pywbem.Uint16(3)
[docs]class LMI_LVElementCapabilities(BaseProvider): """ Base class for LMI_*ElementCapabilities providers. If all capabilities instances are associated only with appropriate LMI_*Service, this class does not need to be subclasses. Otherwise, subclasses can associate capabilities to other managed elements. """ @cmpi_logging.trace_method
[docs] def __init__(self, classname, capabilities_provider, device_provider, *args, **kwargs): self.classname = classname self.capabilities_provider = capabilities_provider self.device_provider = device_provider super(LMI_LVElementCapabilities, self).__init__(*args, **kwargs)
@cmpi_logging.trace_method
[docs] def enumerate_capabilities(self): """ Return iterable with (managed_element_name, capabilities_name), where managed_element_name and capabilities_name are CIMInstanceName. By default, all capabilities provided by capabilities_provider are associated to service_provider. Subclasses can override this method if different behavior is requested. """ for capabilities in self.capabilities_provider.enumerate_capabilities(): provider = self.capabilities_provider managed_element_name = provider.get_pool_name_for_capabilities( capabilities['InstanceID']) capabilities_name = pywbem.CIMInstanceName( classname=self.capabilities_provider.classname, namespace=self.config.namespace, keybindings={'InstanceID' : capabilities['InstanceID']}) yield (managed_element_name, capabilities_name)
@cmpi_logging.trace_method
[docs] def enum_instances(self, env, model, keys_only): """ Provider implementation of EnumerateInstances intrinsic method. """ model.path.update({'Capabilities': None, 'ManagedElement': None}) for (managed_element, capabilities) in self.enumerate_capabilities(): model['Capabilities'] = capabilities model['ManagedElement'] = managed_element if keys_only: yield model else: yield self.get_instance(env, model, capabilities)
@cmpi_logging.trace_method # pylint: disable-msg=W0221
[docs] def get_instance(self, env, model, capabilities_name=None): """ Provider implementation of GetInstance intrinsic method. """ # find the capabilities instance instance_id = None if not capabilities_name: capabilities = self.capabilities_provider.get_capabilities_for_id( model['Capabilities']['InstanceID']) if not capabilities: raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND, "Capabilities not found.") instance_id = capabilities['InstanceID'] else: instance_id = capabilities_name['InstanceID'] name = self.capabilities_provider.get_pool_name_for_capabilities( instance_id) if not name: raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND, "Cannot find StoragePool for Capabilities.") if name['InstanceID'] != model['ManagedElement']['InstanceID']: raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND, "ManagedElement is not associated to Capabilities.") return model
@cmpi_logging.trace_method
[docs] def references(self, env, object_name, model, result_class_name, role, result_role, keys_only): """Instrument Associations. """ return self.simple_references(env, object_name, model, result_class_name, role, result_role, keys_only, "CIM_Capabilities", "CIM_ManagedElement")
class Values(object): class Characteristics(object): Default = pywbem.Uint16(2) Current = pywbem.Uint16(3) # DMTF_Reserved = .. # Vendor_Specific = 32768..65535