From 9995c45ef6321af021561af8f5c2ae58784c5574 Mon Sep 17 00:00:00 2001 From: Frode Nordahl Date: Tue, 23 Jul 2019 17:48:26 +0200 Subject: [PATCH] Replace ``python-apt`` functionality The ``python-apt`` package is a wrapper around the ``apt`` C++ library which is tightly connected to the version of the distribution it is shipped on. This in turn makes it incredibly hard to distribute as a wheel for a charm that supports a large span of distro versions. We do not want to rely on system installed Python packages but distribute the direct charm dependencies as part of the charms wheelhouse. As the span of distributions we need to support with reactive charms widens we will run into compability problems with the current model. For further reference see discussion in LP: #1824112 and juju-solutions/layer-basic#135 Change-Id: I292dcba7cf2de18e53ae80339d07c6e1fe5c90fc --- charms_openstack/charm/classes.py | 3 +-- charms_openstack/charm/core.py | 8 +++---- charms_openstack/charm/utils.py | 23 ------------------- charms_openstack/test_mocks.py | 4 ---- unit_tests/__init__.py | 2 -- .../charms_openstack/charm/test_classes.py | 6 ++--- .../charms_openstack/charm/test_core.py | 11 +++++---- 7 files changed, 13 insertions(+), 44 deletions(-) diff --git a/charms_openstack/charm/classes.py b/charms_openstack/charm/classes.py index 14ded42..8fabe45 100644 --- a/charms_openstack/charm/classes.py +++ b/charms_openstack/charm/classes.py @@ -24,7 +24,6 @@ from charms_openstack.charm.core import ( get_snap_version, ) from charms_openstack.charm.utils import ( - get_upstream_version, is_data_changed, ) import charms_openstack.adapters as os_adapters @@ -201,7 +200,7 @@ class OpenStackCharm(BaseOpenStackCharm, else: if not self.version_package: self.version_package = self.packages[0] - version = get_upstream_version( + version = fetch.get_upstream_version( self.version_package ) if not version: diff --git a/charms_openstack/charm/core.py b/charms_openstack/charm/core.py index d1b01f8..f442e18 100644 --- a/charms_openstack/charm/core.py +++ b/charms_openstack/charm/core.py @@ -6,8 +6,6 @@ import os import re import subprocess -import apt_pkg as apt - import charmhelpers.contrib.openstack.templating as os_templating import charmhelpers.contrib.openstack.utils as os_utils import charmhelpers.core.hookenv as hookenv @@ -505,7 +503,7 @@ class BaseOpenStackCharm(object, metaclass=BaseOpenStackCharmMeta): if not fatal: return None - vers = apt.upstream_version(pkg.current_ver.ver_str) + vers = fetch.apt_pkg.upstream_version(pkg.current_ver.ver_str) # x.y match only for 20XX.X # and ignore patch level for other packages match = re.match('^(\d+)\.(\d+)', vers) @@ -905,8 +903,8 @@ class BaseOpenStackCharmActions(object): cur_vers = self.get_os_version_snap(snap) else: cur_vers = self.get_os_version_package(package) - apt.init() - return apt.version_compare(avail_vers, cur_vers) == 1 + fetch.apt_pkg.init() + return fetch.apt_pkg.version_compare(avail_vers, cur_vers) == 1 def run_upgrade(self, interfaces_list=None): """Upgrade OpenStack. diff --git a/charms_openstack/charm/utils.py b/charms_openstack/charm/utils.py index 58a47a3..c0035c4 100644 --- a/charms_openstack/charm/utils.py +++ b/charms_openstack/charm/utils.py @@ -2,29 +2,6 @@ import json import hashlib import charmhelpers.core as core -import charmhelpers.fetch as fetch - - -# TODO: drop once charmhelpers releases a new version -# with this function in the fetch helper (> 0.9.1) -def get_upstream_version(package): - """Determine upstream version based on installed package - - @returns None (if not installed) or the upstream version - """ - import apt_pkg - cache = fetch.apt_cache() - try: - pkg = cache[package] - except: - # the package is unknown to the current apt cache. - return None - - if not pkg.current_ver: - # package is known, but no version is currently installed. - return None - - return apt_pkg.upstream_version(pkg.current_ver.ver_str) # TODO(AJK): Once this is in charms.reactive, drop it here and just reference diff --git a/charms_openstack/test_mocks.py b/charms_openstack/test_mocks.py index 341504d..3f12474 100644 --- a/charms_openstack/test_mocks.py +++ b/charms_openstack/test_mocks.py @@ -2,17 +2,13 @@ import sys import mock charmhelpers = None -apt_pkg = None def mock_charmhelpers(): # Mock out charmhelpers so that we can test without it. # also stops sideeffects from occuring. global charmhelpers - global apt_pkg charmhelpers = mock.MagicMock() - apt_pkg = mock.MagicMock() - sys.modules['apt_pkg'] = apt_pkg sys.modules['charmhelpers'] = charmhelpers sys.modules['charmhelpers.core'] = charmhelpers.core sys.modules['charmhelpers.core.hookenv'] = charmhelpers.core.hookenv diff --git a/unit_tests/__init__.py b/unit_tests/__init__.py index 54399be..3d1a5cb 100644 --- a/unit_tests/__init__.py +++ b/unit_tests/__init__.py @@ -17,9 +17,7 @@ import mock import os # mock out some charmhelpers libraries as they have apt install side effects -apt_pkg = mock.MagicMock() charmhelpers = mock.MagicMock() -sys.modules['apt_pkg'] = apt_pkg sys.modules['charmhelpers'] = charmhelpers sys.modules['charmhelpers.core'] = charmhelpers.core sys.modules['charmhelpers.core.decorators'] = charmhelpers.core.decorators diff --git a/unit_tests/charms_openstack/charm/test_classes.py b/unit_tests/charms_openstack/charm/test_classes.py index fcbc0c8..64763d2 100644 --- a/unit_tests/charms_openstack/charm/test_classes.py +++ b/unit_tests/charms_openstack/charm/test_classes.py @@ -267,7 +267,7 @@ class TestMyOpenStackCharm(BaseOpenStackCharmTest): def test_application_version_unspecified(self): self.patch_object(chm.os_utils, 'os_release') - self.patch_object(chm, 'get_upstream_version', + self.patch_object(chm_core.charmhelpers.fetch, 'get_upstream_version', return_value='1.2.3') self.patch_object(chm.os_utils, 'snap_install_requested', return_value=False) @@ -277,7 +277,7 @@ class TestMyOpenStackCharm(BaseOpenStackCharmTest): def test_application_version_package(self): self.patch_object(chm.os_utils, 'os_release') - self.patch_object(chm, 'get_upstream_version', + self.patch_object(chm_core.charmhelpers.fetch, 'get_upstream_version', return_value='1.2.3') self.patch_object(chm.os_utils, 'snap_install_requested', return_value=False) @@ -295,7 +295,7 @@ class TestMyOpenStackCharm(BaseOpenStackCharmTest): def test_application_version_dfs(self): self.patch_object(chm.os_utils, 'os_release', return_value='mitaka') - self.patch_object(chm, 'get_upstream_version', + self.patch_object(chm_core.charmhelpers.fetch, 'get_upstream_version', return_value=None) self.patch_object(chm.os_utils, 'snap_install_requested', return_value=False) diff --git a/unit_tests/charms_openstack/charm/test_core.py b/unit_tests/charms_openstack/charm/test_core.py index 544e050..34578a4 100644 --- a/unit_tests/charms_openstack/charm/test_core.py +++ b/unit_tests/charms_openstack/charm/test_core.py @@ -765,7 +765,8 @@ class TestMyOpenStackCharm(BaseOpenStackCharmTest): pkg_mock = mock.MagicMock() self.apt_cache.return_value = { 'testpkg': pkg_mock} - self.patch_object(chm_core.apt, 'upstream_version') + self.patch_object(chm_core.charmhelpers.fetch.apt_pkg, + 'upstream_version') self.patch_object(chm_core.os_utils, 'snap_install_requested', return_value=False) self.upstream_version.return_value = '3.0.0~b1' @@ -800,7 +801,7 @@ class TestMyOpenStackCharm(BaseOpenStackCharmTest): def test_openstack_upgrade_available_package(self): self.patch_target('get_os_version_package') self.patch_object(chm_core.os_utils, 'get_os_version_install_source') - self.patch_object(chm_core, 'apt') + self.patch_object(chm_core.charmhelpers.fetch, 'apt_pkg') self.patch_target('config', new={'openstack-origin': 'cloud:natty-folsom'}) self.patch_object(chm_core.os_utils, 'snap_install_requested', @@ -808,12 +809,12 @@ class TestMyOpenStackCharm(BaseOpenStackCharmTest): self.get_os_version_package.return_value = 2 self.get_os_version_install_source.return_value = 3 self.target.openstack_upgrade_available(package='testpkg') - self.apt.version_compare.assert_called_once_with(3, 2) + self.apt_pkg.version_compare.assert_called_once_with(3, 2) def test_openstack_upgrade_available_snap(self): self.patch_target('get_os_version_snap') self.patch_object(chm_core.os_utils, 'get_os_version_install_source') - self.patch_object(chm_core, 'apt') + self.patch_object(chm_core.charmhelpers.fetch, 'apt_pkg') self.patch_target('config', new={'openstack-origin': 'snap:ocata/stable'}) self.patch_object(chm_core.os_utils, 'snap_install_requested', @@ -822,7 +823,7 @@ class TestMyOpenStackCharm(BaseOpenStackCharmTest): self.get_os_version_install_source.return_value = 3 self.target.openstack_upgrade_available(snap='testsnap') self.get_os_version_snap.assert_called_once_with('testsnap') - self.apt.version_compare.assert_called_once_with(3, 2) + self.apt_pkg.version_compare.assert_called_once_with(3, 2) def test_upgrade_if_available(self): self.patch_target('run_upgrade')