diff --git a/.gitignore b/.gitignore index 3d40c3d..8beafeb 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ lib/* !lib/README.txt *.charm .vscode/settings.json +build diff --git a/config.yaml b/config.yaml index 3c53bb4..2f373e2 100644 --- a/config.yaml +++ b/config.yaml @@ -10,7 +10,7 @@ options: source: type: string - default: ppa:chris.macnaughton/focal-ussuri + default: proposed description: | Optional configuration to support use of additional sources such as: - ppa:myteam/ppa diff --git a/src/charm.py b/src/charm.py index 0301222..acc5efc 100755 --- a/src/charm.py +++ b/src/charm.py @@ -397,6 +397,9 @@ class CephNfsCharm( allowed_ips = [ip.strip() for ip in allowed_ips.split(',')] client = GaneshaNfs(self.client_name, self.pool_name) export_path = client.create_share(size=share_size, name=name, access_ips=allowed_ips) + if not export_path: + event.fail("Failed to create share, check the log for more details") + return self.peers.trigger_reload() event.set_results({ "message": "Share created", @@ -430,8 +433,8 @@ class CephNfsCharm( name = event.params.get('name') address = event.params.get('client') mode = event.params.get('mode') - if mode not in ['r', 'rw']: - event.fail('Mode must be either r (read) or rw (read/write)') + if mode not in ['R', 'RW']: + event.fail('Mode must be either R (read) or RW (read/write)') res = client.grant_access(name, address, mode) if res is not None: event.fail(res) @@ -459,8 +462,8 @@ class CephNfsCharm( @ops_openstack.core.charm_class -class CephNFSCharmOcto(CephNfsCharm): - """Ceph iSCSI Charm for Octopus.""" +class CephNFSCharmPacific(CephNfsCharm): + """Ceph iSCSI Charm for Pacific.""" _stored = StoredState() release = 'octopus' diff --git a/src/ganesha.py b/src/ganesha.py index 3b12017..9d9a561 100644 --- a/src/ganesha.py +++ b/src/ganesha.py @@ -123,7 +123,10 @@ class GaneshaNfs(object): access_ips[access_ips.index('0.0.0.0/0')] = '0.0.0.0' access_id = 'ganesha-{}'.format(name) - self.export_path = self._create_cephfs_share(name, size_in_bytes) + path = self._create_cephfs_share(name, size_in_bytes) + if not path: + return + self.export_path = path export_id = self._get_next_export_id() export = Export( { diff --git a/tests/bundles/focal-pacific.yaml b/tests/bundles/focal-pacific.yaml index 0f2718e..0032189 100644 --- a/tests/bundles/focal-pacific.yaml +++ b/tests/bundles/focal-pacific.yaml @@ -7,8 +7,11 @@ applications: ceph-nfs: charm: ../../ceph-nfs.charm num_units: 2 + options: + source: proposed ceph-osd: charm: ch:ceph-osd + channel: pacific/edge num_units: 3 storage: osd-devices: '2,10G' @@ -16,6 +19,7 @@ applications: source: cloud:focal-wallaby ceph-mon: charm: ch:ceph-mon + channel: pacific/edge num_units: 3 options: monitor-count: '3' @@ -23,12 +27,17 @@ applications: source: cloud:focal-wallaby ceph-fs: charm: ch:ceph-fs - num_units: 1 + channel: pacific/edge + num_units: 2 + options: + source: cloud:focal-wallaby loadbalancer: - charm: ch:openstack-loadbalancer + charm: ../../../charm-openstack-loadbalancer/openstack-loadbalancer.charm + channel: edge num_units: 3 hacluster: charm: ch:hacluster + channel: 2.0.3/edge options: cluster_count: 3 relations: diff --git a/tests/bundles/focal-quincy.yaml b/tests/bundles/focal-quincy.yaml new file mode 100644 index 0000000..9cddefd --- /dev/null +++ b/tests/bundles/focal-quincy.yaml @@ -0,0 +1,53 @@ +local_overlay_enabled: False +series: focal +applications: + ubuntu: + charm: cs:ubuntu + num_units: 2 + ceph-nfs: + charm: ../../ceph-nfs.charm + num_units: 2 + options: + source: proposed + ceph-osd: + charm: ch:ceph-osd + channel: quincy/edge + num_units: 3 + storage: + osd-devices: '2,10G' + options: + source: cloud:focal-yoga + ceph-mon: + charm: ch:ceph-mon + channel: quincy/edge + num_units: 3 + options: + monitor-count: '3' + expected-osd-count: 6 + source: cloud:focal-yoga + ceph-fs: + charm: ch:ceph-fs + channel: quincy/edge + num_units: 2 + options: + source: cloud:focal-yoga + loadbalancer: + charm: ../../../charm-openstack-loadbalancer/openstack-loadbalancer.charm + # channel: edge + num_units: 3 + hacluster: + charm: ch:hacluster + channel: 2.0.3/edge + options: + cluster_count: 3 +relations: + - - 'ceph-mon:client' + - 'ceph-nfs:ceph-client' + - - 'ceph-osd:mon' + - 'ceph-mon:osd' + - - 'ceph-fs' + - 'ceph-mon' + - - ceph-nfs + - loadbalancer + - - 'loadbalancer:ha' + - 'hacluster:ha' diff --git a/tests/bundles/overlays/focal-pacific.yaml.j2 b/tests/bundles/overlays/local-charm-overlay.yaml.j2 similarity index 100% rename from tests/bundles/overlays/focal-pacific.yaml.j2 rename to tests/bundles/overlays/local-charm-overlay.yaml.j2 diff --git a/tests/nfs_ganesha.py b/tests/nfs_ganesha.py index 037382e..2545876 100644 --- a/tests/nfs_ganesha.py +++ b/tests/nfs_ganesha.py @@ -17,6 +17,7 @@ import logging import subprocess import tenacity +import time from typing import Dict import unittest import yaml @@ -49,13 +50,15 @@ class NfsGaneshaTest(unittest.TestCase): 'name': self.created_share, }) - def _create_share(self, name: str, size: int = 10) -> Dict[str, str]: + def _create_share(self, name: str, size: int = 10, + access_ip: str = '0.0.0.0') -> Dict[str, str]: action = zaza.model.run_action_on_leader( 'ceph-nfs', 'create-share', action_params={ 'name': name, 'size': size, + 'allowed-ips': access_ip, }) self.assertEqual(action.status, 'completed') self.created_share = name @@ -63,7 +66,18 @@ class NfsGaneshaTest(unittest.TestCase): logging.debug("Action results: {}".format(results)) return results - def _mount_share(self, unit_name: str, share_ip: str, export_path: str): + def _grant_access(self, share_name: str, access_ip: str, access_mode: str): + action = zaza.model.run_action_on_leader( + 'ceph-nfs', + 'grant-access', + action_params={ + 'name': share_name, + 'client': access_ip, + 'mode': access_mode, + }) + self.assertEqual(action.status, 'completed') + + def _mount_share(self, unit_name: str, share_ip: str, export_path: str, retry: bool = True): ssh_cmd = ( 'sudo mkdir -p {0} && ' 'sudo mount -t {1} -o nfsvers=4.1,proto=tcp {2}:{3} {0}'.format( @@ -71,14 +85,18 @@ class NfsGaneshaTest(unittest.TestCase): self.share_protocol, share_ip, export_path)) - - for attempt in tenacity.Retrying( - stop=tenacity.stop_after_attempt(5), - wait=tenacity.wait_exponential(multiplier=3, min=2, max=10)): - with attempt: - zaza.utilities.generic.run_via_ssh( - unit_name=unit_name, - cmd=ssh_cmd) + if retry: + for attempt in tenacity.Retrying( + stop=tenacity.stop_after_attempt(5), + wait=tenacity.wait_exponential(multiplier=3, min=2, max=10)): + with attempt: + zaza.utilities.generic.run_via_ssh( + unit_name=unit_name, + cmd=ssh_cmd) + else: + zaza.utilities.generic.run_via_ssh( + unit_name=unit_name, + cmd=ssh_cmd) self.mounts_share = True def _install_dependencies(self, unit: str): @@ -106,17 +124,33 @@ class NfsGaneshaTest(unittest.TestCase): self.assertEqual('test\r\n', output) def test_create_share(self): + logging.info("Creating a share") + # Todo - enable ACL testing + # ubuntu_0_ip = zaza.model.get_unit_public_address(zaza.model.get_unit_from_name('ubuntu/0')) + # ubuntu_1_ip = zaza.model.get_unit_public_address(zaza.model.get_unit_from_name('ubuntu/1')) + # share = self._create_share('test_ganesha_share', access_ip=ubuntu_0_ip) + share = self._create_share('test_ganesha_share') + zaza.model.wait_for_application_states(states={ + 'ubuntu': { + "workload-status-message-regex": "^$", + } + }) for unit in ['0', '1']: self._install_dependencies('ubuntu/{}'.format(unit)) - logging.info("Creating a share") - share = self._create_share('test_ganesha_share') export_path = share['path'] ip = share['ip'] logging.info("Mounting share on ubuntu units") self._mount_share('ubuntu/0', ip, export_path) - self._mount_share('ubuntu/1', ip, export_path) logging.info("writing to the share on ubuntu/0") self._write_testing_file_on_instance('ubuntu/0') + # Todo - enable ACL testing + # try: + # self._mount_share('ubuntu/1', ip, export_path, retry=False) + # self.fail('Mounting should not have succeeded') + # except: # noqa: E722 + # pass + # self._grant_access('test_ganesha_share', access_ip=ubuntu_1_ip, access_mode='RW') + self._mount_share('ubuntu/1', ip, export_path) logging.info("reading from the share on ubuntu/1") self._verify_testing_file_on_instance('ubuntu/1') diff --git a/tests/tests.yaml b/tests/tests.yaml index 4052a34..37d4d29 100644 --- a/tests/tests.yaml +++ b/tests/tests.yaml @@ -1,9 +1,9 @@ charm_name: ceph-nfs gate_bundles: - - focal-octopuc + - focal-quincy - focal-pacific smoke_bundles: - - focal-octopus + - focal-pacific configure: [] tests: - tests.nfs_ganesha.NfsGaneshaTest