DIRAC 9.0.6__py3-none-any.whl → 9.0.8__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/Core/DISET/private/Transports/M2SSLTransport.py +9 -7
- DIRAC/DataManagementSystem/Agent/FTS3Agent.py +8 -7
- DIRAC/DataManagementSystem/Client/FTS3Job.py +94 -24
- DIRAC/DataManagementSystem/Client/test/Test_FTS3Objects.py +1 -0
- DIRAC/DataManagementSystem/Client/test/Test_scitag.py +69 -0
- DIRAC/FrameworkSystem/DB/ProxyDB.py +6 -2
- DIRAC/ResourceStatusSystem/Command/FreeDiskSpaceCommand.py +3 -1
- DIRAC/Resources/Computing/AREXComputingElement.py +18 -2
- DIRAC/TransformationSystem/Client/Utilities.py +6 -3
- DIRAC/WorkloadManagementSystem/Agent/SiteDirector.py +6 -5
- DIRAC/WorkloadManagementSystem/Client/DownloadInputData.py +4 -3
- DIRAC/WorkloadManagementSystem/ConfigTemplate.cfg +3 -3
- DIRAC/WorkloadManagementSystem/Service/WMSAdministratorHandler.py +18 -31
- {dirac-9.0.6.dist-info → dirac-9.0.8.dist-info}/METADATA +2 -2
- {dirac-9.0.6.dist-info → dirac-9.0.8.dist-info}/RECORD +19 -18
- {dirac-9.0.6.dist-info → dirac-9.0.8.dist-info}/WHEEL +0 -0
- {dirac-9.0.6.dist-info → dirac-9.0.8.dist-info}/entry_points.txt +0 -0
- {dirac-9.0.6.dist-info → dirac-9.0.8.dist-info}/licenses/LICENSE +0 -0
- {dirac-9.0.6.dist-info → dirac-9.0.8.dist-info}/top_level.txt +0 -0
|
@@ -110,19 +110,18 @@ class SSLTransport(BaseTransport):
|
|
|
110
110
|
if self.serverMode():
|
|
111
111
|
raise RuntimeError("SSLTransport is in server mode.")
|
|
112
112
|
|
|
113
|
-
|
|
113
|
+
errors = []
|
|
114
114
|
host, port = self.stServerAddress
|
|
115
115
|
|
|
116
116
|
# The following piece of code was inspired by the python socket documentation
|
|
117
117
|
# as well as the implementation of M2Crypto.httpslib.HTTPSConnection
|
|
118
118
|
|
|
119
|
-
#
|
|
120
|
-
# a host name.
|
|
119
|
+
# Get all available addresses (IPv6 and IPv4) and try them in order
|
|
121
120
|
try:
|
|
122
121
|
addrInfoList = socket.getaddrinfo(host, port, socket.AF_UNSPEC, socket.SOCK_STREAM)
|
|
123
122
|
except OSError as e:
|
|
124
123
|
return S_ERROR(f"DNS lookup failed {e!r}")
|
|
125
|
-
for family, _socketType, _proto, _canonname,
|
|
124
|
+
for family, _socketType, _proto, _canonname, socketAddress in addrInfoList:
|
|
126
125
|
try:
|
|
127
126
|
self.oSocket = SSL.Connection(self.__ctx, family=family)
|
|
128
127
|
|
|
@@ -138,7 +137,10 @@ class SSLTransport(BaseTransport):
|
|
|
138
137
|
# set SNI server name since we know it at this point
|
|
139
138
|
self.oSocket.set_tlsext_host_name(host)
|
|
140
139
|
|
|
141
|
-
|
|
140
|
+
# tell the connection which host we are connecting to so we can
|
|
141
|
+
# use the address we obtained from DNS
|
|
142
|
+
self.oSocket.set1_host(host)
|
|
143
|
+
self.oSocket.connect(socketAddress)
|
|
142
144
|
|
|
143
145
|
# Once the connection is established, we can use the timeout
|
|
144
146
|
# asked for RPC
|
|
@@ -151,12 +153,12 @@ class SSLTransport(BaseTransport):
|
|
|
151
153
|
# They should be propagated upwards and caught by the BaseClient
|
|
152
154
|
# not to enter the retry loop
|
|
153
155
|
except OSError as e:
|
|
154
|
-
|
|
156
|
+
errors.append(f"{socketAddress} {e}:{repr(e)}")
|
|
155
157
|
|
|
156
158
|
if self.oSocket is not None:
|
|
157
159
|
self.close()
|
|
158
160
|
|
|
159
|
-
return S_ERROR(
|
|
161
|
+
return S_ERROR("; ".join(errors))
|
|
160
162
|
|
|
161
163
|
def initAsServer(self):
|
|
162
164
|
"""Prepare this server socket for use."""
|
|
@@ -719,10 +719,11 @@ class FTS3Agent(AgentModule):
|
|
|
719
719
|
return self.dataOpSender.concludeSending()
|
|
720
720
|
|
|
721
721
|
def __sendAccounting(self, ftsJob):
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
722
|
+
for accountingDict in ftsJob.accountingDicts:
|
|
723
|
+
self.dataOpSender.sendData(
|
|
724
|
+
accountingDict,
|
|
725
|
+
commitFlag=True,
|
|
726
|
+
delayedCommit=True,
|
|
727
|
+
startTime=fromString(ftsJob.submitTime),
|
|
728
|
+
endTime=fromString(ftsJob.lastUpdate),
|
|
729
|
+
)
|
|
@@ -3,9 +3,13 @@
|
|
|
3
3
|
import datetime
|
|
4
4
|
import errno
|
|
5
5
|
import os
|
|
6
|
+
import requests
|
|
6
7
|
from packaging.version import Version
|
|
7
8
|
|
|
8
|
-
from cachetools import cachedmethod, LRUCache
|
|
9
|
+
from cachetools import cachedmethod, LRUCache, TTLCache, cached
|
|
10
|
+
from threading import Lock
|
|
11
|
+
from typing import Optional
|
|
12
|
+
|
|
9
13
|
|
|
10
14
|
# Requires at least version 3.3.3
|
|
11
15
|
from fts3 import __version__ as fts3_version
|
|
@@ -44,6 +48,50 @@ BRING_ONLINE_TIMEOUT = 259200
|
|
|
44
48
|
IDP_CACHE_SIZE = 8
|
|
45
49
|
|
|
46
50
|
|
|
51
|
+
_scitag_cache = TTLCache(maxsize=10, ttl=3600)
|
|
52
|
+
_scitag_lock = Lock()
|
|
53
|
+
_scitag_json_cache = TTLCache(maxsize=1, ttl=86400)
|
|
54
|
+
_scitag_json_lock = Lock()
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
@cached(_scitag_cache, lock=_scitag_lock)
|
|
58
|
+
def get_scitag(vo: str, activity: Optional[str] = None) -> int:
|
|
59
|
+
"""
|
|
60
|
+
Get the scitag based on the VO and activity.
|
|
61
|
+
If the VO is not found in the scitag.json, it defaults to 1.
|
|
62
|
+
If no specific activity is provided, it defaults to the "default" activityName.
|
|
63
|
+
|
|
64
|
+
:param vo: The VO for which to get the scitag
|
|
65
|
+
:param activity: The activity for which to get the scitag
|
|
66
|
+
:return: The scitag value
|
|
67
|
+
"""
|
|
68
|
+
|
|
69
|
+
@cached(_scitag_json_cache, lock=_scitag_json_lock)
|
|
70
|
+
def get_remote_json():
|
|
71
|
+
gLogger.verbose("Fetching https://scitags.org/api.json from the network")
|
|
72
|
+
response = requests.get("https://scitags.org/api.json")
|
|
73
|
+
response.raise_for_status()
|
|
74
|
+
return response.json()
|
|
75
|
+
|
|
76
|
+
vo_id = 1 # Default VO ID
|
|
77
|
+
activity_id = 1 # Default activity ID
|
|
78
|
+
|
|
79
|
+
try:
|
|
80
|
+
# Load the JSON data from the cache or network
|
|
81
|
+
sj = get_remote_json()
|
|
82
|
+
|
|
83
|
+
for experiment in sj.get("experiments", []):
|
|
84
|
+
if experiment.get("expName") == vo.lower():
|
|
85
|
+
vo_id = experiment.get("expId")
|
|
86
|
+
for act in experiment.get("activities", []):
|
|
87
|
+
if act.get("activityName") == activity:
|
|
88
|
+
activity_id = act.get("activityId")
|
|
89
|
+
except Exception as e:
|
|
90
|
+
gLogger.error(f"Error fetching or parsing scitag.json. Using default scitag values.", repr(e))
|
|
91
|
+
# Logic to determine the scitag based on vo and activity (this is what FTS wants)
|
|
92
|
+
return vo_id << 6 | activity_id # Example logic, replace with actual implementation
|
|
93
|
+
|
|
94
|
+
|
|
47
95
|
class FTS3Job(JSerializable):
|
|
48
96
|
"""Abstract class to represent a job to be executed by FTS. It belongs
|
|
49
97
|
to an FTS3Operation
|
|
@@ -120,7 +168,7 @@ class FTS3Job(JSerializable):
|
|
|
120
168
|
# temporary used only for accounting
|
|
121
169
|
# it is set by the monitor method
|
|
122
170
|
# when a job is in a final state
|
|
123
|
-
self.
|
|
171
|
+
self.accountingDicts = None
|
|
124
172
|
|
|
125
173
|
@classmethod
|
|
126
174
|
@cachedmethod(lambda cls: cls._idp_cache)
|
|
@@ -157,7 +205,6 @@ class FTS3Job(JSerializable):
|
|
|
157
205
|
|
|
158
206
|
if not self.ftsGUID:
|
|
159
207
|
return S_ERROR("FTSGUID not set, FTS job not submitted?")
|
|
160
|
-
|
|
161
208
|
if not context:
|
|
162
209
|
if not ftsServer:
|
|
163
210
|
ftsServer = self.ftsServer
|
|
@@ -184,13 +231,14 @@ class FTS3Job(JSerializable):
|
|
|
184
231
|
self.error = jobStatusDict["reason"]
|
|
185
232
|
|
|
186
233
|
if newStatus in self.FINAL_STATES:
|
|
187
|
-
self.
|
|
234
|
+
self._fillAccountingDicts(jobStatusDict)
|
|
188
235
|
|
|
189
236
|
filesInfoList = jobStatusDict["files"]
|
|
190
237
|
filesStatus = {}
|
|
191
238
|
statusSummary = {}
|
|
192
239
|
|
|
193
240
|
# Make a copy, since we are potentially
|
|
241
|
+
|
|
194
242
|
# deleting objects
|
|
195
243
|
for fileDict in list(filesInfoList):
|
|
196
244
|
file_state = fileDict["file_state"].capitalize()
|
|
@@ -245,7 +293,7 @@ class FTS3Job(JSerializable):
|
|
|
245
293
|
# so we put this back into the monitoring data such that the accounting is done properly
|
|
246
294
|
jobStatusDict["files"] = filesInfoList
|
|
247
295
|
if newStatus in self.FINAL_STATES:
|
|
248
|
-
self.
|
|
296
|
+
self._fillAccountingDicts(jobStatusDict)
|
|
249
297
|
|
|
250
298
|
total = len(filesInfoList)
|
|
251
299
|
completed = sum(statusSummary.get(state, 0) for state in FTS3File.FTS_FINAL_STATES)
|
|
@@ -470,6 +518,9 @@ class FTS3Job(JSerializable):
|
|
|
470
518
|
|
|
471
519
|
ftsFileID = getattr(ftsFile, "fileID")
|
|
472
520
|
|
|
521
|
+
# scitag 65 is 1 << 6 | 1 (default experiment, default activity)
|
|
522
|
+
scitag = get_scitag(vo=self.vo, activity=self.activity)
|
|
523
|
+
|
|
473
524
|
# Under normal circumstances, we simply submit an fts transfer as such:
|
|
474
525
|
# * srcProto://myFile -> destProto://myFile
|
|
475
526
|
#
|
|
@@ -499,6 +550,7 @@ class FTS3Job(JSerializable):
|
|
|
499
550
|
filesize=ftsFile.size,
|
|
500
551
|
metadata=stageTrans_metadata,
|
|
501
552
|
activity=self.activity,
|
|
553
|
+
scitag=scitag,
|
|
502
554
|
)
|
|
503
555
|
transfers.append(stageTrans)
|
|
504
556
|
|
|
@@ -572,6 +624,7 @@ class FTS3Job(JSerializable):
|
|
|
572
624
|
activity=self.activity,
|
|
573
625
|
source_token=srcToken,
|
|
574
626
|
destination_token=dstToken,
|
|
627
|
+
scitag=scitag,
|
|
575
628
|
)
|
|
576
629
|
|
|
577
630
|
transfers.append(trans)
|
|
@@ -902,9 +955,9 @@ class FTS3Job(JSerializable):
|
|
|
902
955
|
gLogger.exception("Error generating context", repr(e))
|
|
903
956
|
return S_ERROR(repr(e))
|
|
904
957
|
|
|
905
|
-
def
|
|
906
|
-
"""This methods generates the necessary information to create
|
|
907
|
-
accounting
|
|
958
|
+
def _fillAccountingDicts(self, jobStatusDict):
|
|
959
|
+
"""This methods generates the necessary information to create DataOperation
|
|
960
|
+
accounting records, and stores them as a instance attribute.
|
|
908
961
|
|
|
909
962
|
For it to be relevant, it should be called only when the job is in a final state.
|
|
910
963
|
|
|
@@ -913,6 +966,7 @@ class FTS3Job(JSerializable):
|
|
|
913
966
|
:returns: None
|
|
914
967
|
"""
|
|
915
968
|
|
|
969
|
+
accountingDicts = []
|
|
916
970
|
accountingDict = dict()
|
|
917
971
|
sourceSE = None
|
|
918
972
|
targetSE = None
|
|
@@ -923,16 +977,24 @@ class FTS3Job(JSerializable):
|
|
|
923
977
|
accountingDict["Protocol"] = "FTS3"
|
|
924
978
|
accountingDict["ExecutionSite"] = self.ftsServer
|
|
925
979
|
|
|
980
|
+
# Registration values must be set anyway
|
|
981
|
+
accountingDict["RegistrationTime"] = 0.0
|
|
982
|
+
accountingDict["RegistrationOK"] = 0
|
|
983
|
+
accountingDict["RegistrationTotal"] = 0
|
|
984
|
+
|
|
926
985
|
# We cannot rely on all the transient attributes (like self.filesToSubmit)
|
|
927
986
|
# because it is probably not filed by the time we monitor !
|
|
928
987
|
|
|
929
988
|
filesInfoList = jobStatusDict["files"]
|
|
930
989
|
successfulFiles = []
|
|
990
|
+
failedFiles = []
|
|
931
991
|
|
|
932
992
|
for fileDict in filesInfoList:
|
|
933
993
|
file_state = fileDict["file_state"].capitalize()
|
|
934
994
|
if file_state in FTS3File.FTS_SUCCESS_STATES:
|
|
935
995
|
successfulFiles.append(fileDict)
|
|
996
|
+
else:
|
|
997
|
+
failedFiles.append(fileDict)
|
|
936
998
|
|
|
937
999
|
job_metadata = jobStatusDict["job_metadata"]
|
|
938
1000
|
# previous version of the code did not have dictionary as
|
|
@@ -941,23 +1003,31 @@ class FTS3Job(JSerializable):
|
|
|
941
1003
|
sourceSE = job_metadata.get("sourceSE")
|
|
942
1004
|
targetSE = job_metadata.get("targetSE")
|
|
943
1005
|
|
|
944
|
-
accountingDict["TransferOK"] = len(successfulFiles)
|
|
945
|
-
accountingDict["TransferTotal"] = len(filesInfoList)
|
|
946
|
-
# We need this if in the list comprehension because staging only jobs have `None` as filesize
|
|
947
|
-
accountingDict["TransferSize"] = sum(
|
|
948
|
-
fileDict["filesize"] for fileDict in successfulFiles if fileDict["filesize"]
|
|
949
|
-
)
|
|
950
|
-
accountingDict["FinalStatus"] = self.status
|
|
951
1006
|
accountingDict["Source"] = sourceSE
|
|
952
1007
|
accountingDict["Destination"] = targetSE
|
|
953
|
-
# We need this if in the list comprehension because staging only jobs have `None` as tx_duration
|
|
954
|
-
accountingDict["TransferTime"] = sum(
|
|
955
|
-
int(fileDict["tx_duration"]) for fileDict in successfulFiles if fileDict["tx_duration"]
|
|
956
|
-
)
|
|
957
1008
|
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
1009
|
+
if successfulFiles:
|
|
1010
|
+
successfulDict = accountingDict.copy()
|
|
1011
|
+
successfulDict["TransferOK"] = len(successfulFiles)
|
|
1012
|
+
successfulDict["TransferTotal"] = len(successfulFiles)
|
|
1013
|
+
# We need this if in the list comprehension because staging only jobs have `None` as filesize
|
|
1014
|
+
successfulDict["TransferSize"] = sum(
|
|
1015
|
+
fileDict["filesize"] for fileDict in successfulFiles if fileDict["filesize"]
|
|
1016
|
+
)
|
|
1017
|
+
successfulDict["FinalStatus"] = "Finished"
|
|
962
1018
|
|
|
963
|
-
|
|
1019
|
+
# We need this if in the list comprehension because staging only jobs have `None` as tx_duration
|
|
1020
|
+
successfulDict["TransferTime"] = sum(
|
|
1021
|
+
int(fileDict["tx_duration"]) for fileDict in successfulFiles if fileDict["tx_duration"]
|
|
1022
|
+
)
|
|
1023
|
+
accountingDicts.append(successfulDict)
|
|
1024
|
+
if failedFiles:
|
|
1025
|
+
failedDict = accountingDict.copy()
|
|
1026
|
+
failedDict["TransferOK"] = 0
|
|
1027
|
+
failedDict["TransferTotal"] = len(failedFiles)
|
|
1028
|
+
failedDict["TransferSize"] = 0
|
|
1029
|
+
failedDict["FinalStatus"] = "Failed"
|
|
1030
|
+
failedDict["TransferTime"] = 0
|
|
1031
|
+
accountingDicts.append(failedDict)
|
|
1032
|
+
|
|
1033
|
+
self.accountingDicts = accountingDicts
|
|
@@ -204,6 +204,7 @@ def generateFTS3Job(sourceSE, targetSE, lfns, multiHopSE=None):
|
|
|
204
204
|
newJob.sourceSE = sourceSE
|
|
205
205
|
newJob.targetSE = targetSE
|
|
206
206
|
newJob.multiHopSE = multiHopSE
|
|
207
|
+
newJob.vo = "lhcb"
|
|
207
208
|
filesToSubmit = []
|
|
208
209
|
|
|
209
210
|
for i, lfn in enumerate(lfns, start=1):
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
from unittest.mock import Mock, patch
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
|
|
5
|
+
from DIRAC.DataManagementSystem.Client.FTS3Job import get_scitag
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class TestGetScitag:
|
|
9
|
+
def test_valid_vo_and_activity(self):
|
|
10
|
+
"""Test get_scitag with valid VO and activity."""
|
|
11
|
+
result = get_scitag("atlas", "Analysis Input")
|
|
12
|
+
expected = 2 << 6 | 17 # atlas expId=2, analysis activityId=17
|
|
13
|
+
assert result == expected
|
|
14
|
+
|
|
15
|
+
def test_valid_vo_no_activity(self):
|
|
16
|
+
"""Test get_scitag with valid VO but no specific activity (should use default)."""
|
|
17
|
+
result = get_scitag("cms")
|
|
18
|
+
expected = 3 << 6 | 1 # cms expId=200, default activityId=1
|
|
19
|
+
assert result == expected
|
|
20
|
+
|
|
21
|
+
def test_invalid_vo(self):
|
|
22
|
+
"""Test get_scitag with invalid VO (should use default vo_id=1)."""
|
|
23
|
+
result = get_scitag("nonexistent")
|
|
24
|
+
expected = 1 << 6 | 1 # default vo_id=1, default activity_id=1
|
|
25
|
+
assert result == expected
|
|
26
|
+
|
|
27
|
+
def test_valid_vo_invalid_activity(self):
|
|
28
|
+
"""Test get_scitag with valid VO but invalid activity."""
|
|
29
|
+
result = get_scitag("atlas", "nonexistent_activity")
|
|
30
|
+
expected = 2 << 6 | 1 # atlas expId=2, default activity_id=1
|
|
31
|
+
assert result == expected
|
|
32
|
+
|
|
33
|
+
def test_case_insensitive_vo(self):
|
|
34
|
+
"""Test that VO matching is case insensitive."""
|
|
35
|
+
result = get_scitag("ATLAS", "Data Brokering")
|
|
36
|
+
expected = 2 << 6 | 3 # atlas expId=2, production activityId=3
|
|
37
|
+
assert result == expected
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@pytest.mark.parametrize(
|
|
41
|
+
"vo,activity,expected_vo_id,expected_activity_id",
|
|
42
|
+
[
|
|
43
|
+
("atlas", "Analysis Output", 2, 18),
|
|
44
|
+
("atlas", "Debug", 2, 9),
|
|
45
|
+
("cms", "Cache", 3, 3),
|
|
46
|
+
("cms", "default", 3, 1),
|
|
47
|
+
("nonexistent", "any", 1, 1), # defaults
|
|
48
|
+
("atlas", "nonexistent", 2, 1), # valid vo, invalid activity
|
|
49
|
+
],
|
|
50
|
+
)
|
|
51
|
+
def test_parametrized_scenarios(vo, activity, expected_vo_id, expected_activity_id):
|
|
52
|
+
"""Parametrized test for various VO and activity combinations."""
|
|
53
|
+
result = get_scitag(vo, activity)
|
|
54
|
+
expected = expected_vo_id << 6 | expected_activity_id
|
|
55
|
+
assert result == expected
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
@pytest.mark.parametrize(
|
|
59
|
+
"vo,expected_result",
|
|
60
|
+
[
|
|
61
|
+
("atlas", 2 << 6 | 1), # Should use default activity
|
|
62
|
+
("cms", 3 << 6 | 1), # Should use default activity
|
|
63
|
+
("unknown", 1 << 6 | 1), # Should use all defaults
|
|
64
|
+
],
|
|
65
|
+
)
|
|
66
|
+
def test_no_activity_parameter(vo, expected_result):
|
|
67
|
+
"""Test behavior when no activity parameter is provided."""
|
|
68
|
+
result = get_scitag(vo)
|
|
69
|
+
assert result == expected_result
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
import textwrap
|
|
12
12
|
from threading import Lock
|
|
13
13
|
|
|
14
|
-
from cachetools import TTLCache,
|
|
14
|
+
from cachetools import TTLCache, cachedmethod
|
|
15
15
|
|
|
16
16
|
from DIRAC import S_ERROR, S_OK, gLogger
|
|
17
17
|
from DIRAC.ConfigurationSystem.Client.Helpers import Registry
|
|
@@ -25,6 +25,10 @@ from DIRAC.Resources.ProxyProvider.ProxyProviderFactory import ProxyProviderFact
|
|
|
25
25
|
|
|
26
26
|
DEFAULT_MAIL_FROM = "proxymanager@diracgrid.org"
|
|
27
27
|
|
|
28
|
+
# Module-level cache for getProxyStrength method (shared across ProxyDB instances)
|
|
29
|
+
_get_proxy_strength_cache = TTLCache(maxsize=1000, ttl=600)
|
|
30
|
+
_get_proxy_strength_lock = Lock()
|
|
31
|
+
|
|
28
32
|
|
|
29
33
|
class ProxyDB(DB):
|
|
30
34
|
NOTIFICATION_TIMES = [2592000, 1296000]
|
|
@@ -398,7 +402,7 @@ class ProxyDB(DB):
|
|
|
398
402
|
return S_ERROR(", ".join(errMsgs))
|
|
399
403
|
return result
|
|
400
404
|
|
|
401
|
-
@
|
|
405
|
+
@cachedmethod(lambda self: _get_proxy_strength_cache, lock=lambda self: _get_proxy_strength_lock)
|
|
402
406
|
def getProxyStrength(self, userDN, userGroup=None, vomsAttr=None):
|
|
403
407
|
"""Load the proxy in cache corresponding to the criteria, and check its strength
|
|
404
408
|
|
|
@@ -121,7 +121,9 @@ class FreeDiskSpaceCommand(Command):
|
|
|
121
121
|
"Site": siteRes["Value"] if siteRes["Value"] else "unassigned",
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
-
|
|
124
|
+
# There are sometimes small discrepencies which can lead to negative
|
|
125
|
+
# used values.
|
|
126
|
+
results["Used"] = max(0, results["Total"] - results["Free"])
|
|
125
127
|
|
|
126
128
|
for sType in ["Total", "Free", "Used"]:
|
|
127
129
|
spaceTokenAccounting = StorageOccupancy()
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""AREX Computing Element (ARC REST interface)
|
|
2
2
|
|
|
3
3
|
Allows interacting with ARC AREX services via a REST interface.
|
|
4
4
|
|
|
@@ -807,7 +807,23 @@ class AREXComputingElement(ComputingElement):
|
|
|
807
807
|
return S_ERROR(f"Failed decoding the status of the CE")
|
|
808
808
|
|
|
809
809
|
# Look only in the relevant section out of the headache
|
|
810
|
-
|
|
810
|
+
# This "safe_get" function allows to go down the dictionary
|
|
811
|
+
# even if some elements are lists instead of dictionaries
|
|
812
|
+
# and returns None if any element is not found
|
|
813
|
+
# FIXME: this is a temporary measure to be removed after https://github.com/DIRACGrid/DIRAC/issues/8354
|
|
814
|
+
def safe_get(d, *keys):
|
|
815
|
+
for k in keys:
|
|
816
|
+
if isinstance(d, list):
|
|
817
|
+
d = d[0] # assume first element
|
|
818
|
+
d = d.get(k) if isinstance(d, dict) else None
|
|
819
|
+
if d is None:
|
|
820
|
+
break
|
|
821
|
+
return d
|
|
822
|
+
|
|
823
|
+
queueInfo = safe_get(ceData, "Domains", "AdminDomain", "Services", "ComputingService", "ComputingShare")
|
|
824
|
+
if queueInfo is None:
|
|
825
|
+
self.log.error("Failed to extract queue info")
|
|
826
|
+
|
|
811
827
|
if not isinstance(queueInfo, list):
|
|
812
828
|
queueInfo = [queueInfo]
|
|
813
829
|
|
|
@@ -9,7 +9,7 @@ Utilities for Transformation system
|
|
|
9
9
|
import ast
|
|
10
10
|
import random
|
|
11
11
|
|
|
12
|
-
from cachetools import LRUCache,
|
|
12
|
+
from cachetools import LRUCache, cachedmethod
|
|
13
13
|
from cachetools.keys import hashkey
|
|
14
14
|
from DIRAC import S_OK, S_ERROR, gLogger
|
|
15
15
|
|
|
@@ -24,6 +24,9 @@ from DIRAC.Resources.Catalog.FileCatalog import FileCatalog
|
|
|
24
24
|
from DIRAC.Resources.Storage.StorageElement import StorageElement
|
|
25
25
|
from DIRAC.TransformationSystem.Client.TransformationClient import TransformationClient
|
|
26
26
|
|
|
27
|
+
# Module-level cache for isSameSEInList method (shared across PluginUtilities instances)
|
|
28
|
+
_is_same_se_in_list_cache = LRUCache(maxsize=1024)
|
|
29
|
+
|
|
27
30
|
|
|
28
31
|
class PluginUtilities:
|
|
29
32
|
"""
|
|
@@ -402,8 +405,8 @@ class PluginUtilities:
|
|
|
402
405
|
|
|
403
406
|
return StorageElement(se1).isSameSE(StorageElement(se2))
|
|
404
407
|
|
|
405
|
-
@
|
|
406
|
-
|
|
408
|
+
@cachedmethod(
|
|
409
|
+
lambda self: _is_same_se_in_list_cache,
|
|
407
410
|
key=lambda _, a, b: hashkey(a, *sorted(b)),
|
|
408
411
|
)
|
|
409
412
|
def isSameSEInList(self, se1, seList):
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""The Site Director is an agent performing pilot job submission to particular sites/Computing Elements.
|
|
2
2
|
|
|
3
3
|
.. literalinclude:: ../ConfigTemplate.cfg
|
|
4
4
|
:start-after: ##BEGIN SiteDirector
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
:caption: SiteDirector options
|
|
8
8
|
|
|
9
9
|
"""
|
|
10
|
+
|
|
10
11
|
import datetime
|
|
11
12
|
import os
|
|
12
13
|
from collections import defaultdict
|
|
@@ -147,10 +148,10 @@ class SiteDirector(AgentModule):
|
|
|
147
148
|
self.sendSubmissionAccounting = True
|
|
148
149
|
|
|
149
150
|
# Get the site description dictionary
|
|
150
|
-
siteNames = self.am_getOption("Site", [])
|
|
151
|
-
ceTypes = self.am_getOption("CETypes", [])
|
|
152
|
-
ces = self.am_getOption("CEs", [])
|
|
153
|
-
tags = self.am_getOption("Tags", [])
|
|
151
|
+
siteNames = self.am_getOption("Site", []) or None
|
|
152
|
+
ceTypes = self.am_getOption("CETypes", []) or None
|
|
153
|
+
ces = self.am_getOption("CEs", []) or None
|
|
154
|
+
tags = self.am_getOption("Tags", []) or None
|
|
154
155
|
|
|
155
156
|
# Display options used
|
|
156
157
|
self.log.always("VO:", self.vo)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
"""
|
|
2
|
-
|
|
1
|
+
"""The Download Input Data module wraps around the Replica Management
|
|
2
|
+
components to provide access to datasets by downloading locally
|
|
3
3
|
"""
|
|
4
|
+
|
|
4
5
|
import os
|
|
5
6
|
import random
|
|
6
7
|
import tempfile
|
|
@@ -226,7 +227,7 @@ class DownloadInputData:
|
|
|
226
227
|
diskSpace = getDiskSpace(self.__getDownloadDir(False)) # MB
|
|
227
228
|
availableBytes = diskSpace * 1024 * 1024 # bytes
|
|
228
229
|
bufferGBs = gConfig.getValue(
|
|
229
|
-
os.path.join("/Systems/WorkloadManagement/JobWrapper", "
|
|
230
|
+
os.path.join("/Systems/WorkloadManagement/JobWrapper", "MinOutputDataBufferGB"), 5.0
|
|
230
231
|
)
|
|
231
232
|
data = bufferGBs * 1024 * 1024 * 1024 # bufferGBs in bytes
|
|
232
233
|
if (data + totalSize) < availableBytes:
|
|
@@ -263,11 +263,11 @@ Agents
|
|
|
263
263
|
# the DN of the certificate proxy used to submit pilots. If not found here, what is in Operations/Pilot section of the CS will be used
|
|
264
264
|
PilotDN =
|
|
265
265
|
|
|
266
|
-
# List of
|
|
266
|
+
# List of Sites that will be treated by this SiteDirector (No value can refer to any CE defined in the CS)
|
|
267
267
|
Site =
|
|
268
|
-
# List of CEs that will be treated by this SiteDirector (No value can refer to any CE defined in the CS)
|
|
268
|
+
# List of CEs that will be treated by this SiteDirector (No value can refer to any type of CE defined in the CS)
|
|
269
269
|
CEs =
|
|
270
|
-
# List of
|
|
270
|
+
# List of CETypes that are required to be present in the CE/Queue definition
|
|
271
271
|
CETypes =
|
|
272
272
|
# List of Tags that are required to be present in the CE/Queue definition
|
|
273
273
|
Tags =
|
|
@@ -150,37 +150,24 @@ class WMSAdministratorHandlerMixin:
|
|
|
150
150
|
:param str jobID: job ID
|
|
151
151
|
:return: S_OK(dict)/S_ERROR()
|
|
152
152
|
"""
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
# Failed to get the pilot reference, try to look in the attic parameters
|
|
172
|
-
res = self.jobDB.getAtticJobParameters(int(jobID), ["Pilot_Reference"])
|
|
173
|
-
if res["OK"]:
|
|
174
|
-
c = -1
|
|
175
|
-
# Get the pilot reference for the last rescheduling cycle
|
|
176
|
-
for cycle in res["Value"]:
|
|
177
|
-
if cycle > c:
|
|
178
|
-
pilotReference = res["Value"][cycle]["Pilot_Reference"]
|
|
179
|
-
c = cycle
|
|
180
|
-
|
|
181
|
-
if pilotReference:
|
|
182
|
-
return self.pilotManager.getPilotOutput(pilotReference)
|
|
183
|
-
return S_ERROR("No pilot job reference found")
|
|
153
|
+
result = self.pilotManager.getPilots(jobID)
|
|
154
|
+
|
|
155
|
+
if not result["OK"]:
|
|
156
|
+
return result
|
|
157
|
+
pilotJobReferences = result["Value"].keys()
|
|
158
|
+
|
|
159
|
+
outputs = {"StdOut": "", "StdErr": ""}
|
|
160
|
+
for pilotRef in pilotJobReferences:
|
|
161
|
+
result = self.pilotManager.getPilotOutput(pilotRef)
|
|
162
|
+
if not result["OK"]:
|
|
163
|
+
stdout = f"Could not retrieve output: {result['Message']}"
|
|
164
|
+
error = f"Could not retrieve error: {result['Message']}"
|
|
165
|
+
else:
|
|
166
|
+
stdout, error = result["Value"]["StdOut"], result["Value"]["StdErr"]
|
|
167
|
+
outputs["StdOut"] += f"# PilotJobReference: {pilotRef}\n\n{stdout}\n"
|
|
168
|
+
outputs["StdErr"] += f"# PilotJobReference: {pilotRef}\n\n{error}\n"
|
|
169
|
+
|
|
170
|
+
return S_OK(outputs)
|
|
184
171
|
|
|
185
172
|
|
|
186
173
|
class WMSAdministratorHandler(WMSAdministratorHandlerMixin, RequestHandler):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: DIRAC
|
|
3
|
-
Version: 9.0.
|
|
3
|
+
Version: 9.0.8
|
|
4
4
|
Summary: DIRAC is an interware, meaning a software framework for distributed computing.
|
|
5
5
|
Home-page: https://github.com/DIRACGrid/DIRAC/
|
|
6
6
|
License: GPL-3.0-only
|
|
@@ -19,7 +19,7 @@ Requires-Dist: cachetools
|
|
|
19
19
|
Requires-Dist: certifi
|
|
20
20
|
Requires-Dist: cwltool
|
|
21
21
|
Requires-Dist: diraccfg
|
|
22
|
-
Requires-Dist: DIRACCommon==v9.0.
|
|
22
|
+
Requires-Dist: DIRACCommon==v9.0.8
|
|
23
23
|
Requires-Dist: diracx-client>=v0.0.1
|
|
24
24
|
Requires-Dist: diracx-core>=v0.0.1
|
|
25
25
|
Requires-Dist: diracx-cli>=v0.0.1
|
|
@@ -138,7 +138,7 @@ DIRAC/Core/DISET/private/ServiceConfiguration.py,sha256=jnJB5AF04m3KhbJ8LQUvT265
|
|
|
138
138
|
DIRAC/Core/DISET/private/TransportPool.py,sha256=2zSdCa1Nz9GqZOvzFIbFfSaGkvhG4-7VmoVa98ax8Kg,4745
|
|
139
139
|
DIRAC/Core/DISET/private/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
140
140
|
DIRAC/Core/DISET/private/Transports/BaseTransport.py,sha256=mUsaa7OzbhCADCGDhmjGb0XKaovUCj0aYl9-VoL3yoo,13728
|
|
141
|
-
DIRAC/Core/DISET/private/Transports/M2SSLTransport.py,sha256=
|
|
141
|
+
DIRAC/Core/DISET/private/Transports/M2SSLTransport.py,sha256=mWbkHzTA7K9Hzv_Sr1FGJZXR3kWQXlbbhEZlU4DYwYs,23830
|
|
142
142
|
DIRAC/Core/DISET/private/Transports/PlainTransport.py,sha256=uQaZD5wN20KMNetQS58jOiqXI3HTTURxVEB1cSft6YU,4647
|
|
143
143
|
DIRAC/Core/DISET/private/Transports/SSLTransport.py,sha256=xWyyb4VVREHkgUcgM1MokicaJdlH2JQE8PDWXSrqnFg,4111
|
|
144
144
|
DIRAC/Core/DISET/private/Transports/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -339,7 +339,7 @@ DIRAC/Core/scripts/install_full.cfg,sha256=ady1OUXuqO0LoFiQOX3-tij9DbqQvL_arMW5o
|
|
|
339
339
|
DIRAC/Core/test/Test_API.py,sha256=KiX4NEqM4CXOQ_KI8zebW3pIU89E3ettTy6DYjxfQac,236
|
|
340
340
|
DIRAC/DataManagementSystem/ConfigTemplate.cfg,sha256=tn7uj9u9KB9vy83XcpQCsKA82fkhYWGSYrIVWUUxGCc,3327
|
|
341
341
|
DIRAC/DataManagementSystem/__init__.py,sha256=AvnxrdyArZPvCB8YNPmp8mS9wZ8hs1rM-npLLJKi2ds,46
|
|
342
|
-
DIRAC/DataManagementSystem/Agent/FTS3Agent.py,sha256=
|
|
342
|
+
DIRAC/DataManagementSystem/Agent/FTS3Agent.py,sha256=4rU9w5Sd-kM402CiL9Mf-roPqdL5_l6DyefQC-xxU6M,27109
|
|
343
343
|
DIRAC/DataManagementSystem/Agent/__init__.py,sha256=z_25ILvodsjDJSEFpmGzmnYGmY4BcwfVOF_R69oibW8,52
|
|
344
344
|
DIRAC/DataManagementSystem/Agent/RequestOperations/ArchiveFiles.py,sha256=NPBove4c2Tn-bqE5Ya5iSCjjCyZLhhNzjQCHpA489aI,9479
|
|
345
345
|
DIRAC/DataManagementSystem/Agent/RequestOperations/CheckMigration.py,sha256=zVFC6QqWFj8m4zCoghdO8AcrAxyNtlH3BT2UiHZIjmY,2593
|
|
@@ -365,7 +365,7 @@ DIRAC/DataManagementSystem/Client/DataManager.py,sha256=edLmRUHJtZEYAMyen3y9qwdG
|
|
|
365
365
|
DIRAC/DataManagementSystem/Client/DirectoryListing.py,sha256=CvQZ5Da5WhgwdDL8iLk0xVBjKZrBHTdwMKWwSJwzwEI,7582
|
|
366
366
|
DIRAC/DataManagementSystem/Client/FTS3Client.py,sha256=Kk1wy4YnkYuOI6IltyDYZqkzxV7Zsf7ZuoKT12_VbTw,3531
|
|
367
367
|
DIRAC/DataManagementSystem/Client/FTS3File.py,sha256=gZFN_Uxc2tblUCETb4qWPJ2M1tSmKUvTMiZUL-yJ6M0,3122
|
|
368
|
-
DIRAC/DataManagementSystem/Client/FTS3Job.py,sha256=
|
|
368
|
+
DIRAC/DataManagementSystem/Client/FTS3Job.py,sha256=5MAtSZoWb_rwglNHdYJAuoXzoW5_TAX96E5jUWEYds8,42090
|
|
369
369
|
DIRAC/DataManagementSystem/Client/FTS3Operation.py,sha256=L3yqc0X0ziluMPegoQU6o3aYDnTYwLtujShgbGFJjsw,24455
|
|
370
370
|
DIRAC/DataManagementSystem/Client/FailoverTransfer.py,sha256=2V-dKtgAndMuw9iZHYV019V0hLwlezUNP33wvClpsaA,13373
|
|
371
371
|
DIRAC/DataManagementSystem/Client/FileCatalogClientCLI.py,sha256=sc_6mT0BCbXgj5wOEFtCxNc0AvyQ186A_yLi2lnduvw,80094
|
|
@@ -376,7 +376,8 @@ DIRAC/DataManagementSystem/Client/CmdDirCompletion/AbstractFileSystem.py,sha256=
|
|
|
376
376
|
DIRAC/DataManagementSystem/Client/CmdDirCompletion/DirectoryCompletion.py,sha256=TdOCEfVQ3QppTl0iHrf472rT3YkDw2EX2sUviKIYL2s,2394
|
|
377
377
|
DIRAC/DataManagementSystem/Client/CmdDirCompletion/__init__.py,sha256=IU_DNOfkPtg8iBqQatUKTNBMj2LldGrhf6KseBgx14M,236
|
|
378
378
|
DIRAC/DataManagementSystem/Client/test/Test_Client_DataManagementSystem.py,sha256=qb0mERTlHOysiSfNPDsbLbadWgbuQLulT9Py8RqTIYc,3956
|
|
379
|
-
DIRAC/DataManagementSystem/Client/test/Test_FTS3Objects.py,sha256=
|
|
379
|
+
DIRAC/DataManagementSystem/Client/test/Test_FTS3Objects.py,sha256=DZHRZPfiTJrqinXolneRE06Wf51sVtRw0Fx0bq85AAA,15455
|
|
380
|
+
DIRAC/DataManagementSystem/Client/test/Test_scitag.py,sha256=llvY98ODaBZhyhDquP9IMzCB-uXJz8xL-TO2-sbNf68,2545
|
|
380
381
|
DIRAC/DataManagementSystem/Client/test/__init__.py,sha256=IL2xDyzb5nr2dkH2hpT4Zx6vvc9m4jDryuUmfyIY_RY,58
|
|
381
382
|
DIRAC/DataManagementSystem/Client/test/mock_DM.py,sha256=S7qWHjN3ZyjqKIjHkXwuUWJqp75waEchc1IsNB9y-28,1167
|
|
382
383
|
DIRAC/DataManagementSystem/Client/test/new_dir_completion.py,sha256=_Km7jE4IRe-pY8BJ62hK6IbwRROoj0wxvL7WMClEJ0E,1212
|
|
@@ -509,7 +510,7 @@ DIRAC/FrameworkSystem/DB/AuthDB.py,sha256=QLotpINMq45FNoFO2AV3OH5Ij5i__HHk-p-m-b
|
|
|
509
510
|
DIRAC/FrameworkSystem/DB/AuthDB.sql,sha256=tcAnRmBBEDxljAXILp8tlLzuEb7vOoN190KQK7NSbQQ,95
|
|
510
511
|
DIRAC/FrameworkSystem/DB/InstalledComponentsDB.py,sha256=rVarVs61K1kPHZIf1U_kfia-5pxR5uSXsuDutr8EcFY,43156
|
|
511
512
|
DIRAC/FrameworkSystem/DB/InstalledComponentsDB.sql,sha256=-LFjjn1gRQo7zDOclKmFwmbZi_lXXnx_B17cZPLBUak,113
|
|
512
|
-
DIRAC/FrameworkSystem/DB/ProxyDB.py,sha256=
|
|
513
|
+
DIRAC/FrameworkSystem/DB/ProxyDB.py,sha256=wt72y-ZtHyes1oLGgB-LiLuyZRNBelmCaEijad3raxI,39934
|
|
513
514
|
DIRAC/FrameworkSystem/DB/ProxyDB.sql,sha256=QwWe_mRX_NbZQVBo3TzA60L3FemI-oLY8G7_4uRFPzU,96
|
|
514
515
|
DIRAC/FrameworkSystem/DB/TokenDB.py,sha256=FjHsPuTYt2KaXs0fST_tOAZyXY1R6417BB-lblxduZ4,8652
|
|
515
516
|
DIRAC/FrameworkSystem/DB/TokenDB.sql,sha256=D-D78eFUkCRb4YLNZqdCfmyaEIJFupgMhIwgSs91yE4,96
|
|
@@ -796,7 +797,7 @@ DIRAC/ResourceStatusSystem/Client/__init__.py,sha256=HyBt2_a0tkIu9-SxlTVN2YPwr39
|
|
|
796
797
|
DIRAC/ResourceStatusSystem/Command/Command.py,sha256=joJgiBTyItOencX35hT33LQVjOA0ORNzhTws_IF6Kpo,2404
|
|
797
798
|
DIRAC/ResourceStatusSystem/Command/CommandCaller.py,sha256=jwDk2VjcikBpVd3FNnXrhRQH8B0chc8F0h6Q-zMvCEw,1275
|
|
798
799
|
DIRAC/ResourceStatusSystem/Command/DowntimeCommand.py,sha256=HWkyp8hrgSzw16TJnqXSgpylE2HFypAxGkm7Bt2KT6o,15782
|
|
799
|
-
DIRAC/ResourceStatusSystem/Command/FreeDiskSpaceCommand.py,sha256=
|
|
800
|
+
DIRAC/ResourceStatusSystem/Command/FreeDiskSpaceCommand.py,sha256=84pPYecmFTYl-7v4hYgqB-kJ89VTm2_-nMgWG3uvbgw,8649
|
|
800
801
|
DIRAC/ResourceStatusSystem/Command/GGUSTicketsCommand.py,sha256=bCFE7MgnyFXC0JZAvc1tLWSPRVokojEYjY2vb4ha8mE,5216
|
|
801
802
|
DIRAC/ResourceStatusSystem/Command/GOCDBSyncCommand.py,sha256=GxHnSWIWQFpZEzxqfw9hGW1SelyoJMiJW3rwy5Zrwwc,4575
|
|
802
803
|
DIRAC/ResourceStatusSystem/Command/JobCommand.py,sha256=CRKdGLwpCiQAS8ACXEwxQ0T7ata0-n3fJCRsJjIfLY4,6371
|
|
@@ -899,7 +900,7 @@ DIRAC/Resources/Catalog/test/Test_FileCatalog.py,sha256=6v-T1YDFcGHYLuYr_48Lz3z9
|
|
|
899
900
|
DIRAC/Resources/Catalog/test/Test_RucioFileCatalogClient.py,sha256=12F5Laf3-FdnS3HTcmKg-nU7p2XEFi0t_scTzF5hMOk,8525
|
|
900
901
|
DIRAC/Resources/Catalog/test/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
901
902
|
DIRAC/Resources/Catalog/test/mock_FC.py,sha256=a3RhfF3FU8RrEkSNvSRwSyHJ67DZ08YkW5347VhVLHc,4658
|
|
902
|
-
DIRAC/Resources/Computing/AREXComputingElement.py,sha256=
|
|
903
|
+
DIRAC/Resources/Computing/AREXComputingElement.py,sha256=wJDbFqM8wneCuAeqlxF_72BpjCqkLl_qy9E1GH5akMU,43950
|
|
903
904
|
DIRAC/Resources/Computing/CloudComputingElement.py,sha256=N8wfRL6ppozkKFzbCuWuVvudNfAqTox1zNeDZY6lED0,21102
|
|
904
905
|
DIRAC/Resources/Computing/ComputingElement.py,sha256=lAvlx7AOtkftku6sekIaEK4Wp_GlaDHnYeNfxW54zu4,19424
|
|
905
906
|
DIRAC/Resources/Computing/ComputingElementFactory.py,sha256=gaYP8TvvP7OJsL2o6IMTIYYoBn6flt3Ue7f1NX4HmNY,2541
|
|
@@ -1071,7 +1072,7 @@ DIRAC/TransformationSystem/Client/TransformationCLI.py,sha256=EFAbksFDLjX92KcT6V
|
|
|
1071
1072
|
DIRAC/TransformationSystem/Client/TransformationClient.py,sha256=6NtwGALJIe7XCrk1XC1HtGCN0IcqeEAL6fiMv1S2rt8,26405
|
|
1072
1073
|
DIRAC/TransformationSystem/Client/TransformationFilesStatus.py,sha256=3O89wYkPdvYPXnwxyM9x7QLcN6uODEV5yH76LFpmQ80,822
|
|
1073
1074
|
DIRAC/TransformationSystem/Client/TransformationStatus.py,sha256=f7lzca1m6AfGG09OkA9_bQUthUyojeurS_p02r2oXyQ,1411
|
|
1074
|
-
DIRAC/TransformationSystem/Client/Utilities.py,sha256=
|
|
1075
|
+
DIRAC/TransformationSystem/Client/Utilities.py,sha256=OO2XBMYbFCpEs961k676WXDtn-tPUm7lQSxilUQhdiA,20369
|
|
1075
1076
|
DIRAC/TransformationSystem/Client/WorkflowTasks.py,sha256=fMBIXMYZ8xTEBxgIZ8ouHubHDMb-eb8YRo9zLX7pl1M,28433
|
|
1076
1077
|
DIRAC/TransformationSystem/Client/__init__.py,sha256=feIGEsKJKa_lcuM7I4BVlzwEtxVzHrq-fLw4XdjcLRk,50
|
|
1077
1078
|
DIRAC/TransformationSystem/Client/BodyPlugin/BaseBody.py,sha256=oFRyrN46dzw5XbRd1biwwMTtWYv1s6jygl0WYs7VE2s,1022
|
|
@@ -1118,7 +1119,7 @@ DIRAC/Workflow/Modules/test/Test_Modules.py,sha256=d92bA2SpF7Wwg9gy3roEvPt_7QlnB
|
|
|
1118
1119
|
DIRAC/Workflow/Utilities/Utils.py,sha256=9f395ylWaLRaaC6EExPAyvOhPK3FXD7I_XGevqueRkM,2545
|
|
1119
1120
|
DIRAC/Workflow/Utilities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
1120
1121
|
DIRAC/Workflow/Utilities/test/Test_Utilities.py,sha256=DNjFPpBmpojwCWhZSUSoG3AIhMQvqyiZdSuVkrHkOtk,2595
|
|
1121
|
-
DIRAC/WorkloadManagementSystem/ConfigTemplate.cfg,sha256=
|
|
1122
|
+
DIRAC/WorkloadManagementSystem/ConfigTemplate.cfg,sha256=uHa3ZiSC7cyhbJUNvWwqiL0E-m9UmBinrLIQdWmre3k,9030
|
|
1122
1123
|
DIRAC/WorkloadManagementSystem/__init__.py,sha256=9-_-HOT_8S3i-TMmTR_gFVVlNyktBRk-S2qSuOBKoIc,50
|
|
1123
1124
|
DIRAC/WorkloadManagementSystem/Agent/JobAgent.py,sha256=LzLypd3m4a6M-J5_nmUMsMqgflb_1Xm77eONDE6G1Vg,40843
|
|
1124
1125
|
DIRAC/WorkloadManagementSystem/Agent/JobCleaningAgent.py,sha256=TR8nDO43DuJxOQVIdOUrqpWjRjJp52dVzOKUUewL9U4,14708
|
|
@@ -1126,7 +1127,7 @@ DIRAC/WorkloadManagementSystem/Agent/PilotLoggingAgent.py,sha256=ZIgvFpasGTh76GW
|
|
|
1126
1127
|
DIRAC/WorkloadManagementSystem/Agent/PilotStatusAgent.py,sha256=qY6TbYCPOFFXhHffmRJLNEbWvZPyg5Lc5B_8BbyQ7zc,9711
|
|
1127
1128
|
DIRAC/WorkloadManagementSystem/Agent/PilotSyncAgent.py,sha256=qzDFCGZ8EtjxDUaPgyFDlSmJfyF2KLuyXTC7au3-p2Q,4860
|
|
1128
1129
|
DIRAC/WorkloadManagementSystem/Agent/PushJobAgent.py,sha256=IvHshnw2xN0AZrruEu86C47GDez8enBD6jjNIZd6QcA,38594
|
|
1129
|
-
DIRAC/WorkloadManagementSystem/Agent/SiteDirector.py,sha256=
|
|
1130
|
+
DIRAC/WorkloadManagementSystem/Agent/SiteDirector.py,sha256=ZSGWVKO64ztnv_R19I6TT7660jf7LMuYcff_aPq2xCM,45162
|
|
1130
1131
|
DIRAC/WorkloadManagementSystem/Agent/StalledJobAgent.py,sha256=foEbmRotEmfeQG6nyIsJv1kSJkm4flkQsPYbSylS3SM,24572
|
|
1131
1132
|
DIRAC/WorkloadManagementSystem/Agent/StatesAccountingAgent.py,sha256=iNIlWQEDBk6R1S8oHOIusZUwxOwLtgwuzR_4s32-o5w,8707
|
|
1132
1133
|
DIRAC/WorkloadManagementSystem/Agent/TaskQueuesAgent.py,sha256=ypsmo233TFXq9IC5uz6pum7_joOh2gFPUYNmmCpukAY,943
|
|
@@ -1139,7 +1140,7 @@ DIRAC/WorkloadManagementSystem/Agent/test/Test_Agent_PushJobAgent.py,sha256=Uf5j
|
|
|
1139
1140
|
DIRAC/WorkloadManagementSystem/Agent/test/Test_Agent_SiteDirector.py,sha256=o6imUULkKrvbmkfpvER8wyg0Ncn3gxvJNTNO8xKX7_w,11670
|
|
1140
1141
|
DIRAC/WorkloadManagementSystem/Agent/test/Test_Agent_StalledJobAgent.py,sha256=BgDP1um-5WLSJYDbyHgLUkZocN8TrrG6QvRcffzD02E,1829
|
|
1141
1142
|
DIRAC/WorkloadManagementSystem/Client/CPUNormalization.py,sha256=txBgRfnTAY5KykpKRrK1jp5x4FInWjv-Rja4R7Dqdis,5423
|
|
1142
|
-
DIRAC/WorkloadManagementSystem/Client/DownloadInputData.py,sha256=
|
|
1143
|
+
DIRAC/WorkloadManagementSystem/Client/DownloadInputData.py,sha256=Ug2mhig5KbC1d4fYsVLpFhE5SvWhUJpVp7TuP8GxJxs,16285
|
|
1143
1144
|
DIRAC/WorkloadManagementSystem/Client/InputDataByProtocol.py,sha256=tjK6L8iNqWOBENcGJbG0yJsQYwGvFLRFcTMNnrusFAI,12837
|
|
1144
1145
|
DIRAC/WorkloadManagementSystem/Client/InputDataResolution.py,sha256=z8K8VKoUH4KtlTPe0mfyVsQKH6BQh80YIUhu61Fpgeg,6162
|
|
1145
1146
|
DIRAC/WorkloadManagementSystem/Client/JobManagerClient.py,sha256=ySi2lxiwuEf8gx3exIbS_HekJRvpXR7q3h2MdwsRcYA,689
|
|
@@ -1234,7 +1235,7 @@ DIRAC/WorkloadManagementSystem/Service/TornadoJobStateUpdateHandler.py,sha256=r_
|
|
|
1234
1235
|
DIRAC/WorkloadManagementSystem/Service/TornadoPilotLoggingHandler.py,sha256=PtSoXZLlwglOWkS9GcmBjad89TVrfT63gTWu5_zJN7A,4178
|
|
1235
1236
|
DIRAC/WorkloadManagementSystem/Service/TornadoSandboxStoreHandler.py,sha256=o6ar3Dqz6QF9LO3P2UVOZKDHXXTd9d0KwdKR9qnRdqA,929
|
|
1236
1237
|
DIRAC/WorkloadManagementSystem/Service/TornadoWMSAdministratorHandler.py,sha256=A9ygBHuDT9rHHvUyzJhL8EibQpFPpoVdBVsEgWFcFzM,484
|
|
1237
|
-
DIRAC/WorkloadManagementSystem/Service/WMSAdministratorHandler.py,sha256=
|
|
1238
|
+
DIRAC/WorkloadManagementSystem/Service/WMSAdministratorHandler.py,sha256=Hwi6RBQ6WKxjhXOwXid4aExaPd78AYqBtdwWf-Fbalo,5547
|
|
1238
1239
|
DIRAC/WorkloadManagementSystem/Service/WMSUtilities.py,sha256=VMSOEHkpOrNB_VIGESnxMYdnDjkmR4Qbnf_H7Yp0m88,4528
|
|
1239
1240
|
DIRAC/WorkloadManagementSystem/Service/__init__.py,sha256=IRaXIxMoS1SbRehm7ONo87SD1l44VBmowjbfkChvdsc,58
|
|
1240
1241
|
DIRAC/WorkloadManagementSystem/Utilities/JobModel.py,sha256=jN9sFbzMZo9tab6Kp7OeBCMCrfx21gCqRbm1XjLxong,1781
|
|
@@ -1295,9 +1296,9 @@ DIRAC/tests/Workflow/Integration/exe-script.py,sha256=B_slYdTocEzqfQLRhwuPiLyYUn
|
|
|
1295
1296
|
DIRAC/tests/Workflow/Integration/helloWorld.py,sha256=tBgEHH3ZF7ZiTS57gtmm3DW-Qxgm_57HWHpM-Y8XSws,205
|
|
1296
1297
|
DIRAC/tests/Workflow/Regression/helloWorld.py,sha256=69eCgFuVSYo-mK3Dj2dw1c6g86sF5FksKCf8V2aGVoM,509
|
|
1297
1298
|
DIRAC/tests/Workflow/Regression/helloWorld.xml,sha256=xwydIcFTAHIX-YPfQfyxuQ7hzvIO3IhR3UAF7ORgkGg,5310
|
|
1298
|
-
dirac-9.0.
|
|
1299
|
-
dirac-9.0.
|
|
1300
|
-
dirac-9.0.
|
|
1301
|
-
dirac-9.0.
|
|
1302
|
-
dirac-9.0.
|
|
1303
|
-
dirac-9.0.
|
|
1299
|
+
dirac-9.0.8.dist-info/licenses/LICENSE,sha256=uyr4oV6jmjUeepXZPPjkJRwa5q5MrI7jqJz5sVXNblQ,32452
|
|
1300
|
+
dirac-9.0.8.dist-info/METADATA,sha256=gpKRR8YAjDBxrxogcUUGPNXojPku4FhNUVqBVSPRNWg,10016
|
|
1301
|
+
dirac-9.0.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
1302
|
+
dirac-9.0.8.dist-info/entry_points.txt,sha256=hupzIL8aVmjK3nn7RLKdhcaiPmLOiD3Kulh3CSDHKmw,16492
|
|
1303
|
+
dirac-9.0.8.dist-info/top_level.txt,sha256=RISrnN9kb_mPqmVu8_o4jF-DSX8-h6AcgfkO9cgfkHA,6
|
|
1304
|
+
dirac-9.0.8.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|