From acc0d2636bb72289e675d4c2ea222b6b1eb21f6a Mon Sep 17 00:00:00 2001 From: Dragomir Penev <6687393+dragomirp@users.noreply.github.com> Date: Wed, 7 Feb 2024 00:21:08 +0200 Subject: [PATCH] [DPE-3202] Architecture specific snap revision (#345) * Arm tweaks * Bump snap revision * Snap version bump * Tweak plugins test * Architecture based snap revision * Try to set channel * Revert conftest * Remove string revision check --- src/charm.py | 20 ++++++++++++-------- src/constants.py | 4 +++- tests/unit/test_charm.py | 36 +++++++++++++++++++++++++++++++----- 3 files changed, 46 insertions(+), 14 deletions(-) diff --git a/src/charm.py b/src/charm.py index 4f64355054..6d95f131e8 100755 --- a/src/charm.py +++ b/src/charm.py @@ -6,6 +6,7 @@ import json import logging import os +import platform import subprocess import time from typing import Dict, List, Literal, Optional, Set, get_args @@ -965,12 +966,9 @@ def _setup_exporter(self) -> None: cache = snap.SnapCache() postgres_snap = cache[POSTGRESQL_SNAP_NAME] - if ( - postgres_snap.revision - != list( - filter(lambda snap_package: snap_package[0] == POSTGRESQL_SNAP_NAME, SNAP_PACKAGES) - )[0][1]["revision"] - ): + if postgres_snap.revision != list( + filter(lambda snap_package: snap_package[0] == POSTGRESQL_SNAP_NAME, SNAP_PACKAGES) + )[0][1]["revision"].get(platform.machine()): logger.debug( "Early exit _setup_exporter: snap was not refreshed to the right version yet" ) @@ -1274,9 +1272,15 @@ def _install_snap_packages(self, packages: List[str], refresh: bool = False) -> snap_package = snap_cache[snap_name] if not snap_package.present or refresh: - if snap_version.get("revision"): + if revision := snap_version.get("revision"): + try: + revision = revision[platform.machine()] + except Exception: + logger.error("Unavailable snap architecture %s", platform.machine()) + raise + channel = snap_version.get("channel", "") snap_package.ensure( - snap.SnapState.Latest, revision=snap_version["revision"] + snap.SnapState.Latest, revision=revision, channel=channel ) snap_package.hold() else: diff --git a/src/constants.py b/src/constants.py index 319feea5c1..4e248a4992 100644 --- a/src/constants.py +++ b/src/constants.py @@ -32,7 +32,9 @@ # Snap constants. PGBACKREST_EXECUTABLE = "charmed-postgresql.pgbackrest" POSTGRESQL_SNAP_NAME = "charmed-postgresql" -SNAP_PACKAGES = [(POSTGRESQL_SNAP_NAME, {"revision": "96"})] +SNAP_PACKAGES = [ + (POSTGRESQL_SNAP_NAME, {"revision": {"aarch64": "97", "x86_64": "98"}, "channel": "14/stable"}) +] SNAP_COMMON_PATH = "/var/snap/charmed-postgresql/common" SNAP_CURRENT_PATH = "/var/snap/charmed-postgresql/current" diff --git a/tests/unit/test_charm.py b/tests/unit/test_charm.py index 09bfa6f445..726ffc110f 100644 --- a/tests/unit/test_charm.py +++ b/tests/unit/test_charm.py @@ -1,6 +1,7 @@ # Copyright 2021 Canonical Ltd. # See LICENSE file for licensing details. import logging +import platform import subprocess import unittest from unittest.mock import MagicMock, Mock, PropertyMock, mock_open, patch @@ -1025,31 +1026,56 @@ def test_install_snap_packages(self, _snap_cache): _snap_cache.reset_mock() _snap_package.reset_mock() _snap_package.ensure.side_effect = None - self.charm._install_snap_packages([("postgresql", {"revision": 42})]) + self.charm._install_snap_packages( + [("postgresql", {"revision": {platform.machine(): "42"}})] + ) _snap_cache.assert_called_once_with() _snap_cache.return_value.__getitem__.assert_called_once_with("postgresql") - _snap_package.ensure.assert_called_once_with(snap.SnapState.Latest, revision=42) + _snap_package.ensure.assert_called_once_with( + snap.SnapState.Latest, revision="42", channel="" + ) _snap_package.hold.assert_called_once_with() # Test with refresh _snap_cache.reset_mock() _snap_package.reset_mock() _snap_package.present = True - self.charm._install_snap_packages([("postgresql", {"revision": 42})], refresh=True) + self.charm._install_snap_packages( + [("postgresql", {"revision": {platform.machine(): "42"}, "channel": "latest/test"})], + refresh=True, + ) _snap_cache.assert_called_once_with() _snap_cache.return_value.__getitem__.assert_called_once_with("postgresql") - _snap_package.ensure.assert_called_once_with(snap.SnapState.Latest, revision=42) + _snap_package.ensure.assert_called_once_with( + snap.SnapState.Latest, revision="42", channel="latest/test" + ) _snap_package.hold.assert_called_once_with() # Test without refresh _snap_cache.reset_mock() _snap_package.reset_mock() - self.charm._install_snap_packages([("postgresql", {"revision": 42})]) + self.charm._install_snap_packages( + [("postgresql", {"revision": {platform.machine(): "42"}})] + ) _snap_cache.assert_called_once_with() _snap_cache.return_value.__getitem__.assert_called_once_with("postgresql") _snap_package.ensure.assert_not_called() _snap_package.hold.assert_not_called() + # test missing architecture + _snap_cache.reset_mock() + _snap_package.reset_mock() + _snap_package.present = True + with self.assertRaises(KeyError): + self.charm._install_snap_packages( + [("postgresql", {"revision": {"missingarch": "42"}})], + refresh=True, + ) + _snap_cache.assert_called_once_with() + _snap_cache.return_value.__getitem__.assert_called_once_with("postgresql") + assert not _snap_package.ensure.called + assert not _snap_package.hold.called + @patch( "subprocess.check_call", side_effect=[None, subprocess.CalledProcessError(1, "fake command")],