21
21
22
22
logger = logging .getLogger (__name__ )
23
23
24
- _snap_name = charm_refresh .snap_name ()
25
- _snap = snap_lib .SnapCache ()[_snap_name ]
26
- _installed_by_unit = pathlib .Path (
27
- "/var/snap" , _snap_name , "common" , "installed_by_mysql_router_charm_unit"
28
- )
29
24
_UNIX_USERNAME = "snap_daemon"
30
25
31
26
@@ -38,48 +33,60 @@ def _raise_if_snap_installed_not_by_this_charm(*, unit: ops.Unit, model_uuid: st
38
33
39
34
Assumes snap is installed
40
35
"""
36
+ snap_name = charm_refresh .snap_name ()
37
+ installed_by_unit = pathlib .Path (
38
+ "/var/snap" , snap_name , "common" , "installed_by_mysql_router_charm_unit"
39
+ )
40
+
41
41
if not (
42
- _installed_by_unit .exists ()
43
- and _installed_by_unit .read_text () == _unique_unit_name (unit = unit , model_uuid = model_uuid )
42
+ installed_by_unit .exists ()
43
+ and installed_by_unit .read_text () == _unique_unit_name (unit = unit , model_uuid = model_uuid )
44
44
):
45
45
# The snap could be in use by another charm (e.g. MySQL Server charm, a different MySQL
46
46
# Router charm).
47
47
logger .debug (
48
- f"{ _installed_by_unit .exists () and _installed_by_unit .read_text ()= } { _unique_unit_name (unit = unit , model_uuid = model_uuid )= } "
48
+ f"{ installed_by_unit .exists () and installed_by_unit .read_text ()= } "
49
+ f"{ _unique_unit_name (unit = unit , model_uuid = model_uuid )= } "
49
50
)
50
- logger .error (f"{ _snap_name } snap already installed on machine. Installation aborted" )
51
- raise Exception (f"Multiple { _snap_name } snap installs not supported on one machine" )
51
+ logger .error (f"{ snap_name } snap already installed on machine. Installation aborted" )
52
+ raise Exception (f"Multiple { snap_name } snap installs not supported on one machine" )
52
53
53
54
54
55
def uninstall ():
55
56
"""Uninstall snap if installed"""
56
- logger .debug (f"Ensuring { _snap_name = } is uninstalled" )
57
- _snap .ensure (state = snap_lib .SnapState .Absent )
58
- logger .debug (f"Ensured { _snap_name = } is uninstalled" )
57
+ snap_name = charm_refresh .snap_name ()
58
+ snap = snap_lib .SnapCache ()[snap_name ]
59
+
60
+ logger .debug (f"Ensuring { snap_name = } is uninstalled" )
61
+ snap .ensure (state = snap_lib .SnapState .Absent )
62
+ logger .debug (f"Ensured { snap_name = } is uninstalled" )
59
63
60
64
61
65
class _Path (pathlib .PosixPath , container .Path ):
62
66
def __new__ (cls , * args , ** kwargs ):
63
67
path = super ().__new__ (cls , * args , ** kwargs )
68
+ snap_name = charm_refresh .snap_name ()
69
+
64
70
if args and isinstance (args [0 ], cls ) and (parent_ := args [0 ]._container_parent ):
65
71
path ._container_parent = parent_
66
72
else :
67
73
if str (path ).startswith ("/etc/mysqlrouter" ) or str (path ).startswith (
68
74
"/var/lib/mysqlrouter"
69
75
):
70
- parent = f"/var/snap/{ _snap_name } /current"
76
+ parent = f"/var/snap/{ snap_name } /current"
71
77
elif str (path ).startswith ("/run/mysqlrouter" ) or str (path ).startswith (
72
78
"/var/log/mysqlrouter"
73
79
):
74
- parent = f"/var/snap/{ _snap_name } /common"
80
+ parent = f"/var/snap/{ snap_name } /common"
75
81
elif str (path ).startswith ("/tmp" ):
76
- parent = f"/tmp/snap-private-tmp/snap.{ _snap_name } "
82
+ parent = f"/tmp/snap-private-tmp/snap.{ snap_name } "
77
83
else :
78
84
parent = None
79
85
if parent :
80
86
assert str (path ).startswith ("/" )
81
87
path = super ().__new__ (cls , parent , path .relative_to ("/" ), ** kwargs )
82
88
path ._container_parent = parent
89
+
83
90
return path
84
91
85
92
def __truediv__ (self , other ):
@@ -128,42 +135,51 @@ class Snap(container.Container):
128
135
_EXPORTER_SERVICE_NAME = "mysqlrouter-exporter"
129
136
130
137
def __init__ (self , * , unit_name : str ) -> None :
138
+ self ._snap_name = charm_refresh .snap_name ()
139
+ self ._installed_by_unit = pathlib .Path (
140
+ "/var/snap" , self ._snap_name , "common" , "installed_by_mysql_router_charm_unit"
141
+ )
142
+
131
143
super ().__init__ (
132
- mysql_router_command = f"{ _snap_name } .mysqlrouter" ,
133
- mysql_shell_command = f"{ _snap_name } .mysqlsh" ,
134
- mysql_router_password_command = f"{ _snap_name } .mysqlrouter-passwd" ,
144
+ mysql_router_command = f"{ self . _snap_name } .mysqlrouter" ,
145
+ mysql_shell_command = f"{ self . _snap_name } .mysqlsh" ,
146
+ mysql_router_password_command = f"{ self . _snap_name } .mysqlrouter-passwd" ,
135
147
unit_name = unit_name ,
136
148
)
137
149
150
+ @property
151
+ def _snap (self ):
152
+ return snap_lib .SnapCache ()[self ._snap_name ]
153
+
138
154
@property
139
155
def ready (self ) -> bool :
140
156
return True
141
157
142
158
@property
143
159
def mysql_router_service_enabled (self ) -> bool :
144
- return _snap .services [self ._SERVICE_NAME ]["active" ]
160
+ return self . _snap .services [self ._SERVICE_NAME ]["active" ]
145
161
146
162
@property
147
163
def mysql_router_exporter_service_enabled (self ) -> bool :
148
- return _snap .services [self ._EXPORTER_SERVICE_NAME ]["active" ]
164
+ return self . _snap .services [self ._EXPORTER_SERVICE_NAME ]["active" ]
149
165
150
166
def update_mysql_router_service (self , * , enabled : bool , tls : bool = None ) -> None :
151
167
super ().update_mysql_router_service (enabled = enabled , tls = tls )
152
168
153
169
if tls :
154
- _snap .set ({"mysqlrouter.extra-options" : f"--extra-config { self .tls_config_file } " })
170
+ self . _snap .set ({"mysqlrouter.extra-options" : f"--extra-config { self .tls_config_file } " })
155
171
else :
156
- _snap .unset ("mysqlrouter.extra-options" )
172
+ self . _snap .unset ("mysqlrouter.extra-options" )
157
173
158
- router_is_running = _snap .services [self ._SERVICE_NAME ]["active" ]
174
+ router_is_running = self . _snap .services [self ._SERVICE_NAME ]["active" ]
159
175
160
176
if enabled :
161
177
if router_is_running :
162
- _snap .restart ([self ._SERVICE_NAME ])
178
+ self . _snap .restart ([self ._SERVICE_NAME ])
163
179
else :
164
- _snap .start ([self ._SERVICE_NAME ], enable = True )
180
+ self . _snap .start ([self ._SERVICE_NAME ], enable = True )
165
181
else :
166
- _snap .stop ([self ._SERVICE_NAME ], disable = True )
182
+ self . _snap .stop ([self ._SERVICE_NAME ], disable = True )
167
183
168
184
def update_mysql_router_exporter_service (
169
185
self ,
@@ -185,38 +201,42 @@ def update_mysql_router_exporter_service(
185
201
)
186
202
187
203
if enabled :
188
- _snap .set ({
204
+ self . _snap .set ({
189
205
"mysqlrouter-exporter.listen-port" : config .listen_port ,
190
206
"mysqlrouter-exporter.user" : config .username ,
191
207
"mysqlrouter-exporter.password" : config .password ,
192
208
"mysqlrouter-exporter.url" : config .url ,
193
209
"mysqlrouter-exporter.service-name" : self ._unit_name .replace ("/" , "-" ),
194
210
})
195
211
if tls :
196
- _snap .set ({
212
+ self . _snap .set ({
197
213
"mysqlrouter.tls-cacert-path" : certificate_authority_filename ,
198
214
"mysqlrouter.tls-cert-path" : certificate_filename ,
199
215
"mysqlrouter.tls-key-path" : key_filename ,
200
216
})
201
217
else :
202
- _snap .unset ("mysqlrouter.tls-cacert-path" )
203
- _snap .unset ("mysqlrouter.tls-cert-path" )
204
- _snap .unset ("mysqlrouter.tls-key-path" )
205
- _snap .start ([self ._EXPORTER_SERVICE_NAME ], enable = True )
218
+ self . _snap .unset ("mysqlrouter.tls-cacert-path" )
219
+ self . _snap .unset ("mysqlrouter.tls-cert-path" )
220
+ self . _snap .unset ("mysqlrouter.tls-key-path" )
221
+ self . _snap .start ([self ._EXPORTER_SERVICE_NAME ], enable = True )
206
222
else :
207
- _snap .stop ([self ._EXPORTER_SERVICE_NAME ], disable = True )
208
- _snap .unset ("mysqlrouter-exporter.listen-port" )
209
- _snap .unset ("mysqlrouter-exporter.user" )
210
- _snap .unset ("mysqlrouter-exporter.password" )
211
- _snap .unset ("mysqlrouter-exporter.url" )
212
- _snap .unset ("mysqlrouter-exporter.service-name" )
213
- _snap .unset ("mysqlrouter.tls-cacert-path" )
214
- _snap .unset ("mysqlrouter.tls-cert-path" )
215
- _snap .unset ("mysqlrouter.tls-key-path" )
216
-
217
- @staticmethod
223
+ self ._snap .stop ([self ._EXPORTER_SERVICE_NAME ], disable = True )
224
+ self ._snap .unset ("mysqlrouter-exporter.listen-port" )
225
+ self ._snap .unset ("mysqlrouter-exporter.user" )
226
+ self ._snap .unset ("mysqlrouter-exporter.password" )
227
+ self ._snap .unset ("mysqlrouter-exporter.url" )
228
+ self ._snap .unset ("mysqlrouter-exporter.service-name" )
229
+ self ._snap .unset ("mysqlrouter.tls-cacert-path" )
230
+ self ._snap .unset ("mysqlrouter.tls-cert-path" )
231
+ self ._snap .unset ("mysqlrouter.tls-key-path" )
232
+
218
233
def install (
219
- * , unit : ops .Unit , model_uuid : str , snap_revision : str , refresh : charm_refresh .Machines
234
+ self ,
235
+ * ,
236
+ unit : ops .Unit ,
237
+ model_uuid : str ,
238
+ snap_revision : str ,
239
+ refresh : charm_refresh .Machines ,
220
240
) -> None :
221
241
"""Ensure snap is installed by this charm
222
242
@@ -226,7 +246,7 @@ def install(
226
246
Automatically retries if snap installation fails
227
247
"""
228
248
unique_unit_name = f"{ model_uuid } _{ unit .name } "
229
- if _snap .present :
249
+ if self . _snap .present :
230
250
_raise_if_snap_installed_not_by_this_charm (unit = unit , model_uuid = model_uuid )
231
251
return
232
252
# Install snap
@@ -246,16 +266,15 @@ def _set_retry_status(_) -> None:
246
266
reraise = True ,
247
267
):
248
268
with attempt :
249
- _snap .ensure (state = snap_lib .SnapState .Present , revision = snap_revision )
269
+ self . _snap .ensure (state = snap_lib .SnapState .Present , revision = snap_revision )
250
270
refresh .update_snap_revision ()
251
- _snap .hold ()
252
- _installed_by_unit .write_text (unique_unit_name )
253
- logger .debug (f"Wrote { unique_unit_name = } to { _installed_by_unit .name = } " )
271
+ self . _snap .hold ()
272
+ self . _installed_by_unit .write_text (unique_unit_name )
273
+ logger .debug (f"Wrote { unique_unit_name = } to { self . _installed_by_unit .name = } " )
254
274
logger .info (f"Installed snap revision { repr (snap_revision )} " )
255
275
256
- @classmethod
257
276
def refresh (
258
- cls ,
277
+ self ,
259
278
* ,
260
279
unit : ops .Unit ,
261
280
model_uuid : str ,
@@ -268,24 +287,24 @@ def refresh(
268
287
269
288
Does not automatically retry if snap installation fails
270
289
"""
271
- if not _snap .present :
272
- cls .install (
290
+ if not self . _snap .present :
291
+ self .install (
273
292
unit = unit , model_uuid = model_uuid , snap_revision = snap_revision , refresh = refresh
274
293
)
275
294
return
276
295
_raise_if_snap_installed_not_by_this_charm (unit = unit , model_uuid = model_uuid )
277
296
278
- revision_before_refresh = _snap .revision
297
+ revision_before_refresh = self . _snap .revision
279
298
if revision_before_refresh == snap_revision :
280
299
raise ValueError (f"Cannot refresh snap; { snap_revision = } is already installed" )
281
300
282
301
logger .info (f"Refreshing snap to revision { repr (snap_revision )} " )
283
302
unit .status = ops .MaintenanceStatus ("Refreshing snap" )
284
303
try :
285
- _snap .ensure (state = snap_lib .SnapState .Present , revision = snap_revision )
304
+ self . _snap .ensure (state = snap_lib .SnapState .Present , revision = snap_revision )
286
305
except (snap_lib .SnapError , snap_lib .SnapAPIError ):
287
306
logger .exception ("Snap refresh failed" )
288
- if _snap .revision == revision_before_refresh :
307
+ if self . _snap .revision == revision_before_refresh :
289
308
raise container .RefreshFailed
290
309
else :
291
310
refresh .update_snap_revision ()
0 commit comments