2121
2222logger = logging .getLogger (__name__ )
2323
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- )
2924_UNIX_USERNAME = "snap_daemon"
3025
3126
@@ -38,48 +33,60 @@ def _raise_if_snap_installed_not_by_this_charm(*, unit: ops.Unit, model_uuid: st
3833
3934 Assumes snap is installed
4035 """
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+
4141 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 )
4444 ):
4545 # The snap could be in use by another charm (e.g. MySQL Server charm, a different MySQL
4646 # Router charm).
4747 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 )= } "
4950 )
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" )
5253
5354
5455def uninstall ():
5556 """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" )
5963
6064
6165class _Path (pathlib .PosixPath , container .Path ):
6266 def __new__ (cls , * args , ** kwargs ):
6367 path = super ().__new__ (cls , * args , ** kwargs )
68+ snap_name = charm_refresh .snap_name ()
69+
6470 if args and isinstance (args [0 ], cls ) and (parent_ := args [0 ]._container_parent ):
6571 path ._container_parent = parent_
6672 else :
6773 if str (path ).startswith ("/etc/mysqlrouter" ) or str (path ).startswith (
6874 "/var/lib/mysqlrouter"
6975 ):
70- parent = f"/var/snap/{ _snap_name } /current"
76+ parent = f"/var/snap/{ snap_name } /current"
7177 elif str (path ).startswith ("/run/mysqlrouter" ) or str (path ).startswith (
7278 "/var/log/mysqlrouter"
7379 ):
74- parent = f"/var/snap/{ _snap_name } /common"
80+ parent = f"/var/snap/{ snap_name } /common"
7581 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 } "
7783 else :
7884 parent = None
7985 if parent :
8086 assert str (path ).startswith ("/" )
8187 path = super ().__new__ (cls , parent , path .relative_to ("/" ), ** kwargs )
8288 path ._container_parent = parent
89+
8390 return path
8491
8592 def __truediv__ (self , other ):
@@ -128,42 +135,51 @@ class Snap(container.Container):
128135 _EXPORTER_SERVICE_NAME = "mysqlrouter-exporter"
129136
130137 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+
131143 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" ,
135147 unit_name = unit_name ,
136148 )
137149
150+ @property
151+ def _snap (self ):
152+ return snap_lib .SnapCache ()[self ._snap_name ]
153+
138154 @property
139155 def ready (self ) -> bool :
140156 return True
141157
142158 @property
143159 def mysql_router_service_enabled (self ) -> bool :
144- return _snap .services [self ._SERVICE_NAME ]["active" ]
160+ return self . _snap .services [self ._SERVICE_NAME ]["active" ]
145161
146162 @property
147163 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" ]
149165
150166 def update_mysql_router_service (self , * , enabled : bool , tls : bool = None ) -> None :
151167 super ().update_mysql_router_service (enabled = enabled , tls = tls )
152168
153169 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 } " })
155171 else :
156- _snap .unset ("mysqlrouter.extra-options" )
172+ self . _snap .unset ("mysqlrouter.extra-options" )
157173
158- router_is_running = _snap .services [self ._SERVICE_NAME ]["active" ]
174+ router_is_running = self . _snap .services [self ._SERVICE_NAME ]["active" ]
159175
160176 if enabled :
161177 if router_is_running :
162- _snap .restart ([self ._SERVICE_NAME ])
178+ self . _snap .restart ([self ._SERVICE_NAME ])
163179 else :
164- _snap .start ([self ._SERVICE_NAME ], enable = True )
180+ self . _snap .start ([self ._SERVICE_NAME ], enable = True )
165181 else :
166- _snap .stop ([self ._SERVICE_NAME ], disable = True )
182+ self . _snap .stop ([self ._SERVICE_NAME ], disable = True )
167183
168184 def update_mysql_router_exporter_service (
169185 self ,
@@ -185,38 +201,42 @@ def update_mysql_router_exporter_service(
185201 )
186202
187203 if enabled :
188- _snap .set ({
204+ self . _snap .set ({
189205 "mysqlrouter-exporter.listen-port" : config .listen_port ,
190206 "mysqlrouter-exporter.user" : config .username ,
191207 "mysqlrouter-exporter.password" : config .password ,
192208 "mysqlrouter-exporter.url" : config .url ,
193209 "mysqlrouter-exporter.service-name" : self ._unit_name .replace ("/" , "-" ),
194210 })
195211 if tls :
196- _snap .set ({
212+ self . _snap .set ({
197213 "mysqlrouter.tls-cacert-path" : certificate_authority_filename ,
198214 "mysqlrouter.tls-cert-path" : certificate_filename ,
199215 "mysqlrouter.tls-key-path" : key_filename ,
200216 })
201217 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 )
206222 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+
218233 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 ,
220240 ) -> None :
221241 """Ensure snap is installed by this charm
222242
@@ -226,7 +246,7 @@ def install(
226246 Automatically retries if snap installation fails
227247 """
228248 unique_unit_name = f"{ model_uuid } _{ unit .name } "
229- if _snap .present :
249+ if self . _snap .present :
230250 _raise_if_snap_installed_not_by_this_charm (unit = unit , model_uuid = model_uuid )
231251 return
232252 # Install snap
@@ -246,16 +266,15 @@ def _set_retry_status(_) -> None:
246266 reraise = True ,
247267 ):
248268 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 )
250270 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 = } " )
254274 logger .info (f"Installed snap revision { repr (snap_revision )} " )
255275
256- @classmethod
257276 def refresh (
258- cls ,
277+ self ,
259278 * ,
260279 unit : ops .Unit ,
261280 model_uuid : str ,
@@ -268,24 +287,24 @@ def refresh(
268287
269288 Does not automatically retry if snap installation fails
270289 """
271- if not _snap .present :
272- cls .install (
290+ if not self . _snap .present :
291+ self .install (
273292 unit = unit , model_uuid = model_uuid , snap_revision = snap_revision , refresh = refresh
274293 )
275294 return
276295 _raise_if_snap_installed_not_by_this_charm (unit = unit , model_uuid = model_uuid )
277296
278- revision_before_refresh = _snap .revision
297+ revision_before_refresh = self . _snap .revision
279298 if revision_before_refresh == snap_revision :
280299 raise ValueError (f"Cannot refresh snap; { snap_revision = } is already installed" )
281300
282301 logger .info (f"Refreshing snap to revision { repr (snap_revision )} " )
283302 unit .status = ops .MaintenanceStatus ("Refreshing snap" )
284303 try :
285- _snap .ensure (state = snap_lib .SnapState .Present , revision = snap_revision )
304+ self . _snap .ensure (state = snap_lib .SnapState .Present , revision = snap_revision )
286305 except (snap_lib .SnapError , snap_lib .SnapAPIError ):
287306 logger .exception ("Snap refresh failed" )
288- if _snap .revision == revision_before_refresh :
307+ if self . _snap .revision == revision_before_refresh :
289308 raise container .RefreshFailed
290309 else :
291310 refresh .update_snap_revision ()
0 commit comments