import contextlib
import datetime
+import mock
import os
import shutil
import socket
import tempfile
import eventlet
-import mock
import mox
from oslo.config import cfg
from stevedore import extension
from cinder import keymgr
from cinder.openstack.common import fileutils
from cinder.openstack.common import importutils
+from cinder.openstack.common import jsonutils
from cinder.openstack.common.notifier import api as notifier_api
from cinder.openstack.common.notifier import test_notifier
from cinder.openstack.common import rpc
from cinder.volume import configuration as conf
from cinder.volume import driver
from cinder.volume.drivers import lvm
+from cinder.volume.manager import VolumeManager
from cinder.volume import rpcapi as volume_rpcapi
from cinder.volume import utils as volutils
from cinder.volume import volume_types
self.context,
volume['id'])
+ def test_extra_capabilities(self):
+ # Test valid extra_capabilities.
+ fake_capabilities = {'key1': 1, 'key2': 2}
+
+ with mock.patch.object(jsonutils, 'loads') as mock_loads:
+ mock_loads.return_value = fake_capabilities
+ manager = VolumeManager()
+ manager.driver.set_initialized()
+ manager.publish_service_capabilities(self.context)
+ self.assertTrue(mock_loads.called)
+ volume_stats = manager.last_capabilities
+ self.assertEqual(volume_stats['key1'],
+ fake_capabilities['key1'])
+ self.assertEqual(volume_stats['key2'],
+ fake_capabilities['key2'])
+
+ def test_extra_capabilities_fail(self):
+ with mock.patch.object(jsonutils, 'loads') as mock_loads:
+ mock_loads.side_effect = exception.CinderException('test')
+ self.assertRaises(exception.CinderException, VolumeManager)
+
def test_delete_busy_volume(self):
"""Test volume survives deletion if driver reports it as busy."""
volume = tests_utils.create_volume(self.context, **self.volume_params)
from cinder import manager
from cinder.openstack.common import excutils
from cinder.openstack.common import importutils
+from cinder.openstack.common import jsonutils
from cinder.openstack.common import log as logging
from cinder.openstack.common import periodic_task
from cinder.openstack.common import timeutils
cfg.StrOpt('zoning_mode',
default='none',
help='FC Zoning mode configured'),
+ cfg.StrOpt('extra_capabilities',
+ default='{}',
+ help='User defined capabilities, a JSON formatted string '
+ 'specifying key/value pairs.'),
]
CONF = cfg.CONF
host=self.host)
self.zonemanager = None
+ try:
+ self.extra_capabilities = jsonutils.loads(
+ self.driver.configuration.extra_capabilities)
+ except AttributeError:
+ self.extra_capabilities = {}
+ except Exception:
+ with excutils.save_and_reraise_exception():
+ LOG.error("Invalid JSON: %s" %
+ self.driver.configuration.extra_capabilities)
def _add_to_threadpool(self, func, *args, **kwargs):
self._tp.spawn_n(func, *args, **kwargs)
'config_group': config_group})
else:
volume_stats = self.driver.get_volume_stats(refresh=True)
+ if self.extra_capabilities:
+ volume_stats.update(self.extra_capabilities)
if volume_stats:
# Append volume stats with 'allocated_capacity_gb'
volume_stats.update(self.stats)