From 7c87c90c60d3183c652a3119a41eb7df54b0b6bf Mon Sep 17 00:00:00 2001 From: Marcelo Henrique Neppel Date: Thu, 2 Oct 2025 11:12:08 -0300 Subject: [PATCH 01/10] Remove old revision of secret Signed-off-by: Marcelo Henrique Neppel --- src/charm.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/charm.py b/src/charm.py index 87c8b5edf1..4a15b960d5 100755 --- a/src/charm.py +++ b/src/charm.py @@ -46,6 +46,7 @@ InstallEvent, LeaderElectedEvent, RelationDepartedEvent, + SecretRemoveEvent, StartEvent, ) from ops.framework import EventBase @@ -201,6 +202,7 @@ def __init__(self, *args): self.framework.observe(self.on.set_password_action, self._on_set_password) self.framework.observe(self.on.promote_to_primary_action, self._on_promote_to_primary) self.framework.observe(self.on.update_status, self._on_update_status) + self.framework.observe(self.on.secret_remove, self._on_secret_remove) self.cluster_name = self.app.name self._member_name = self.unit.name.replace("/", "-") @@ -435,6 +437,9 @@ def get_hostname_by_unit(self, _) -> str: # the underlying provider (LXD, MAAS, etc.), the unit IP is returned. return self._unit_ip + def _on_secret_remove(self, event: SecretRemoveEvent) -> None: + event.remove_revision() + def _on_get_primary(self, event: ActionEvent) -> None: """Get primary instance.""" try: From d5aac003020f03eeaee4aa27a34f09725541976b Mon Sep 17 00:00:00 2001 From: Marcelo Henrique Neppel Date: Thu, 2 Oct 2025 20:40:43 -0300 Subject: [PATCH 02/10] Remove secrets' old revision on upgrade Signed-off-by: Marcelo Henrique Neppel --- src/upgrade.py | 13 +++++++++++++ tests/unit/test_upgrade.py | 1 + 2 files changed, 14 insertions(+) diff --git a/src/upgrade.py b/src/upgrade.py index 08dee25eaf..b3f4096ea1 100644 --- a/src/upgrade.py +++ b/src/upgrade.py @@ -23,6 +23,7 @@ MONITORING_PASSWORD_KEY, MONITORING_USER, PATRONI_PASSWORD_KEY, + PEER, RAFT_PASSWORD_KEY, SNAP_PACKAGES, ) @@ -198,6 +199,8 @@ def _on_upgrade_granted(self, event: UpgradeGrantedEvent) -> None: self._set_up_new_access_roles_for_legacy() + self._remove_secrets_old_revisions() + self.set_unit_completed() # Ensures leader gets its own relation-changed when it upgrades @@ -261,6 +264,16 @@ def _prepare_upgrade_from_legacy(self) -> None: ) self.charm.postgresql.set_up_database() + def _remove_secrets_old_revisions(self) -> None: + """Remove secrets' old revisions.""" + if self.charm.unit.is_leader(): + secret = self.charm.model.get_secret(label=f"{PEER}.{self.charm.app.name}.app") + latest_revision = secret.get_info().revision + logger.debug(f"Latest revision of secret is {latest_revision}") + for revision in range(1, latest_revision): + secret.remove_revision(revision) + logger.debug(f"Removed secret revision {revision}") + def _set_up_new_access_roles_for_legacy(self) -> None: """Create missing access groups and their memberships.""" access_groups = self.charm.postgresql.list_access_groups() diff --git a/tests/unit/test_upgrade.py b/tests/unit/test_upgrade.py index 22a186cbdb..f4923226a5 100644 --- a/tests/unit/test_upgrade.py +++ b/tests/unit/test_upgrade.py @@ -110,6 +110,7 @@ def test_on_upgrade_granted(harness): "charm.PostgresqlOperatorCharm.updated_synchronous_node_count" ) as _updated_synchronous_node_count, patch("upgrade.PostgreSQLUpgrade._set_up_new_access_roles_for_legacy"), + patch("upgrade.PostgreSQLUpgrade._remove_secrets_old_revisions"), ): # Test when the charm fails to start Patroni. mock_event = MagicMock() From 521d108d5393e65f5e6a9ccce545ac11d2d66188 Mon Sep 17 00:00:00 2001 From: Marcelo Henrique Neppel Date: Sat, 4 Oct 2025 12:16:59 -0300 Subject: [PATCH 03/10] Remove all previous secret revisions Signed-off-by: Marcelo Henrique Neppel --- src/charm.py | 1 + src/upgrade.py | 28 ++++++++++++++++++++++------ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/charm.py b/src/charm.py index 4a15b960d5..061e326c47 100755 --- a/src/charm.py +++ b/src/charm.py @@ -214,6 +214,7 @@ def __init__(self, *args): model=get_postgresql_dependencies_model(), relation_name="upgrade", substrate="vm", + run_cmd=run_cmd, ) self.postgresql_client_relation = PostgreSQLProvider(self) self.legacy_db_relation = DbProvides(self, admin=False) diff --git a/src/upgrade.py b/src/upgrade.py index b3f4096ea1..9caa062570 100644 --- a/src/upgrade.py +++ b/src/upgrade.py @@ -5,6 +5,8 @@ import json import logging +import os +import subprocess from charms.data_platform_libs.v0.upgrade import ( ClusterNotReadyError, @@ -49,10 +51,11 @@ def get_postgresql_dependencies_model() -> PostgreSQLDependencyModel: class PostgreSQLUpgrade(DataUpgrade): """PostgreSQL upgrade class.""" - def __init__(self, charm, model: BaseModel, **kwargs) -> None: + def __init__(self, charm, model: BaseModel, run_cmd: str, **kwargs) -> None: """Initialize the class.""" super().__init__(charm, model, **kwargs) self.charm = charm + self.run_cmd = run_cmd self._on_upgrade_charm_check_legacy() @override @@ -146,6 +149,8 @@ def _on_upgrade_charm_check_legacy(self) -> None: def _on_upgrade_granted(self, event: UpgradeGrantedEvent) -> None: # Refresh the charmed PostgreSQL snap and restart the database. # Update the configuration. + self._remove_secrets_old_revisions() + self.charm.unit.status = MaintenanceStatus("updating configuration") self.charm.update_config() self.charm.updated_synchronous_node_count() @@ -199,8 +204,6 @@ def _on_upgrade_granted(self, event: UpgradeGrantedEvent) -> None: self._set_up_new_access_roles_for_legacy() - self._remove_secrets_old_revisions() - self.set_unit_completed() # Ensures leader gets its own relation-changed when it upgrades @@ -268,11 +271,24 @@ def _remove_secrets_old_revisions(self) -> None: """Remove secrets' old revisions.""" if self.charm.unit.is_leader(): secret = self.charm.model.get_secret(label=f"{PEER}.{self.charm.app.name}.app") + secret_id = secret.get_info().id latest_revision = secret.get_info().revision - logger.debug(f"Latest revision of secret is {latest_revision}") + new_env = os.environ.copy() + if "JUJU_CONTEXT_ID" in new_env: + new_env.pop("JUJU_CONTEXT_ID") for revision in range(1, latest_revision): - secret.remove_revision(revision) - logger.debug(f"Removed secret revision {revision}") + command = [ + self.run_cmd, + self.charm.unit.name, + "--", + "secret-remove", + "--revision", + str(revision), + secret_id, + ] + # Input comes from the charm. + subprocess.Popen(command, env=new_env) # noqa: S603 + logger.info(f"Removing secret revision {revision}") def _set_up_new_access_roles_for_legacy(self) -> None: """Create missing access groups and their memberships.""" From 0e29e0e18b4718e5470a297f7771292c38b2fd0a Mon Sep 17 00:00:00 2001 From: Marcelo Henrique Neppel Date: Sun, 5 Oct 2025 10:02:19 -0300 Subject: [PATCH 04/10] Handle https://github.com/juju/juju/issues/20782 Signed-off-by: Marcelo Henrique Neppel --- src/upgrade.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/upgrade.py b/src/upgrade.py index 9caa062570..f3f6a65c52 100644 --- a/src/upgrade.py +++ b/src/upgrade.py @@ -271,12 +271,19 @@ def _remove_secrets_old_revisions(self) -> None: """Remove secrets' old revisions.""" if self.charm.unit.is_leader(): secret = self.charm.model.get_secret(label=f"{PEER}.{self.charm.app.name}.app") - secret_id = secret.get_info().id latest_revision = secret.get_info().revision + # We need to trick Juju into thinking that we are not running in a hook context, + # as Juju will disallow use of juju-run / juju-exec. new_env = os.environ.copy() if "JUJU_CONTEXT_ID" in new_env: new_env.pop("JUJU_CONTEXT_ID") for revision in range(1, latest_revision): + if str(latest_revision).startswith(str(revision)): + # Skip if the revision is a prefix of the latest revision. + logger.info( + f"Skipping secret revision {revision} because it's the prefix of the latest revision (see https://github.com/juju/juju/issues/20782)" + ) + continue command = [ self.run_cmd, self.charm.unit.name, @@ -284,7 +291,7 @@ def _remove_secrets_old_revisions(self) -> None: "secret-remove", "--revision", str(revision), - secret_id, + secret.get_info().id, ] # Input comes from the charm. subprocess.Popen(command, env=new_env) # noqa: S603 From 0e23c96e5f6abd35e1e7ceb617dca502e07711b5 Mon Sep 17 00:00:00 2001 From: Marcelo Henrique Neppel Date: Sun, 5 Oct 2025 10:02:36 -0300 Subject: [PATCH 05/10] Revert "Handle https://github.com/juju/juju/issues/20782" This reverts commit 0e29e0e18b4718e5470a297f7771292c38b2fd0a. Signed-off-by: Marcelo Henrique Neppel --- src/upgrade.py | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/upgrade.py b/src/upgrade.py index f3f6a65c52..9caa062570 100644 --- a/src/upgrade.py +++ b/src/upgrade.py @@ -271,19 +271,12 @@ def _remove_secrets_old_revisions(self) -> None: """Remove secrets' old revisions.""" if self.charm.unit.is_leader(): secret = self.charm.model.get_secret(label=f"{PEER}.{self.charm.app.name}.app") + secret_id = secret.get_info().id latest_revision = secret.get_info().revision - # We need to trick Juju into thinking that we are not running in a hook context, - # as Juju will disallow use of juju-run / juju-exec. new_env = os.environ.copy() if "JUJU_CONTEXT_ID" in new_env: new_env.pop("JUJU_CONTEXT_ID") for revision in range(1, latest_revision): - if str(latest_revision).startswith(str(revision)): - # Skip if the revision is a prefix of the latest revision. - logger.info( - f"Skipping secret revision {revision} because it's the prefix of the latest revision (see https://github.com/juju/juju/issues/20782)" - ) - continue command = [ self.run_cmd, self.charm.unit.name, @@ -291,7 +284,7 @@ def _remove_secrets_old_revisions(self) -> None: "secret-remove", "--revision", str(revision), - secret.get_info().id, + secret_id, ] # Input comes from the charm. subprocess.Popen(command, env=new_env) # noqa: S603 From 1ff60faa93ad9f2efeda08d7eacb1361878a2a67 Mon Sep 17 00:00:00 2001 From: Marcelo Henrique Neppel Date: Sun, 5 Oct 2025 10:19:53 -0300 Subject: [PATCH 06/10] Reapply "Handle https://github.com/juju/juju/issues/20782" This reverts commit 0e23c96e5f6abd35e1e7ceb617dca502e07711b5. Signed-off-by: Marcelo Henrique Neppel --- src/upgrade.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/upgrade.py b/src/upgrade.py index 9caa062570..f3f6a65c52 100644 --- a/src/upgrade.py +++ b/src/upgrade.py @@ -271,12 +271,19 @@ def _remove_secrets_old_revisions(self) -> None: """Remove secrets' old revisions.""" if self.charm.unit.is_leader(): secret = self.charm.model.get_secret(label=f"{PEER}.{self.charm.app.name}.app") - secret_id = secret.get_info().id latest_revision = secret.get_info().revision + # We need to trick Juju into thinking that we are not running in a hook context, + # as Juju will disallow use of juju-run / juju-exec. new_env = os.environ.copy() if "JUJU_CONTEXT_ID" in new_env: new_env.pop("JUJU_CONTEXT_ID") for revision in range(1, latest_revision): + if str(latest_revision).startswith(str(revision)): + # Skip if the revision is a prefix of the latest revision. + logger.info( + f"Skipping secret revision {revision} because it's the prefix of the latest revision (see https://github.com/juju/juju/issues/20782)" + ) + continue command = [ self.run_cmd, self.charm.unit.name, @@ -284,7 +291,7 @@ def _remove_secrets_old_revisions(self) -> None: "secret-remove", "--revision", str(revision), - secret_id, + secret.get_info().id, ] # Input comes from the charm. subprocess.Popen(command, env=new_env) # noqa: S603 From a6c36bbc48d9ebc3eb3ff2d593be2d76e73c9d39 Mon Sep 17 00:00:00 2001 From: Marcelo Henrique Neppel Date: Mon, 6 Oct 2025 16:25:54 -0300 Subject: [PATCH 07/10] Handle https://github.com/juju/juju/issues/20794 Signed-off-by: Marcelo Henrique Neppel --- src/charm.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/charm.py b/src/charm.py index 061e326c47..0922bab6fb 100755 --- a/src/charm.py +++ b/src/charm.py @@ -439,6 +439,14 @@ def get_hostname_by_unit(self, _) -> str: return self._unit_ip def _on_secret_remove(self, event: SecretRemoveEvent) -> None: + # A secret removal (entire removal, not just a revision removal) causes + # https://github.com/juju/juju/issues/20794. This check is to avoid the + # errors that would happen if we tried to remove the revision in that case + # (in the revision removal, the label is present). + if event.secret.label is None: + logger.debug("Secret with no label cannot be removed") + return + logger.debug(f"Removing secret with label {event.secret.label} revision {event.revision}") event.remove_revision() def _on_get_primary(self, event: ActionEvent) -> None: From 63a5f44a1cfc03866d32bb3f1b53af244c199eee Mon Sep 17 00:00:00 2001 From: Marcelo Henrique Neppel Date: Mon, 6 Oct 2025 17:26:15 -0300 Subject: [PATCH 08/10] Consider all secrets created by the charm Signed-off-by: Marcelo Henrique Neppel --- src/upgrade.py | 76 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 50 insertions(+), 26 deletions(-) diff --git a/src/upgrade.py b/src/upgrade.py index f3f6a65c52..7c9e759e32 100644 --- a/src/upgrade.py +++ b/src/upgrade.py @@ -15,7 +15,7 @@ UpgradeGrantedEvent, ) from charms.postgresql_k8s.v0.postgresql import ACCESS_GROUPS -from ops.model import MaintenanceStatus, RelationDataContent, WaitingStatus +from ops.model import MaintenanceStatus, RelationDataContent, SecretNotFoundError, WaitingStatus from pydantic import BaseModel from tenacity import RetryError, Retrying, stop_after_attempt, wait_fixed from typing_extensions import override @@ -29,6 +29,7 @@ RAFT_PASSWORD_KEY, SNAP_PACKAGES, ) +from relations.async_replication import SECRET_LABEL as ASYNC_REPLICATION_SECRET_LABEL from utils import new_password logger = logging.getLogger(__name__) @@ -270,32 +271,55 @@ def _prepare_upgrade_from_legacy(self) -> None: def _remove_secrets_old_revisions(self) -> None: """Remove secrets' old revisions.""" if self.charm.unit.is_leader(): - secret = self.charm.model.get_secret(label=f"{PEER}.{self.charm.app.name}.app") - latest_revision = secret.get_info().revision - # We need to trick Juju into thinking that we are not running in a hook context, - # as Juju will disallow use of juju-run / juju-exec. - new_env = os.environ.copy() - if "JUJU_CONTEXT_ID" in new_env: - new_env.pop("JUJU_CONTEXT_ID") - for revision in range(1, latest_revision): - if str(latest_revision).startswith(str(revision)): - # Skip if the revision is a prefix of the latest revision. - logger.info( - f"Skipping secret revision {revision} because it's the prefix of the latest revision (see https://github.com/juju/juju/issues/20782)" - ) + # Internal app and async replication secrets. + ids_and_labels = [f"{PEER}.{self.charm.app.name}.app", ASYNC_REPLICATION_SECRET_LABEL] + # Retrieve the database relation secrets' IDs and add them to the list. + for relation in self.charm.model.relations.get("database", []): + ids_and_labels.extend([ + relation.data[self.charm.app].get(secret_field) + for secret_field in ["secret-tls", "secret-user"] + if secret_field in relation.data[self.charm.app] + ]) + for id_or_label in ids_and_labels: + if id_or_label.startswith("secret://"): + secret = self.charm.model.get_secret(id=id_or_label) + label = secret.get_info().label + else: + try: + secret = self.charm.model.get_secret(label=id_or_label) + label = id_or_label + except SecretNotFoundError: + logger.debug(f"Skipping secret not found with label {id_or_label}") + continue + latest_revision = secret.get_info().revision + if latest_revision == 1: + # No old revisions to remove. continue - command = [ - self.run_cmd, - self.charm.unit.name, - "--", - "secret-remove", - "--revision", - str(revision), - secret.get_info().id, - ] - # Input comes from the charm. - subprocess.Popen(command, env=new_env) # noqa: S603 - logger.info(f"Removing secret revision {revision}") + logger.info(f"Removing old revisions of secret with label {label}") + # We need to trick Juju into thinking that we are not running in a hook context, + # as Juju will disallow use of juju-run / juju-exec. + new_env = os.environ.copy() + if "JUJU_CONTEXT_ID" in new_env: + new_env.pop("JUJU_CONTEXT_ID") + for revision in range(1, latest_revision): + if str(latest_revision).startswith(str(revision)): + # Skip if the revision is a prefix of the latest revision. + logger.info( + f"Skipping secret revision {revision} because it's the prefix of the latest revision (see https://github.com/juju/juju/issues/20782)" + ) + continue + command = [ + self.run_cmd, + self.charm.unit.name, + "--", + "secret-remove", + "--revision", + str(revision), + secret.get_info().id, + ] + # Input comes from the charm. + subprocess.Popen(command, env=new_env) # noqa: S603 + logger.info(f"Removing secret revision {revision} if it exists") def _set_up_new_access_roles_for_legacy(self) -> None: """Create missing access groups and their memberships.""" From cbfe719a0597661f3349204ed2a9ef5d0af465d9 Mon Sep 17 00:00:00 2001 From: Marcelo Henrique Neppel Date: Mon, 6 Oct 2025 17:52:59 -0300 Subject: [PATCH 09/10] Check for secrets support Signed-off-by: Marcelo Henrique Neppel --- src/upgrade.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/upgrade.py b/src/upgrade.py index 7c9e759e32..e269333bb2 100644 --- a/src/upgrade.py +++ b/src/upgrade.py @@ -270,7 +270,7 @@ def _prepare_upgrade_from_legacy(self) -> None: def _remove_secrets_old_revisions(self) -> None: """Remove secrets' old revisions.""" - if self.charm.unit.is_leader(): + if self.charm.unit.is_leader() and self.charm.model.juju_version.has_secrets: # Internal app and async replication secrets. ids_and_labels = [f"{PEER}.{self.charm.app.name}.app", ASYNC_REPLICATION_SECRET_LABEL] # Retrieve the database relation secrets' IDs and add them to the list. From fec93f20658a94d1ec16e6ca8c71ca4bb34121fe Mon Sep 17 00:00:00 2001 From: Marcelo Henrique Neppel Date: Tue, 7 Oct 2025 12:08:11 -0300 Subject: [PATCH 10/10] Remove upgrade logic Signed-off-by: Marcelo Henrique Neppel --- src/charm.py | 1 - src/upgrade.py | 64 ++------------------------------------ tests/unit/test_upgrade.py | 1 - 3 files changed, 2 insertions(+), 64 deletions(-) diff --git a/src/charm.py b/src/charm.py index 0922bab6fb..e90658cca1 100755 --- a/src/charm.py +++ b/src/charm.py @@ -214,7 +214,6 @@ def __init__(self, *args): model=get_postgresql_dependencies_model(), relation_name="upgrade", substrate="vm", - run_cmd=run_cmd, ) self.postgresql_client_relation = PostgreSQLProvider(self) self.legacy_db_relation = DbProvides(self, admin=False) diff --git a/src/upgrade.py b/src/upgrade.py index e269333bb2..08dee25eaf 100644 --- a/src/upgrade.py +++ b/src/upgrade.py @@ -5,8 +5,6 @@ import json import logging -import os -import subprocess from charms.data_platform_libs.v0.upgrade import ( ClusterNotReadyError, @@ -15,7 +13,7 @@ UpgradeGrantedEvent, ) from charms.postgresql_k8s.v0.postgresql import ACCESS_GROUPS -from ops.model import MaintenanceStatus, RelationDataContent, SecretNotFoundError, WaitingStatus +from ops.model import MaintenanceStatus, RelationDataContent, WaitingStatus from pydantic import BaseModel from tenacity import RetryError, Retrying, stop_after_attempt, wait_fixed from typing_extensions import override @@ -25,11 +23,9 @@ MONITORING_PASSWORD_KEY, MONITORING_USER, PATRONI_PASSWORD_KEY, - PEER, RAFT_PASSWORD_KEY, SNAP_PACKAGES, ) -from relations.async_replication import SECRET_LABEL as ASYNC_REPLICATION_SECRET_LABEL from utils import new_password logger = logging.getLogger(__name__) @@ -52,11 +48,10 @@ def get_postgresql_dependencies_model() -> PostgreSQLDependencyModel: class PostgreSQLUpgrade(DataUpgrade): """PostgreSQL upgrade class.""" - def __init__(self, charm, model: BaseModel, run_cmd: str, **kwargs) -> None: + def __init__(self, charm, model: BaseModel, **kwargs) -> None: """Initialize the class.""" super().__init__(charm, model, **kwargs) self.charm = charm - self.run_cmd = run_cmd self._on_upgrade_charm_check_legacy() @override @@ -150,8 +145,6 @@ def _on_upgrade_charm_check_legacy(self) -> None: def _on_upgrade_granted(self, event: UpgradeGrantedEvent) -> None: # Refresh the charmed PostgreSQL snap and restart the database. # Update the configuration. - self._remove_secrets_old_revisions() - self.charm.unit.status = MaintenanceStatus("updating configuration") self.charm.update_config() self.charm.updated_synchronous_node_count() @@ -268,59 +261,6 @@ def _prepare_upgrade_from_legacy(self) -> None: ) self.charm.postgresql.set_up_database() - def _remove_secrets_old_revisions(self) -> None: - """Remove secrets' old revisions.""" - if self.charm.unit.is_leader() and self.charm.model.juju_version.has_secrets: - # Internal app and async replication secrets. - ids_and_labels = [f"{PEER}.{self.charm.app.name}.app", ASYNC_REPLICATION_SECRET_LABEL] - # Retrieve the database relation secrets' IDs and add them to the list. - for relation in self.charm.model.relations.get("database", []): - ids_and_labels.extend([ - relation.data[self.charm.app].get(secret_field) - for secret_field in ["secret-tls", "secret-user"] - if secret_field in relation.data[self.charm.app] - ]) - for id_or_label in ids_and_labels: - if id_or_label.startswith("secret://"): - secret = self.charm.model.get_secret(id=id_or_label) - label = secret.get_info().label - else: - try: - secret = self.charm.model.get_secret(label=id_or_label) - label = id_or_label - except SecretNotFoundError: - logger.debug(f"Skipping secret not found with label {id_or_label}") - continue - latest_revision = secret.get_info().revision - if latest_revision == 1: - # No old revisions to remove. - continue - logger.info(f"Removing old revisions of secret with label {label}") - # We need to trick Juju into thinking that we are not running in a hook context, - # as Juju will disallow use of juju-run / juju-exec. - new_env = os.environ.copy() - if "JUJU_CONTEXT_ID" in new_env: - new_env.pop("JUJU_CONTEXT_ID") - for revision in range(1, latest_revision): - if str(latest_revision).startswith(str(revision)): - # Skip if the revision is a prefix of the latest revision. - logger.info( - f"Skipping secret revision {revision} because it's the prefix of the latest revision (see https://github.com/juju/juju/issues/20782)" - ) - continue - command = [ - self.run_cmd, - self.charm.unit.name, - "--", - "secret-remove", - "--revision", - str(revision), - secret.get_info().id, - ] - # Input comes from the charm. - subprocess.Popen(command, env=new_env) # noqa: S603 - logger.info(f"Removing secret revision {revision} if it exists") - def _set_up_new_access_roles_for_legacy(self) -> None: """Create missing access groups and their memberships.""" access_groups = self.charm.postgresql.list_access_groups() diff --git a/tests/unit/test_upgrade.py b/tests/unit/test_upgrade.py index f4923226a5..22a186cbdb 100644 --- a/tests/unit/test_upgrade.py +++ b/tests/unit/test_upgrade.py @@ -110,7 +110,6 @@ def test_on_upgrade_granted(harness): "charm.PostgresqlOperatorCharm.updated_synchronous_node_count" ) as _updated_synchronous_node_count, patch("upgrade.PostgreSQLUpgrade._set_up_new_access_roles_for_legacy"), - patch("upgrade.PostgreSQLUpgrade._remove_secrets_old_revisions"), ): # Test when the charm fails to start Patroni. mock_event = MagicMock()