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