Skip to content

Commit 45a3b9e

Browse files
aldbrweb-flow
authored andcommitted
sweep: #7104 fix: MultiVO proxy renewal in AREXCE
1 parent 7b5fedf commit 45a3b9e

File tree

1 file changed

+89
-42
lines changed

1 file changed

+89
-42
lines changed

src/DIRAC/Resources/Computing/AREXComputingElement.py

Lines changed: 89 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,6 @@ def __init__(self, ceUniqueID):
4646
self.restVersion = "1.0"
4747
# Time left before proxy renewal: 3 hours is a good default
4848
self.proxyTimeLeftBeforeRenewal = 10800
49-
# Current delegation ID, generated/fetched in submitJob(), renewed in getJobStatus()
50-
self._delegationID = None
5149
# Timeout
5250
self.timeout = 5.0
5351
# Request session
@@ -179,6 +177,10 @@ def _checkSession(self):
179177
self.headers.pop("Authorization", None)
180178

181179
# Get a proxy: still mandatory, even if tokens are used to authenticate
180+
if not self.proxy:
181+
self.log.error("Proxy not set")
182+
return S_ERROR("Proxy not set")
183+
182184
result = self._prepareProxy()
183185
if not result["OK"]:
184186
self.log.error("Failed to set up proxy", result["Message"])
@@ -190,7 +192,7 @@ def _checkSession(self):
190192
return S_OK()
191193

192194
# Attach the proxy to the session, only if the token is unavailable
193-
self.session.cert = Locations.getProxyLocation()
195+
self.session.cert = os.environ["X509_USER_PROXY"]
194196
return S_OK()
195197

196198
#############################################################################
@@ -233,15 +235,8 @@ def __uploadCertificate(self, delegationID, csrContent):
233235
headers = {"Content-Type": "x-pem-file"}
234236
query = self._urlJoin(os.path.join("delegations", delegationID))
235237

236-
# Get a proxy and sign the CSR
237-
proxy = X509Chain()
238-
proxyFile = Locations.getProxyLocation()
239-
if not proxyFile:
240-
return S_ERROR(f"No proxy available")
241-
result = proxy.loadProxyFromFile(proxyFile)
242-
if not result["OK"]:
243-
return S_ERROR(f"Can't load {proxyFile}: {result['Message']}")
244-
result = proxy.generateChainFromRequestString(csrContent)
238+
# Sign the CSR
239+
result = self.proxy.generateChainFromRequestString(csrContent)
245240
if not result["OK"]:
246241
self.log.error("Problem with the Certificate Signing Request:", result["Message"])
247242
return S_ERROR("Problem with the Certificate Signing Request")
@@ -314,6 +309,32 @@ def _getDelegationIDs(self):
314309
delegationIDs = [delegationContent["id"] for delegationContent in delegations]
315310
return S_OK(delegationIDs)
316311

312+
def _getProxyFromDelegationID(self, delegationID):
313+
"""Get proxy stored within the delegation
314+
315+
:param str delegationID: delegation ID
316+
"""
317+
query = self._urlJoin(os.path.join("delegations", delegationID))
318+
params = {"action": "get"}
319+
320+
# Submit the POST request to get the delegation
321+
result = self._request("post", query, params=params)
322+
if not result["OK"]:
323+
self.log.error("Issue while interacting with the delegations.", result["Message"])
324+
return S_ERROR("Issue while interacting with the delegations")
325+
response = result["Value"]
326+
327+
proxyContent = response.text
328+
proxy = X509Chain()
329+
result = proxy.loadChainFromString(proxyContent)
330+
if not result["OK"]:
331+
self.log.error(
332+
"Issue while trying to load proxy content from delegation", f"{delegationID}: {result['Message']}"
333+
)
334+
return S_ERROR("Issue while trying to load proxy content from delegation")
335+
336+
return S_OK(proxy)
337+
317338
#############################################################################
318339

319340
def _getArcJobID(self, executableFile, inputs, outputs, delegation):
@@ -398,18 +419,33 @@ def submitJob(self, executableFile, proxy, numberOfJobs=1, inputs=None, outputs=
398419
if not result["OK"]:
399420
self.log.error("Could not get delegation IDs.", result["Message"])
400421
return S_ERROR("Could not get delegation IDs")
401-
402422
delegationIDs = result["Value"]
403-
if not delegationIDs:
423+
424+
# Get the delegationID which corresponds to the DIRAC group of the proxy if it exists
425+
currentDelegationID = None
426+
proxyGroup = self.proxy.getDIRACGroup()
427+
for delegationID in delegationIDs:
428+
# Get the proxy attached to the delegationID
429+
result = self._getProxyFromDelegationID(delegationID)
430+
if not result["OK"]:
431+
return result
432+
proxy = result["Value"]
433+
434+
if proxy.getDIRACGroup() != proxyGroup:
435+
continue
436+
437+
# If we are here, we have found the right delegationID to use
438+
currentDelegationID = delegationID
439+
440+
if not currentDelegationID:
404441
# No existing delegation, we need to prepare one
405442
result = self._prepareDelegation()
406443
if not result["OK"]:
407444
self.log.warn("Could not get a new delegation", f"for CE {self.ceHost}")
408445
return S_ERROR("Could not get a new delegation")
409-
self._delegationID = result["Value"]
410-
else:
411-
self._delegationID = delegationIDs[0]
412-
delegation = f"\n(delegationid={self._delegationID})"
446+
currentDelegationID = result["Value"]
447+
448+
delegation = f"\n(delegationid={currentDelegationID})"
413449

414450
if not inputs:
415451
inputs = []
@@ -554,10 +590,14 @@ def getCEStatus(self):
554590
self.log.error("Cannot get CE Status", result["Message"])
555591
return result
556592

557-
# Try to find out which VO we are running for.
593+
# Find out which VO we are running for.
558594
# Essential now for REST interface.
559-
res = getVOfromProxyGroup()
560-
vo = res["Value"] if res["OK"] else ""
595+
result = getVOfromProxyGroup()
596+
if not result["OK"]:
597+
return result
598+
if not result["Value"]:
599+
return S_ERROR("Could not get VO value from the proxy group")
600+
vo = result["Value"]
561601

562602
# Prepare the command
563603
params = {"schema": "glue2"}
@@ -591,33 +631,36 @@ def getCEStatus(self):
591631

592632
#############################################################################
593633

594-
def _renewDelegation(self):
595-
"""Renew the delegations"""
634+
def _renewDelegation(self, delegationID):
635+
"""Renew the delegation
636+
637+
:params delegationID: delegation ID to renew
638+
"""
596639
# Prepare the command
597640
params = {"action": "get"}
598-
query = self._urlJoin(os.path.join("delegations", self._delegationID))
641+
query = self._urlJoin(os.path.join("delegations", delegationID))
599642

600643
# Submit the POST request to get the proxy
601644
result = self._request("post", query, params=params)
602645
if not result["OK"]:
603-
self.log.error("Could not get a proxy for", f"delegation {self._delegationID}: {result['Message']}")
604-
return S_ERROR(f"Could not get a proxy for delegation {self._delegationID}")
646+
self.log.error("Could not get a proxy for", f"delegation {delegationID}: {result['Message']}")
647+
return S_ERROR(f"Could not get a proxy for delegation {delegationID}")
605648
response = result["Value"]
606649

607650
proxy = X509Chain()
608651
result = proxy.loadChainFromString(response.text)
609652
if not result["OK"]:
610-
self.log.error("Could not load proxy for", f"delegation {self._delegationID}: {result['Message']}")
611-
return S_ERROR(f"Could not load proxy for delegation {self._delegationID}")
653+
self.log.error("Could not load proxy for", f"delegation {delegationID}: {result['Message']}")
654+
return S_ERROR(f"Could not load proxy for delegation {delegationID}")
612655

613656
# Now test and renew the proxy
614657
result = proxy.getRemainingSecs()
615658
if not result["OK"]:
616659
self.log.error(
617660
"Could not get remaining time from the proxy for",
618-
f"delegation {self._delegationID}: {result['Message']}",
661+
f"delegation {delegationID}: {result['Message']}",
619662
)
620-
return S_ERROR(f"Could not get remaining time from the proxy for delegation {self._delegationID}")
663+
return S_ERROR(f"Could not get remaining time from the proxy for delegation {delegationID}")
621664
timeLeft = result["Value"]
622665

623666
if timeLeft >= self.proxyTimeLeftBeforeRenewal:
@@ -626,31 +669,31 @@ def _renewDelegation(self):
626669

627670
self.log.verbose(
628671
"Renewing delegation",
629-
f"{self._delegationID} whose proxy expires at {timeLeft}",
672+
f"{delegationID} whose proxy expires at {timeLeft}",
630673
)
631674
# Proxy needs to be renewed - try to renew it
632675
# First, get a new CSR from the delegation
633676
params = {"action": "renew"}
634-
query = self._urlJoin(os.path.join("delegations", self._delegationID))
677+
query = self._urlJoin(os.path.join("delegations", delegationID))
635678
result = self._request("post", query, params=params)
636679
if not result["OK"]:
637680
self.log.error(
638681
"Proxy not renewed, failed to get CSR",
639-
f"for delegation {self._delegationID}",
682+
f"for delegation {delegationID}",
640683
)
641-
return S_ERROR(f"Proxy not renewed, failed to get CSR for delegation {self._delegationID}")
684+
return S_ERROR(f"Proxy not renewed, failed to get CSR for delegation {delegationID}")
642685
response = result["Value"]
643686

644687
# Then, sign and upload the certificate
645-
result = self.__uploadCertificate(self._delegationID, response.text)
688+
result = self.__uploadCertificate(delegationID, response.text)
646689
if not result["OK"]:
647690
self.log.error(
648691
"Proxy not renewed, failed to send renewed proxy",
649-
f"delegation {self._delegationID}: {result['Message']}",
692+
f"delegation {delegationID}: {result['Message']}",
650693
)
651-
return S_ERROR(f"Proxy not renewed, failed to send renewed proxy for delegation {self._delegationID}")
694+
return S_ERROR(f"Proxy not renewed, failed to send renewed proxy for delegation {delegationID}")
652695

653-
self.log.verbose("Proxy successfully renewed", f"for delegation {self._delegationID}")
696+
self.log.verbose("Proxy successfully renewed", f"for delegation {delegationID}")
654697

655698
return S_OK()
656699

@@ -706,12 +749,16 @@ def getJobStatus(self, jobIDList):
706749
jobsToCancel.append(arcJob["id"])
707750
self.log.debug(f"Killing held job {jobID}")
708751

709-
# Renew delegation to renew the proxies of the jobs
710-
if self._delegationID:
711-
result = self._renewDelegation()
752+
# Renew delegations to renew the proxies of the jobs
753+
result = self._getDelegationIDs()
754+
if not result["OK"]:
755+
return result
756+
delegationIDs = result["Value"]
757+
for delegationID in delegationIDs:
758+
result = self._renewDelegation(delegationID)
712759
if not result["OK"]:
713760
# Only log here as we still want to return statuses
714-
self.log.warn("Failed to renew delegation", f"{self._delegationID}: {result['Message']}")
761+
self.log.warn("Failed to renew delegation", f"{delegationID}: {result['Message']}")
715762

716763
# Kill held jobs
717764
if jobsToCancel:

0 commit comments

Comments
 (0)