diff --git a/src/lib/charm/openstack/trilio_dm.py b/src/lib/charm/openstack/trilio_dm.py index b1664dc..9b7bb73 100644 --- a/src/lib/charm/openstack/trilio_dm.py +++ b/src/lib/charm/openstack/trilio_dm.py @@ -12,13 +12,10 @@ # See the License for the specific language governing permissions and # limitations under the License. -import base64 import os import charmhelpers.core.hookenv as hookenv -import charmhelpers.core.host as host import charmhelpers.contrib.openstack.utils as os_utils -import charmhelpers.fetch as fetch import charms.reactive as reactive @@ -67,7 +64,8 @@ class DataMoverRelationAdapaters(os_adapters.OpenStackAPIRelationAdapters): class TrilioDataMoverBaseCharm( - charms_openstack.charm.OpenStackCharm, + charms_openstack.plugins.TrilioVaultSubordinateCharm, + charms_openstack.plugins.TrilioVaultCharmGhostAction, charms_openstack.plugins.BaseOpenStackCephCharm, ): @@ -140,13 +138,6 @@ class TrilioDataMoverBaseCharm( def get_amqp_credentials(self): return ("datamover", "openstack") - def configure_source(self): - with open( - "/etc/apt/sources.list.d/" "trilio-gemfury-sources.list", "w" - ) as tsources: - tsources.write(hookenv.config("triliovault-pkg-source")) - fetch.apt_update(fatal=True) - @property def services(self): if hookenv.config("backup-target-type") == "s3": @@ -164,49 +155,6 @@ class TrilioDataMoverBaseCharm( self.data_mover_conf: self.services, } - def install(self): - self.configure_source() - super().install() - - def _encode_endpoint(self, backup_endpoint): - """base64 encode an backup endpoint for cross mounting support""" - return base64.b64encode(backup_endpoint.encode()).decode() - - # TODO: refactor into a layer/module - def ghost_nfs_share(self, ghost_share): - """Bind mount the local units nfs share to another sites location - - :param ghost_share: NFS share URL to ghost - :type ghost_share: str - """ - nfs_share_path = os.path.join( - TV_MOUNTS, self._encode_endpoint(hookenv.config("nfs-shares")) - ) - ghost_share_path = os.path.join( - TV_MOUNTS, self._encode_endpoint(ghost_share) - ) - - current_mounts = [mount[0] for mount in host.mounts()] - - if nfs_share_path not in current_mounts: - # Trilio has not mounted the NFS share so return - raise NFSShareNotMountedException( - "nfs-shares ({}) not mounted".format( - hookenv.config("nfs-shares") - ) - ) - - if ghost_share_path in current_mounts: - # bind mount already setup so return - raise GhostShareAlreadyMountedException( - "ghost mountpoint ({}) already bound".format(ghost_share_path) - ) - - if not os.path.exists(ghost_share_path): - os.mkdir(ghost_share_path) - - host.mount(nfs_share_path, ghost_share_path, options="bind") - def custom_assess_status_check(self): """Check required configuration options are set""" if not hookenv.config("nfs-shares"): diff --git a/src/reactive/data_mover_handlers.py b/src/reactive/data_mover_handlers.py index 2adc65b..d58ca2b 100644 --- a/src/reactive/data_mover_handlers.py +++ b/src/reactive/data_mover_handlers.py @@ -54,6 +54,7 @@ def default_amqp_connection(amqp): def install_source_changed(): """Trigger re-install of charm if source configuration options change""" reactive.clear_flag("charm.installed") + reactive.set_flag("upgrade.triliovault") @reactive.when_not("ceph.access.req.sent") diff --git a/unit_tests/test_lib_charm_openstack_trilio_dm.py b/unit_tests/test_lib_charm_openstack_trilio_dm.py index f2e463a..2d25286 100644 --- a/unit_tests/test_lib_charm_openstack_trilio_dm.py +++ b/unit_tests/test_lib_charm_openstack_trilio_dm.py @@ -12,8 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -import os - import charm.openstack.trilio_dm as trilio_dm import charms_openstack.test_utils as test_utils @@ -44,61 +42,3 @@ class TestTrilioDataMoverRockyCharms(Helper): self.assertEqual( dm_charm.services, ["tvault-contego", "tvault-object-store"] ) - - -# TODO: refactor into a layer/module -class TestTrilioDataMoverRockyCharmGhostShareAction(Helper): - - _nfs_shares = "10.20.30.40:/srv/trilioshare" - _ghost_shares = "50.20.30.40:/srv/trilioshare" - - def setUp(self): - super().setUp() - self.patch_object(trilio_dm.hookenv, "config") - self.patch_object(trilio_dm.host, "mounts") - self.patch_object(trilio_dm.host, "mount") - self.patch_object(trilio_dm.os.path, "exists") - self.patch_object(trilio_dm.os, "mkdir") - - self.trilio_wlm_charm = trilio_dm.TrilioDataMoverRockyCharm() - self._nfs_path = os.path.join( - trilio_dm.TV_MOUNTS, - self.trilio_wlm_charm._encode_endpoint(self._nfs_shares), - ) - self._ghost_path = os.path.join( - trilio_dm.TV_MOUNTS, - self.trilio_wlm_charm._encode_endpoint(self._ghost_shares), - ) - - def test_ghost_share(self): - self.config.return_value = self._nfs_shares - self.mounts.return_value = [ - ["/srv/nova", "/dev/sda"], - [self._nfs_path, self._nfs_shares], - ] - self.exists.return_value = False - self.trilio_wlm_charm.ghost_nfs_share(self._ghost_shares) - self.exists.assert_called_once_with(self._ghost_path) - self.mkdir.assert_called_once_with(self._ghost_path) - self.mount.assert_called_once_with( - self._nfs_path, self._ghost_path, options="bind" - ) - - def test_ghost_share_already_bound(self): - self.config.return_value = self._nfs_shares - self.mounts.return_value = [ - ["/srv/nova", "/dev/sda"], - [self._nfs_path, self._nfs_shares], - [self._ghost_path, self._nfs_shares], - ] - with self.assertRaises(trilio_dm.GhostShareAlreadyMountedException): - self.trilio_wlm_charm.ghost_nfs_share(self._ghost_shares) - self.mount.assert_not_called() - - def test_ghost_share_nfs_unmounted(self): - self.config.return_value = self._nfs_shares - self.mounts.return_value = [["/srv/nova", "/dev/sda"]] - self.exists.return_value = False - with self.assertRaises(trilio_dm.NFSShareNotMountedException): - self.trilio_wlm_charm.ghost_nfs_share(self._ghost_shares) - self.mount.assert_not_called()