VMware: add support for default pbm policy
This is part of the blueprint vmware-spbm-support.
If there is no defined storage policy in the flavor then the default
storage policy will be used. This patch set adds in the definition of
the default storage policy and validates it existence when the service
starts.
DocImpact
- pbm_enabled - enables storage policy based placement
- pbm_default_policy - the default policy that will be used if there
is none in the flavor
- pbm_wsdl_location (optional) - PBM service WSDL file location URL.
e.g. file:///opt/SDK/spbm/wsdl/pbmService.wsdl.
Co-authored-by: Radoslav Gerganov <rgerganov@vmware.com>
Change-Id: I1fc5a99c153d815ea735dccda9d2958dba52ec49
This commit is contained in:
@@ -31,6 +31,7 @@ from oslo.config import cfg
|
||||
from oslo.utils import timeutils
|
||||
from oslo.utils import units
|
||||
from oslo.vmware import exceptions as vexc
|
||||
from oslo.vmware import pbm
|
||||
from oslo.vmware import vim
|
||||
import suds
|
||||
|
||||
@@ -116,6 +117,8 @@ def _fake_create_session(inst):
|
||||
session = vmwareapi_fake.DataObject()
|
||||
session.key = 'fake_key'
|
||||
session.userName = 'fake_username'
|
||||
session._pbm_wsdl_loc = None
|
||||
session._pbm = None
|
||||
inst._session = session
|
||||
|
||||
|
||||
@@ -317,6 +320,28 @@ class VMwareAPIVMTestCase(test.NoDBTestCase):
|
||||
self.assertTrue(self.conn.capabilities['has_imagecache'])
|
||||
self.assertFalse(self.conn.capabilities['supports_recreate'])
|
||||
|
||||
def test_configuration_linked_clone(self):
|
||||
self.flags(use_linked_clone=None, group='vmware')
|
||||
self.assertRaises(error_util.UseLinkedCloneConfigurationFault,
|
||||
self.conn._validate_configuration)
|
||||
|
||||
@mock.patch.object(pbm, 'get_profile_id_by_name')
|
||||
def test_configuration_pbm(self, get_profile_mock):
|
||||
get_profile_mock.return_value = 'fake-profile'
|
||||
self.flags(pbm_enabled=True,
|
||||
pbm_default_policy='fake-policy',
|
||||
pbm_wsdl_location='fake-location', group='vmware')
|
||||
self.conn._validate_configuration()
|
||||
|
||||
@mock.patch.object(pbm, 'get_profile_id_by_name')
|
||||
def test_configuration_pbm_bad_default(self, get_profile_mock):
|
||||
get_profile_mock.return_value = None
|
||||
self.flags(pbm_enabled=True,
|
||||
pbm_wsdl_location='fake-location',
|
||||
pbm_default_policy='fake-policy', group='vmware')
|
||||
self.assertRaises(error_util.PbmDefaultPolicyDoesNotExist,
|
||||
self.conn._validate_configuration)
|
||||
|
||||
def test_login_retries(self):
|
||||
self.attempts = 0
|
||||
self.login_session = vmwareapi_fake.FakeVim()._login()
|
||||
@@ -2592,3 +2617,11 @@ class VMwareAPIVCDriverTestCase(VMwareAPIVMTestCase):
|
||||
|
||||
def test_finish_revert_migration_power_off(self):
|
||||
self._test_finish_revert_migration(power_on=False)
|
||||
|
||||
def test_pbm_wsdl_location(self):
|
||||
self.flags(pbm_enabled=True,
|
||||
pbm_wsdl_location='fira',
|
||||
group='vmware')
|
||||
self.conn._update_pbm_location()
|
||||
self.assertEqual('fira', self.conn._session._pbm_wsdl_loc)
|
||||
self.assertIsNone(self.conn._session._pbm)
|
||||
|
||||
@@ -23,7 +23,9 @@ import re
|
||||
|
||||
from oslo.config import cfg
|
||||
from oslo.vmware import api
|
||||
from oslo.vmware import pbm
|
||||
from oslo.vmware import vim
|
||||
from oslo.vmware import vim_util
|
||||
import suds
|
||||
|
||||
from nova import exception
|
||||
@@ -79,8 +81,24 @@ vmwareapi_opts = [
|
||||
'work-arounds')
|
||||
]
|
||||
|
||||
spbm_opts = [
|
||||
cfg.BoolOpt('pbm_enabled',
|
||||
default=False,
|
||||
help='The PBM status.'),
|
||||
cfg.StrOpt('pbm_wsdl_location',
|
||||
help='PBM service WSDL file location URL. '
|
||||
'e.g. file:///opt/SDK/spbm/wsdl/pbmService.wsdl '
|
||||
'Not setting this will disable storage policy based '
|
||||
'placement of instances.'),
|
||||
cfg.StrOpt('pbm_default_policy',
|
||||
help='The PBM default policy. If pbm_wsdl_location is set and '
|
||||
'there is no defined storage policy for the specific '
|
||||
'request then this policy will be used.'),
|
||||
]
|
||||
|
||||
CONF = cfg.CONF
|
||||
CONF.register_opts(vmwareapi_opts, 'vmware')
|
||||
CONF.register_opts(spbm_opts, 'vmware')
|
||||
|
||||
TIME_BETWEEN_API_CALL_RETRIES = 1.0
|
||||
|
||||
@@ -136,9 +154,11 @@ class VMwareVCDriver(driver.ComputeDriver):
|
||||
|
||||
self._session = VMwareAPISession(scheme=scheme)
|
||||
|
||||
# TODO(hartsocks): back-off into a configuration test module.
|
||||
if CONF.vmware.use_linked_clone is None:
|
||||
raise error_util.UseLinkedCloneConfigurationFault()
|
||||
# Update the PBM location if necessary
|
||||
if CONF.vmware.pbm_enabled:
|
||||
self._update_pbm_location()
|
||||
|
||||
self._validate_configuration()
|
||||
|
||||
# Get the list of clusters to be used
|
||||
self._cluster_names = CONF.vmware.cluster_name
|
||||
@@ -171,6 +191,33 @@ class VMwareVCDriver(driver.ComputeDriver):
|
||||
self._volumeops = self._resources.get(first_cluster).get('volumeops')
|
||||
self._vc_state = self._resources.get(first_cluster).get('vcstate')
|
||||
|
||||
def _update_pbm_location(self):
|
||||
if CONF.vmware.pbm_wsdl_location:
|
||||
pbm_wsdl_loc = CONF.vmware.pbm_wsdl_location
|
||||
else:
|
||||
version = vim_util.get_vc_version(self._session)
|
||||
pbm_wsdl_loc = pbm.get_pbm_wsdl_location(version)
|
||||
# TODO(garyk): Update this with oslo.vmware method. The session.pbm
|
||||
# is lazy loaded so this enables us to update this entry on the fly
|
||||
self._session._pbm_wsdl_loc = pbm_wsdl_loc
|
||||
self._session._pbm = None
|
||||
|
||||
def _validate_configuration(self):
|
||||
if CONF.vmware.use_linked_clone is None:
|
||||
raise error_util.UseLinkedCloneConfigurationFault()
|
||||
|
||||
if CONF.vmware.pbm_enabled:
|
||||
if not CONF.vmware.pbm_default_policy:
|
||||
raise error_util.PbmDefaultPolicyUnspecified()
|
||||
if not pbm.get_profile_id_by_name(
|
||||
self._session,
|
||||
CONF.vmware.pbm_default_policy):
|
||||
raise error_util.PbmDefaultPolicyDoesNotExist()
|
||||
if CONF.vmware.datastore_regex:
|
||||
LOG.warning(_LW(
|
||||
"datastore_regex is ignored when PBM is enabled"))
|
||||
self._datastore_regex = None
|
||||
|
||||
def init_host(self, host):
|
||||
vim = self._session.vim
|
||||
if vim is None:
|
||||
|
||||
@@ -42,3 +42,11 @@ class NoRootDiskDefined(vexc.VMwareDriverException):
|
||||
|
||||
class TaskInProgress(vexc.VMwareDriverException):
|
||||
msg_fmt = _("Virtual machine is busy.")
|
||||
|
||||
|
||||
class PbmDefaultPolicyUnspecified(VMwareDriverConfigurationException):
|
||||
msg_fmt = _("Default PBM policy is required if PBM is enabled.")
|
||||
|
||||
|
||||
class PbmDefaultPolicyDoesNotExist(VMwareDriverConfigurationException):
|
||||
msg_fmt = _("The default PBM policy doesn't exist on the backend.")
|
||||
|
||||
Reference in New Issue
Block a user