[openstack-hypervisor] error out on snap installation failure
When the openstack-hypervisor snap fails to install, then set the unit status to error instead of blocked. Closes-Bug: #2065944. Change-Id: I0b3817c8e8321e5bfd8eaabe63646c9cd48cdf36
This commit is contained in:
@@ -71,6 +71,10 @@ DATA_BINDING = "data"
|
||||
MTLS_USAGES = {x509.OID_SERVER_AUTH, x509.OID_CLIENT_AUTH}
|
||||
|
||||
|
||||
class SnapInstallationError(Exception):
|
||||
"""Custom exception for snap installation failure errors."""
|
||||
|
||||
|
||||
class HypervisorError(Exception):
|
||||
"""Custom exception for Hypervisor errors."""
|
||||
|
||||
@@ -217,7 +221,10 @@ class HypervisorOperatorCharm(sunbeam_charm.OSBaseOperatorCharm):
|
||||
|
||||
def _on_install(self, _: ops.InstallEvent):
|
||||
"""Run install on this unit."""
|
||||
self.ensure_snap_present()
|
||||
with sunbeam_guard.guard(
|
||||
self, "Executing install hook event handler", False
|
||||
):
|
||||
self.ensure_snap_present()
|
||||
|
||||
@property
|
||||
def migration_address(self) -> Optional[str]:
|
||||
@@ -490,12 +497,16 @@ class HypervisorOperatorCharm(sunbeam_charm.OSBaseOperatorCharm):
|
||||
hypervisor.ensure(
|
||||
snap.SnapState.Latest, channel=config("snap-channel")
|
||||
)
|
||||
except snap.SnapError as e:
|
||||
except (snap.SnapError, snap.SnapNotFoundError) as e:
|
||||
logger.error(
|
||||
"An exception occurred when installing openstack-hypervisor. Reason: %s",
|
||||
e.message,
|
||||
)
|
||||
|
||||
raise SnapInstallationError(
|
||||
"openstack-hypervisor installation failed"
|
||||
)
|
||||
|
||||
@functools.cache
|
||||
def get_snap_cache(self) -> snap.SnapCache:
|
||||
"""Return snap cache."""
|
||||
|
||||
@@ -21,6 +21,7 @@ from unittest.mock import (
|
||||
)
|
||||
|
||||
import charm
|
||||
import charms.operator_libs_linux.v2.snap as snap
|
||||
import ops
|
||||
import ops.testing
|
||||
import ops_sunbeam.test_utils as test_utils
|
||||
@@ -289,6 +290,13 @@ class TestCharm(test_utils.CharmTestCase):
|
||||
}
|
||||
hypervisor_snap_mock.set.assert_any_call(expect_settings, typed=True)
|
||||
|
||||
def test_openstack_hypervisor_snap_not_installed(self):
|
||||
"""Check action raises SnapNotFoundError if openstack-hypervisor snap is not installed."""
|
||||
self.harness.begin()
|
||||
self.snap.SnapCache.side_effect = snap.SnapNotFoundError
|
||||
with self.assertRaises(snap.SnapNotFoundError):
|
||||
self.harness.run_action("list-nics")
|
||||
|
||||
def test_list_nics_snap_not_installed(self):
|
||||
"""Check action raises ActionFailed if snap is not installed."""
|
||||
self.harness.begin()
|
||||
|
||||
@@ -63,6 +63,10 @@ def _identity(x: bool) -> bool:
|
||||
return x
|
||||
|
||||
|
||||
class SnapInstallationError(Exception):
|
||||
"""Custom exception for snap installation failure errors."""
|
||||
|
||||
|
||||
@sunbeam_tracing.trace_type
|
||||
class ClusterCertificatesHandler(sunbeam_rhandlers.TlsCertificatesHandler):
|
||||
"""Handler for certificates interface."""
|
||||
@@ -204,7 +208,8 @@ class SunbeamClusterdCharm(sunbeam_charm.OSBaseOperatorCharm):
|
||||
def _on_install(self, event: ops.InstallEvent) -> None:
|
||||
"""Handle install event."""
|
||||
try:
|
||||
self.ensure_snap_present()
|
||||
with sunbeam_guard.guard(self, "Ensure snap installation", False):
|
||||
self.ensure_snap_present()
|
||||
except TimeoutError:
|
||||
logger.debug("Snap installation failed, retrying.")
|
||||
event.defer()
|
||||
@@ -275,11 +280,12 @@ class SunbeamClusterdCharm(sunbeam_charm.OSBaseOperatorCharm):
|
||||
openstack.ensure(snap.SnapState.Latest, channel=snap_channel)
|
||||
self._state.channel = openstack.channel
|
||||
self.set_workload_version()
|
||||
except snap.SnapError as e:
|
||||
except (snap.SnapError, snap.SnapNotFoundError) as e:
|
||||
logger.error(
|
||||
"An exception occurred when installing snap. Reason: %s",
|
||||
e.message,
|
||||
)
|
||||
raise SnapInstallationError("openstack snap installation failed")
|
||||
|
||||
def set_workload_version(self):
|
||||
"""Set workload version."""
|
||||
|
||||
@@ -15,6 +15,9 @@ import ops
|
||||
import ops.testing as testing
|
||||
import ops_sunbeam.test_utils as test_utils
|
||||
import yaml
|
||||
from charms.operator_libs_linux.v2 import (
|
||||
snap,
|
||||
)
|
||||
|
||||
|
||||
class _SunbeamClusterdCharm(charm.SunbeamClusterdCharm):
|
||||
@@ -59,6 +62,13 @@ class TestCharm(test_utils.CharmTestCase):
|
||||
self.harness.add_network("10.0.0.10")
|
||||
self.harness.begin_with_initial_hooks()
|
||||
|
||||
def test_openstack_snap_not_installed(self):
|
||||
"""Check action raises SnapNotFoundError if openstack snap is not installed."""
|
||||
self.harness.begin()
|
||||
self.ensure_snap_present.side_effect = snap.SnapNotFoundError
|
||||
with self.assertRaises(snap.SnapNotFoundError):
|
||||
self.harness.charm.on.install.emit()
|
||||
|
||||
def test_initial_bootstrap(self):
|
||||
"""Test charm is bootstrapped."""
|
||||
self.initial_setup()
|
||||
|
||||
Reference in New Issue
Block a user