6
6
7
7
from DIRAC import S_OK , S_ERROR
8
8
import DIRAC .Core .Utilities .TimeUtilities as TimeUtilities
9
-
10
- from DIRAC .ConfigurationSystem .Client .Helpers import Registry
11
9
from DIRAC .Core .Utilities .Decorators import deprecated
10
+ from DIRAC .ConfigurationSystem .Client .Helpers .Operations import Operations
11
+ from DIRAC .ConfigurationSystem .Client .Helpers .Registry import getVOForGroup
12
+ from DIRAC .Core .DISET .RequestHandler import getServiceOption
12
13
from DIRAC .Core .DISET .RequestHandler import RequestHandler
13
14
from DIRAC .Core .Utilities .ObjectLoader import ObjectLoader
14
- from DIRAC .ConfigurationSystem .Client .Helpers .Registry import getUsernameForDN , getDNForUsername
15
15
from DIRAC .WorkloadManagementSystem .Client import PilotStatus
16
16
from DIRAC .WorkloadManagementSystem .Service .WMSUtilities import (
17
17
getPilotCE ,
@@ -35,6 +35,10 @@ def initializeHandler(cls, serviceInfoDict):
35
35
except RuntimeError as excp :
36
36
return S_ERROR (f"Can't connect to DB: { excp } " )
37
37
38
+ # prepare remote pilot plugin initialization
39
+ defaultOption , defaultClass = "DownloadPlugin" , "FileCacheDownloadPlugin"
40
+ cls .configValue = getServiceOption (serviceInfoDict , defaultOption , defaultClass )
41
+ cls .loggingPlugin = None
38
42
return S_OK ()
39
43
40
44
##############################################################################
@@ -92,9 +96,16 @@ def export_addPilotTQRef(cls, pilotRef, taskQueueID, ownerGroup, gridType="DIRAC
92
96
types_getPilotOutput = [str ]
93
97
94
98
def export_getPilotOutput (self , pilotReference ):
95
- """Get the pilot job standard output and standard error files for the Grid
96
- job reference
97
99
"""
100
+ Get the pilot job standard output and standard error files for a pilot reference.
101
+ Handles both classic, CE-based logs and remote logs. The type og logs returned is determined
102
+ by the server.
103
+
104
+ :param str pilotReference:
105
+ :return: S_OK or S_ERROR Dirac object
106
+ :rtype: dict
107
+ """
108
+
98
109
result = self .pilotAgentsDB .getPilotInfo (pilotReference )
99
110
if not result ["OK" ]:
100
111
self .log .error ("Failed to get info for pilot" , result ["Message" ])
@@ -104,6 +115,25 @@ def export_getPilotOutput(self, pilotReference):
104
115
return S_ERROR ("Pilot info is empty" )
105
116
106
117
pilotDict = result ["Value" ][pilotReference ]
118
+ vo = getVOForGroup (pilotDict ["OwnerGroup" ])
119
+ opsHelper = Operations (vo = vo )
120
+ remote = opsHelper .getValue ("Pilot/RemoteLogsPriority" , False )
121
+ funcs = [self ._getRemotePilotOutput , self ._getPilotOutput ]
122
+ if remote :
123
+ funcs .reverse ()
124
+
125
+ result = funcs [0 ](pilotReference , pilotDict )
126
+ if not result ["OK" ]:
127
+ self .log .warn ("Pilot log retrieval failed (first attempt), remote ?" , remote )
128
+ result = funcs [1 ](pilotReference , pilotDict )
129
+ return result
130
+ else :
131
+ return result
132
+
133
+ def _getPilotOutput (self , pilotReference , pilotDict ):
134
+ """Get the pilot job standard output and standard error files for the Grid
135
+ job reference
136
+ """
107
137
108
138
group = pilotDict ["OwnerGroup" ]
109
139
@@ -158,6 +188,39 @@ def export_getPilotOutput(self, pilotReference):
158
188
shutil .rmtree (ce .ceParameters ["WorkingDirectory" ])
159
189
return S_OK (resultDict )
160
190
191
+ def _getRemotePilotOutput (self , pilotReference , pilotDict ):
192
+ """
193
+ Get remote pilot log files.
194
+
195
+ :param str pilotReference:
196
+ :return: S_OK Dirac object
197
+ :rtype: dict
198
+ """
199
+
200
+ pilotStamp = pilotDict ["PilotStamp" ]
201
+ group = pilotDict ["OwnerGroup" ]
202
+ vo = getVOForGroup (group )
203
+
204
+ if self .loggingPlugin is None :
205
+ result = ObjectLoader ().loadObject (
206
+ f"WorkloadManagementSystem.Client.PilotLoggingPlugins.{ self .configValue } " , self .configValue
207
+ )
208
+ if not result ["OK" ]:
209
+ self .log .error ("Failed to load LoggingPlugin" , f"{ self .configValue } : { result ['Message' ]} " )
210
+ return result
211
+
212
+ componentClass = result ["Value" ]
213
+ self .loggingPlugin = componentClass ()
214
+ self .log .info ("Loaded: PilotLoggingPlugin class" , self .configValue )
215
+
216
+ res = self .loggingPlugin .getRemotePilotLogs (pilotStamp , vo )
217
+
218
+ if res ["OK" ]:
219
+ res ["Value" ]["OwnerGroup" ] = group
220
+ res ["Value" ]["FileList" ] = []
221
+ # return res, correct or not
222
+ return res
223
+
161
224
##############################################################################
162
225
types_getPilotInfo = [[list , str ]]
163
226
0 commit comments