DIRAC 9.0.0a68__py3-none-any.whl → 9.0.0a70__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/Types/Network.py +8 -8
- DIRAC/AccountingSystem/Client/Types/PilotSubmission.py +3 -3
- DIRAC/ConfigurationSystem/Client/CSAPI.py +11 -1
- DIRAC/ConfigurationSystem/Client/Helpers/CSGlobals.py +0 -9
- DIRAC/ConfigurationSystem/Client/Helpers/Registry.py +3 -29
- DIRAC/ConfigurationSystem/Client/SyncPlugins/CERNLDAPSyncPlugin.py +4 -1
- DIRAC/ConfigurationSystem/ConfigTemplate.cfg +3 -0
- DIRAC/ConfigurationSystem/private/Modificator.py +11 -3
- DIRAC/ConfigurationSystem/private/RefresherBase.py +4 -2
- DIRAC/Core/DISET/ServiceReactor.py +11 -3
- DIRAC/Core/DISET/private/Transports/M2SSLTransport.py +9 -7
- DIRAC/Core/Security/DiracX.py +11 -6
- DIRAC/Core/Security/test/test_diracx_token_from_pem.py +161 -0
- DIRAC/Core/Tornado/Server/TornadoService.py +1 -1
- DIRAC/Core/Utilities/ElasticSearchDB.py +1 -2
- DIRAC/Core/Utilities/Subprocess.py +66 -57
- DIRAC/Core/Utilities/test/Test_Profiler.py +20 -20
- DIRAC/Core/Utilities/test/Test_Subprocess.py +58 -8
- DIRAC/Core/scripts/dirac_apptainer_exec.py +8 -8
- DIRAC/DataManagementSystem/Agent/FTS3Agent.py +8 -7
- DIRAC/DataManagementSystem/Client/DataManager.py +6 -7
- DIRAC/DataManagementSystem/Client/FTS3Job.py +125 -34
- DIRAC/DataManagementSystem/Client/test/Test_FTS3Objects.py +1 -0
- DIRAC/DataManagementSystem/Client/test/Test_scitag.py +69 -0
- DIRAC/DataManagementSystem/DB/FileCatalogComponents/DatasetManager/DatasetManager.py +1 -1
- DIRAC/DataManagementSystem/scripts/dirac_dms_create_moving_request.py +2 -0
- DIRAC/FrameworkSystem/DB/InstalledComponentsDB.py +3 -2
- DIRAC/FrameworkSystem/DB/ProxyDB.py +9 -5
- DIRAC/FrameworkSystem/Utilities/MonitoringUtilities.py +1 -0
- DIRAC/FrameworkSystem/Utilities/TokenManagementUtilities.py +3 -2
- DIRAC/FrameworkSystem/Utilities/diracx.py +41 -10
- DIRAC/FrameworkSystem/scripts/dirac_login.py +2 -2
- DIRAC/FrameworkSystem/scripts/dirac_proxy_init.py +1 -1
- DIRAC/FrameworkSystem/scripts/dirac_uninstall_component.py +1 -0
- DIRAC/Interfaces/API/Dirac.py +3 -6
- DIRAC/Interfaces/Utilities/DConfigCache.py +2 -0
- DIRAC/Interfaces/scripts/dirac_wms_job_parameters.py +0 -1
- DIRAC/MonitoringSystem/DB/MonitoringDB.py +6 -5
- DIRAC/MonitoringSystem/Service/WebAppHandler.py +25 -6
- DIRAC/MonitoringSystem/private/MainReporter.py +0 -3
- DIRAC/RequestManagementSystem/Agent/RequestExecutingAgent.py +8 -6
- DIRAC/RequestManagementSystem/ConfigTemplate.cfg +6 -6
- DIRAC/ResourceStatusSystem/Command/FreeDiskSpaceCommand.py +3 -1
- DIRAC/Resources/Computing/AREXComputingElement.py +18 -2
- DIRAC/Resources/Computing/BatchSystems/Condor.py +0 -3
- DIRAC/Resources/Computing/BatchSystems/executeBatch.py +15 -7
- DIRAC/Resources/Computing/LocalComputingElement.py +0 -2
- DIRAC/Resources/Computing/SSHComputingElement.py +61 -38
- DIRAC/Resources/IdProvider/CheckInIdProvider.py +13 -0
- DIRAC/Resources/IdProvider/IdProviderFactory.py +13 -3
- DIRAC/Resources/IdProvider/tests/Test_IdProviderFactory.py +7 -0
- DIRAC/Resources/Storage/FileStorage.py +121 -2
- DIRAC/TransformationSystem/Agent/InputDataAgent.py +4 -1
- DIRAC/TransformationSystem/Agent/MCExtensionAgent.py +5 -2
- DIRAC/TransformationSystem/Agent/TaskManagerAgentBase.py +3 -4
- DIRAC/TransformationSystem/Agent/TransformationCleaningAgent.py +44 -9
- DIRAC/TransformationSystem/Agent/ValidateOutputDataAgent.py +4 -2
- DIRAC/TransformationSystem/Client/TransformationClient.py +9 -1
- DIRAC/TransformationSystem/Client/Utilities.py +6 -3
- DIRAC/TransformationSystem/DB/TransformationDB.py +105 -43
- 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/WorkloadManagementSystem/Agent/JobAgent.py +1 -5
- DIRAC/WorkloadManagementSystem/Agent/PilotSyncAgent.py +4 -3
- DIRAC/WorkloadManagementSystem/Agent/PushJobAgent.py +0 -4
- DIRAC/WorkloadManagementSystem/Agent/SiteDirector.py +8 -11
- DIRAC/WorkloadManagementSystem/Agent/StalledJobAgent.py +39 -7
- DIRAC/WorkloadManagementSystem/Agent/test/Test_Agent_SiteDirector.py +8 -2
- DIRAC/WorkloadManagementSystem/Agent/test/Test_Agent_StalledJobAgent.py +24 -4
- DIRAC/WorkloadManagementSystem/Client/DownloadInputData.py +4 -3
- DIRAC/WorkloadManagementSystem/ConfigTemplate.cfg +3 -3
- DIRAC/WorkloadManagementSystem/DB/JobParametersDB.py +8 -8
- DIRAC/WorkloadManagementSystem/DB/SandboxMetadataDB.py +1 -1
- DIRAC/WorkloadManagementSystem/DB/StatusUtils.py +48 -21
- DIRAC/WorkloadManagementSystem/DB/tests/Test_StatusUtils.py +19 -4
- DIRAC/WorkloadManagementSystem/JobWrapper/JobWrapper.py +3 -4
- DIRAC/WorkloadManagementSystem/JobWrapper/Watchdog.py +16 -45
- DIRAC/WorkloadManagementSystem/JobWrapper/test/Test_JobWrapper.py +18 -9
- DIRAC/WorkloadManagementSystem/Service/JobManagerHandler.py +25 -2
- DIRAC/WorkloadManagementSystem/Service/WMSAdministratorHandler.py +18 -31
- DIRAC/WorkloadManagementSystem/Utilities/PilotCStoJSONSynchronizer.py +73 -7
- {dirac-9.0.0a68.dist-info → dirac-9.0.0a70.dist-info}/METADATA +6 -5
- {dirac-9.0.0a68.dist-info → dirac-9.0.0a70.dist-info}/RECORD +88 -86
- {dirac-9.0.0a68.dist-info → dirac-9.0.0a70.dist-info}/WHEEL +0 -0
- {dirac-9.0.0a68.dist-info → dirac-9.0.0a70.dist-info}/entry_points.txt +0 -0
- {dirac-9.0.0a68.dist-info → dirac-9.0.0a70.dist-info}/licenses/LICENSE +0 -0
- {dirac-9.0.0a68.dist-info → dirac-9.0.0a70.dist-info}/top_level.txt +0 -0
|
@@ -65,6 +65,11 @@ class JobManagerHandlerMixin:
|
|
|
65
65
|
return result
|
|
66
66
|
cls.pilotAgentsDB = result["Value"](parentLogger=cls.log)
|
|
67
67
|
|
|
68
|
+
result = ObjectLoader().loadObject("StorageManagementSystem.DB.StorageManagementDB", "StorageManagementDB")
|
|
69
|
+
if not result["OK"]:
|
|
70
|
+
return result
|
|
71
|
+
cls.storageManagementDB = result["Value"](parentLogger=cls.log)
|
|
72
|
+
|
|
68
73
|
except RuntimeError as excp:
|
|
69
74
|
return S_ERROR(f"Can't connect to DB: {excp!r}")
|
|
70
75
|
|
|
@@ -449,7 +454,16 @@ class JobManagerHandlerMixin:
|
|
|
449
454
|
jobList, RIGHT_DELETE
|
|
450
455
|
)
|
|
451
456
|
|
|
452
|
-
result = kill_delete_jobs(
|
|
457
|
+
result = kill_delete_jobs(
|
|
458
|
+
RIGHT_DELETE,
|
|
459
|
+
validJobList,
|
|
460
|
+
nonauthJobList,
|
|
461
|
+
force=force,
|
|
462
|
+
jobdb=self.jobDB,
|
|
463
|
+
taskqueuedb=self.taskQueueDB,
|
|
464
|
+
pilotagentsdb=self.pilotAgentsDB,
|
|
465
|
+
storagemanagementdb=self.storageManagementDB,
|
|
466
|
+
)
|
|
453
467
|
|
|
454
468
|
result["requireProxyUpload"] = len(ownerJobList) > 0 and self.__checkIfProxyUploadIsRequired()
|
|
455
469
|
|
|
@@ -478,7 +492,16 @@ class JobManagerHandlerMixin:
|
|
|
478
492
|
jobList, RIGHT_KILL
|
|
479
493
|
)
|
|
480
494
|
|
|
481
|
-
result = kill_delete_jobs(
|
|
495
|
+
result = kill_delete_jobs(
|
|
496
|
+
RIGHT_KILL,
|
|
497
|
+
validJobList,
|
|
498
|
+
nonauthJobList,
|
|
499
|
+
force=force,
|
|
500
|
+
jobdb=self.jobDB,
|
|
501
|
+
taskqueuedb=self.taskQueueDB,
|
|
502
|
+
pilotagentsdb=self.pilotAgentsDB,
|
|
503
|
+
storagemanagementdb=self.storageManagementDB,
|
|
504
|
+
)
|
|
482
505
|
|
|
483
506
|
result["requireProxyUpload"] = len(ownerJobList) > 0 and self.__checkIfProxyUploadIsRequired()
|
|
484
507
|
|
|
@@ -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,16 +1,16 @@
|
|
|
1
|
-
"""
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
"""CStoJSONSynchronizer
|
|
2
|
+
Module that keeps the pilot parameters file synchronized with the information
|
|
3
|
+
in the Operations/Pilot section of the CS. If there are additions in the CS,
|
|
4
|
+
these are incorporated to the file.
|
|
5
|
+
The module uploads to a web server the latest version of the pilot scripts.
|
|
6
6
|
"""
|
|
7
|
+
|
|
7
8
|
import datetime
|
|
8
9
|
import glob
|
|
9
10
|
import os
|
|
10
11
|
import shutil
|
|
11
12
|
import tarfile
|
|
12
13
|
from typing import Any
|
|
13
|
-
|
|
14
14
|
from git import Repo
|
|
15
15
|
|
|
16
16
|
from DIRAC import S_OK, gConfig, gLogger
|
|
@@ -19,6 +19,67 @@ from DIRAC.ConfigurationSystem.Client.Helpers.Operations import Operations
|
|
|
19
19
|
from DIRAC.ConfigurationSystem.Client.Helpers.Path import cfgPath
|
|
20
20
|
from DIRAC.Core.Utilities.ReturnValues import DOKReturnType, DReturnType
|
|
21
21
|
|
|
22
|
+
import socket
|
|
23
|
+
from urllib.parse import urlparse
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def exclude_master_cs_aliases(urls: list[str], master_cs_url: str) -> list[str]:
|
|
27
|
+
"""
|
|
28
|
+
Excludes URLs that are DNS aliases of the given MasterCS server URL.
|
|
29
|
+
|
|
30
|
+
This function resolves the IP addresses of the MasterCS server and each URL in the input list.
|
|
31
|
+
It returns a new list containing only those URLs whose hostnames do not resolve to any of the
|
|
32
|
+
MasterCS server's IP addresses, effectively excluding all DNS aliases of the MasterCS server.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
urls (list[str]): A list of URLs to filter. Each URL should be a string in a valid URL format.
|
|
36
|
+
master_cs_url (str): The reference URL (e.g., MasterCS server URL) whose DNS aliases are to be excluded.
|
|
37
|
+
|
|
38
|
+
Returns:
|
|
39
|
+
list[str]: A new list of URLs with all aliases of the MasterCS server removed.
|
|
40
|
+
If the MasterCS hostname cannot be resolved, the original list is returned unchanged.
|
|
41
|
+
|
|
42
|
+
Example:
|
|
43
|
+
>>> urls = [
|
|
44
|
+
... 'dips://lbvobox303.cern.ch:9135/Configuration/Server',
|
|
45
|
+
... 'dips://ccwlcglhcb02.in2p3.fr:9135/Configuration/Server',
|
|
46
|
+
... 'dips://lbvobox302.cern.ch:9135/Configuration/Server',
|
|
47
|
+
... ]
|
|
48
|
+
>>> master_cs_url = "dips://mastercs.cern.ch:9135/Configuration/Server"
|
|
49
|
+
>>> exclude_master_cs_aliases(urls, master_cs_url)
|
|
50
|
+
['dips://ccwlcglhcb02.in2p3.fr:9135/Configuration/Server']
|
|
51
|
+
|
|
52
|
+
Notes:
|
|
53
|
+
- If the MasterCS hostname cannot be resolved, the function returns the original list.
|
|
54
|
+
- If a hostname in the input list cannot be resolved, it is included in the result.
|
|
55
|
+
- The comparison is based on IP addresses, not hostnames.
|
|
56
|
+
"""
|
|
57
|
+
master_cs_hostname = urlparse(master_cs_url).hostname
|
|
58
|
+
if not master_cs_hostname:
|
|
59
|
+
return urls
|
|
60
|
+
|
|
61
|
+
# Resolve IP addresses for the MasterCS hostname
|
|
62
|
+
try:
|
|
63
|
+
master_cs_ips = set(socket.gethostbyname_ex(master_cs_hostname)[2])
|
|
64
|
+
except socket.gaierror:
|
|
65
|
+
return urls
|
|
66
|
+
|
|
67
|
+
# Function to get IPs for a hostname
|
|
68
|
+
def get_ips(hostname):
|
|
69
|
+
try:
|
|
70
|
+
return set(socket.gethostbyname_ex(hostname)[2])
|
|
71
|
+
except socket.gaierror:
|
|
72
|
+
return set()
|
|
73
|
+
|
|
74
|
+
filtered_urls = []
|
|
75
|
+
for url in urls:
|
|
76
|
+
hostname = urlparse(url).hostname
|
|
77
|
+
ips = get_ips(hostname)
|
|
78
|
+
if not ips & master_cs_ips:
|
|
79
|
+
filtered_urls.append(url)
|
|
80
|
+
|
|
81
|
+
return filtered_urls
|
|
82
|
+
|
|
22
83
|
|
|
23
84
|
class PilotCStoJSONSynchronizer:
|
|
24
85
|
"""
|
|
@@ -151,9 +212,14 @@ class PilotCStoJSONSynchronizer:
|
|
|
151
212
|
configurationServers = gConfig.getServersList()
|
|
152
213
|
if not includeMasterCS:
|
|
153
214
|
masterCS = gConfigurationData.getMasterServer()
|
|
154
|
-
configurationServers =
|
|
215
|
+
configurationServers = exclude_master_cs_aliases(configurationServers, masterCS)
|
|
216
|
+
|
|
155
217
|
pilotDict["ConfigurationServers"] = configurationServers
|
|
156
218
|
|
|
219
|
+
preferredURLPatterns = gConfigurationData.extractOptionFromCFG("/DIRAC/PreferredURLPatterns")
|
|
220
|
+
if preferredURLPatterns:
|
|
221
|
+
pilotDict["PreferredURLPatterns"] = preferredURLPatterns.replace(" ", "").split(",")
|
|
222
|
+
|
|
157
223
|
self.log.debug("Got pilotDict", str(pilotDict))
|
|
158
224
|
|
|
159
225
|
return S_OK(pilotDict)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: DIRAC
|
|
3
|
-
Version: 9.0.
|
|
3
|
+
Version: 9.0.0a70
|
|
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,9 +19,10 @@ Requires-Dist: cachetools
|
|
|
19
19
|
Requires-Dist: certifi
|
|
20
20
|
Requires-Dist: cwltool
|
|
21
21
|
Requires-Dist: diraccfg
|
|
22
|
-
Requires-Dist: DIRACCommon==v9.0.
|
|
23
|
-
Requires-Dist: diracx-client>=v0.0.
|
|
24
|
-
Requires-Dist: diracx-core>=v0.0.
|
|
22
|
+
Requires-Dist: DIRACCommon==v9.0.0a70
|
|
23
|
+
Requires-Dist: diracx-client>=v0.0.1
|
|
24
|
+
Requires-Dist: diracx-core>=v0.0.1
|
|
25
|
+
Requires-Dist: diracx-cli>=v0.0.1
|
|
25
26
|
Requires-Dist: db12
|
|
26
27
|
Requires-Dist: fts3
|
|
27
28
|
Requires-Dist: gfal2-python
|
|
@@ -40,13 +41,13 @@ Requires-Dist: python-dateutil
|
|
|
40
41
|
Requires-Dist: pytz
|
|
41
42
|
Requires-Dist: requests
|
|
42
43
|
Requires-Dist: rucio-clients>=34.4.2
|
|
43
|
-
Requires-Dist: setuptools
|
|
44
44
|
Requires-Dist: sqlalchemy
|
|
45
45
|
Requires-Dist: typing_extensions>=4.3.0
|
|
46
46
|
Requires-Dist: Authlib>=1.0.0.a2
|
|
47
47
|
Requires-Dist: pyjwt
|
|
48
48
|
Requires-Dist: dominate
|
|
49
49
|
Requires-Dist: zstandard
|
|
50
|
+
Requires-Dist: xattr
|
|
50
51
|
Provides-Extra: server
|
|
51
52
|
Requires-Dist: CMRESHandler; extra == "server"
|
|
52
53
|
Requires-Dist: opensearch-py; extra == "server"
|