33
44import logging
55from datetime import date , datetime
6- from typing import Optional , Union
6+ from typing import Callable , Optional , Union
77
88import koji
99from specfile .changelog import ChangelogEntry
1414logger = logging .getLogger (__name__ )
1515
1616
17- class KojiHelper :
18- """
19- Class for querying Koji.
17+ class SessionWrapper :
18+ def __init__ (self ) -> None :
19+ self .session = self ._open_session ()
20+
21+ def __getattr__ (self , name : str ) -> Callable :
22+ if name in self .__dict__ :
23+ return self .__dict__ [name ]
24+ return self ._wrap (getattr (self .session , name ))
25+
26+ def _open_session (self ) -> koji .ClientSession :
27+ return koji .ClientSession (baseurl = KOJI_BASEURL )
28+
29+ def _wrap (self , call : Callable ) -> Callable :
30+ call_name = f"{ call ._VirtualMethod__name } ()" # type: ignore[attr-defined]
31+
32+ def wrapper (* args , ** kwargs ):
33+ exceptions = []
34+ while True :
35+ try :
36+ return call (* args , ** kwargs )
37+ except koji .ActionNotAllowed as e : # noqa: PERF203
38+ if (type (e ), e .faultCode , e .args ) in exceptions :
39+ # break the loop if the same exception has already occurred
40+ raise
41+ exceptions .append ((type (e ), e .faultCode , e .args ))
42+ logger .debug (
43+ f"{ call_name } requires authenticated Koji session, logging in" ,
44+ )
45+ self .session .gssapi_login ()
46+ continue
47+ except koji .AuthError as e :
48+ if (type (e ), e .faultCode , e .args ) in exceptions :
49+ # break the loop if the same exception has already occurred
50+ raise
51+ exceptions .append ((type (e ), e .faultCode , e .args ))
52+ logger .debug (
53+ f"Koji session authentication error during { call_name } : { e } ;"
54+ "opening new session" ,
55+ )
56+ self .session = self ._open_session ()
57+ continue
58+
59+ return wrapper
2060
21- Attributes:
22- session: Koji client session.
23- """
2461
25- def __init__ (self , session : Optional [koji .ClientSession ] = None ) -> None :
26- self .session = (
27- session if session is not None else koji .ClientSession (baseurl = KOJI_BASEURL )
28- )
62+ class KojiHelper :
63+ def __init__ (self ) -> None :
64+ self .session = SessionWrapper ()
2965
3066 def get_builds (self , package : str , since : datetime ) -> list [dict ]:
3167 """
@@ -306,12 +342,6 @@ def create_sidetag(self, dist_git_branch: str) -> Optional[dict]:
306342 if not (build_tag := target .get ("build_tag_name" )):
307343 logger .debug (f"Failed to get build tag for { dist_git_branch } " )
308344 return None
309- if not self .session .logged_in :
310- try :
311- self .session .gssapi_login ()
312- except Exception as e :
313- logger .debug (f"Authentication failed: { e } " )
314- return None
315345 try :
316346 info = self .session .createSideTag (build_tag )
317347 except Exception as e :
@@ -328,12 +358,6 @@ def remove_sidetag(self, sidetag: str) -> None:
328358 Args:
329359 sidetag: Sidetag name.
330360 """
331- if not self .session .logged_in :
332- try :
333- self .session .gssapi_login ()
334- except Exception as e :
335- logger .debug (f"Authentication failed: { e } " )
336- return
337361 try :
338362 self .session .removeSideTag (sidetag )
339363 except Exception as e :
@@ -352,12 +376,6 @@ def tag_build(self, nvr: str, tag: str) -> Optional[str]:
352376 Returns:
353377 Task ID if tagging was successfully requested else None.
354378 """
355- if not self .session .logged_in :
356- try :
357- self .session .gssapi_login ()
358- except Exception as e :
359- logger .debug (f"Authentication failed: { e } " )
360- return None
361379 try :
362380 task_id = self .session .tagBuild (tag , nvr )
363381 except Exception as e :
@@ -375,12 +393,6 @@ def untag_build(self, nvr: str, tag: str) -> None:
375393 nvr: NVR of the build.
376394 tag: Tag name.
377395 """
378- if not self .session .logged_in :
379- try :
380- self .session .gssapi_login ()
381- except Exception as e :
382- logger .debug (f"Authentication failed: { e } " )
383- return
384396 try :
385397 self .session .untagBuild (tag , nvr , strict = True )
386398 except Exception as e :
0 commit comments