DIRAC 9.0.0a60__py3-none-any.whl → 9.0.0a62__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.
Files changed (49) hide show
  1. DIRAC/AccountingSystem/Client/AccountingCLI.py +0 -140
  2. DIRAC/AccountingSystem/Client/DataStoreClient.py +0 -13
  3. DIRAC/AccountingSystem/Client/Types/BaseAccountingType.py +0 -7
  4. DIRAC/AccountingSystem/ConfigTemplate.cfg +0 -5
  5. DIRAC/AccountingSystem/Service/DataStoreHandler.py +0 -72
  6. DIRAC/ConfigurationSystem/Client/Helpers/Registry.py +34 -6
  7. DIRAC/ConfigurationSystem/Client/LocalConfiguration.py +3 -0
  8. DIRAC/ConfigurationSystem/Client/VOMS2CSSynchronizer.py +8 -1
  9. DIRAC/Core/DISET/private/BaseClient.py +1 -2
  10. DIRAC/Core/Security/ProxyInfo.py +9 -5
  11. DIRAC/Core/Utilities/Os.py +32 -1
  12. DIRAC/Core/scripts/dirac_apptainer_exec.py +12 -4
  13. DIRAC/DataManagementSystem/Utilities/DMSHelpers.py +5 -1
  14. DIRAC/Interfaces/API/DiracAdmin.py +17 -5
  15. DIRAC/Interfaces/scripts/dirac_admin_allow_site.py +7 -1
  16. DIRAC/Interfaces/scripts/dirac_admin_ban_site.py +7 -1
  17. DIRAC/MonitoringSystem/Client/Types/WMSHistory.py +4 -0
  18. DIRAC/MonitoringSystem/DB/MonitoringDB.py +0 -20
  19. DIRAC/MonitoringSystem/Service/MonitoringHandler.py +0 -33
  20. DIRAC/MonitoringSystem/Service/WebAppHandler.py +68 -1
  21. DIRAC/ResourceStatusSystem/Client/SiteStatus.py +4 -2
  22. DIRAC/ResourceStatusSystem/Utilities/CSHelpers.py +2 -31
  23. DIRAC/ResourceStatusSystem/scripts/dirac_rss_set_status.py +18 -4
  24. DIRAC/Resources/Computing/BatchSystems/Condor.py +126 -108
  25. DIRAC/Resources/Computing/HTCondorCEComputingElement.py +33 -15
  26. DIRAC/Resources/Computing/test/Test_HTCondorCEComputingElement.py +67 -49
  27. DIRAC/Resources/Storage/StorageBase.py +4 -2
  28. DIRAC/TransformationSystem/Agent/TaskManagerAgentBase.py +10 -13
  29. DIRAC/TransformationSystem/Agent/TransformationAgent.py +22 -1
  30. DIRAC/TransformationSystem/Agent/TransformationCleaningAgent.py +6 -3
  31. DIRAC/TransformationSystem/Client/Utilities.py +6 -0
  32. DIRAC/WorkloadManagementSystem/Agent/JobCleaningAgent.py +4 -3
  33. DIRAC/WorkloadManagementSystem/Agent/StatesAccountingAgent.py +34 -1
  34. DIRAC/WorkloadManagementSystem/Client/JobMonitoringClient.py +0 -9
  35. DIRAC/WorkloadManagementSystem/Client/SandboxStoreClient.py +0 -37
  36. DIRAC/WorkloadManagementSystem/DB/JobDB.py +0 -58
  37. DIRAC/WorkloadManagementSystem/DB/SandboxMetadataDB.py +25 -37
  38. DIRAC/WorkloadManagementSystem/Executor/JobSanity.py +3 -3
  39. DIRAC/WorkloadManagementSystem/JobWrapper/JobWrapper.py +9 -6
  40. DIRAC/WorkloadManagementSystem/Service/JobManagerHandler.py +0 -10
  41. DIRAC/WorkloadManagementSystem/Service/JobMonitoringHandler.py +0 -126
  42. DIRAC/WorkloadManagementSystem/Service/PilotManagerHandler.py +6 -3
  43. DIRAC/WorkloadManagementSystem/Service/SandboxStoreHandler.py +5 -51
  44. {dirac-9.0.0a60.dist-info → dirac-9.0.0a62.dist-info}/METADATA +1 -1
  45. {dirac-9.0.0a60.dist-info → dirac-9.0.0a62.dist-info}/RECORD +49 -49
  46. {dirac-9.0.0a60.dist-info → dirac-9.0.0a62.dist-info}/WHEEL +0 -0
  47. {dirac-9.0.0a60.dist-info → dirac-9.0.0a62.dist-info}/entry_points.txt +0 -0
  48. {dirac-9.0.0a60.dist-info → dirac-9.0.0a62.dist-info}/licenses/LICENSE +0 -0
  49. {dirac-9.0.0a60.dist-info → dirac-9.0.0a62.dist-info}/top_level.txt +0 -0
@@ -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
@@ -447,26 +447,6 @@ class MonitoringDB(ElasticDB):
447
447
  records.append({paramName: getattr(resObj["_source"], paramName) for paramName in paramNames})
448
448
  return S_OK(records)
449
449
 
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
450
  def getLimitedData(self, typeName, condDict, size=10):
471
451
  """
472
452
  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):
@@ -6,7 +6,6 @@ from DIRAC import S_ERROR, S_OK
6
6
  from DIRAC.ConfigurationSystem.Client.Helpers.Operations import Operations
7
7
  from DIRAC.ConfigurationSystem.Client.Helpers.Resources import getSites
8
8
  from DIRAC.Core.DISET.RequestHandler import RequestHandler
9
- from DIRAC.Core.Utilities.JEncode import strToIntDict
10
9
  from DIRAC.Core.Utilities.ObjectLoader import ObjectLoader
11
10
  from DIRAC.RequestManagementSystem.Client.Operation import Operation
12
11
  from DIRAC.RequestManagementSystem.Client.Request import Request
@@ -334,6 +333,74 @@ class WebAppHandler(RequestHandler):
334
333
 
335
334
  return S_OK(resultDict)
336
335
 
336
+ types_getApplicationStates = []
337
+
338
+ @classmethod
339
+ def export_getApplicationStates(cls, condDict=None, older=None, newer=None):
340
+ """Return Distinct Values of ApplicationStatus job Attribute in WMS"""
341
+ return cls.jobDB.getDistinctJobAttributes("ApplicationStatus", condDict, older, newer)
342
+
343
+ types_getJobTypes = []
344
+
345
+ @classmethod
346
+ def export_getJobTypes(cls, condDict=None, older=None, newer=None):
347
+ """Return Distinct Values of JobType job Attribute in WMS"""
348
+ return cls.jobDB.getDistinctJobAttributes("JobType", condDict, older, newer)
349
+
350
+ types_getOwners = []
351
+
352
+ @classmethod
353
+ def export_getOwners(cls, condDict=None, older=None, newer=None):
354
+ """
355
+ Return Distinct Values of Owner job Attribute in WMS
356
+ """
357
+ return cls.jobDB.getDistinctJobAttributes("Owner", condDict, older, newer)
358
+
359
+ types_getOwnerGroup = []
360
+
361
+ @classmethod
362
+ def export_getOwnerGroup(cls):
363
+ """
364
+ Return Distinct Values of OwnerGroup from the JobDB
365
+ """
366
+ return cls.jobDB.getDistinctJobAttributes("OwnerGroup")
367
+
368
+ types_getJobGroups = []
369
+
370
+ @classmethod
371
+ def export_getJobGroups(cls, condDict=None, older=None, cutDate=None):
372
+ """
373
+ Return Distinct Values of ProductionId job Attribute in WMS
374
+ """
375
+ return cls.jobDB.getDistinctJobAttributes("JobGroup", condDict, older, newer=cutDate)
376
+
377
+ types_getSites = []
378
+
379
+ @classmethod
380
+ def export_getSites(cls, condDict=None, older=None, newer=None):
381
+ """
382
+ Return Distinct Values of Site job Attribute in WMS
383
+ """
384
+ return cls.jobDB.getDistinctJobAttributes("Site", condDict, older, newer)
385
+
386
+ types_getStates = []
387
+
388
+ @classmethod
389
+ def export_getStates(cls, condDict=None, older=None, newer=None):
390
+ """
391
+ Return Distinct Values of Status job Attribute in WMS
392
+ """
393
+ return cls.jobDB.getDistinctJobAttributes("Status", condDict, older, newer)
394
+
395
+ types_getMinorStates = []
396
+
397
+ @classmethod
398
+ def export_getMinorStates(cls, condDict=None, older=None, newer=None):
399
+ """
400
+ Return Distinct Values of Minor Status job Attribute in WMS
401
+ """
402
+ return cls.jobDB.getDistinctJobAttributes("MinorStatus", condDict, older, newer)
403
+
337
404
  ##############################################################################
338
405
  # Transformations
339
406
  ##############################################################################
@@ -1,4 +1,4 @@
1
- """ SiteStatus helper
1
+ """SiteStatus helper
2
2
 
3
3
  Module that acts as a helper for knowing the status of a site.
4
4
  It takes care of switching between the CS and the RSS.
@@ -195,7 +195,7 @@ class SiteStatus(metaclass=DIRACSingleton):
195
195
 
196
196
  return S_OK(siteList)
197
197
 
198
- def setSiteStatus(self, site, status, comment="No comment"):
198
+ def setSiteStatus(self, site, status, comment="No comment", expiry=None):
199
199
  """
200
200
  Set the status of a site in the 'SiteStatus' table of RSS
201
201
 
@@ -231,6 +231,8 @@ class SiteStatus(metaclass=DIRACSingleton):
231
231
  return S_ERROR(f"Unable to get user proxy info {result['Message']} ")
232
232
 
233
233
  tokenExpiration = datetime.utcnow() + timedelta(days=1)
234
+ if expiry:
235
+ tokenExpiration = expiry
234
236
 
235
237
  self.rssCache.acquireLock()
236
238
  try:
@@ -3,11 +3,10 @@ Module containing functions interacting with the CS and useful for the RSS
3
3
  modules.
4
4
  """
5
5
 
6
- from DIRAC import gConfig, gLogger, S_OK
6
+ from DIRAC import S_OK, gConfig, gLogger
7
+ from DIRAC.ConfigurationSystem.Client.Helpers.Resources import getQueues
7
8
  from DIRAC.Core.Utilities.SiteSEMapping import getSEParameters
8
- from DIRAC.ConfigurationSystem.Client.Helpers.Resources import getQueues, getCESiteMapping
9
9
  from DIRAC.DataManagementSystem.Utilities.DMSHelpers import DMSHelpers
10
- from DIRAC.ResourceStatusSystem.Utilities import Utils
11
10
 
12
11
 
13
12
  def warmUp():
@@ -19,28 +18,6 @@ def warmUp():
19
18
  gRefresher.refreshConfigurationIfNeeded()
20
19
 
21
20
 
22
- def getResources():
23
- """
24
- Gets all resources
25
- """
26
-
27
- resources = DMSHelpers().getStorageElements()
28
-
29
- fts = getFTS()
30
- if fts["OK"]:
31
- resources = resources + fts["Value"]
32
-
33
- fc = getFileCatalogs()
34
- if fc["OK"]:
35
- resources = resources + fc["Value"]
36
-
37
- res = getCESiteMapping()
38
- if res["OK"]:
39
- resources = resources + list(res["Value"])
40
-
41
- return S_OK(resources)
42
-
43
-
44
21
  def getStorageElementEndpoint(seName):
45
22
  """Get endpoints of a StorageElement
46
23
 
@@ -86,12 +63,6 @@ def getFTS():
86
63
  return S_OK([])
87
64
 
88
65
 
89
- def getSpaceTokenEndpoints():
90
- """Get Space Token Endpoints"""
91
-
92
- return Utils.getCSTree("Shares/Disk")
93
-
94
-
95
66
  def getFileCatalogs():
96
67
  """
97
68
  Gets all storage elements from /Resources/FileCatalogs
@@ -29,6 +29,7 @@ def registerSwitches():
29
29
  ("reason=", "Reason to set the Status"),
30
30
  ("VO=", "VO to change a status for. When omitted, status will be changed for all VOs"),
31
31
  ("tokenOwner=", "Owner of the token"),
32
+ ("days=", "Number of days the token is valid for. Default is 1 day. 0 or less days denotes forever."),
32
33
  )
33
34
 
34
35
  for switch in switches:
@@ -50,6 +51,7 @@ def parseSwitches():
50
51
  switches = dict(Script.getUnprocessedSwitches())
51
52
  switches.setdefault("statusType", None)
52
53
  switches.setdefault("VO", None)
54
+ switches.setdefault("days", 1)
53
55
 
54
56
  for key in ("element", "name", "status", "reason"):
55
57
  if key not in switches:
@@ -183,7 +185,11 @@ def setStatus(switchDict, tokenOwner):
183
185
  )
184
186
  return S_OK()
185
187
 
186
- tomorrow = datetime.utcnow().replace(microsecond=0) + timedelta(days=1)
188
+ tokenLifetime = int(switchDict["days"])
189
+ if tokenLifetime <= 0:
190
+ tokenExpiration = datetime.max
191
+ else:
192
+ tokenExpiration = datetime.utcnow().replace(microsecond=0) + timedelta(days=tokenLifetime)
187
193
 
188
194
  for status, statusType in elements:
189
195
  gLogger.debug(f"{status} {statusType}")
@@ -193,8 +199,16 @@ def setStatus(switchDict, tokenOwner):
193
199
  continue
194
200
 
195
201
  gLogger.debug(
196
- "About to set status %s -> %s for %s, statusType: %s, VO: %s, reason: %s"
197
- % (status, switchDict["status"], switchDict["name"], statusType, switchDict["VO"], switchDict["reason"])
202
+ "About to set status %s -> %s for %s, statusType: %s, VO: %s, reason: %s, days: %s"
203
+ % (
204
+ status,
205
+ switchDict["status"],
206
+ switchDict["name"],
207
+ statusType,
208
+ switchDict["VO"],
209
+ switchDict["reason"],
210
+ switchDict["days"],
211
+ )
198
212
  )
199
213
  result = rssClient.modifyStatusElement(
200
214
  switchDict["element"],
@@ -205,7 +219,7 @@ def setStatus(switchDict, tokenOwner):
205
219
  reason=switchDict["reason"],
206
220
  vO=switchDict["VO"],
207
221
  tokenOwner=tokenOwner,
208
- tokenExpiration=tomorrow,
222
+ tokenExpiration=tokenExpiration,
209
223
  )
210
224
  if not result["OK"]:
211
225
  return result