diff --git a/requirements.txt b/requirements.txt index 20f335d..f65abf7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,4 +4,6 @@ # # Build requirements charm-tools>=2.4.4 +# importlib-resources 1.1.0 removed Python 3.5 support +importlib-resources<1.1.0 simplejson diff --git a/src/lib/charm/openstack/ovn_chassis.py b/src/lib/charm/openstack/ovn_chassis.py index 5b6e416..8d5ab28 100644 --- a/src/lib/charm/openstack/ovn_chassis.py +++ b/src/lib/charm/openstack/ovn_chassis.py @@ -11,11 +11,66 @@ # 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. +import inspect + +import charmhelpers.fetch as ch_fetch + import charms.ovn_charm -class OVNChassisCharm(charms.ovn_charm.BaseOVNChassisCharm): +class OVNSubordinateChassisCharm(object): + """Mix-in for subordinate-specific handling.""" + + @staticmethod + def get_os_codename_package(package, codenames, fatal=True): + """Override to conditionally decide based on packages in apt cache. + + Please inspect parent method for documentation of parameters. + + The parent method also requires a package to already be installed, + and on initial charm deploy the fall back is to retrieve information + from a source configuration option. + + Since we are a subordinate charm, we do not have a source configuration + option, thus we want to make the decision based on what is currently + available in the system APT cache alone. Our principle charm should + already have configured the system with the desired UCA pocket enabled. + """ + # When the method is called outside of the context of the select + # release handler we do want it to assert presence of an installed + # package, as it is then used to detect available upgrades. + if (not inspect.currentframe().f_back.f_code.co_name == '' + 'default_select_release'): + return super().get_os_codename_package( + package, codenames, fatal=fatal) + + cache = ch_fetch.apt_cache() + try: + pkg = cache[package] + except KeyError: + if not fatal: + return + raise ValueError( + 'Could not determine version of package with no installation ' + 'candidate: {}'.format(package)) + ver = ch_fetch.apt_pkg.upstream_version(pkg.version) + major_ver = ver.split('.')[0] + if (package in codenames and + major_ver in codenames[package]): + return codenames[package][major_ver] + + +class TrainOVNChassisCharm(OVNSubordinateChassisCharm, + charms.ovn_charm.BaseTrainOVNChassisCharm): # OpenvSwitch and OVN is distributed as part of the Ubuntu Cloud Archive # Pockets get their name from OpenStack releases release = 'train' name = 'ovn-chassis' + + +class UssuriOVNChassisCharm(OVNSubordinateChassisCharm, + charms.ovn_charm.BaseUssuriOVNChassisCharm): + # OpenvSwitch and OVN is distributed as part of the Ubuntu Cloud Archive + # Pockets get their name from OpenStack releases + release = 'ussuri' + name = 'ovn-chassis' diff --git a/src/metadata.yaml b/src/metadata.yaml index 96768c2..072d657 100644 --- a/src/metadata.yaml +++ b/src/metadata.yaml @@ -9,6 +9,7 @@ tags: series: - bionic - eoan + - focal subordinate: true extra-bindings: data: diff --git a/src/tests/bundles/bionic.yaml b/src/tests/bundles/bionic-train.yaml similarity index 87% rename from src/tests/bundles/bionic.yaml rename to src/tests/bundles/bionic-train.yaml index 5755b46..b5025a8 100644 --- a/src/tests/bundles/bionic.yaml +++ b/src/tests/bundles/bionic-train.yaml @@ -23,8 +23,10 @@ applications: options: source: cloud:bionic-train magpie: - charm: cs:~admcleod/magpie + charm: cs:~openstack-charmers-next/magpie num_units: 2 + options: + source: cloud:bionic-train ovn-chassis: series: bionic charm: cs:~openstack-charmers-next/ovn-chassis diff --git a/src/tests/bundles/bionic-ussuri.yaml b/src/tests/bundles/bionic-ussuri.yaml new file mode 100644 index 0000000..8c26ec8 --- /dev/null +++ b/src/tests/bundles/bionic-ussuri.yaml @@ -0,0 +1,32 @@ +series: bionic +relations: +- - vault:shared-db + - mysql:shared-db +- - ovn-central:certificates + - vault:certificates +- - magpie:juju-info + - ovn-chassis:juju-info +- - ovn-chassis:ovsdb + - ovn-central:ovsdb +- - ovn-chassis:certificates + - vault:certificates +applications: + mysql: + charm: cs:~openstack-charmers-next/percona-cluster + num_units: 1 + vault: + charm: cs:~openstack-charmers-next/vault + num_units: 1 + ovn-central: + charm: cs:~openstack-charmers-next/ovn-central + num_units: 3 + options: + source: cloud:bionic-ussuri/proposed + magpie: + charm: cs:~openstack-charmers-next/magpie + num_units: 2 + options: + source: cloud:bionic-ussuri/proposed + ovn-chassis: + series: bionic + charm: cs:~openstack-charmers-next/ovn-chassis diff --git a/src/tests/bundles/eoan.yaml b/src/tests/bundles/eoan.yaml index 760ba9a..2c790d3 100644 --- a/src/tests/bundles/eoan.yaml +++ b/src/tests/bundles/eoan.yaml @@ -1,7 +1,9 @@ series: eoan relations: +- - vault-mysql-router:db-router + - mysql-innodb-cluster:db-router - - vault:shared-db - - mysql:shared-db + - vault-mysql-router:shared-db - - ovn-central:certificates - vault:certificates - - magpie:juju-info @@ -11,9 +13,11 @@ relations: - - ovn-chassis:certificates - vault:certificates applications: - mysql: + mysql-innodb-cluster: charm: cs:~openstack-charmers-next/mysql-innodb-cluster num_units: 3 + vault-mysql-router: + charm: cs:~openstack-charmers-next/mysql-router vault: charm: cs:~openstack-charmers-next/vault num_units: 1 @@ -21,7 +25,7 @@ applications: charm: cs:~openstack-charmers-next/ovn-central num_units: 3 magpie: - charm: cs:~admcleod/magpie + charm: cs:~openstack-charmers-next/magpie num_units: 2 ovn-chassis: series: eoan diff --git a/src/tests/bundles/focal.yaml b/src/tests/bundles/focal.yaml new file mode 100644 index 0000000..958973d --- /dev/null +++ b/src/tests/bundles/focal.yaml @@ -0,0 +1,31 @@ +series: focal +relations: +- - vault-mysql-router:db-router + - mysql-innodb-cluster:db-router +- - vault:shared-db + - vault-mysql-router:shared-db + - vault:certificates +- - magpie:juju-info + - ovn-chassis:juju-info +- - ovn-chassis:ovsdb + - ovn-central:ovsdb +- - ovn-chassis:certificates + - vault:certificates +applications: + mysql-innodb-cluster: + charm: cs:~openstack-charmers-next/mysql-innodb-cluster + num_units: 3 + vault-mysql-router: + charm: cs:~openstack-charmers-next/mysql-router + vault: + charm: cs:~openstack-charmers-next/vault + num_units: 1 + ovn-central: + charm: cs:~openstack-charmers-next/ovn-central + num_units: 3 + magpie: + charm: cs:~openstack-charmers-next/magpie + num_units: 2 + ovn-chassis: + series: focal + charm: cs:~openstack-charmers-next/ovn-chassis diff --git a/src/tests/tests.yaml b/src/tests/tests.yaml index 917e3a7..ddbb6b6 100644 --- a/src/tests/tests.yaml +++ b/src/tests/tests.yaml @@ -1,9 +1,12 @@ charm_name: ovn-chassis gate_bundles: +- bionic-train - eoan -- bionic +- bionic-ussuri smoke_bundles: -- bionic +- bionic-ussuri +dev_bundles: +- focal target_deploy_status: magpie: workload-status-message: icmp ok diff --git a/test-requirements.txt b/test-requirements.txt index 14b380e..c43a8db 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -3,11 +3,10 @@ # requirements management in charms via bot-control. Thank you. # # Lint and unit test requirements -flake8>=2.2.4,<=2.4.1 -stestr>=2.2.0 -requests>=2.18.4 -charms.reactive -mock>=1.2 -nose>=1.3.7 coverage>=3.6 +mock>=1.2 +pep8>=1.7.0 +flake8>=2.2.4 +os-testr>=0.4.1 + git+https://github.com/openstack/charms.openstack.git#egg=charms.openstack diff --git a/tox.ini b/tox.ini index 23750a8..a45c381 100644 --- a/tox.ini +++ b/tox.ini @@ -77,4 +77,4 @@ commands = {posargs} [flake8] # E402 ignore necessary for path append before sys module import in actions -ignore = E402 +ignore = E402,W504 diff --git a/unit_tests/__init__.py b/unit_tests/__init__.py index 5408a9d..4670b81 100644 --- a/unit_tests/__init__.py +++ b/unit_tests/__init__.py @@ -22,21 +22,45 @@ import charms_openstack.test_mocks # noqa charms_openstack.test_mocks.mock_charmhelpers() import mock -import charms + + +class _fake_decorator(object): + + def __init__(self, *args): + pass + + def __call__(self, f): + return f + + +charms = mock.MagicMock() +sys.modules['charms'] = charms charms.leadership = mock.MagicMock() -keystoneauth1 = mock.MagicMock() -neutronclient = mock.MagicMock() sys.modules['charms.leadership'] = charms.leadership -keystoneauth1 = mock.MagicMock() -novaclient = mock.MagicMock() -neutron_lib = mock.MagicMock() +charms.reactive = mock.MagicMock() +charms.reactive.when = _fake_decorator +charms.reactive.when_all = _fake_decorator +charms.reactive.when_any = _fake_decorator +charms.reactive.when_not = _fake_decorator +charms.reactive.when_none = _fake_decorator +charms.reactive.when_not_all = _fake_decorator +charms.reactive.not_unless = _fake_decorator +charms.reactive.when_file_changed = _fake_decorator +charms.reactive.collect_metrics = _fake_decorator +charms.reactive.meter_status_changed = _fake_decorator +charms.reactive.only_once = _fake_decorator +charms.reactive.hook = _fake_decorator +charms.reactive.bus = mock.MagicMock() +charms.reactive.flags = mock.MagicMock() +charms.reactive.relations = mock.MagicMock() +sys.modules['charms.reactive'] = charms.reactive +sys.modules['charms.reactive.bus'] = charms.reactive.bus +sys.modules['charms.reactive.bus'] = charms.reactive.decorators +sys.modules['charms.reactive.flags'] = charms.reactive.flags +sys.modules['charms.reactive.relations'] = charms.reactive.relations sys.modules['charms.leadership'] = charms.leadership -sys.modules['keystoneauth1'] = keystoneauth1 -sys.modules['novaclient'] = novaclient -sys.modules['neutronclient'] = neutronclient -sys.modules['neutronclient.v2_0'] = neutronclient.v2_0 -sys.modules['neutron_lib'] = neutron_lib -sys.modules['neutron_lib.constants'] = neutron_lib.constants +netaddr = mock.MagicMock() +sys.modules['netaddr'] = netaddr import reactive reactive.ovn_chassis_charm_handlers = mock.MagicMock() reactive.ovn_chassis_charm_handlers.OVN_CHASSIS_ENABLE_HANDLERS_FLAG = \