Revert "Add OPS framework interface"
This reverts commit 1730dfe3fd
.
Reason for revert: Causing issues with reactive charms
Change-Id: Ib529b973ba8856348b0bd7383d403ceb28f235d5
This commit is contained in:
parent
1730dfe3fd
commit
73d507e04a
|
@ -11,5 +11,3 @@ ignore:
|
||||||
- 'tox.ini'
|
- 'tox.ini'
|
||||||
- 'unit_tests'
|
- 'unit_tests'
|
||||||
- '.zuul.yaml'
|
- '.zuul.yaml'
|
||||||
- 'setup.cfg'
|
|
||||||
- 'setup.py'
|
|
||||||
|
|
|
@ -1,109 +0,0 @@
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
# Copyright 2021 Ubuntu
|
|
||||||
# See LICENSE file for licensing details.
|
|
||||||
|
|
||||||
import hashlib
|
|
||||||
import json
|
|
||||||
import interface_hacluster.common as common
|
|
||||||
|
|
||||||
from ops.framework import (
|
|
||||||
StoredState,
|
|
||||||
EventBase,
|
|
||||||
ObjectEvents,
|
|
||||||
EventSource,
|
|
||||||
Object)
|
|
||||||
|
|
||||||
|
|
||||||
class HAServiceReadyEvent(EventBase):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class HAServiceEvents(ObjectEvents):
|
|
||||||
ha_ready = EventSource(HAServiceReadyEvent)
|
|
||||||
|
|
||||||
|
|
||||||
class HAServiceRequires(Object, common.ResourceManagement):
|
|
||||||
|
|
||||||
on = HAServiceEvents()
|
|
||||||
_stored = StoredState()
|
|
||||||
|
|
||||||
def __init__(self, charm, relation_name):
|
|
||||||
super().__init__(charm, relation_name)
|
|
||||||
self.relation_name = relation_name
|
|
||||||
self.framework.observe(
|
|
||||||
charm.on[self.relation_name].relation_changed,
|
|
||||||
self._on_relation_changed)
|
|
||||||
self._stored.set_default(
|
|
||||||
resources={})
|
|
||||||
|
|
||||||
def get_local(self, key, default=None):
|
|
||||||
key = '%s.%s' % ('local-data', key)
|
|
||||||
json_value = getattr(self._stored, key, None)
|
|
||||||
if json_value:
|
|
||||||
return json.loads(json_value)
|
|
||||||
if default:
|
|
||||||
return default
|
|
||||||
return None
|
|
||||||
|
|
||||||
def set_local(self, key=None, value=None, data=None, **kwdata):
|
|
||||||
if data is None:
|
|
||||||
data = {}
|
|
||||||
if key is not None:
|
|
||||||
data[key] = value
|
|
||||||
data.update(kwdata)
|
|
||||||
if not data:
|
|
||||||
return
|
|
||||||
for k, v in data.items():
|
|
||||||
setattr(
|
|
||||||
self._stored,
|
|
||||||
'local-data.{}'.format(k),
|
|
||||||
json.dumps(v))
|
|
||||||
|
|
||||||
def _on_relation_changed(self, event):
|
|
||||||
if self.is_clustered():
|
|
||||||
self.on.ha_ready.emit()
|
|
||||||
|
|
||||||
def data_changed(self, data_id, data, hash_type='md5'):
|
|
||||||
key = 'data_changed.%s' % data_id
|
|
||||||
alg = getattr(hashlib, hash_type)
|
|
||||||
serialized = json.dumps(data, sort_keys=True).encode('utf8')
|
|
||||||
old_hash = self.get_local(key)
|
|
||||||
new_hash = alg(serialized).hexdigest()
|
|
||||||
self.set_local(key, new_hash)
|
|
||||||
return old_hash != new_hash
|
|
||||||
|
|
||||||
def set_remote(self, key=None, value=None, data=None, **kwdata):
|
|
||||||
if data is None:
|
|
||||||
data = {}
|
|
||||||
if key is not None:
|
|
||||||
data[key] = value
|
|
||||||
data.update(kwdata)
|
|
||||||
if not data:
|
|
||||||
return
|
|
||||||
for relation in self.framework.model.relations[self.relation_name]:
|
|
||||||
for k, v in data.items():
|
|
||||||
# The reactive framework copes with integer values but the ops
|
|
||||||
# framework insists on strings so convert them.
|
|
||||||
if isinstance(v, int):
|
|
||||||
v = str(v)
|
|
||||||
relation.data[self.model.unit][k] = v
|
|
||||||
|
|
||||||
def get_remote_all(self, key, default=None):
|
|
||||||
"""Return a list of all values presented by remote units for key"""
|
|
||||||
values = []
|
|
||||||
for relation in self.framework.model.relations[self.relation_name]:
|
|
||||||
for unit in relation.units:
|
|
||||||
value = relation.data[unit].get(key)
|
|
||||||
if value:
|
|
||||||
values.append(value)
|
|
||||||
return list(set(values))
|
|
18
setup.cfg
18
setup.cfg
|
@ -1,18 +0,0 @@
|
||||||
[metadata]
|
|
||||||
name = interface_hacluster
|
|
||||||
summary = Charm interface for Hacluster using Operator Framework
|
|
||||||
version = 0.0.1.dev1
|
|
||||||
description-file =
|
|
||||||
README.rst
|
|
||||||
author = OpenStack Charmers
|
|
||||||
author-email = openstack-charmers@lists.ubuntu.com
|
|
||||||
url = https://github.com/openstack/charm-interface-hacluster.git
|
|
||||||
classifier =
|
|
||||||
Development Status :: 2 - Pre-Alpha
|
|
||||||
Intended Audience :: Developers
|
|
||||||
Topic :: System
|
|
||||||
Topic :: System :: Installation/Setup
|
|
||||||
opic :: System :: Software Distribution
|
|
||||||
Programming Language :: Python :: 3
|
|
||||||
Programming Language :: Python :: 3.5
|
|
||||||
License :: OSI Approved :: Apache Software License
|
|
38
setup.py
38
setup.py
|
@ -1,38 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# Copyright 2021 Canonical Ltd.
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
|
|
||||||
"""Module used to setup the interface_hacluster framework."""
|
|
||||||
|
|
||||||
from __future__ import print_function
|
|
||||||
|
|
||||||
from setuptools import setup, find_packages
|
|
||||||
|
|
||||||
version = "0.0.1.dev1"
|
|
||||||
install_require = [
|
|
||||||
'charmhelpers',
|
|
||||||
'ops',
|
|
||||||
]
|
|
||||||
|
|
||||||
tests_require = [
|
|
||||||
'tox >= 2.3.1',
|
|
||||||
]
|
|
||||||
|
|
||||||
setup(
|
|
||||||
license='Apache-2.0: http://www.apache.org/licenses/LICENSE-2.0',
|
|
||||||
packages=find_packages(exclude=["unit_tests"]),
|
|
||||||
zip_safe=False,
|
|
||||||
install_requires=install_require,
|
|
||||||
)
|
|
|
@ -4,4 +4,3 @@ stestr>=2.2.0
|
||||||
charms.reactive
|
charms.reactive
|
||||||
coverage>=3.6
|
coverage>=3.6
|
||||||
netifaces
|
netifaces
|
||||||
git+https://github.com/canonical/operator.git#egg=ops
|
|
||||||
|
|
|
@ -1,158 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
# Copyright 2021 Ubuntu
|
|
||||||
# See LICENSE file for licensing details.
|
|
||||||
|
|
||||||
import unittest
|
|
||||||
import sys
|
|
||||||
sys.path.append('.') # noqa
|
|
||||||
from ops.testing import Harness
|
|
||||||
from ops.charm import CharmBase
|
|
||||||
import interface_hacluster.ops_ha_interface as ops_ha_interface
|
|
||||||
|
|
||||||
|
|
||||||
class HAServiceRequires(unittest.TestCase):
|
|
||||||
|
|
||||||
class MyCharm(CharmBase):
|
|
||||||
|
|
||||||
def __init__(self, *args):
|
|
||||||
super().__init__(*args)
|
|
||||||
self.seen_events = []
|
|
||||||
self.ha = ops_ha_interface.HAServiceRequires(self, 'ha')
|
|
||||||
|
|
||||||
self.framework.observe(
|
|
||||||
self.ha.on.ha_ready,
|
|
||||||
self._log_event)
|
|
||||||
|
|
||||||
def _log_event(self, event):
|
|
||||||
self.seen_events.append(type(event).__name__)
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
super().setUp()
|
|
||||||
self.harness = Harness(
|
|
||||||
self.MyCharm,
|
|
||||||
meta='''
|
|
||||||
name: my-charm
|
|
||||||
requires:
|
|
||||||
ha:
|
|
||||||
interface: hacluster
|
|
||||||
scope: container
|
|
||||||
'''
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_local_vars(self):
|
|
||||||
self.harness.begin()
|
|
||||||
self.harness.charm.ha.set_local('a', 'b')
|
|
||||||
self.assertEqual(
|
|
||||||
self.harness.charm.ha.get_local('a'),
|
|
||||||
'b')
|
|
||||||
self.harness.charm.ha.set_local(**{'c': 'd', 'e': 'f'})
|
|
||||||
self.assertEqual(
|
|
||||||
self.harness.charm.ha.get_local('c'),
|
|
||||||
'd')
|
|
||||||
self.assertEqual(
|
|
||||||
self.harness.charm.ha.get_local('e'),
|
|
||||||
'f')
|
|
||||||
self.harness.charm.ha.set_local(data={'g': 'h', 'i': 'j'})
|
|
||||||
self.assertEqual(
|
|
||||||
self.harness.charm.ha.get_local('g'),
|
|
||||||
'h')
|
|
||||||
self.assertEqual(
|
|
||||||
self.harness.charm.ha.get_local('i'),
|
|
||||||
'j')
|
|
||||||
|
|
||||||
def test_remote_vars(self):
|
|
||||||
self.harness.begin()
|
|
||||||
rel_id = self.harness.add_relation(
|
|
||||||
'ha',
|
|
||||||
'hacluster')
|
|
||||||
self.harness.add_relation_unit(
|
|
||||||
rel_id,
|
|
||||||
'hacluster/0')
|
|
||||||
self.harness.charm.ha.set_remote('a', 'b')
|
|
||||||
rel_data = self.harness.get_relation_data(
|
|
||||||
rel_id,
|
|
||||||
'my-charm/0')
|
|
||||||
self.assertEqual(rel_data, {'a': 'b'})
|
|
||||||
|
|
||||||
def test_get_remote_all(self):
|
|
||||||
self.harness.begin()
|
|
||||||
rel_id1 = self.harness.add_relation(
|
|
||||||
'ha',
|
|
||||||
'hacluster-a')
|
|
||||||
self.harness.add_relation_unit(
|
|
||||||
rel_id1,
|
|
||||||
'hacluster-a/0')
|
|
||||||
self.harness.update_relation_data(
|
|
||||||
rel_id1,
|
|
||||||
'hacluster-a/0',
|
|
||||||
{'fruit': 'banana'})
|
|
||||||
self.harness.add_relation_unit(
|
|
||||||
rel_id1,
|
|
||||||
'hacluster-a/1')
|
|
||||||
self.harness.update_relation_data(
|
|
||||||
rel_id1,
|
|
||||||
'hacluster-a/1',
|
|
||||||
{'fruit': 'orange'})
|
|
||||||
rel_id2 = self.harness.add_relation(
|
|
||||||
'ha',
|
|
||||||
'hacluster-b')
|
|
||||||
self.harness.add_relation_unit(
|
|
||||||
rel_id2,
|
|
||||||
'hacluster-b/0')
|
|
||||||
self.harness.update_relation_data(
|
|
||||||
rel_id2,
|
|
||||||
'hacluster-b/0',
|
|
||||||
{'fruit': 'grape'})
|
|
||||||
self.harness.add_relation_unit(
|
|
||||||
rel_id2,
|
|
||||||
'hacluster-b/1')
|
|
||||||
self.harness.update_relation_data(
|
|
||||||
rel_id2,
|
|
||||||
'hacluster-b/1',
|
|
||||||
{'veg': 'carrot'})
|
|
||||||
self.assertEqual(
|
|
||||||
self.harness.charm.ha.get_remote_all('fruit'),
|
|
||||||
['orange', 'grape', 'banana'])
|
|
||||||
|
|
||||||
def test_ha_ready(self):
|
|
||||||
self.harness.begin()
|
|
||||||
self.assertEqual(
|
|
||||||
self.harness.charm.seen_events,
|
|
||||||
[])
|
|
||||||
rel_id = self.harness.add_relation(
|
|
||||||
'ha',
|
|
||||||
'hacluster')
|
|
||||||
self.harness.add_relation_unit(
|
|
||||||
rel_id,
|
|
||||||
'hacluster/0')
|
|
||||||
self.harness.update_relation_data(
|
|
||||||
rel_id,
|
|
||||||
'hacluster/0',
|
|
||||||
{'clustered': 'yes'})
|
|
||||||
self.assertEqual(
|
|
||||||
self.harness.charm.seen_events,
|
|
||||||
['HAServiceReadyEvent'])
|
|
||||||
|
|
||||||
def test_data_changed(self):
|
|
||||||
self.harness.begin()
|
|
||||||
self.assertTrue(
|
|
||||||
self.harness.charm.ha.data_changed(
|
|
||||||
'relation-data', {'a': 'b'}))
|
|
||||||
self.assertFalse(
|
|
||||||
self.harness.charm.ha.data_changed(
|
|
||||||
'relation-data', {'a': 'b'}))
|
|
||||||
self.assertTrue(
|
|
||||||
self.harness.charm.ha.data_changed(
|
|
||||||
'relation-data', {'a': 'c'}))
|
|
Loading…
Reference in New Issue