Merge "Optimize access to the snap data" into main

This commit is contained in:
Zuul 2024-07-31 00:44:25 +00:00 committed by Gerrit Code Review
commit bd0990f2ad
2 changed files with 37 additions and 19 deletions

View File

@ -21,6 +21,7 @@ This charm provide hypervisor services as part of an OpenStack deployment
"""
import base64
import functools
import logging
import os
import secrets
@ -121,10 +122,16 @@ class MTlsCertificatesHandler(sunbeam_rhandlers.TlsCertificatesHandler):
if csr is None:
return {}
main_key = self._private_keys.get("main")
if main_key is None:
# this can happen when the relation is removed
# or unit is departing
logger.debug("No main key found")
return {}
for cert in certs:
if cert.csr == csr:
return {
"key": self._private_keys["main"],
"key": main_key,
"cert": cert.certificate,
"ca_cert": cert.ca,
"ca_with_intermediates": cert.ca
@ -307,21 +314,21 @@ class HypervisorOperatorCharm(sunbeam_charm.OSBaseOperatorCharm):
def set_snap_data(self, snap_data: dict):
"""Set snap data on local snap."""
cache = snap.SnapCache()
cache = self.get_snap_cache()
hypervisor = cache["openstack-hypervisor"]
new_settings = {}
for k in sorted(snap_data.keys()):
try:
if snap_data[k] != hypervisor.get(k, typed=True):
new_settings[k] = snap_data[k]
except snap.SnapError:
# Trying to retrieve an unset parameter results in a snapError
# so assume the snap.SnapError means there is missing config
# that needs setting.
# Setting a value to None will unset the value from the snap,
# which will fail if the value was never set.
if snap_data[k] is not None:
new_settings[k] = snap_data[k]
old_settings = hypervisor.get(None, typed=True)
for key, new_value in snap_data.items():
group, subkey = key.split(".")
if (
old_value := old_settings.get(group, {}).get(subkey)
) is not None:
if old_value != new_value:
new_settings[key] = new_value
# Setting a value to None will unset the value from the snap,
# which will fail if the value was never set.
elif new_value is not None:
new_settings[key] = new_value
if new_settings:
logger.debug(f"Applying new snap settings {new_settings}")
hypervisor.set(new_settings, typed=True)
@ -332,7 +339,7 @@ class HypervisorOperatorCharm(sunbeam_charm.OSBaseOperatorCharm):
"""Install snap if it is not already present."""
config = self.model.config.get
try:
cache = snap.SnapCache()
cache = self.get_snap_cache()
hypervisor = cache["openstack-hypervisor"]
if not hypervisor.present:
@ -345,6 +352,11 @@ class HypervisorOperatorCharm(sunbeam_charm.OSBaseOperatorCharm):
e.message,
)
@functools.cache
def get_snap_cache(self) -> snap.SnapCache:
"""Return snap cache."""
return snap.SnapCache()
def configure_unit(self, event) -> None:
"""Run configuration on this unit."""
self.check_leader_ready()

View File

@ -83,7 +83,7 @@ LIBAPI = 2
# Increment this PATCH version before using `charmcraft publish-lib` or reset
# to 0 if you are raising the major API version
LIBPATCH = 5
LIBPATCH = 7
# Regex to locate 7-bit C1 ANSI sequences
@ -319,7 +319,10 @@ class Snap(object):
Default is to return a string.
"""
if typed:
config = json.loads(self._snap("get", ["-d", key]))
args = ["-d"]
if key:
args.append(key)
config = json.loads(self._snap("get", args))
if key:
return config.get(key)
return config
@ -584,13 +587,16 @@ class Snap(object):
"Installing snap %s, revision %s, tracking %s", self._name, revision, channel
)
self._install(channel, cohort, revision)
else:
logger.info("The snap installation completed successfully")
elif revision is None or revision != self._revision:
# The snap is installed, but we are changing it (e.g., switching channels).
logger.info(
"Refreshing snap %s, revision %s, tracking %s", self._name, revision, channel
)
self._refresh(channel=channel, cohort=cohort, revision=revision, devmode=devmode)
logger.info("The snap installation completed successfully")
logger.info("The snap refresh completed successfully")
else:
logger.info("Refresh of snap %s was unnecessary", self._name)
self._update_snap_apps()
self._state = state