|
37 | 37 | from DIRAC.WorkloadManagementSystem.Client.PilotScopes import PILOT_SCOPES
|
38 | 38 | from DIRAC.WorkloadManagementSystem.Client.ServerUtils import getPilotAgentsDB
|
39 | 39 | from DIRAC.WorkloadManagementSystem.private.ConfigHelper import findGenericPilotCredentials
|
| 40 | +from DIRAC.WorkloadManagementSystem.Client.PilotManagerClient import PilotManagerClient |
40 | 41 | from DIRAC.WorkloadManagementSystem.Utilities.PilotWrapper import (
|
41 | 42 | _writePilotWrapperFile,
|
42 | 43 | getPilotFilesCompressedEncodedDict,
|
@@ -103,6 +104,7 @@ def initialize(self):
|
103 | 104 | self.rssClient = ResourceStatus()
|
104 | 105 | self.pilotAgentsDB = getPilotAgentsDB()
|
105 | 106 | self.matcherClient = MatcherClient()
|
| 107 | + self.pilotManagementClient = PilotManagerClient() |
106 | 108 |
|
107 | 109 | return S_OK()
|
108 | 110 |
|
@@ -348,15 +350,15 @@ def _submitPilotsPerQueue(self, queueName: str):
|
348 | 350 | if not result["OK"]:
|
349 | 351 | self.log.info("Failed pilot submission", f"Queue: {queueName}")
|
350 | 352 | return result
|
351 |
| - pilotList, stampDict = result["Value"] |
| 353 | + stampDict, secretDict = result["Value"] |
352 | 354 |
|
353 |
| - # updating the pilotAgentsDB... done by default but maybe not strictly necessary |
354 |
| - result = self._addPilotReferences(queueName, pilotList, stampDict) |
| 355 | + submittedPilots = len(stampDict) |
| 356 | + self.log.info("Total number of pilots submitted", f"to {queueName}: {submittedPilots}") |
| 357 | + |
| 358 | + result = self._addPilotReferences(queueName, stampDict, secretDict) |
355 | 359 | if not result["OK"]:
|
356 | 360 | return result
|
357 | 361 |
|
358 |
| - submittedPilots = len(pilotList) |
359 |
| - self.log.info("Total number of pilots submitted", f"to {queueName}: {submittedPilots}") |
360 | 362 | return S_OK(submittedPilots)
|
361 | 363 |
|
362 | 364 | def _getQueueSlots(self, queue: str):
|
@@ -460,8 +462,12 @@ def _submitPilotsToQueue(self, pilotsToSubmit: int, ce: ComputingElement, queue:
|
460 | 462 | jobProxy = result["Value"]
|
461 | 463 | executable = self._getExecutable(queue, proxy=jobProxy, jobExecDir=jobExecDir, envVariables=envVariables)
|
462 | 464 |
|
| 465 | + secrets = self.pilotManagementClient.createNSecrets(vo=self.vo, n=pilotsToSubmit) |
| 466 | + |
463 | 467 | # Submit the job
|
464 |
| - submitResult = ce.submitJob(executable, "", pilotsToSubmit) |
| 468 | + # NOTE FOR DIRACX /!\ : We need in each CE to create a secret |
| 469 | + submitResult = ce.submitJob(executable, "", pilotsToSubmit, diracXSecrets=secrets) |
| 470 | + |
465 | 471 | # In case the CE does not need the executable after the submission, we delete it
|
466 | 472 | # Else, we keep it, the CE will delete it after the end of the pilot execution
|
467 | 473 | if submitResult.get("ExecutableToKeep") != executable:
|
@@ -531,34 +537,56 @@ def _submitPilotsToQueue(self, pilotsToSubmit: int, ce: ComputingElement, queue:
|
531 | 537 | if not result["OK"]:
|
532 | 538 | self.log.error("Failure submitting Monitoring report", result["Message"])
|
533 | 539 |
|
534 |
| - return S_OK((pilotList, stampDict)) |
| 540 | + secretDict = {} |
| 541 | + if "SecretDict" in submitResult: |
| 542 | + # TODO: Update this comment as we add DiracX support |
| 543 | + # V9+, only for: |
| 544 | + # 1. Arex |
| 545 | + |
| 546 | + # Result body: {"secret": "PilotStamps": ["stamp"]} |
| 547 | + secretDict = submitResult["SecretDict"] |
| 548 | + |
| 549 | + references = stampDict.keys() |
| 550 | + stamps = stampDict.values() |
| 551 | + stampDict = dict(zip(stamps, references)) |
| 552 | + |
| 553 | + return S_OK((stampDict, secretDict)) |
535 | 554 |
|
536 |
| - def _addPilotReferences(self, queue: str, pilotList: list[str], stampDict: dict[str, str]): |
| 555 | + def _addPilotReferences(self, queue: str, stampDict: dict[str, str], secretDict: dict[str, str]): |
537 | 556 | """Add pilotReference to pilotAgentsDB
|
538 | 557 |
|
539 | 558 | :param queue: the queue name
|
540 | 559 | :param pilotList: list of pilots
|
541 |
| - :param stampDict: dictionary of pilots timestamps |
| 560 | + :param refDict: dictionary {"pilotstamp":"pilotref"} |
| 561 | + :param secretDict: dictionary {"pilotstamp":"secret"} |
542 | 562 | """
|
543 |
| - result = self.pilotAgentsDB.addPilotReferences( |
544 |
| - pilotList, |
545 |
| - self.vo, |
546 |
| - self.queueDict[queue]["CEType"], |
547 |
| - stampDict, |
| 563 | + # FIXME: Change for a client or at least request to DiracX |
| 564 | + |
| 565 | + # First, create pilots |
| 566 | + stamps = stampDict.keys() |
| 567 | + result = self.pilotManagementClient.addPilotReferences( |
| 568 | + stamps, self.vo, self.queueDict[queue]["CEType"], stampDict |
548 | 569 | )
|
549 | 570 | if not result["OK"]:
|
550 |
| - self.log.error("Failed add pilots to the PilotAgentsDB", result["Message"]) |
551 | 571 | return result
|
552 | 572 |
|
553 |
| - for pilot in pilotList: |
554 |
| - result = self.pilotAgentsDB.setPilotStatus( |
555 |
| - pilot, |
556 |
| - PilotStatus.SUBMITTED, |
557 |
| - self.queueDict[queue]["CEName"], |
558 |
| - "Successfully submitted by the SiteDirector", |
559 |
| - self.queueDict[queue]["Site"], |
560 |
| - self.queueDict[queue]["QueueName"], |
| 573 | + # We associate all of the pilots with their secrets |
| 574 | + if secretDict: |
| 575 | + result = self.pilotManagementClient.associatePilotWithSecret(secretDict) |
| 576 | + if not result["OK"]: |
| 577 | + return result |
| 578 | + |
| 579 | + for stamp in stamps: |
| 580 | + result = self.pilotManagementClient.set_pilot_field( |
| 581 | + stamp, |
| 582 | + { |
| 583 | + "DestinationSite": self.queueDict[queue]["CEName"], |
| 584 | + "StatusReason": "Successfully submitted by the SiteDirector", |
| 585 | + "GridSite": self.queueDict[queue]["Site"], |
| 586 | + "Queue": self.queueDict[queue]["QueueName"], |
| 587 | + }, |
561 | 588 | )
|
| 589 | + |
562 | 590 | if not result["OK"]:
|
563 | 591 | self.log.error("Failed to set pilot status", result["Message"])
|
564 | 592 | return result
|
@@ -591,14 +619,13 @@ def _getExecutable(self, queue: str, proxy: X509Chain, jobExecDir: str = "", env
|
591 | 619 | ce = self.queueCECache[queue]["CE"]
|
592 | 620 | workingDirectory = getattr(ce, "workingDirectory", self.workingDirectory)
|
593 | 621 |
|
594 |
| - executable = self._writePilotScript( |
| 622 | + return self._writePilotScript( |
595 | 623 | workingDirectory=workingDirectory,
|
596 | 624 | pilotOptions=pilotOptions,
|
597 | 625 | proxy=proxy,
|
598 | 626 | pilotExecDir=jobExecDir,
|
599 | 627 | envVariables=envVariables,
|
600 | 628 | )
|
601 |
| - return executable |
602 | 629 |
|
603 | 630 | def _getPilotOptions(self, queue: str) -> list[str]:
|
604 | 631 | """Prepare pilot options
|
@@ -680,6 +707,13 @@ def _getPilotOptions(self, queue: str) -> list[str]:
|
680 | 707 | if "PipInstallOptions" in queueDict:
|
681 | 708 | pilotOptions.append(f"--pipInstallOptions={queueDict['PipInstallOptions']}")
|
682 | 709 |
|
| 710 | + # FIXME: Get secret |
| 711 | + # if "secret" in queueDict: |
| 712 | + # pilotOptions.append(f"--pilotSecret={queueDict['...']}") |
| 713 | + # FIXME: Get clientID |
| 714 | + # pilotOptions.append(f"--clientID={opsHelper.getValue('TO CHANGE')}) |
| 715 | + pilotOptions.append(f"--diracx_URL={DIRAC.gConfig.getValue('/DiracX/URL')}") |
| 716 | + |
683 | 717 | return pilotOptions
|
684 | 718 |
|
685 | 719 | def _writePilotScript(
|
|
0 commit comments