33import functools
44import os
55import random
6+ import string
67
78import kopf
89import yaml
3031CREDENTIAL_ANNOTATION = "janitor.capi.stackhpc.com/credential-policy"
3132CREDENTIAL_ANNOTATION_DELETE = "delete"
3233
33- RETRY_ANNOTATION = "janitor.capi.stackhpc.com/retries "
34- RETRY_MAX_BACKOFF = int (os .environ .get ("CAPI_JANITOR_RETRY_MAX_BACKOFF " , "60" ))
34+ RETRY_ANNOTATION = "janitor.capi.stackhpc.com/retry "
35+ RETRY_DEFAULT_DELAY = int (os .environ .get ("CAPI_JANITOR_RETRY_DEFAULT_DELAY " , "60" ))
3536
3637
3738@kopf .on .cleanup ()
@@ -264,10 +265,8 @@ async def wrapper(**kwargs):
264265 body = kwargs ["body" ]
265266 resource = await ekclient .api (body ["apiVersion" ]).resource (body ["kind" ])
266267 try :
267- result = await handler (** kwargs )
268+ return await handler (** kwargs )
268269 except Exception as exc :
269- # Check to see how many times a handler has been retried
270- retries = int (kwargs ["annotations" ].get (RETRY_ANNOTATION , "0" ))
271270 if isinstance (exc , kopf .TemporaryError ):
272271 kwargs ["logger" ].warn (str (exc ))
273272 backoff = exc .delay
@@ -277,16 +276,22 @@ async def wrapper(**kwargs):
277276 else :
278277 kwargs ["logger" ].exception (str (exc ))
279278 # Calculate the backoff
280- backoff = min ( 2 ** retries + random . uniform ( 0 , 1 ), RETRY_MAX_BACKOFF )
279+ backoff = RETRY_DEFAULT_DELAY
281280 # Wait for the backoff before annotating the resource
282281 await asyncio .sleep (backoff )
282+ # Annotate the object with a random value to trigger another event
283283 try :
284284 await resource .patch (
285285 kwargs ["name" ],
286286 {
287287 "metadata" : {
288288 "annotations" : {
289- RETRY_ANNOTATION : str (retries + 1 ),
289+ RETRY_ANNOTATION : "" .join (
290+ random .choices (
291+ string .ascii_lowercase + string .digits ,
292+ k = 8
293+ )
294+ ),
290295 }
291296 }
292297 },
@@ -295,26 +300,6 @@ async def wrapper(**kwargs):
295300 except easykube .ApiError as exc :
296301 if exc .status_code != 404 :
297302 raise
298- else :
299- if RETRY_ANNOTATION in kwargs ["annotations" ]:
300- # If the handler completes successfully, ensure the annotation is removed
301- # The forward slash in the annotation is designated by '~1' in JSON patch
302- annotation = RETRY_ANNOTATION .replace ('/' , '~1' )
303- try :
304- await resource .json_patch (
305- kwargs ["name" ],
306- [
307- {
308- "op" : "remove" ,
309- "path" : f"/metadata/annotations/{ annotation } " ,
310- },
311- ],
312- namespace = kwargs ["namespace" ]
313- )
314- except easykube .ApiError as exc :
315- if exc .status_code != 404 :
316- raise
317- return result
318303 return wrapper
319304
320305
0 commit comments