mongo-charms-single-kernel 1.8.5__tar.gz → 1.8.7__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of mongo-charms-single-kernel might be problematic. Click here for more details.
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/PKG-INFO +2 -1
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/pyproject.toml +9 -2
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/abstract_charm.py +8 -0
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/config/literals.py +1 -20
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/config/relations.py +0 -1
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/config/statuses.py +35 -57
- mongo_charms_single_kernel-1.8.7/single_kernel_mongo/core/abstract_upgrades_v3.py +149 -0
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/core/k8s_workload.py +2 -2
- mongo_charms_single_kernel-1.8.7/single_kernel_mongo/core/kubernetes_upgrades_v3.py +17 -0
- mongo_charms_single_kernel-1.8.7/single_kernel_mongo/core/machine_upgrades_v3.py +54 -0
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/core/operator.py +26 -5
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/core/version_checker.py +7 -6
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/core/vm_workload.py +30 -13
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/core/workload.py +17 -19
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/events/backups.py +10 -3
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/events/cluster.py +1 -1
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/events/database.py +5 -4
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/events/lifecycle.py +5 -4
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/events/tls.py +7 -4
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/exceptions.py +4 -24
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/managers/backups.py +14 -0
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/managers/cluster.py +8 -8
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/managers/config.py +5 -3
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/managers/ldap.py +2 -1
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/managers/mongo.py +48 -9
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/managers/mongodb_operator.py +227 -84
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/managers/mongos_operator.py +99 -37
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/managers/sharding.py +8 -6
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/managers/tls.py +54 -27
- mongo_charms_single_kernel-1.8.7/single_kernel_mongo/managers/upgrade_v3.py +452 -0
- mongo_charms_single_kernel-1.8.7/single_kernel_mongo/managers/upgrade_v3_status.py +133 -0
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/state/app_peer_state.py +12 -2
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/state/charm_state.py +31 -141
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/state/config_server_state.py +0 -33
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/state/unit_peer_state.py +10 -0
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/utils/helpers.py +0 -6
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/utils/mongo_config.py +32 -8
- mongo_charms_single_kernel-1.8.5/single_kernel_mongo/core/abstract_upgrades.py +0 -890
- mongo_charms_single_kernel-1.8.5/single_kernel_mongo/core/kubernetes_upgrades.py +0 -194
- mongo_charms_single_kernel-1.8.5/single_kernel_mongo/core/machine_upgrades.py +0 -188
- mongo_charms_single_kernel-1.8.5/single_kernel_mongo/events/upgrades.py +0 -157
- mongo_charms_single_kernel-1.8.5/single_kernel_mongo/managers/upgrade.py +0 -334
- mongo_charms_single_kernel-1.8.5/single_kernel_mongo/state/upgrade_state.py +0 -134
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/LICENSE +0 -0
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/README.md +0 -0
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/__init__.py +0 -0
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/config/__init__.py +0 -0
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/config/models.py +0 -0
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/core/__init__.py +0 -0
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/core/secrets.py +0 -0
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/core/structured_config.py +0 -0
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/events/__init__.py +0 -0
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/events/ldap.py +0 -0
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/events/primary_action.py +0 -0
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/events/sharding.py +0 -0
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/lib/charms/certificate_transfer_interface/v0/certificate_transfer.py +0 -0
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/lib/charms/data_platform_libs/v0/data_interfaces.py +0 -0
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/lib/charms/data_platform_libs/v0/s3.py +0 -0
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/lib/charms/glauth_k8s/v0/ldap.py +0 -0
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/lib/charms/grafana_agent/v0/cos_agent.py +0 -0
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/lib/charms/grafana_k8s/v0/grafana_dashboard.py +0 -0
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/lib/charms/loki_k8s/v0/loki_push_api.py +0 -0
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/lib/charms/operator_libs_linux/v0/sysctl.py +0 -0
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/lib/charms/operator_libs_linux/v2/snap.py +0 -0
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/lib/charms/prometheus_k8s/v0/prometheus_scrape.py +0 -0
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/lib/charms/tls_certificates_interface/v3/tls_certificates.py +0 -0
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/managers/__init__.py +0 -0
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/managers/k8s.py +0 -0
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/managers/observability.py +0 -0
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/observability_rules/__init__.py +0 -0
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/observability_rules/grafana_dashboards/MongoDB_Cluster_Summary.json +0 -0
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/observability_rules/grafana_dashboards/MongoDB_ReplSet_Summary.json +0 -0
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/observability_rules/k8s_prometheus_alert_rules/percona-mongodb-exporter.rule +0 -0
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/observability_rules/loki/.gitkeep +0 -0
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/observability_rules/vm_prometheus_alert_rules/percona-mongodb-exporter.yml +0 -0
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/state/__init__.py +0 -0
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/state/abstract_state.py +0 -0
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/state/cluster_state.py +0 -0
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/state/ldap_state.py +0 -0
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/state/models.py +0 -0
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/state/tls_state.py +0 -0
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/templates/__init__.py +0 -0
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/templates/ldap.conf.j2 +0 -0
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/templates/logrotate.j2 +0 -0
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/utils/__init__.py +0 -0
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/utils/event_helpers.py +0 -0
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/utils/mongo_connection.py +0 -0
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/utils/mongo_error_codes.py +0 -0
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/utils/mongodb_users.py +0 -0
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/workload/__init__.py +0 -0
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/workload/backup_workload.py +0 -0
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/workload/log_rotate_workload.py +0 -0
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/workload/mongodb_workload.py +0 -0
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/workload/mongos_workload.py +0 -0
- {mongo_charms_single_kernel-1.8.5 → mongo_charms_single_kernel-1.8.7}/single_kernel_mongo/workload/monitor_workload.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mongo-charms-single-kernel
|
|
3
|
-
Version: 1.8.
|
|
3
|
+
Version: 1.8.7
|
|
4
4
|
Summary: Shared and reusable code for Mongo-related charms
|
|
5
5
|
License-Expression: Apache-2.0
|
|
6
6
|
License-File: LICENSE
|
|
@@ -12,6 +12,7 @@ Classifier: Intended Audience :: Developers
|
|
|
12
12
|
Classifier: Intended Audience :: System Administrators
|
|
13
13
|
Classifier: Operating System :: POSIX :: Linux
|
|
14
14
|
Requires-Dist: boto3 (>=1.37.12,<1.38.0)
|
|
15
|
+
Requires-Dist: charm-refresh (>=3.1.0.2,<4.0.0.0)
|
|
15
16
|
Requires-Dist: cosl
|
|
16
17
|
Requires-Dist: cryptography
|
|
17
18
|
Requires-Dist: dacite (>=1.9.0,<1.10.0)
|
|
@@ -37,9 +37,10 @@ dependencies = [
|
|
|
37
37
|
"deepmerge (>=2.0)",
|
|
38
38
|
"boto3 (~=1.37.12)",
|
|
39
39
|
"mypy-boto3-s3 (~=1.37.0)",
|
|
40
|
-
"python-ldap"
|
|
40
|
+
"python-ldap",
|
|
41
|
+
"charm-refresh (>=3.1.0.2,<4.0.0.0)",
|
|
41
42
|
]
|
|
42
|
-
version = "1.8.
|
|
43
|
+
version = "1.8.7"
|
|
43
44
|
|
|
44
45
|
[project.urls]
|
|
45
46
|
homepage = "https://github.com/canonical/mongo-single-kernel-library"
|
|
@@ -136,6 +137,12 @@ httpx = "*"
|
|
|
136
137
|
boto3 = "^1.37.12"
|
|
137
138
|
mypy-boto3-s3 = "^1.37.0"
|
|
138
139
|
|
|
140
|
+
[tool.poetry.group.build-refresh-version]
|
|
141
|
+
optional = true
|
|
142
|
+
|
|
143
|
+
[tool.poetry.group.build-refresh-version.dependencies]
|
|
144
|
+
charm-refresh-build-version = "^0.4.0"
|
|
145
|
+
|
|
139
146
|
[tool.ruff]
|
|
140
147
|
target-version = "py310"
|
|
141
148
|
line-length = 100
|
|
@@ -26,6 +26,7 @@ a DB Engine and storage), and the main peer relation name will be
|
|
|
26
26
|
import logging
|
|
27
27
|
from typing import ClassVar, Generic, TypeVar
|
|
28
28
|
|
|
29
|
+
import ops.log
|
|
29
30
|
from data_platform_helpers.advanced_statuses.handler import StatusHandler
|
|
30
31
|
from data_platform_helpers.advanced_statuses.models import StatusObject
|
|
31
32
|
from data_platform_helpers.advanced_statuses.protocol import ManagerStatusProtocol
|
|
@@ -43,6 +44,8 @@ T = TypeVar("T", bound=MongoConfigModel)
|
|
|
43
44
|
U = TypeVar("U", bound=OperatorProtocol)
|
|
44
45
|
|
|
45
46
|
logger = logging.getLogger(__name__)
|
|
47
|
+
logging.getLogger("httpx").setLevel(logging.WARNING)
|
|
48
|
+
logging.getLogger("httpcore").setLevel(logging.WARNING)
|
|
46
49
|
|
|
47
50
|
|
|
48
51
|
class AbstractMongoCharm(ManagerStatusProtocol, Generic[T, U], CharmBase):
|
|
@@ -69,6 +72,11 @@ class AbstractMongoCharm(ManagerStatusProtocol, Generic[T, U], CharmBase):
|
|
|
69
72
|
# Init the Juju object Object
|
|
70
73
|
super(Generic, self).__init__(*args)
|
|
71
74
|
|
|
75
|
+
root_logger = logging.getLogger()
|
|
76
|
+
for handler in root_logger.handlers:
|
|
77
|
+
if isinstance(handler, ops.log.JujuLogHandler):
|
|
78
|
+
handler.setFormatter(logging.Formatter("{name}:{message}", style="{"))
|
|
79
|
+
|
|
72
80
|
# Create the operator instance (one of MongoDBOperator or MongosOperator)
|
|
73
81
|
self.operator = self.operator_type(self)
|
|
74
82
|
self.state = self.operator.state
|
|
@@ -50,28 +50,9 @@ class InternalUsernames(str, Enum):
|
|
|
50
50
|
LOGROTATE = "logrotate"
|
|
51
51
|
|
|
52
52
|
|
|
53
|
-
class UnitState(str, Enum):
|
|
54
|
-
"""Unit upgrade state."""
|
|
55
|
-
|
|
56
|
-
HEALTHY = "healthy"
|
|
57
|
-
RESTARTING = "restarting" # Kubernetes only
|
|
58
|
-
UPGRADING = "upgrading" # Machines only
|
|
59
|
-
OUTDATED = "outdated" # Machines only
|
|
60
|
-
|
|
61
|
-
|
|
62
53
|
SECRETS_APP = [f"{user}-password" for user in InternalUsernames] + ["keyfile"]
|
|
63
54
|
|
|
64
|
-
|
|
65
|
-
@dataclass(frozen=True)
|
|
66
|
-
class Snap:
|
|
67
|
-
"""The Snap related information."""
|
|
68
|
-
|
|
69
|
-
name: str = "charmed-mongodb"
|
|
70
|
-
channel: str = "8/edge"
|
|
71
|
-
revision: str = "133"
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
SNAP = Snap(channel="8/edge", revision="133")
|
|
55
|
+
VERSIONS_FILE = Path("refresh_versions.toml")
|
|
75
56
|
|
|
76
57
|
T = TypeVar("T", bound=str | int)
|
|
77
58
|
|
|
@@ -38,6 +38,20 @@ class MongoDBStatuses(Enum):
|
|
|
38
38
|
check="Relation validation.",
|
|
39
39
|
action="Remove the relation on the shards interface (config-server or sharding relation) from this application.",
|
|
40
40
|
)
|
|
41
|
+
INVALID_CFG_SRV_ON_SHARD_REL = StatusObject(
|
|
42
|
+
status="blocked",
|
|
43
|
+
message="The config-server interface cannot be used by shards.",
|
|
44
|
+
short_message="Invalid config-server relation.",
|
|
45
|
+
check="Relation validation.",
|
|
46
|
+
action="Remove the relation on the config-server interface from this application.",
|
|
47
|
+
)
|
|
48
|
+
INVALID_SHARD_ON_CFG_SRV_REL = StatusObject(
|
|
49
|
+
status="blocked",
|
|
50
|
+
message="The sharding interface cannot be used by a config-server.",
|
|
51
|
+
short_message="Invalid sharding relation.",
|
|
52
|
+
check="Relation validation.",
|
|
53
|
+
action="Remove the relation on the sharding interface from this application.",
|
|
54
|
+
)
|
|
41
55
|
INVALID_MONGOS_REL = StatusObject(
|
|
42
56
|
status="blocked",
|
|
43
57
|
message="The cluster relation can only be used by config servers.",
|
|
@@ -91,6 +105,12 @@ class MongosStatuses(Enum):
|
|
|
91
105
|
message="Waiting for mongos to start...",
|
|
92
106
|
check="mongos process status check.",
|
|
93
107
|
)
|
|
108
|
+
INVALID_REL = StatusObject(
|
|
109
|
+
status="blocked",
|
|
110
|
+
message="The relation is invalid.",
|
|
111
|
+
check="Mongos charm relation check",
|
|
112
|
+
action="Remove the relation on mongos",
|
|
113
|
+
)
|
|
94
114
|
INVALID_EXPOSE_EXTERNAL = StatusObject(
|
|
95
115
|
status="blocked",
|
|
96
116
|
message="The expose-external config option is invalid. Valid options are `nodeport` and `none`.",
|
|
@@ -119,16 +139,16 @@ class MongosStatuses(Enum):
|
|
|
119
139
|
check="Relation validation failed.",
|
|
120
140
|
action="Verify the certificates relations. Use the same CA for all cluster components.",
|
|
121
141
|
)
|
|
122
|
-
|
|
123
|
-
# Running statuses:
|
|
142
|
+
MONGOS_NOT_STARTED = StatusObject(status="waiting", message="Waiting to start mongos...")
|
|
124
143
|
MISSING_CONF_SERVER_REL = StatusObject(
|
|
125
144
|
status="blocked",
|
|
126
145
|
message="The cluster relation with the config-server is missing.",
|
|
127
146
|
short_message="Missing cluster relation.",
|
|
128
147
|
check="Relation validation failed.",
|
|
129
148
|
action="Add the cluster relation (config-server interface) to mongos.",
|
|
130
|
-
running="async",
|
|
131
149
|
)
|
|
150
|
+
|
|
151
|
+
# Running statuses:
|
|
132
152
|
STARTING_MONGOS = StatusObject(
|
|
133
153
|
status="maintenance", message="Starting mongos.", running="blocking"
|
|
134
154
|
)
|
|
@@ -229,6 +249,11 @@ class BackupStatuses(Enum):
|
|
|
229
249
|
PBM_WAITING_TO_SYNC = StatusObject(
|
|
230
250
|
status="waiting", message="Waiting to sync S3 configurations...", running="async"
|
|
231
251
|
)
|
|
252
|
+
ACTION_RUNNING = StatusObject(
|
|
253
|
+
status="waiting",
|
|
254
|
+
message="Waiting for backup/restore to finish before removing the relation",
|
|
255
|
+
running="blocking",
|
|
256
|
+
)
|
|
232
257
|
|
|
233
258
|
@staticmethod
|
|
234
259
|
def backup_running(backup_id: str) -> StatusObject:
|
|
@@ -412,66 +437,19 @@ class UpgradeStatuses(Enum):
|
|
|
412
437
|
"""Upgrade statuses."""
|
|
413
438
|
|
|
414
439
|
ACTIVE_IDLE = StatusObject(status="active", message="")
|
|
415
|
-
|
|
416
|
-
status="
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
status="blocked",
|
|
420
|
-
message="Unhealthy after refresh. Rollback to previous revision with `juju refresh`.",
|
|
421
|
-
approved_critical_component=True,
|
|
422
|
-
)
|
|
423
|
-
INCOMPATIBLE_UPGRADE = StatusObject(
|
|
424
|
-
status="blocked",
|
|
425
|
-
message="Refresh incompatible. Rollback to previous revision with `juju refresh`.",
|
|
440
|
+
HEALTH_CHECK_FAILED = StatusObject(
|
|
441
|
+
status="maintenance",
|
|
442
|
+
message="MongoDB is not running after upgrade",
|
|
443
|
+
action="check logs for extra information.",
|
|
426
444
|
approved_critical_component=True,
|
|
427
445
|
)
|
|
428
|
-
|
|
446
|
+
CLUSTER_CHECK_FAILED = StatusObject(
|
|
429
447
|
status="maintenance",
|
|
430
|
-
message="
|
|
431
|
-
action="
|
|
448
|
+
message="Cluster is not healthy after upgrade",
|
|
449
|
+
action="check logs for extra information.",
|
|
432
450
|
approved_critical_component=True,
|
|
433
451
|
)
|
|
434
452
|
|
|
435
|
-
@staticmethod
|
|
436
|
-
def vm_active_upgrade(
|
|
437
|
-
unit_workload_version: str | None,
|
|
438
|
-
unit_workload_container_version: str | None,
|
|
439
|
-
current_versions: str,
|
|
440
|
-
outdated: bool = False,
|
|
441
|
-
) -> StatusObject:
|
|
442
|
-
"""Returns the active status for a vm unit."""
|
|
443
|
-
outdated_str = " (outdated)" if outdated else ""
|
|
444
|
-
return StatusObject(
|
|
445
|
-
status="active",
|
|
446
|
-
message=f"MongoDB {unit_workload_version} running; "
|
|
447
|
-
f"Snap revision {unit_workload_container_version}{outdated_str}; "
|
|
448
|
-
f"Charm revision {current_versions}.",
|
|
449
|
-
approved_critical_component=True,
|
|
450
|
-
)
|
|
451
|
-
|
|
452
|
-
@staticmethod
|
|
453
|
-
def k8s_active_upgrade(
|
|
454
|
-
workload_version: str, charm_version: str, outdated=False
|
|
455
|
-
) -> StatusObject:
|
|
456
|
-
"""Returns the active status for a k8s unit."""
|
|
457
|
-
outdated_str = " (restart pending)" if outdated else ""
|
|
458
|
-
return StatusObject(
|
|
459
|
-
status="active",
|
|
460
|
-
message=f"MongoDB {workload_version} running{outdated_str}; Charm revision {charm_version}.",
|
|
461
|
-
approved_critical_component=True,
|
|
462
|
-
)
|
|
463
|
-
|
|
464
|
-
@staticmethod
|
|
465
|
-
def refreshing_needs_resume(
|
|
466
|
-
resume_string: str,
|
|
467
|
-
) -> StatusObject:
|
|
468
|
-
"""Returns refreshing status."""
|
|
469
|
-
return StatusObject(
|
|
470
|
-
status="blocked",
|
|
471
|
-
message=f"Refreshing. {resume_string}To rollback, `juju refresh` to last revision.",
|
|
472
|
-
approved_critical_component=True,
|
|
473
|
-
)
|
|
474
|
-
|
|
475
453
|
|
|
476
454
|
class LdapStatuses(Enum):
|
|
477
455
|
"""Ldap Statuses."""
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
"""Common code for upgrades."""
|
|
2
|
+
|
|
3
|
+
import abc
|
|
4
|
+
import dataclasses
|
|
5
|
+
import logging
|
|
6
|
+
|
|
7
|
+
import charm_refresh
|
|
8
|
+
import poetry.core.constraints.version as poetry_version
|
|
9
|
+
from tenacity import RetryError
|
|
10
|
+
from typing_extensions import override
|
|
11
|
+
|
|
12
|
+
from single_kernel_mongo.config.literals import CharmKind
|
|
13
|
+
from single_kernel_mongo.config.models import BackupState
|
|
14
|
+
from single_kernel_mongo.core.operator import OperatorProtocol
|
|
15
|
+
from single_kernel_mongo.exceptions import (
|
|
16
|
+
FailedToMovePrimaryError,
|
|
17
|
+
)
|
|
18
|
+
from single_kernel_mongo.managers.upgrade_v3 import MongoDBUpgradesManager
|
|
19
|
+
from single_kernel_mongo.state.charm_state import CharmState
|
|
20
|
+
|
|
21
|
+
logger = logging.getLogger()
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@dataclasses.dataclass(eq=False)
|
|
25
|
+
class MongoDBRefresh(charm_refresh.CharmSpecificCommon, abc.ABC):
|
|
26
|
+
"""Common code for MongoDB Refreshes."""
|
|
27
|
+
|
|
28
|
+
dependent: OperatorProtocol
|
|
29
|
+
upgrades_manager: MongoDBUpgradesManager
|
|
30
|
+
state: CharmState
|
|
31
|
+
|
|
32
|
+
@classmethod
|
|
33
|
+
@override
|
|
34
|
+
def is_compatible(
|
|
35
|
+
cls,
|
|
36
|
+
*,
|
|
37
|
+
old_charm_version: charm_refresh.CharmVersion,
|
|
38
|
+
new_charm_version: charm_refresh.CharmVersion,
|
|
39
|
+
old_workload_version: str,
|
|
40
|
+
new_workload_version: str,
|
|
41
|
+
) -> bool:
|
|
42
|
+
# Check charm version compatibility
|
|
43
|
+
if not super().is_compatible(
|
|
44
|
+
old_charm_version=old_charm_version,
|
|
45
|
+
new_charm_version=new_charm_version,
|
|
46
|
+
old_workload_version=old_workload_version,
|
|
47
|
+
new_workload_version=new_workload_version,
|
|
48
|
+
):
|
|
49
|
+
return False
|
|
50
|
+
return cls.is_workload_compatible(
|
|
51
|
+
old_workload_version=old_workload_version, new_workload_version=new_workload_version
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
@staticmethod
|
|
55
|
+
def is_workload_compatible(
|
|
56
|
+
old_workload_version: str,
|
|
57
|
+
new_workload_version: str,
|
|
58
|
+
) -> bool:
|
|
59
|
+
"""Check if the workload versions are compatible.
|
|
60
|
+
|
|
61
|
+
This method is called on the new charm code version. This means that it is responsible for
|
|
62
|
+
determining which versions the charm code supports refreshing from - not refreshing to.
|
|
63
|
+
"""
|
|
64
|
+
try:
|
|
65
|
+
old_version = poetry_version.Version.parse(old_workload_version)
|
|
66
|
+
new_version = poetry_version.Version.parse(new_workload_version)
|
|
67
|
+
except ValueError:
|
|
68
|
+
# Not enough values to unpack or cannot convert
|
|
69
|
+
logger.error(
|
|
70
|
+
"Unable to parse workload versions."
|
|
71
|
+
f"Got {old_workload_version} to {new_workload_version}"
|
|
72
|
+
)
|
|
73
|
+
return False
|
|
74
|
+
|
|
75
|
+
if old_version.major != new_version.major:
|
|
76
|
+
logger.info(
|
|
77
|
+
"Refreshing to a different major version workload is not supported. "
|
|
78
|
+
f"Got {old_version.major} to {new_version.major}"
|
|
79
|
+
)
|
|
80
|
+
return False
|
|
81
|
+
|
|
82
|
+
if old_version > new_version:
|
|
83
|
+
logger.info(
|
|
84
|
+
"Refreshing to an older minor version workload is not supported. "
|
|
85
|
+
f"Got {old_version} to {new_version}"
|
|
86
|
+
)
|
|
87
|
+
return False
|
|
88
|
+
|
|
89
|
+
return True
|
|
90
|
+
|
|
91
|
+
def _mongodb_checks(self) -> None:
|
|
92
|
+
"""MongoDB specific checks."""
|
|
93
|
+
try:
|
|
94
|
+
self.upgrades_manager.wait_for_cluster_healthy()
|
|
95
|
+
except RetryError as e:
|
|
96
|
+
logger.error(
|
|
97
|
+
"Cannot proceed with refresh. Failed to check cluster health, error: %s", e
|
|
98
|
+
)
|
|
99
|
+
raise charm_refresh.PrecheckFailed("Cluster is not healthy")
|
|
100
|
+
|
|
101
|
+
try:
|
|
102
|
+
self.upgrades_manager.move_primary_to_last_upgrade_unit()
|
|
103
|
+
except FailedToMovePrimaryError:
|
|
104
|
+
logger.error("Cluster failed to move primary before re-election.")
|
|
105
|
+
raise charm_refresh.PrecheckFailed("Primary switchover failed")
|
|
106
|
+
|
|
107
|
+
if not self.upgrades_manager.is_cluster_able_to_read_write():
|
|
108
|
+
logger.error("Cluster cannot read/write to replicas")
|
|
109
|
+
raise charm_refresh.PrecheckFailed("Cluster is not able to read/write to replicas")
|
|
110
|
+
|
|
111
|
+
fcv = self.state.app_peer_data.feature_compatibility_version
|
|
112
|
+
if not self.upgrades_manager.is_feature_compatibility_version(fcv):
|
|
113
|
+
logger.info(
|
|
114
|
+
"Not all replicas have the expected feature compatibility: %s",
|
|
115
|
+
fcv,
|
|
116
|
+
)
|
|
117
|
+
raise charm_refresh.PrecheckFailed(f"Not all replicas have the expected FCV {fcv}.")
|
|
118
|
+
|
|
119
|
+
def run_pre_refresh_checks_after_1_unit_refreshed(self):
|
|
120
|
+
"""Implement pre-refresh checks."""
|
|
121
|
+
if not self.state.db_initialised:
|
|
122
|
+
return
|
|
123
|
+
|
|
124
|
+
if self.dependent.name == CharmKind.MONGOS:
|
|
125
|
+
if not self.upgrades_manager.is_mongos_able_to_read_write():
|
|
126
|
+
raise charm_refresh.PrecheckFailed("mongos is not able to read/write")
|
|
127
|
+
return
|
|
128
|
+
|
|
129
|
+
backup_state = self.dependent.backup_manager.backup_state()
|
|
130
|
+
|
|
131
|
+
if backup_state == BackupState.BACKUP_RUNNING:
|
|
132
|
+
raise charm_refresh.PrecheckFailed("Backup in progress.")
|
|
133
|
+
if backup_state == BackupState.RESTORE_RUNNING:
|
|
134
|
+
raise charm_refresh.PrecheckFailed("Restore in progress.")
|
|
135
|
+
|
|
136
|
+
self._mongodb_checks()
|
|
137
|
+
|
|
138
|
+
if not self.upgrades_manager.are_pre_upgrade_operations_config_server_successful():
|
|
139
|
+
raise charm_refresh.PrecheckFailed("Failed to disabled balancer.")
|
|
140
|
+
|
|
141
|
+
def run_pre_refresh_checks_before_any_units_refreshed(self):
|
|
142
|
+
"""Runs before the upgrade."""
|
|
143
|
+
if not self.state.db_initialised:
|
|
144
|
+
return
|
|
145
|
+
if self.dependent.name == CharmKind.MONGOD:
|
|
146
|
+
if not self.dependent.mongo_manager.mongod_ready():
|
|
147
|
+
logger.error("Cannot proceed with refresh. Service mongod is not running.")
|
|
148
|
+
raise charm_refresh.PrecheckFailed("mongod is not running")
|
|
149
|
+
self.run_pre_refresh_checks_after_1_unit_refreshed()
|
|
@@ -39,8 +39,8 @@ class KubernetesWorkload(WorkloadBase):
|
|
|
39
39
|
return self.container.can_connect()
|
|
40
40
|
|
|
41
41
|
@override
|
|
42
|
-
def install(self) ->
|
|
43
|
-
return
|
|
42
|
+
def install(self, revision: str | None = None, retry_and_raise: bool = True) -> bool:
|
|
43
|
+
return True
|
|
44
44
|
|
|
45
45
|
@override
|
|
46
46
|
def start(self) -> None:
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"""Kubernetes code for upgrades."""
|
|
2
|
+
|
|
3
|
+
import dataclasses
|
|
4
|
+
|
|
5
|
+
import charm_refresh
|
|
6
|
+
|
|
7
|
+
from single_kernel_mongo.core.abstract_upgrades_v3 import MongoDBRefresh
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@dataclasses.dataclass(eq=False)
|
|
11
|
+
class KubernetesMongoDBRefresh(
|
|
12
|
+
MongoDBRefresh,
|
|
13
|
+
charm_refresh.CharmSpecificKubernetes,
|
|
14
|
+
):
|
|
15
|
+
"""Kubernetes specific refresh code."""
|
|
16
|
+
|
|
17
|
+
pass
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"""Machine code for upgrades."""
|
|
2
|
+
|
|
3
|
+
import dataclasses
|
|
4
|
+
import logging
|
|
5
|
+
|
|
6
|
+
import charm_refresh
|
|
7
|
+
|
|
8
|
+
from single_kernel_mongo.config.literals import CharmKind
|
|
9
|
+
from single_kernel_mongo.core.abstract_upgrades_v3 import MongoDBRefresh
|
|
10
|
+
from single_kernel_mongo.exceptions import FailedToElectNewPrimaryError, MongoDBUpgradeError
|
|
11
|
+
|
|
12
|
+
logger = logging.getLogger(__name__)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@dataclasses.dataclass(eq=False)
|
|
16
|
+
class MachineMongoDBRefresh(
|
|
17
|
+
MongoDBRefresh,
|
|
18
|
+
charm_refresh.CharmSpecificMachines,
|
|
19
|
+
):
|
|
20
|
+
"""Machine specific refresh code."""
|
|
21
|
+
|
|
22
|
+
def refresh_snap(
|
|
23
|
+
self, *, snap_name: str, snap_revision: str, refresh: charm_refresh.Machines
|
|
24
|
+
) -> None:
|
|
25
|
+
"""Refreshes a snap."""
|
|
26
|
+
self.dependent.stop_charm_services()
|
|
27
|
+
|
|
28
|
+
if self.dependent.name == CharmKind.MONGOD:
|
|
29
|
+
try:
|
|
30
|
+
if self.dependent.charm.unit.name == self.dependent.primary_unit_name:
|
|
31
|
+
self.dependent.mongo_manager.step_down_primary_and_wait_reelection()
|
|
32
|
+
except FailedToElectNewPrimaryError:
|
|
33
|
+
logger.error("Failed to reelect primary before upgrading unit.")
|
|
34
|
+
return
|
|
35
|
+
|
|
36
|
+
revision_before_refresh = self.dependent.workload.snap_revision()
|
|
37
|
+
assert (
|
|
38
|
+
snap_revision != revision_before_refresh
|
|
39
|
+
), "current snap revision and target revision are equal"
|
|
40
|
+
|
|
41
|
+
logger.info("Updating snap installation")
|
|
42
|
+
if not self.dependent.workload.install(revision=snap_revision, retry_and_raise=False):
|
|
43
|
+
logger.exception("Snap refresh failed")
|
|
44
|
+
|
|
45
|
+
if self.charm.workload.snap_revision() == revision_before_refresh:
|
|
46
|
+
self.dependent.start_charm_services()
|
|
47
|
+
else:
|
|
48
|
+
refresh.update_snap_revision()
|
|
49
|
+
|
|
50
|
+
# Ensures that the unit receives another juju event.
|
|
51
|
+
raise MongoDBUpgradeError("Snap Refresh failed.")
|
|
52
|
+
|
|
53
|
+
refresh.update_snap_revision()
|
|
54
|
+
logger.info(f"Updated snap to revision {snap_revision}")
|
|
@@ -21,6 +21,7 @@ from logging import getLogger
|
|
|
21
21
|
from pathlib import Path
|
|
22
22
|
from typing import TYPE_CHECKING, ClassVar, TypeAlias
|
|
23
23
|
|
|
24
|
+
import charm_refresh
|
|
24
25
|
from data_platform_helpers.advanced_statuses.models import StatusObject
|
|
25
26
|
from data_platform_helpers.advanced_statuses.protocol import ManagerStatusProtocol
|
|
26
27
|
from ops.charm import RelationDepartedEvent
|
|
@@ -49,10 +50,10 @@ if TYPE_CHECKING:
|
|
|
49
50
|
from single_kernel_mongo.abstract_charm import AbstractMongoCharm
|
|
50
51
|
from single_kernel_mongo.events.database import DatabaseEventsHandler
|
|
51
52
|
from single_kernel_mongo.events.tls import TLSEventsHandler
|
|
52
|
-
from single_kernel_mongo.events.upgrades import UpgradeEventHandler
|
|
53
53
|
from single_kernel_mongo.managers.ldap import LDAPManager
|
|
54
54
|
from single_kernel_mongo.managers.tls import TLSManager
|
|
55
|
-
from single_kernel_mongo.managers.
|
|
55
|
+
from single_kernel_mongo.managers.upgrade_v3 import MongoDBUpgradesManager
|
|
56
|
+
from single_kernel_mongo.managers.upgrade_v3_status import MongoDBUpgradesStatusManager
|
|
56
57
|
|
|
57
58
|
logger = getLogger(__name__)
|
|
58
59
|
|
|
@@ -79,13 +80,14 @@ class OperatorProtocol(ABC, Object, ManagerStatusProtocol):
|
|
|
79
80
|
config_manager: FileBasedConfigManager
|
|
80
81
|
tls_manager: TLSManager
|
|
81
82
|
state: CharmState
|
|
83
|
+
refresh: charm_refresh.Common | None
|
|
82
84
|
mongo_manager: MongoManager
|
|
83
|
-
|
|
85
|
+
upgrades_manager: MongoDBUpgradesManager
|
|
86
|
+
upgrades_status_manager: MongoDBUpgradesStatusManager
|
|
84
87
|
ldap_manager: LDAPManager
|
|
85
88
|
workload: MainWorkloadType
|
|
86
89
|
client_events: DatabaseEventsHandler
|
|
87
90
|
tls_events: TLSEventsHandler
|
|
88
|
-
upgrade_events: UpgradeEventHandler
|
|
89
91
|
ldap_events: LDAPEventHandler
|
|
90
92
|
|
|
91
93
|
if TYPE_CHECKING:
|
|
@@ -173,7 +175,7 @@ class OperatorProtocol(ABC, Object, ManagerStatusProtocol):
|
|
|
173
175
|
...
|
|
174
176
|
|
|
175
177
|
@abstractmethod
|
|
176
|
-
def
|
|
178
|
+
def get_relation_feasible_status(self, name: str) -> StatusObject | None:
|
|
177
179
|
"""Checks if the relation is feasible in this context."""
|
|
178
180
|
...
|
|
179
181
|
|
|
@@ -215,6 +217,13 @@ class OperatorProtocol(ABC, Object, ManagerStatusProtocol):
|
|
|
215
217
|
"Scaling down the application, no need to process removed relation in broken hook."
|
|
216
218
|
)
|
|
217
219
|
|
|
220
|
+
@property
|
|
221
|
+
def refresh_in_progress(self) -> bool:
|
|
222
|
+
"""Check if charm-refresh is currently in progress."""
|
|
223
|
+
# If charm_refresh.UnitTearDown or charm_refresh.PeerRelationNotReady
|
|
224
|
+
# we consider a refresh to be in progress.
|
|
225
|
+
return not self.refresh or self.refresh.in_progress
|
|
226
|
+
|
|
218
227
|
def handle_licenses(self) -> None:
|
|
219
228
|
"""Pull / Push licenses.
|
|
220
229
|
|
|
@@ -305,3 +314,15 @@ class OperatorProtocol(ABC, Object, ManagerStatusProtocol):
|
|
|
305
314
|
self.workload.exec(["update-ca-certificates"])
|
|
306
315
|
# Restart the service
|
|
307
316
|
self.restart_charm_services(force=True)
|
|
317
|
+
|
|
318
|
+
def build_local_tls_directory(self) -> None:
|
|
319
|
+
"""On Kubernetes, we need the local configuration directory.
|
|
320
|
+
|
|
321
|
+
This will store the certificates locally, which allows to construct the
|
|
322
|
+
same URIS to connect locally and on the sidecar container running
|
|
323
|
+
mongodb.
|
|
324
|
+
"""
|
|
325
|
+
if self.substrate == Substrates.VM:
|
|
326
|
+
return
|
|
327
|
+
|
|
328
|
+
Path(self.state.paths.conf_path).mkdir(exist_ok=True)
|
|
@@ -36,19 +36,20 @@ class VersionChecker:
|
|
|
36
36
|
# revision 88 and a config-server running on revision 110
|
|
37
37
|
current_charms_version = get_charm_revision(
|
|
38
38
|
self.charm.unit,
|
|
39
|
-
local_version=self.dependent.workload.
|
|
39
|
+
local_version=self.dependent.workload.get_charm_revision(),
|
|
40
40
|
)
|
|
41
41
|
local_identifier = (
|
|
42
42
|
"-locally built" if self.version_checker.is_local_charm(self.charm.app.name) else ""
|
|
43
43
|
)
|
|
44
44
|
try:
|
|
45
|
-
# This part needs some explanation:
|
|
46
|
-
# the pre-refresh hook that happens after the upgrade,
|
|
47
|
-
#
|
|
45
|
+
# This part needs some explanation: On VM, if we are running this
|
|
46
|
+
# during the pre-refresh hook that happens after the upgrade, all
|
|
47
|
+
# charm codes have been refreshed.
|
|
48
|
+
# We want to check our version against the already upgraded config server, so
|
|
48
49
|
# we use the current revision that stores the revision of the
|
|
49
|
-
# former charm until
|
|
50
|
+
# former charm until that unit is fully upgraded.
|
|
50
51
|
old_version = self.version_checker.version
|
|
51
|
-
self.version_checker.version = self.state.
|
|
52
|
+
self.version_checker.version = self.state.unit_peer_data.current_revision
|
|
52
53
|
if self.version_checker.are_related_apps_valid():
|
|
53
54
|
return None
|
|
54
55
|
except NoVersionError as e:
|
|
@@ -9,18 +9,18 @@ from collections.abc import Mapping
|
|
|
9
9
|
from itertools import chain
|
|
10
10
|
from logging import getLogger
|
|
11
11
|
from pathlib import Path
|
|
12
|
+
from platform import machine
|
|
12
13
|
from shutil import copyfile
|
|
13
14
|
|
|
14
15
|
from ops import Container
|
|
15
|
-
from tenacity import retry, retry_if_result, stop_after_attempt, wait_fixed
|
|
16
|
+
from tenacity import retry, retry_if_exception_type, retry_if_result, stop_after_attempt, wait_fixed
|
|
16
17
|
from typing_extensions import override
|
|
17
18
|
|
|
18
19
|
from single_kernel_mongo.config.literals import (
|
|
19
20
|
CRON_FILE,
|
|
20
|
-
SNAP,
|
|
21
21
|
VmUser,
|
|
22
22
|
)
|
|
23
|
-
from single_kernel_mongo.config.models import CharmSpec
|
|
23
|
+
from single_kernel_mongo.config.models import SNAP_NAME, CharmSpec
|
|
24
24
|
from single_kernel_mongo.core.workload import WorkloadBase
|
|
25
25
|
from single_kernel_mongo.exceptions import (
|
|
26
26
|
WorkloadExecError,
|
|
@@ -41,8 +41,7 @@ class VMWorkload(WorkloadBase):
|
|
|
41
41
|
|
|
42
42
|
def __init__(self, role: CharmSpec, container: Container | None) -> None:
|
|
43
43
|
super().__init__(role, container)
|
|
44
|
-
self.
|
|
45
|
-
self.mongod_snap = snap.SnapCache()[self.snap.name]
|
|
44
|
+
self.mongod_snap = snap.SnapCache()[SNAP_NAME]
|
|
46
45
|
|
|
47
46
|
@property
|
|
48
47
|
@override
|
|
@@ -186,23 +185,41 @@ class VMWorkload(WorkloadBase):
|
|
|
186
185
|
stop=stop_after_attempt(20),
|
|
187
186
|
wait=wait_fixed(1),
|
|
188
187
|
reraise=True,
|
|
188
|
+
retry=retry_if_exception_type(WorkloadServiceError),
|
|
189
189
|
)
|
|
190
|
-
def install(self) ->
|
|
191
|
-
"""
|
|
190
|
+
def install(self, revision: str | None = None, retry_and_raise: bool = True) -> bool:
|
|
191
|
+
"""Install the charmed-mongodb snap from the snap store.
|
|
192
|
+
|
|
193
|
+
Args:
|
|
194
|
+
revision (str | None): the snap revision to install. Will be loaded from the
|
|
195
|
+
`refresh_versions.toml` file if None.
|
|
196
|
+
retry_and_raise (bool): whether to retry in case of errors. Will raise if the error
|
|
197
|
+
persists.
|
|
192
198
|
|
|
193
199
|
Returns:
|
|
194
|
-
True if successfully installed
|
|
200
|
+
True if successfully installed, False if errors occur and `retry_and_raise` is False.
|
|
195
201
|
"""
|
|
196
202
|
try:
|
|
203
|
+
if not revision:
|
|
204
|
+
versions = self.load_toml_file(Path("refresh_versions.toml"))
|
|
205
|
+
revision = versions["snap"]["revisions"][machine()]
|
|
206
|
+
|
|
197
207
|
self.mongod_snap.ensure(
|
|
198
|
-
snap.SnapState.
|
|
199
|
-
|
|
200
|
-
revision=self.snap.revision,
|
|
208
|
+
snap.SnapState.Present,
|
|
209
|
+
revision=revision,
|
|
201
210
|
)
|
|
202
211
|
self.mongod_snap.hold()
|
|
212
|
+
return True
|
|
203
213
|
except snap.SnapError as err:
|
|
204
|
-
logger.error(f"Failed to install {
|
|
205
|
-
|
|
214
|
+
logger.error(f"Failed to install {SNAP_NAME}. Reason: {err}.")
|
|
215
|
+
if retry_and_raise:
|
|
216
|
+
raise WorkloadNotReadyError("Failed to install mongodb")
|
|
217
|
+
return False
|
|
218
|
+
|
|
219
|
+
@override
|
|
220
|
+
def snap_revision(self) -> str:
|
|
221
|
+
"""The currently installed snap_revision."""
|
|
222
|
+
return self.mongod_snap.revision
|
|
206
223
|
|
|
207
224
|
@override
|
|
208
225
|
def setup_cron(self, lines: list[str]) -> None: # pragma: nocover
|