Skip to content

Commit 622971f

Browse files
Lock file maintenance Python dependencies (16/edge) (#981)
* Update charm libs * Lock file maintenance Python dependencies * Fix linting --------- Co-authored-by: Dragomir Penev <[email protected]> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
1 parent 6b4ccfa commit 622971f

File tree

6 files changed

+164
-142
lines changed

6 files changed

+164
-142
lines changed

lib/charms/operator_libs_linux/v2/snap.py

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@
8787

8888
if typing.TYPE_CHECKING:
8989
# avoid typing_extensions import at runtime
90-
from typing_extensions import NotRequired, ParamSpec, Required, TypeAlias, Unpack
90+
from typing_extensions import NotRequired, ParamSpec, Required, Self, TypeAlias, Unpack
9191

9292
_P = ParamSpec("_P")
9393
_T = TypeVar("_T")
@@ -102,7 +102,7 @@
102102

103103
# Increment this PATCH version before using `charmcraft publish-lib` or reset
104104
# to 0 if you are raising the major API version
105-
LIBPATCH = 11
105+
LIBPATCH = 12
106106

107107

108108
# Regex to locate 7-bit C1 ANSI sequences
@@ -268,6 +268,22 @@ class SnapState(Enum):
268268
class SnapError(Error):
269269
"""Raised when there's an error running snap control commands."""
270270

271+
@classmethod
272+
def _from_called_process_error(cls, msg: str, error: CalledProcessError) -> Self:
273+
lines = [msg]
274+
if error.stdout:
275+
lines.extend(['Stdout:', error.stdout])
276+
if error.stderr:
277+
lines.extend(['Stderr:', error.stderr])
278+
try:
279+
cmd = ['journalctl', '--unit', 'snapd', '--lines', '20']
280+
logs = subprocess.check_output(cmd, text=True)
281+
except Exception as e:
282+
lines.extend(['Error fetching logs:', str(e)])
283+
else:
284+
lines.extend(['Latest logs:', logs])
285+
return cls('\n'.join(lines))
286+
271287

272288
class SnapNotFoundError(Error):
273289
"""Raised when a requested snap is not known to the system."""
@@ -340,11 +356,10 @@ def _snap(self, command: str, optargs: Iterable[str] | None = None) -> str:
340356
optargs = optargs or []
341357
args = ["snap", command, self._name, *optargs]
342358
try:
343-
return subprocess.check_output(args, text=True)
359+
return subprocess.check_output(args, text=True, stderr=subprocess.PIPE)
344360
except CalledProcessError as e:
345-
raise SnapError(
346-
f"Snap: {self._name!r}; command {args!r} failed with output = {e.output!r}"
347-
) from e
361+
msg = f'Snap: {self._name!r} -- command {args!r} failed!'
362+
raise SnapError._from_called_process_error(msg=msg, error=e) from e
348363

349364
def _snap_daemons(
350365
self,
@@ -371,7 +386,8 @@ def _snap_daemons(
371386
try:
372387
return subprocess.run(args, text=True, check=True, capture_output=True)
373388
except CalledProcessError as e:
374-
raise SnapError(f"Could not {args} for snap [{self._name}]: {e.stderr}") from e
389+
msg = f'Snap: {self._name!r} -- command {args!r} failed!'
390+
raise SnapError._from_called_process_error(msg=msg, error=e) from e
375391

376392
@typing.overload
377393
def get(self, key: None | Literal[""], *, typed: Literal[False] = False) -> NoReturn: ...
@@ -477,7 +493,8 @@ def connect(self, plug: str, service: str | None = None, slot: str | None = None
477493
try:
478494
subprocess.run(args, text=True, check=True, capture_output=True)
479495
except CalledProcessError as e:
480-
raise SnapError(f"Could not {args} for snap [{self._name}]: {e.stderr}") from e
496+
msg = f'Snap: {self._name!r} -- command {args!r} failed!'
497+
raise SnapError._from_called_process_error(msg=msg, error=e) from e
481498

482499
def hold(self, duration: timedelta | None = None) -> None:
483500
"""Add a refresh hold to a snap.
@@ -506,11 +523,10 @@ def alias(self, application: str, alias: str | None = None) -> None:
506523
alias = application
507524
args = ["snap", "alias", f"{self.name}.{application}", alias]
508525
try:
509-
subprocess.check_output(args, text=True)
526+
subprocess.run(args, text=True, check=True, capture_output=True)
510527
except CalledProcessError as e:
511-
raise SnapError(
512-
f"Snap: {self._name!r}; command {args!r} failed with output = {e.output!r}"
513-
) from e
528+
msg = f'Snap: {self._name!r} -- command {args!r} failed!'
529+
raise SnapError._from_called_process_error(msg=msg, error=e) from e
514530

515531
def restart(self, services: list[str] | None = None, reload: bool = False) -> None:
516532
"""Restarts a snap's services.
@@ -1264,7 +1280,7 @@ def install_local(
12641280
if dangerous:
12651281
args.append("--dangerous")
12661282
try:
1267-
result = subprocess.check_output(args, text=True).splitlines()[-1]
1283+
result = subprocess.check_output(args, text=True, stderr=subprocess.PIPE).splitlines()[-1]
12681284
snap_name, _ = result.split(" ", 1)
12691285
snap_name = ansi_filter.sub("", snap_name)
12701286

@@ -1280,7 +1296,8 @@ def install_local(
12801296
)
12811297
raise SnapError(f"Failed to find snap {snap_name} in Snap cache") from e
12821298
except CalledProcessError as e:
1283-
raise SnapError(f"Could not install snap {filename}: {e.output}") from e
1299+
msg = f'Cound not install snap {filename}!'
1300+
raise SnapError._from_called_process_error(msg=msg, error=e) from e
12841301

12851302

12861303
def _system_set(config_item: str, value: str) -> None:
@@ -1292,9 +1309,10 @@ def _system_set(config_item: str, value: str) -> None:
12921309
"""
12931310
args = ["snap", "set", "system", f"{config_item}={value}"]
12941311
try:
1295-
subprocess.check_call(args, text=True)
1312+
subprocess.run(args, text=True, check=True, capture_output=True)
12961313
except CalledProcessError as e:
1297-
raise SnapError(f"Failed setting system config '{config_item}' to '{value}'") from e
1314+
msg = f"Failed setting system config '{config_item}' to '{value}'"
1315+
raise SnapError._from_called_process_error(msg=msg, error=e) from e
12981316

12991317

13001318
def hold_refresh(days: int = 90, forever: bool = False) -> None:

lib/charms/tls_certificates_interface/v4/tls_certificates.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252

5353
# Increment this PATCH version before using `charmcraft publish-lib` or reset
5454
# to 0 if you are raising the major API version
55-
LIBPATCH = 18
55+
LIBPATCH = 19
5656

5757
PYDEPS = [
5858
"cryptography>=43.0.0",
@@ -1417,6 +1417,7 @@ def _store_private_key_in_secret(self, private_key: PrivateKey) -> None:
14171417
try:
14181418
secret = self.charm.model.get_secret(label=self._get_private_key_secret_label())
14191419
secret.set_content({"private-key": str(private_key)})
1420+
secret.get_content(refresh=True)
14201421
except SecretNotFoundError:
14211422
self.charm.unit.add_secret(
14221423
content={"private-key": str(private_key)},
@@ -1586,10 +1587,13 @@ def _find_certificate_in_relation_data(
15861587
if not self.private_key:
15871588
return None
15881589
for provider_certificate in self.get_provider_certificates():
1589-
if (
1590-
provider_certificate.certificate_signing_request == csr.certificate_signing_request
1591-
and provider_certificate.certificate.is_ca == csr.is_ca
1592-
):
1590+
if provider_certificate.certificate_signing_request == csr.certificate_signing_request:
1591+
if provider_certificate.certificate.is_ca and not csr.is_ca:
1592+
logger.warning("Non CA certificate requested, got a CA certificate, ignoring")
1593+
continue
1594+
elif not provider_certificate.certificate.is_ca and csr.is_ca:
1595+
logger.warning("CA certificate requested, got a non CA certificate, ignoring")
1596+
continue
15931597
if not provider_certificate.certificate.matches_private_key(self.private_key):
15941598
logger.warning(
15951599
"Certificate does not match the private key. Ignoring invalid certificate."

0 commit comments

Comments
 (0)