1
1
"""k8s background jobs"""
2
2
3
3
import asyncio
4
+ import os
4
5
from datetime import datetime
5
6
from typing import Optional , Tuple , Union , List , Dict , TYPE_CHECKING , cast
6
7
from uuid import UUID
19
20
BgJobType ,
20
21
CreateReplicaJob ,
21
22
DeleteReplicaJob ,
23
+ DeleteOrgJob ,
22
24
PaginatedBackgroundJobResponse ,
23
25
AnyJob ,
24
26
StorageRef ,
@@ -273,6 +275,51 @@ async def create_delete_replica_job(
273
275
)
274
276
return None
275
277
278
+ async def create_delete_org_job (
279
+ self ,
280
+ org : Organization ,
281
+ existing_job_id : Optional [str ] = None ,
282
+ ) -> Optional [str ]:
283
+ """Create background job to delete org and its data"""
284
+
285
+ try :
286
+ job_id = await self .crawl_manager .run_delete_org_job (
287
+ oid = str (org .id ),
288
+ backend_image = os .environ .get ("BACKEND_IMAGE" , "" ),
289
+ pull_policy = os .environ .get ("BACKEND_IMAGE_PULL_POLICY" , "" ),
290
+ existing_job_id = existing_job_id ,
291
+ )
292
+ if existing_job_id :
293
+ delete_org_job = await self .get_background_job (existing_job_id , org .id )
294
+ previous_attempt = {
295
+ "started" : delete_org_job .started ,
296
+ "finished" : delete_org_job .finished ,
297
+ }
298
+ if delete_org_job .previousAttempts :
299
+ delete_org_job .previousAttempts .append (previous_attempt )
300
+ else :
301
+ delete_org_job .previousAttempts = [previous_attempt ]
302
+ delete_org_job .started = dt_now ()
303
+ delete_org_job .finished = None
304
+ delete_org_job .success = None
305
+ else :
306
+ delete_org_job = DeleteOrgJob (
307
+ id = job_id ,
308
+ oid = org .id ,
309
+ started = dt_now (),
310
+ )
311
+
312
+ await self .jobs .find_one_and_update (
313
+ {"_id" : job_id }, {"$set" : delete_org_job .to_dict ()}, upsert = True
314
+ )
315
+
316
+ return job_id
317
+ # pylint: disable=broad-exception-caught
318
+ except Exception as exc :
319
+ # pylint: disable=raise-missing-from
320
+ print (f"warning: delete org job could not be started: { exc } " )
321
+ return None
322
+
276
323
async def job_finished (
277
324
self ,
278
325
job_id : str ,
@@ -316,10 +363,13 @@ async def job_finished(
316
363
)
317
364
318
365
async def get_background_job (
319
- self , job_id : str , oid : UUID
320
- ) -> Union [CreateReplicaJob , DeleteReplicaJob ]:
366
+ self , job_id : str , oid : Optional [ UUID ] = None
367
+ ) -> Union [CreateReplicaJob , DeleteReplicaJob , DeleteOrgJob ]:
321
368
"""Get background job"""
322
- query : dict [str , object ] = {"_id" : job_id , "oid" : oid }
369
+ query : dict [str , object ] = {"_id" : job_id }
370
+ if oid :
371
+ query ["oid" ] = oid
372
+
323
373
res = await self .jobs .find_one (query )
324
374
if not res :
325
375
raise HTTPException (status_code = 404 , detail = "job_not_found" )
@@ -331,9 +381,10 @@ def _get_job_by_type_from_data(self, data: dict[str, object]):
331
381
if data ["type" ] == BgJobType .CREATE_REPLICA :
332
382
return CreateReplicaJob .from_dict (data )
333
383
334
- return DeleteReplicaJob .from_dict (data )
384
+ if data ["type" ] == BgJobType .DELETE_REPLICA :
385
+ return DeleteReplicaJob .from_dict (data )
335
386
336
- # return BackgroundJob .from_dict(data)
387
+ return DeleteOrgJob .from_dict (data )
337
388
338
389
async def list_background_jobs (
339
390
self ,
@@ -432,9 +483,8 @@ async def retry_background_job(
432
483
if job .success :
433
484
raise HTTPException (status_code = 400 , detail = "job_already_succeeded" )
434
485
435
- file = await self .get_replica_job_file (job , org )
436
-
437
486
if job .type == BgJobType .CREATE_REPLICA :
487
+ file = await self .get_replica_job_file (job , org )
438
488
primary_storage = self .storage_ops .get_org_storage_by_ref (org , file .storage )
439
489
primary_endpoint , bucket_suffix = self .strip_bucket (
440
490
primary_storage .endpoint_url
@@ -452,6 +502,7 @@ async def retry_background_job(
452
502
)
453
503
454
504
if job .type == BgJobType .DELETE_REPLICA :
505
+ file = await self .get_replica_job_file (job , org )
455
506
await self .create_delete_replica_job (
456
507
org ,
457
508
file ,
@@ -461,6 +512,12 @@ async def retry_background_job(
461
512
existing_job_id = job_id ,
462
513
)
463
514
515
+ if job .type == BgJobType .DELETE_ORG :
516
+ await self .create_delete_org_job (
517
+ org ,
518
+ existing_job_id = job_id ,
519
+ )
520
+
464
521
return {"success" : True }
465
522
466
523
async def retry_failed_background_jobs (
@@ -523,6 +580,14 @@ async def get_background_job(
523
580
"""Retrieve information for background job"""
524
581
return await ops .get_background_job (job_id , org .id )
525
582
583
+ @app .get ("/orgs/all/jobs/{job_id}" , response_model = SuccessResponse , tags = ["jobs" ])
584
+ async def get_background_job_all_orgs (job_id : str , user : User = Depends (user_dep )):
585
+ """Get background job from any org"""
586
+ if not user .is_superuser :
587
+ raise HTTPException (status_code = 403 , detail = "Not Allowed" )
588
+
589
+ return await ops .get_background_job (job_id )
590
+
526
591
@router .post ("/{job_id}/retry" , response_model = SuccessResponse )
527
592
async def retry_background_job (
528
593
job_id : str ,
0 commit comments