Create a base class for cinder plugins
The purpose of this new class is to ease development for existing and upcoming cinder plugins, for instance, the cookiecutter and solidfire ones. This class makes development much more in line with the existing reactive libraries. Change-Id: I55a849dd11e83e5b2b23efcece6ff8dfa511c96f
This commit is contained in:
parent
79c3414d77
commit
0cf56a3bb2
@ -12,6 +12,8 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import json
|
||||
|
||||
import ops_openstack.core
|
||||
# ch_context needed for bluestore validation
|
||||
import charmhelpers.contrib.openstack.context as ch_context
|
||||
@ -53,3 +55,73 @@ class BaseCephClientCharm(ops_openstack.core.OSBaseCharm):
|
||||
bluestore_compression = None
|
||||
if bluestore_compression:
|
||||
return bluestore_compression.get_kwargs()
|
||||
|
||||
|
||||
class CinderStoragePluginCharm(ops_openstack.core.OSBaseCharm):
|
||||
|
||||
def __init__(self, framework):
|
||||
super().__init__(framework)
|
||||
self.framework.observe(self.on.config_changed, self.on_config)
|
||||
self.framework.observe(
|
||||
self.on.storage_backend_relation_changed,
|
||||
self.on_storage_backend)
|
||||
|
||||
def render_config(self, config, app_name):
|
||||
return json.dumps({
|
||||
"cinder": {
|
||||
"/etc/cinder/cinder.confg": {
|
||||
"sections": {app_name: self.cinder_configuration(config)}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
def set_data(self, data, config, app_name):
|
||||
"""Inform another charm of the backend name and configuration."""
|
||||
data['backend_name'] = config['volume-backend-name'] or app_name
|
||||
data['stateless'] = str(self.stateless)
|
||||
data['active_active'] = str(self.active_active)
|
||||
data['subordinate_configuration'] = self.render_config(
|
||||
config, app_name)
|
||||
|
||||
def on_config(self, event):
|
||||
config = dict(self.framework.model.config)
|
||||
app_name = self.framework.model.app.name
|
||||
for relation in self.framework.model.relations.get('storage-backend'):
|
||||
self.set_data(relation.data[self.unit], config, app_name)
|
||||
self.unit.status = ActiveStatus('Unit is ready')
|
||||
|
||||
def on_storage_backend(self, event):
|
||||
self.set_data(
|
||||
event.relation.data[self.unit],
|
||||
self.framework.model.config,
|
||||
self.framework.model.app.name)
|
||||
|
||||
def cinder_configuration(self, charm_config):
|
||||
"""Entry point for cinder subordinates.
|
||||
|
||||
This method should return a list of 2-element tuples, where the
|
||||
first element is the configuration key, and the second, its value."""
|
||||
|
||||
raise NotImplementedError()
|
||||
|
||||
@property
|
||||
def stateless(self):
|
||||
"""Indicate whether the charm is stateless.
|
||||
|
||||
For more information, see: https://cinderlib.readthedocs.io/en/v0.2.1/topics/serialization.html
|
||||
|
||||
:returns: A boolean value indicating statefulness.
|
||||
:rtype: bool
|
||||
""" # noqa
|
||||
return False
|
||||
|
||||
@property
|
||||
def active_active(self):
|
||||
"""Indicate active-active support in the charm.
|
||||
|
||||
For more information, see: https://specs.openstack.org/openstack/cinder-specs/specs/mitaka/cinder-volume-active-active-support.html
|
||||
|
||||
:returns: A boolean indicating active-active support.
|
||||
:rtype: bool
|
||||
""" # noqa
|
||||
return False
|
||||
|
@ -103,3 +103,50 @@ class TestBaseCephClientCharm(CharmTestCase):
|
||||
self.assertIsInstance(
|
||||
self.harness.charm.unit.status,
|
||||
BlockedStatus)
|
||||
|
||||
|
||||
class CinderCharm(ops_openstack.plugins.classes.CinderStoragePluginCharm):
|
||||
|
||||
def cinder_configuration(self, cinder_config):
|
||||
return [('volume_driver', 'my-driver'),
|
||||
('some-config', 'some-value')]
|
||||
|
||||
|
||||
class TestBaseCinderCharm(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.harness = Harness(
|
||||
CinderCharm,
|
||||
meta='''
|
||||
name: cinder-test
|
||||
provides:
|
||||
storage-backend:
|
||||
interface: cinder-backend
|
||||
scope: container
|
||||
requires:
|
||||
juju-info:
|
||||
interface: juju-info
|
||||
scope: container
|
||||
''',
|
||||
config='''
|
||||
options:
|
||||
volume-backend-name:
|
||||
default: ""
|
||||
type: string
|
||||
'''
|
||||
)
|
||||
self.addCleanup(self.harness.cleanup)
|
||||
self.harness.begin()
|
||||
self.harness.set_leader(True)
|
||||
backend = self.harness.add_relation('storage-backend', 'cinder')
|
||||
self.harness.update_config({'volume-backend-name': 'test'})
|
||||
self.harness.add_relation_unit(backend, 'cinder/0')
|
||||
|
||||
def test_cinder_base(self):
|
||||
self.assertEqual(self.harness.framework.model.app.name, 'cinder-test')
|
||||
self.harness.update_config({})
|
||||
self.assertTrue(isinstance(self.harness.model.unit.status,
|
||||
ActiveStatus))
|
||||
config = self.harness.charm.cinder_configuration({})
|
||||
self.assertTrue(config[0], ('volume_driver', 'my-driver'))
|
||||
self.assertTrue(config[1], ('some-config', 'some-value'))
|
||||
|
Loading…
x
Reference in New Issue
Block a user