DIRAC 9.0.0a54__py3-none-any.whl → 9.0.7__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- DIRAC/AccountingSystem/Client/AccountingCLI.py +0 -140
- DIRAC/AccountingSystem/Client/DataStoreClient.py +0 -13
- DIRAC/AccountingSystem/Client/Types/BaseAccountingType.py +0 -7
- DIRAC/AccountingSystem/ConfigTemplate.cfg +0 -5
- DIRAC/AccountingSystem/Service/DataStoreHandler.py +0 -72
- DIRAC/ConfigurationSystem/Client/Helpers/CSGlobals.py +0 -9
- DIRAC/ConfigurationSystem/Client/Helpers/Registry.py +34 -32
- DIRAC/ConfigurationSystem/Client/Helpers/Resources.py +11 -43
- DIRAC/ConfigurationSystem/Client/Helpers/test/Test_Helpers.py +0 -16
- DIRAC/ConfigurationSystem/Client/LocalConfiguration.py +14 -8
- DIRAC/ConfigurationSystem/Client/PathFinder.py +47 -8
- DIRAC/ConfigurationSystem/Client/SyncPlugins/CERNLDAPSyncPlugin.py +4 -1
- DIRAC/ConfigurationSystem/Client/VOMS2CSSynchronizer.py +9 -2
- DIRAC/ConfigurationSystem/Client/test/Test_PathFinder.py +41 -1
- DIRAC/ConfigurationSystem/private/RefresherBase.py +4 -2
- DIRAC/Core/DISET/ServiceReactor.py +11 -3
- DIRAC/Core/DISET/private/BaseClient.py +1 -2
- DIRAC/Core/DISET/private/Transports/M2SSLTransport.py +9 -7
- DIRAC/Core/Security/DiracX.py +12 -7
- DIRAC/Core/Security/IAMService.py +4 -3
- DIRAC/Core/Security/ProxyInfo.py +9 -5
- DIRAC/Core/Security/test/test_diracx_token_from_pem.py +161 -0
- DIRAC/Core/Tornado/Client/ClientSelector.py +4 -1
- DIRAC/Core/Tornado/Server/TornadoService.py +1 -1
- DIRAC/Core/Utilities/ClassAd/ClassAdLight.py +4 -290
- DIRAC/Core/Utilities/DErrno.py +5 -309
- DIRAC/Core/Utilities/Extensions.py +10 -1
- DIRAC/Core/Utilities/Graphs/GraphData.py +1 -1
- DIRAC/Core/Utilities/JDL.py +1 -195
- DIRAC/Core/Utilities/List.py +1 -124
- DIRAC/Core/Utilities/MySQL.py +101 -97
- DIRAC/Core/Utilities/Os.py +32 -1
- DIRAC/Core/Utilities/Platform.py +2 -107
- DIRAC/Core/Utilities/ReturnValues.py +7 -252
- DIRAC/Core/Utilities/StateMachine.py +12 -178
- DIRAC/Core/Utilities/TimeUtilities.py +10 -253
- DIRAC/Core/Utilities/test/Test_JDL.py +0 -3
- DIRAC/Core/Utilities/test/Test_Profiler.py +20 -20
- DIRAC/Core/scripts/dirac_agent.py +1 -1
- DIRAC/Core/scripts/dirac_apptainer_exec.py +16 -7
- DIRAC/Core/scripts/dirac_platform.py +1 -92
- DIRAC/DataManagementSystem/Agent/FTS3Agent.py +8 -7
- DIRAC/DataManagementSystem/Agent/RequestOperations/RemoveFile.py +7 -6
- DIRAC/DataManagementSystem/Client/FTS3Job.py +71 -34
- DIRAC/DataManagementSystem/DB/FTS3DB.py +3 -0
- DIRAC/DataManagementSystem/DB/FileCatalogComponents/DatasetManager/DatasetManager.py +1 -1
- DIRAC/DataManagementSystem/Utilities/DMSHelpers.py +6 -2
- DIRAC/DataManagementSystem/scripts/dirac_dms_create_moving_request.py +2 -0
- DIRAC/DataManagementSystem/scripts/dirac_dms_protocol_matrix.py +0 -1
- DIRAC/FrameworkSystem/Client/ComponentInstaller.py +4 -2
- DIRAC/FrameworkSystem/DB/ProxyDB.py +9 -5
- DIRAC/FrameworkSystem/Utilities/TokenManagementUtilities.py +3 -2
- DIRAC/FrameworkSystem/Utilities/diracx.py +2 -74
- DIRAC/FrameworkSystem/private/authorization/AuthServer.py +2 -2
- DIRAC/FrameworkSystem/scripts/dirac_login.py +2 -2
- DIRAC/FrameworkSystem/scripts/dirac_proxy_init.py +1 -1
- DIRAC/Interfaces/API/Dirac.py +27 -13
- DIRAC/Interfaces/API/DiracAdmin.py +42 -7
- DIRAC/Interfaces/API/Job.py +1 -0
- DIRAC/Interfaces/scripts/dirac_admin_allow_site.py +7 -1
- DIRAC/Interfaces/scripts/dirac_admin_ban_site.py +7 -1
- DIRAC/Interfaces/scripts/dirac_wms_job_parameters.py +0 -1
- DIRAC/MonitoringSystem/Client/Types/WMSHistory.py +4 -0
- DIRAC/MonitoringSystem/Client/WebAppClient.py +26 -0
- DIRAC/MonitoringSystem/ConfigTemplate.cfg +9 -0
- DIRAC/MonitoringSystem/DB/MonitoringDB.py +6 -25
- DIRAC/MonitoringSystem/Service/MonitoringHandler.py +0 -33
- DIRAC/MonitoringSystem/Service/WebAppHandler.py +599 -0
- DIRAC/MonitoringSystem/private/MainReporter.py +0 -3
- DIRAC/ProductionSystem/scripts/dirac_prod_get_trans.py +2 -3
- DIRAC/RequestManagementSystem/Agent/RequestExecutingAgent.py +8 -6
- DIRAC/RequestManagementSystem/ConfigTemplate.cfg +6 -6
- DIRAC/RequestManagementSystem/DB/test/RMSTestScenari.py +2 -0
- DIRAC/ResourceStatusSystem/Client/SiteStatus.py +4 -2
- DIRAC/ResourceStatusSystem/Command/FreeDiskSpaceCommand.py +3 -1
- DIRAC/ResourceStatusSystem/Utilities/CSHelpers.py +2 -31
- DIRAC/ResourceStatusSystem/scripts/dirac_rss_set_status.py +18 -4
- DIRAC/Resources/Catalog/RucioFileCatalogClient.py +1 -1
- DIRAC/Resources/Computing/AREXComputingElement.py +19 -3
- DIRAC/Resources/Computing/BatchSystems/Condor.py +126 -108
- DIRAC/Resources/Computing/BatchSystems/SLURM.py +5 -1
- DIRAC/Resources/Computing/BatchSystems/test/Test_SLURM.py +46 -0
- DIRAC/Resources/Computing/HTCondorCEComputingElement.py +37 -43
- DIRAC/Resources/Computing/SingularityComputingElement.py +6 -1
- DIRAC/Resources/Computing/test/Test_HTCondorCEComputingElement.py +67 -49
- DIRAC/Resources/Computing/test/Test_PoolComputingElement.py +2 -1
- DIRAC/Resources/IdProvider/CheckInIdProvider.py +13 -0
- DIRAC/Resources/IdProvider/IdProviderFactory.py +11 -3
- DIRAC/Resources/Storage/StorageBase.py +4 -2
- DIRAC/Resources/Storage/StorageElement.py +4 -4
- DIRAC/TransformationSystem/Agent/TaskManagerAgentBase.py +10 -16
- DIRAC/TransformationSystem/Agent/TransformationAgent.py +22 -1
- DIRAC/TransformationSystem/Agent/TransformationCleaningAgent.py +15 -15
- DIRAC/TransformationSystem/Client/Transformation.py +2 -1
- DIRAC/TransformationSystem/Client/TransformationClient.py +0 -7
- DIRAC/TransformationSystem/Client/Utilities.py +9 -0
- DIRAC/TransformationSystem/Service/TransformationManagerHandler.py +0 -336
- DIRAC/TransformationSystem/Utilities/ReplicationCLIParameters.py +3 -3
- DIRAC/TransformationSystem/scripts/dirac_production_runjoblocal.py +2 -4
- DIRAC/TransformationSystem/test/Test_replicationTransformation.py +5 -6
- DIRAC/Workflow/Modules/test/Test_Modules.py +5 -0
- DIRAC/WorkloadManagementSystem/Agent/JobAgent.py +1 -5
- DIRAC/WorkloadManagementSystem/Agent/JobCleaningAgent.py +11 -7
- DIRAC/WorkloadManagementSystem/Agent/PilotSyncAgent.py +4 -3
- DIRAC/WorkloadManagementSystem/Agent/PushJobAgent.py +13 -13
- DIRAC/WorkloadManagementSystem/Agent/SiteDirector.py +10 -13
- DIRAC/WorkloadManagementSystem/Agent/StalledJobAgent.py +18 -51
- DIRAC/WorkloadManagementSystem/Agent/StatesAccountingAgent.py +41 -1
- DIRAC/WorkloadManagementSystem/Agent/test/Test_Agent_JobAgent.py +2 -0
- DIRAC/WorkloadManagementSystem/Agent/test/Test_Agent_JobCleaningAgent.py +7 -9
- DIRAC/WorkloadManagementSystem/Agent/test/Test_Agent_PushJobAgent.py +1 -0
- DIRAC/WorkloadManagementSystem/Agent/test/Test_Agent_SiteDirector.py +8 -2
- DIRAC/WorkloadManagementSystem/Agent/test/Test_Agent_StalledJobAgent.py +4 -5
- DIRAC/WorkloadManagementSystem/Client/DownloadInputData.py +7 -5
- DIRAC/WorkloadManagementSystem/Client/JobMonitoringClient.py +10 -11
- DIRAC/WorkloadManagementSystem/Client/JobState/JobManifest.py +32 -261
- DIRAC/WorkloadManagementSystem/Client/JobStateUpdateClient.py +3 -0
- DIRAC/WorkloadManagementSystem/Client/JobStatus.py +8 -152
- DIRAC/WorkloadManagementSystem/Client/SandboxStoreClient.py +25 -38
- DIRAC/WorkloadManagementSystem/Client/WMSClient.py +2 -3
- DIRAC/WorkloadManagementSystem/Client/test/Test_Client_DownloadInputData.py +29 -0
- DIRAC/WorkloadManagementSystem/ConfigTemplate.cfg +4 -8
- DIRAC/WorkloadManagementSystem/DB/JobDB.py +40 -69
- DIRAC/WorkloadManagementSystem/DB/JobDBUtils.py +18 -147
- DIRAC/WorkloadManagementSystem/DB/JobParametersDB.py +9 -9
- DIRAC/WorkloadManagementSystem/DB/PilotAgentsDB.py +3 -2
- DIRAC/WorkloadManagementSystem/DB/SandboxMetadataDB.py +28 -39
- DIRAC/WorkloadManagementSystem/DB/StatusUtils.py +125 -0
- DIRAC/WorkloadManagementSystem/DB/tests/Test_JobDB.py +1 -1
- DIRAC/WorkloadManagementSystem/DB/tests/Test_StatusUtils.py +28 -0
- DIRAC/WorkloadManagementSystem/Executor/JobSanity.py +3 -3
- DIRAC/WorkloadManagementSystem/FutureClient/JobStateUpdateClient.py +2 -14
- DIRAC/WorkloadManagementSystem/JobWrapper/JobWrapper.py +14 -9
- DIRAC/WorkloadManagementSystem/JobWrapper/test/Test_JobWrapper.py +36 -10
- DIRAC/WorkloadManagementSystem/JobWrapper/test/Test_JobWrapperTemplate.py +4 -0
- DIRAC/WorkloadManagementSystem/Service/JobManagerHandler.py +33 -154
- DIRAC/WorkloadManagementSystem/Service/JobMonitoringHandler.py +5 -323
- DIRAC/WorkloadManagementSystem/Service/JobStateUpdateHandler.py +0 -16
- DIRAC/WorkloadManagementSystem/Service/PilotManagerHandler.py +6 -102
- DIRAC/WorkloadManagementSystem/Service/SandboxStoreHandler.py +5 -51
- DIRAC/WorkloadManagementSystem/Service/WMSAdministratorHandler.py +16 -79
- DIRAC/WorkloadManagementSystem/Utilities/JobModel.py +28 -199
- DIRAC/WorkloadManagementSystem/Utilities/JobParameters.py +65 -3
- DIRAC/WorkloadManagementSystem/Utilities/JobStatusUtility.py +2 -64
- DIRAC/WorkloadManagementSystem/Utilities/ParametricJob.py +7 -171
- DIRAC/WorkloadManagementSystem/Utilities/PilotCStoJSONSynchronizer.py +73 -7
- DIRAC/WorkloadManagementSystem/Utilities/PilotWrapper.py +2 -0
- DIRAC/WorkloadManagementSystem/Utilities/RemoteRunner.py +16 -0
- DIRAC/WorkloadManagementSystem/Utilities/Utils.py +36 -1
- DIRAC/WorkloadManagementSystem/Utilities/jobAdministration.py +15 -0
- DIRAC/WorkloadManagementSystem/Utilities/test/Test_JobModel.py +1 -5
- DIRAC/WorkloadManagementSystem/Utilities/test/Test_ParametricJob.py +45 -128
- DIRAC/WorkloadManagementSystem/Utilities/test/Test_PilotWrapper.py +16 -0
- DIRAC/__init__.py +55 -54
- {dirac-9.0.0a54.dist-info → dirac-9.0.7.dist-info}/METADATA +6 -4
- {dirac-9.0.0a54.dist-info → dirac-9.0.7.dist-info}/RECORD +160 -160
- {dirac-9.0.0a54.dist-info → dirac-9.0.7.dist-info}/WHEEL +1 -1
- {dirac-9.0.0a54.dist-info → dirac-9.0.7.dist-info}/entry_points.txt +0 -3
- DIRAC/Core/Utilities/test/Test_List.py +0 -150
- DIRAC/Core/Utilities/test/Test_Time.py +0 -88
- DIRAC/TransformationSystem/scripts/dirac_transformation_archive.py +0 -30
- DIRAC/TransformationSystem/scripts/dirac_transformation_clean.py +0 -30
- DIRAC/TransformationSystem/scripts/dirac_transformation_remove_output.py +0 -30
- DIRAC/WorkloadManagementSystem/Utilities/test/Test_JobManager.py +0 -58
- {dirac-9.0.0a54.dist-info → dirac-9.0.7.dist-info}/licenses/LICENSE +0 -0
- {dirac-9.0.0a54.dist-info → dirac-9.0.7.dist-info}/top_level.txt +0 -0
|
@@ -4,7 +4,9 @@ All administrative functionality is exposed through the DIRAC Admin API. Exampl
|
|
|
4
4
|
site banning and unbanning, WMS proxy uploading etc.
|
|
5
5
|
|
|
6
6
|
"""
|
|
7
|
+
|
|
7
8
|
import os
|
|
9
|
+
from datetime import datetime, timedelta
|
|
8
10
|
|
|
9
11
|
from DIRAC import S_ERROR, S_OK, gConfig, gLogger
|
|
10
12
|
from DIRAC.ConfigurationSystem.Client.CSAPI import CSAPI
|
|
@@ -19,6 +21,9 @@ from DIRAC.ResourceStatusSystem.Client.SiteStatus import SiteStatus
|
|
|
19
21
|
from DIRAC.WorkloadManagementSystem.Client.JobManagerClient import JobManagerClient
|
|
20
22
|
from DIRAC.WorkloadManagementSystem.Client.PilotManagerClient import PilotManagerClient
|
|
21
23
|
from DIRAC.WorkloadManagementSystem.Client.WMSAdministratorClient import WMSAdministratorClient
|
|
24
|
+
from DIRAC.WorkloadManagementSystem.Service.WMSUtilities import (
|
|
25
|
+
killPilotsInQueues,
|
|
26
|
+
)
|
|
22
27
|
|
|
23
28
|
voName = ""
|
|
24
29
|
ret = getProxyInfo(disableVOMS=True)
|
|
@@ -147,7 +152,7 @@ class DiracAdmin(API):
|
|
|
147
152
|
return result
|
|
148
153
|
|
|
149
154
|
#############################################################################
|
|
150
|
-
def allowSite(self, site, comment, printOutput=False):
|
|
155
|
+
def allowSite(self, site, comment, printOutput=False, days=1):
|
|
151
156
|
"""Adds the site to the site mask. The site must be a valid DIRAC site name
|
|
152
157
|
|
|
153
158
|
Example usage:
|
|
@@ -171,7 +176,13 @@ class DiracAdmin(API):
|
|
|
171
176
|
gLogger.notice(f"Site {site} is already Active")
|
|
172
177
|
return S_OK(f"Site {site} is already Active")
|
|
173
178
|
|
|
174
|
-
|
|
179
|
+
tokenLifetime = int(days)
|
|
180
|
+
if tokenLifetime <= 0:
|
|
181
|
+
tokenExpiration = datetime.max
|
|
182
|
+
else:
|
|
183
|
+
tokenExpiration = datetime.utcnow().replace(microsecond=0) + timedelta(days=tokenLifetime)
|
|
184
|
+
|
|
185
|
+
if not (result := self.sitestatus.setSiteStatus(site, "Active", comment, expiry=tokenExpiration))["OK"]:
|
|
175
186
|
return result
|
|
176
187
|
|
|
177
188
|
if printOutput:
|
|
@@ -220,7 +231,7 @@ class DiracAdmin(API):
|
|
|
220
231
|
return S_OK()
|
|
221
232
|
|
|
222
233
|
#############################################################################
|
|
223
|
-
def banSite(self, site, comment, printOutput=False):
|
|
234
|
+
def banSite(self, site, comment, printOutput=False, days=1):
|
|
224
235
|
"""Removes the site from the site mask.
|
|
225
236
|
|
|
226
237
|
Example usage:
|
|
@@ -233,7 +244,6 @@ class DiracAdmin(API):
|
|
|
233
244
|
"""
|
|
234
245
|
if not (result := self._checkSiteIsValid(site))["OK"]:
|
|
235
246
|
return result
|
|
236
|
-
|
|
237
247
|
mask = self.getSiteMask(status="Banned")
|
|
238
248
|
if not mask["OK"]:
|
|
239
249
|
return mask
|
|
@@ -243,7 +253,12 @@ class DiracAdmin(API):
|
|
|
243
253
|
gLogger.notice(f"Site {site} is already Banned")
|
|
244
254
|
return S_OK(f"Site {site} is already Banned")
|
|
245
255
|
|
|
246
|
-
|
|
256
|
+
tokenLifetime = int(days)
|
|
257
|
+
if tokenLifetime <= 0:
|
|
258
|
+
tokenExpiration = datetime.max
|
|
259
|
+
else:
|
|
260
|
+
tokenExpiration = datetime.utcnow().replace(microsecond=0) + timedelta(days=tokenLifetime)
|
|
261
|
+
if not (result := self.sitestatus.setSiteStatus(site, "Banned", comment, expiry=tokenExpiration))["OK"]:
|
|
247
262
|
return result
|
|
248
263
|
|
|
249
264
|
if printOutput:
|
|
@@ -452,8 +467,28 @@ class DiracAdmin(API):
|
|
|
452
467
|
if not isinstance(gridReference, (str, list)):
|
|
453
468
|
return self._errorReport("Expected string or list of strings for pilot reference")
|
|
454
469
|
|
|
455
|
-
|
|
456
|
-
|
|
470
|
+
# Make a list if it is not yet
|
|
471
|
+
if isinstance(gridReference, str):
|
|
472
|
+
gridReference = [gridReference]
|
|
473
|
+
|
|
474
|
+
# Regroup pilots per site
|
|
475
|
+
pilotRefDict = {}
|
|
476
|
+
for pilotReference in gridReference:
|
|
477
|
+
result = PilotManagerClient().getPilotInfo(pilotReference)
|
|
478
|
+
if not result["OK"] or not result["Value"]:
|
|
479
|
+
return S_ERROR(f"Failed to get info for pilot {pilotReference}")
|
|
480
|
+
|
|
481
|
+
pilotDict = result["Value"][pilotReference]
|
|
482
|
+
queue = "@@@".join(
|
|
483
|
+
[pilotDict["VO"], pilotDict["GridSite"], pilotDict["DestinationSite"], pilotDict["Queue"]]
|
|
484
|
+
)
|
|
485
|
+
gridType = pilotDict["GridType"]
|
|
486
|
+
pilotRefDict.setdefault(queue, {})
|
|
487
|
+
pilotRefDict[queue].setdefault("PilotList", [])
|
|
488
|
+
pilotRefDict[queue]["PilotList"].append(pilotReference)
|
|
489
|
+
pilotRefDict[queue]["GridType"] = gridType
|
|
490
|
+
|
|
491
|
+
return killPilotsInQueues(pilotRefDict)
|
|
457
492
|
|
|
458
493
|
#############################################################################
|
|
459
494
|
def getPilotLoggingInfo(self, gridReference):
|
DIRAC/Interfaces/API/Job.py
CHANGED
|
@@ -1105,6 +1105,7 @@ class Job(API):
|
|
|
1105
1105
|
uniqueInputSandbox = uniqueElements(finalInputSandbox.split(";"))
|
|
1106
1106
|
paramsDict["InputSandbox"]["value"] = ";".join(uniqueInputSandbox)
|
|
1107
1107
|
self.log.verbose(f"Final unique Input Sandbox {';'.join(uniqueInputSandbox)}")
|
|
1108
|
+
paramsDict["InputSandbox"]["type"] = "JDL"
|
|
1108
1109
|
else:
|
|
1109
1110
|
paramsDict["InputSandbox"] = {}
|
|
1110
1111
|
paramsDict["InputSandbox"]["value"] = extraFiles
|
|
@@ -13,6 +13,9 @@ from DIRAC.Core.Base.Script import Script
|
|
|
13
13
|
@Script()
|
|
14
14
|
def main():
|
|
15
15
|
Script.registerSwitch("E:", "email=", "Boolean True/False (True by default)")
|
|
16
|
+
Script.registerSwitch(
|
|
17
|
+
"", "days=", "Number of days the token is valid for. Default is 1 day. 0 or less days denotes forever."
|
|
18
|
+
)
|
|
16
19
|
# Registering arguments will automatically add their description to the help menu
|
|
17
20
|
Script.registerArgument("Site: Name of the Site")
|
|
18
21
|
Script.registerArgument("Comment: Reason of the action")
|
|
@@ -32,9 +35,12 @@ def main():
|
|
|
32
35
|
Script.showHelp()
|
|
33
36
|
|
|
34
37
|
email = True
|
|
38
|
+
days = 1
|
|
35
39
|
for switch in Script.getUnprocessedSwitches():
|
|
36
40
|
if switch[0] == "email":
|
|
37
41
|
email = getBoolean(switch[1])
|
|
42
|
+
if switch[0] == "days":
|
|
43
|
+
days = int(switch[1])
|
|
38
44
|
|
|
39
45
|
diracAdmin = DiracAdmin()
|
|
40
46
|
exitCode = 0
|
|
@@ -42,7 +48,7 @@ def main():
|
|
|
42
48
|
|
|
43
49
|
# parseCommandLine show help when mandatory arguments are not specified or incorrect argument
|
|
44
50
|
site, comment = Script.getPositionalArgs(group=True)
|
|
45
|
-
result = diracAdmin.allowSite(site, comment, printOutput=True)
|
|
51
|
+
result = diracAdmin.allowSite(site, comment, printOutput=True, days=days)
|
|
46
52
|
if not result["OK"]:
|
|
47
53
|
errorList.append((site, result["Message"]))
|
|
48
54
|
exitCode = 2
|
|
@@ -13,6 +13,9 @@ from DIRAC.Core.Base.Script import Script
|
|
|
13
13
|
@Script()
|
|
14
14
|
def main():
|
|
15
15
|
Script.registerSwitch("E:", "email=", "Boolean True/False (True by default)")
|
|
16
|
+
Script.registerSwitch(
|
|
17
|
+
"", "days=", "Number of days the token is valid for. Default is 1 day. 0 or less days denotes forever."
|
|
18
|
+
)
|
|
16
19
|
# Registering arguments will automatically add their description to the help menu
|
|
17
20
|
Script.registerArgument("Site: Name of the Site")
|
|
18
21
|
Script.registerArgument("Comment: Reason of the action")
|
|
@@ -32,9 +35,12 @@ def main():
|
|
|
32
35
|
Script.showHelp()
|
|
33
36
|
|
|
34
37
|
email = True
|
|
38
|
+
days = 1
|
|
35
39
|
for switch in Script.getUnprocessedSwitches():
|
|
36
40
|
if switch[0] == "email":
|
|
37
41
|
email = getBoolean(switch[1])
|
|
42
|
+
if switch[0] == "days":
|
|
43
|
+
days = int(switch[1])
|
|
38
44
|
|
|
39
45
|
diracAdmin = DiracAdmin()
|
|
40
46
|
exitCode = 0
|
|
@@ -50,7 +56,7 @@ def main():
|
|
|
50
56
|
|
|
51
57
|
# parseCommandLine show help when mandatory arguments are not specified or incorrect argument
|
|
52
58
|
site, comment = Script.getPositionalArgs(group=True)
|
|
53
|
-
result = diracAdmin.banSite(site, comment, printOutput=True)
|
|
59
|
+
result = diracAdmin.banSite(site, comment, printOutput=True, days=days)
|
|
54
60
|
if not result["OK"]:
|
|
55
61
|
errorList.append((site, result["Message"]))
|
|
56
62
|
exitCode = 2
|
|
@@ -30,6 +30,8 @@ class WMSHistory(BaseType):
|
|
|
30
30
|
"MinorStatus",
|
|
31
31
|
"ApplicationStatus",
|
|
32
32
|
"JobSplitType",
|
|
33
|
+
"Tier",
|
|
34
|
+
"Type",
|
|
33
35
|
]
|
|
34
36
|
|
|
35
37
|
self.monitoringFields = ["Jobs", "Reschedules"]
|
|
@@ -46,6 +48,8 @@ class WMSHistory(BaseType):
|
|
|
46
48
|
"User": {"type": "keyword"},
|
|
47
49
|
"JobGroup": {"type": "keyword"},
|
|
48
50
|
"UserGroup": {"type": "keyword"},
|
|
51
|
+
"Tier": {"type": "keyword"},
|
|
52
|
+
"Type": {"type": "keyword"},
|
|
49
53
|
}
|
|
50
54
|
)
|
|
51
55
|
# {'timestamp': {'type': 'date'}} will be added for all monitoring types
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
""" Module that contains client access to the WebApp handler.
|
|
2
|
+
"""
|
|
3
|
+
|
|
4
|
+
from DIRAC.Core.Base.Client import Client, createClient
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@createClient("Monitoring/WebApp")
|
|
8
|
+
class WebAppClient(Client):
|
|
9
|
+
"""WebAppClient sets url for the WebAppHandler."""
|
|
10
|
+
|
|
11
|
+
def __init__(self, url=None, **kwargs):
|
|
12
|
+
"""
|
|
13
|
+
Sets URL for WebApp handler
|
|
14
|
+
|
|
15
|
+
:param self: self reference
|
|
16
|
+
:param url: url of the WebAppHandler
|
|
17
|
+
:param kwargs: forwarded to the Base Client class
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
super().__init__(**kwargs)
|
|
21
|
+
|
|
22
|
+
if not url:
|
|
23
|
+
self.serverURL = "Monitoring/WebApp"
|
|
24
|
+
|
|
25
|
+
else:
|
|
26
|
+
self.serverURL = url
|
|
@@ -5,8 +5,7 @@ Wrapper on top of ElasticDB. It is used to manage the DIRAC monitoring types.
|
|
|
5
5
|
|
|
6
6
|
The following option can be set in `Systems/Monitoring/Databases/MonitoringDB`
|
|
7
7
|
|
|
8
|
-
* *IndexPrefix*: Prefix used to prepend to indexes created in the
|
|
9
|
-
is not present in the CS, the indexes are prefixed with the setup name.
|
|
8
|
+
* *IndexPrefix*: Prefix used to prepend to indexes created in the OpenSearch instance.
|
|
10
9
|
|
|
11
10
|
For each monitoring types managed, the Period (how often a new index is created)
|
|
12
11
|
can be defined with::
|
|
@@ -33,7 +32,6 @@ import time
|
|
|
33
32
|
|
|
34
33
|
from DIRAC import S_ERROR, S_OK
|
|
35
34
|
from DIRAC.ConfigurationSystem.Client.Config import gConfig
|
|
36
|
-
from DIRAC.ConfigurationSystem.Client.Helpers import CSGlobals
|
|
37
35
|
from DIRAC.ConfigurationSystem.Client.PathFinder import getDatabaseSection
|
|
38
36
|
from DIRAC.Core.Base.ElasticDB import ElasticDB
|
|
39
37
|
from DIRAC.Core.Utilities.Plotting.TypeLoader import TypeLoader
|
|
@@ -48,7 +46,7 @@ class MonitoringDB(ElasticDB):
|
|
|
48
46
|
|
|
49
47
|
try:
|
|
50
48
|
section = getDatabaseSection("Monitoring/MonitoringDB")
|
|
51
|
-
indexPrefix = gConfig.getValue(f"{section}/IndexPrefix",
|
|
49
|
+
indexPrefix = gConfig.getValue(f"{section}/IndexPrefix", "").lower()
|
|
52
50
|
# Connecting to the ES cluster
|
|
53
51
|
super().__init__(fullName=name, indexPrefix=indexPrefix)
|
|
54
52
|
except RuntimeError as ex:
|
|
@@ -192,7 +190,10 @@ class MonitoringDB(ElasticDB):
|
|
|
192
190
|
# and now we group with bucket aggregation
|
|
193
191
|
groupingAggregation = self._A("terms", field=grouping, size=self.RESULT_SIZE)
|
|
194
192
|
groupingAggregation.bucket(
|
|
195
|
-
"end_data",
|
|
193
|
+
"end_data",
|
|
194
|
+
"date_histogram",
|
|
195
|
+
field="timestamp",
|
|
196
|
+
interval=interval,
|
|
196
197
|
).metric("timeAggregation", timeAggregation).pipeline(
|
|
197
198
|
"timeAggregation_avg_bucket", "avg_bucket", buckets_path="timeAggregation>total", gap_policy="insert_zeros"
|
|
198
199
|
)
|
|
@@ -447,26 +448,6 @@ class MonitoringDB(ElasticDB):
|
|
|
447
448
|
records.append({paramName: getattr(resObj["_source"], paramName) for paramName in paramNames})
|
|
448
449
|
return S_OK(records)
|
|
449
450
|
|
|
450
|
-
def getLastDayData(self, typeName, condDict):
|
|
451
|
-
"""
|
|
452
|
-
It returns the last day data for a given monitoring type.
|
|
453
|
-
|
|
454
|
-
:returns: for example
|
|
455
|
-
|
|
456
|
-
.. code-block:: python
|
|
457
|
-
|
|
458
|
-
{'sort': [{'timestamp': {'order': 'desc'}}],
|
|
459
|
-
'query': {'bool': {'must': [{'match': {'host': 'dzmathe.cern.ch'}},
|
|
460
|
-
{'match': {'component': 'Bookkeeping_BookkeepingManager'}}]}}}
|
|
461
|
-
|
|
462
|
-
:param str typeName: name of the monitoring type
|
|
463
|
-
:param dict condDict: conditions for the query
|
|
464
|
-
|
|
465
|
-
* key -> name of the field
|
|
466
|
-
* value -> list of possible values
|
|
467
|
-
"""
|
|
468
|
-
return self.__getRawData(typeName, condDict)
|
|
469
|
-
|
|
470
451
|
def getLimitedData(self, typeName, condDict, size=10):
|
|
471
452
|
"""
|
|
472
453
|
Returns a list of records for a given selection.
|
|
@@ -244,24 +244,6 @@ class MonitoringHandlerMixin:
|
|
|
244
244
|
reportRequest["generatePlot"] = False
|
|
245
245
|
return reporter.generate(reportRequest)
|
|
246
246
|
|
|
247
|
-
types_addMonitoringRecords = [str, list]
|
|
248
|
-
|
|
249
|
-
def export_addMonitoringRecords(self, monitoringtype, data):
|
|
250
|
-
"""
|
|
251
|
-
Bulk insert data directly to the given monitoring type.
|
|
252
|
-
|
|
253
|
-
:param str monitoringtype: monitoring type name
|
|
254
|
-
:param list data: list of documents
|
|
255
|
-
:returns: S_OK or S_ERROR
|
|
256
|
-
"""
|
|
257
|
-
|
|
258
|
-
retVal = self.__db.getIndexName(monitoringtype)
|
|
259
|
-
if not retVal["OK"]:
|
|
260
|
-
return retVal
|
|
261
|
-
prefix = retVal["Value"]
|
|
262
|
-
gLogger.debug("addMonitoringRecords:", prefix)
|
|
263
|
-
return self.__db.bulk_index(prefix, data)
|
|
264
|
-
|
|
265
247
|
types_addRecords = [str, str, list]
|
|
266
248
|
|
|
267
249
|
def export_addRecords(self, indexname, monitoringType, data):
|
|
@@ -290,21 +272,6 @@ class MonitoringHandlerMixin:
|
|
|
290
272
|
gLogger.debug("delete index:", indexName)
|
|
291
273
|
return self.__db.deleteIndex(indexName)
|
|
292
274
|
|
|
293
|
-
types_getLastDayData = [str, dict]
|
|
294
|
-
|
|
295
|
-
def export_getLastDayData(self, typeName, condDict):
|
|
296
|
-
"""
|
|
297
|
-
It returns the data from the last day index. Note: we create daily indexes.
|
|
298
|
-
|
|
299
|
-
:param str typeName: name of the monitoring type
|
|
300
|
-
:param dict condDict: conditions for the query
|
|
301
|
-
|
|
302
|
-
* key -> name of the field
|
|
303
|
-
* value -> list of possible values
|
|
304
|
-
"""
|
|
305
|
-
|
|
306
|
-
return self.__db.getLastDayData(typeName, condDict)
|
|
307
|
-
|
|
308
275
|
types_getLimitedDat = [str, dict, int]
|
|
309
276
|
|
|
310
277
|
def export_getLimitedData(self, typeName, condDict, size):
|