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:
Gary Kotton
2014-08-20 16:17:01 +03:00
parent 4ebd70433f
commit 7ad0a79a4d
3 changed files with 91 additions and 3 deletions

View File

@@ -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)

View File

@@ -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:

View File

@@ -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.")