DIRAC 9.0.0a42__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 +38 -26
- 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 +32 -19
- DIRAC/ConfigurationSystem/Client/test/Test_PathFinder.py +41 -1
- DIRAC/ConfigurationSystem/private/RefresherBase.py +4 -2
- DIRAC/Core/Base/API.py +4 -7
- DIRAC/Core/Base/SQLAlchemyDB.py +1 -0
- 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/DISET/private/Transports/SSL/M2Utils.py +3 -1
- DIRAC/Core/LCG/GOCDBClient.py +5 -7
- DIRAC/Core/Security/DiracX.py +31 -17
- DIRAC/Core/Security/IAMService.py +5 -10
- DIRAC/Core/Security/Locations.py +27 -18
- DIRAC/Core/Security/ProxyInfo.py +9 -5
- DIRAC/Core/Security/VOMSService.py +2 -4
- DIRAC/Core/Security/m2crypto/X509Certificate.py +4 -6
- DIRAC/Core/Security/m2crypto/asn1_utils.py +17 -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/CGroups2.py +328 -0
- 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/File.py +1 -1
- DIRAC/Core/Utilities/Graphs/GraphData.py +1 -1
- DIRAC/Core/Utilities/Graphs/GraphUtilities.py +6 -1
- DIRAC/Core/Utilities/JDL.py +1 -195
- DIRAC/Core/Utilities/List.py +1 -124
- DIRAC/Core/Utilities/MySQL.py +103 -99
- DIRAC/Core/Utilities/Os.py +32 -1
- DIRAC/Core/Utilities/Platform.py +2 -107
- DIRAC/Core/Utilities/Proxy.py +0 -4
- DIRAC/Core/Utilities/ReturnValues.py +7 -252
- DIRAC/Core/Utilities/StateMachine.py +12 -178
- DIRAC/Core/Utilities/Subprocess.py +35 -14
- 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 +72 -46
- DIRAC/Core/scripts/dirac_configure.py +1 -3
- DIRAC/Core/scripts/dirac_install_db.py +24 -6
- 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 +7 -3
- DIRAC/DataManagementSystem/DB/FileCatalogComponents/DatasetManager/DatasetManager.py +1 -1
- DIRAC/DataManagementSystem/DB/FileCatalogDB.sql +9 -9
- DIRAC/DataManagementSystem/DB/FileCatalogWithFkAndPsDB.sql +9 -9
- DIRAC/DataManagementSystem/Utilities/DMSHelpers.py +6 -2
- DIRAC/DataManagementSystem/scripts/dirac_admin_allow_se.py +13 -8
- DIRAC/DataManagementSystem/scripts/dirac_admin_ban_se.py +13 -8
- DIRAC/DataManagementSystem/scripts/dirac_dms_create_moving_request.py +2 -0
- DIRAC/DataManagementSystem/scripts/dirac_dms_protocol_matrix.py +0 -1
- DIRAC/FrameworkSystem/Client/BundleDeliveryClient.py +2 -7
- DIRAC/FrameworkSystem/Client/ComponentInstaller.py +9 -4
- DIRAC/FrameworkSystem/Client/ProxyManagerClient.py +5 -2
- DIRAC/FrameworkSystem/Client/SystemAdministratorClientCLI.py +11 -6
- DIRAC/FrameworkSystem/ConfigTemplate.cfg +2 -0
- DIRAC/FrameworkSystem/DB/AuthDB.py +3 -3
- DIRAC/FrameworkSystem/DB/InstalledComponentsDB.py +4 -4
- DIRAC/FrameworkSystem/DB/ProxyDB.py +11 -3
- DIRAC/FrameworkSystem/DB/TokenDB.py +1 -1
- DIRAC/FrameworkSystem/Service/ProxyManagerHandler.py +8 -6
- DIRAC/FrameworkSystem/Utilities/MonitoringUtilities.py +2 -19
- DIRAC/FrameworkSystem/Utilities/TokenManagementUtilities.py +3 -2
- DIRAC/FrameworkSystem/Utilities/diracx.py +36 -14
- DIRAC/FrameworkSystem/private/authorization/AuthServer.py +2 -2
- DIRAC/FrameworkSystem/scripts/dirac_admin_update_pilot.py +18 -11
- DIRAC/FrameworkSystem/scripts/dirac_login.py +2 -2
- DIRAC/FrameworkSystem/scripts/dirac_proxy_init.py +7 -8
- DIRAC/Interfaces/API/Dirac.py +27 -15
- DIRAC/Interfaces/API/DiracAdmin.py +45 -17
- DIRAC/Interfaces/API/Job.py +9 -13
- DIRAC/Interfaces/scripts/dirac_admin_allow_site.py +12 -18
- DIRAC/Interfaces/scripts/dirac_admin_ban_site.py +12 -10
- DIRAC/Interfaces/scripts/dirac_admin_get_site_mask.py +4 -13
- DIRAC/Interfaces/scripts/dirac_admin_reset_job.py +3 -6
- 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/DB/ProductionDB.sql +4 -4
- DIRAC/ProductionSystem/scripts/dirac_prod_get.py +2 -2
- DIRAC/ProductionSystem/scripts/dirac_prod_get_all.py +2 -2
- DIRAC/ProductionSystem/scripts/dirac_prod_get_trans.py +2 -3
- DIRAC/RequestManagementSystem/Agent/RequestExecutingAgent.py +8 -6
- DIRAC/RequestManagementSystem/Agent/RequestOperations/ForwardDISET.py +2 -14
- DIRAC/RequestManagementSystem/Client/ReqClient.py +66 -13
- DIRAC/RequestManagementSystem/ConfigTemplate.cfg +6 -6
- DIRAC/RequestManagementSystem/DB/RequestDB.py +10 -5
- DIRAC/RequestManagementSystem/DB/test/RMSTestScenari.py +2 -0
- DIRAC/RequestManagementSystem/private/RequestValidator.py +40 -46
- DIRAC/ResourceStatusSystem/Client/SiteStatus.py +4 -2
- DIRAC/ResourceStatusSystem/Command/FreeDiskSpaceCommand.py +3 -1
- DIRAC/ResourceStatusSystem/DB/ResourceManagementDB.py +8 -8
- DIRAC/ResourceStatusSystem/DB/ResourceStatusDB.py +2 -2
- DIRAC/ResourceStatusSystem/Utilities/CSHelpers.py +2 -31
- DIRAC/ResourceStatusSystem/scripts/dirac_rss_set_status.py +30 -12
- DIRAC/Resources/Catalog/RucioFileCatalogClient.py +195 -1
- DIRAC/Resources/Catalog/test/Test_RucioFileCatalogClient.py +181 -0
- DIRAC/Resources/Computing/AREXComputingElement.py +25 -8
- 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/ComputingElement.py +1 -1
- DIRAC/Resources/Computing/HTCondorCEComputingElement.py +44 -44
- DIRAC/Resources/Computing/InProcessComputingElement.py +4 -2
- DIRAC/Resources/Computing/LocalComputingElement.py +1 -18
- DIRAC/Resources/Computing/SSHBatchComputingElement.py +1 -17
- DIRAC/Resources/Computing/SSHComputingElement.py +1 -18
- DIRAC/Resources/Computing/SingularityComputingElement.py +19 -5
- 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/MessageQueue/StompMQConnector.py +1 -1
- DIRAC/Resources/Storage/GFAL2_StorageBase.py +24 -15
- DIRAC/Resources/Storage/OccupancyPlugins/WLCGAccountingHTTPJson.py +1 -3
- DIRAC/Resources/Storage/StorageBase.py +4 -2
- DIRAC/Resources/Storage/StorageElement.py +6 -7
- DIRAC/StorageManagementSystem/DB/StorageManagementDB.sql +2 -2
- DIRAC/TransformationSystem/Agent/TaskManagerAgentBase.py +10 -16
- DIRAC/TransformationSystem/Agent/TransformationAgent.py +22 -1
- DIRAC/TransformationSystem/Agent/TransformationCleaningAgent.py +16 -16
- DIRAC/TransformationSystem/Client/TaskManager.py +2 -4
- DIRAC/TransformationSystem/Client/Transformation.py +6 -7
- DIRAC/TransformationSystem/Client/TransformationClient.py +21 -11
- DIRAC/TransformationSystem/Client/Utilities.py +9 -0
- DIRAC/TransformationSystem/DB/TransformationDB.py +11 -14
- DIRAC/TransformationSystem/DB/TransformationDB.sql +9 -9
- DIRAC/TransformationSystem/Service/TransformationManagerHandler.py +0 -333
- DIRAC/TransformationSystem/Utilities/ReplicationCLIParameters.py +3 -3
- DIRAC/TransformationSystem/Utilities/TransformationInfo.py +7 -5
- DIRAC/TransformationSystem/scripts/dirac_production_runjoblocal.py +2 -4
- DIRAC/TransformationSystem/test/Test_TransformationInfo.py +22 -15
- DIRAC/TransformationSystem/test/Test_replicationTransformation.py +5 -6
- DIRAC/Workflow/Modules/test/Test_Modules.py +5 -0
- DIRAC/WorkloadManagementSystem/Agent/JobAgent.py +38 -26
- DIRAC/WorkloadManagementSystem/Agent/JobCleaningAgent.py +12 -8
- DIRAC/WorkloadManagementSystem/Agent/PilotSyncAgent.py +4 -3
- DIRAC/WorkloadManagementSystem/Agent/PushJobAgent.py +13 -13
- DIRAC/WorkloadManagementSystem/Agent/SiteDirector.py +18 -14
- DIRAC/WorkloadManagementSystem/Agent/StalledJobAgent.py +18 -51
- DIRAC/WorkloadManagementSystem/Agent/StatesAccountingAgent.py +41 -1
- DIRAC/WorkloadManagementSystem/Agent/test/Test_Agent_JobAgent.py +45 -4
- 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 +9 -2
- DIRAC/WorkloadManagementSystem/Agent/test/Test_Agent_StalledJobAgent.py +4 -5
- DIRAC/WorkloadManagementSystem/Client/DownloadInputData.py +9 -9
- DIRAC/WorkloadManagementSystem/Client/InputDataResolution.py +6 -6
- DIRAC/WorkloadManagementSystem/Client/JobMonitoringClient.py +10 -11
- DIRAC/WorkloadManagementSystem/Client/JobReport.py +1 -1
- DIRAC/WorkloadManagementSystem/Client/JobState/CachedJobState.py +3 -0
- DIRAC/WorkloadManagementSystem/Client/JobState/JobManifest.py +32 -261
- DIRAC/WorkloadManagementSystem/Client/JobState/JobState.py +6 -0
- DIRAC/WorkloadManagementSystem/Client/JobStateUpdateClient.py +3 -0
- DIRAC/WorkloadManagementSystem/Client/JobStatus.py +8 -152
- DIRAC/WorkloadManagementSystem/Client/PoolXMLSlice.py +12 -19
- 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 +89 -132
- DIRAC/WorkloadManagementSystem/DB/JobDB.sql +8 -8
- DIRAC/WorkloadManagementSystem/DB/JobDBUtils.py +18 -147
- DIRAC/WorkloadManagementSystem/DB/JobLoggingDB.py +19 -6
- DIRAC/WorkloadManagementSystem/DB/JobParametersDB.py +9 -9
- DIRAC/WorkloadManagementSystem/DB/PilotAgentsDB.py +16 -5
- DIRAC/WorkloadManagementSystem/DB/PilotAgentsDB.sql +3 -3
- DIRAC/WorkloadManagementSystem/DB/SandboxMetadataDB.py +44 -82
- 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 +5 -4
- DIRAC/WorkloadManagementSystem/Executor/JobScheduling.py +4 -0
- DIRAC/WorkloadManagementSystem/FutureClient/JobStateUpdateClient.py +75 -33
- DIRAC/WorkloadManagementSystem/JobWrapper/JobWrapper.py +22 -11
- DIRAC/WorkloadManagementSystem/JobWrapper/JobWrapperTemplate.py +9 -10
- DIRAC/WorkloadManagementSystem/JobWrapper/test/Test_JobWrapper.py +60 -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 -103
- DIRAC/WorkloadManagementSystem/Service/SandboxStoreHandler.py +7 -53
- DIRAC/WorkloadManagementSystem/Service/WMSAdministratorHandler.py +16 -79
- DIRAC/WorkloadManagementSystem/Service/WMSUtilities.py +4 -18
- DIRAC/WorkloadManagementSystem/Utilities/JobModel.py +28 -209
- 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 +41 -11
- 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 -15
- DIRAC/WorkloadManagementSystem/Utilities/test/Test_ParametricJob.py +45 -128
- DIRAC/WorkloadManagementSystem/Utilities/test/Test_PilotWrapper.py +16 -0
- DIRAC/WorkloadManagementSystem/scripts/dirac_jobexec.py +7 -2
- DIRAC/WorkloadManagementSystem/scripts/dirac_wms_pilot_job_info.py +1 -1
- DIRAC/__init__.py +62 -60
- DIRAC/tests/Utilities/testJobDefinitions.py +22 -28
- {DIRAC-9.0.0a42.dist-info → dirac-9.0.7.dist-info}/METADATA +8 -5
- {DIRAC-9.0.0a42.dist-info → dirac-9.0.7.dist-info}/RECORD +229 -228
- {DIRAC-9.0.0a42.dist-info → dirac-9.0.7.dist-info}/WHEEL +1 -1
- {DIRAC-9.0.0a42.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/Resources/Computing/PilotBundle.py +0 -70
- 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.0a42.dist-info → dirac-9.0.7.dist-info/licenses}/LICENSE +0 -0
- {DIRAC-9.0.0a42.dist-info → dirac-9.0.7.dist-info}/top_level.txt +0 -0
|
@@ -23,107 +23,16 @@ try:
|
|
|
23
23
|
except Exception:
|
|
24
24
|
import argparse
|
|
25
25
|
import platform
|
|
26
|
-
import os
|
|
27
|
-
import sys
|
|
28
|
-
import re
|
|
29
|
-
import subprocess
|
|
30
26
|
|
|
31
27
|
parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
|
|
32
28
|
parser.parse_known_args()
|
|
33
29
|
|
|
34
|
-
# We need to patch python platform module. It does a string comparison for the libc versions.
|
|
35
|
-
# it fails when going from 2.9 to 2.10,
|
|
36
|
-
# the fix converts the version to a tuple and attempts a numeric comparison
|
|
37
|
-
|
|
38
|
-
_libc_search = re.compile(r"(__libc_init)" "|" "(GLIBC_([0-9.]+))" "|" r"(libc(_\w+)?\.so(?:\.(\d[0-9.]*))?)")
|
|
39
|
-
|
|
40
|
-
def libc_ver(executable=sys.executable, lib="", version="", chunksize=2048):
|
|
41
|
-
"""Tries to determine the libc version that the file executable
|
|
42
|
-
(which defaults to the Python interpreter) is linked against.
|
|
43
|
-
|
|
44
|
-
Returns a tuple of strings (lib,version) which default to the
|
|
45
|
-
given parameters in case the lookup fails.
|
|
46
|
-
|
|
47
|
-
Note that the function has intimate knowledge of how different
|
|
48
|
-
libc versions add symbols to the executable and thus is probably
|
|
49
|
-
only useable for executables compiled using gcc.
|
|
50
|
-
|
|
51
|
-
The file is read and scanned in chunks of chunksize bytes.
|
|
52
|
-
|
|
53
|
-
"""
|
|
54
|
-
with open(executable, "rb") as f:
|
|
55
|
-
binary = f.read(chunksize)
|
|
56
|
-
pos = 0
|
|
57
|
-
version = [0, 0, 0]
|
|
58
|
-
while True:
|
|
59
|
-
m = _libc_search.search(binary, pos)
|
|
60
|
-
if not m:
|
|
61
|
-
binary = f.read(chunksize)
|
|
62
|
-
if not binary:
|
|
63
|
-
break
|
|
64
|
-
pos = 0
|
|
65
|
-
continue
|
|
66
|
-
libcinit, glibc, glibcversion, so, threads, soversion = m.groups()
|
|
67
|
-
if libcinit and not lib:
|
|
68
|
-
lib = "libc"
|
|
69
|
-
elif glibc:
|
|
70
|
-
glibcversion_parts = glibcversion.split(".")
|
|
71
|
-
for i, part in enumerate(glibcversion_parts):
|
|
72
|
-
try:
|
|
73
|
-
glibcversion_parts[i] = int(part)
|
|
74
|
-
except ValueError:
|
|
75
|
-
glibcversion_parts[i] = 0
|
|
76
|
-
if libcinit and not lib:
|
|
77
|
-
lib = "libc"
|
|
78
|
-
elif glibc:
|
|
79
|
-
if lib != "glibc":
|
|
80
|
-
lib = "glibc"
|
|
81
|
-
version = glibcversion_parts
|
|
82
|
-
elif glibcversion_parts > version:
|
|
83
|
-
version = glibcversion_parts
|
|
84
|
-
elif so:
|
|
85
|
-
if lib != "glibc":
|
|
86
|
-
lib = "libc"
|
|
87
|
-
version = max(version, soversion)
|
|
88
|
-
if threads and version[-len(threads) :] != threads:
|
|
89
|
-
version = version + threads
|
|
90
|
-
pos = m.end()
|
|
91
|
-
return lib, ".".join(map(str, version))
|
|
92
|
-
|
|
93
30
|
# Command line interface
|
|
94
31
|
def getPlatformString():
|
|
95
32
|
# Modified to return our desired platform string, R. Graciani
|
|
96
33
|
platformTuple = (platform.system(), platform.machine())
|
|
97
34
|
if platformTuple[0] == "Linux":
|
|
98
|
-
|
|
99
|
-
ldre = re.compile(r".*=> (.*/libc\.so\..*$)")
|
|
100
|
-
libs = []
|
|
101
|
-
for line in sp.stdout.readlines():
|
|
102
|
-
reM = ldre.match(line)
|
|
103
|
-
if reM:
|
|
104
|
-
libs.append(reM.groups()[0])
|
|
105
|
-
if not libs:
|
|
106
|
-
# get version of higher libc installed
|
|
107
|
-
if platform.machine().find("64") != -1:
|
|
108
|
-
lib = "/lib64"
|
|
109
|
-
else:
|
|
110
|
-
lib = "/lib"
|
|
111
|
-
for libFile in os.listdir(lib):
|
|
112
|
-
if libFile.find("libc-") == 0 or libFile.find("libc.so") == 0:
|
|
113
|
-
libs.append(os.path.join(lib, libFile))
|
|
114
|
-
newest_lib = [0, 0, 0]
|
|
115
|
-
for lib in libs:
|
|
116
|
-
lib_parts = libc_ver(lib)[1].split(".")
|
|
117
|
-
for i, part in enumerate(lib_parts):
|
|
118
|
-
try:
|
|
119
|
-
lib_parts[i] = int(part)
|
|
120
|
-
except ValueError:
|
|
121
|
-
lib_parts[i] = 0
|
|
122
|
-
# print "non integer version numbers"
|
|
123
|
-
if lib_parts > newest_lib:
|
|
124
|
-
newest_lib = lib_parts
|
|
125
|
-
|
|
126
|
-
platformTuple += ("glibc-" + ".".join(map(str, newest_lib)),)
|
|
35
|
+
platformTuple += ("-".join(platform.libc_ver()),)
|
|
127
36
|
elif platformTuple[0] == "Darwin":
|
|
128
37
|
platformTuple += (".".join(platform.mac_ver()[0].split(".")[:2]),)
|
|
129
38
|
else:
|
|
@@ -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
|
+
)
|
|
@@ -4,17 +4,17 @@
|
|
|
4
4
|
# Date: 2013/03/25 07:44:19
|
|
5
5
|
########################################################################
|
|
6
6
|
|
|
7
|
-
"""
|
|
7
|
+
""":mod: RemoveFile
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
================
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
.. module: RemoveFile
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
:synopsis: removeFile operation handler
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
.. moduleauthor:: Krzysztof.Ciba@NOSPAMgmail.com
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
removeFile operation handler
|
|
18
18
|
"""
|
|
19
19
|
# #
|
|
20
20
|
# @file RemoveFile.py
|
|
@@ -132,6 +132,7 @@ class RemoveFile(DMSRequestOperationsBase):
|
|
|
132
132
|
self.rmsMonitoringReporter.addRecord(
|
|
133
133
|
self.createRMSRecord("Successful", len(toRemoveDict) - len(bulkRemoval["Value"]))
|
|
134
134
|
)
|
|
135
|
+
toRemoveDict = bulkRemoval["Value"]
|
|
135
136
|
|
|
136
137
|
# # 2nd step - single file removal
|
|
137
138
|
for lfn, opFile in toRemoveDict.items():
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""FTS3Job module containing only the FTS3Job class"""
|
|
2
2
|
|
|
3
3
|
import datetime
|
|
4
4
|
import errno
|
|
5
|
+
import os
|
|
5
6
|
from packaging.version import Version
|
|
6
7
|
|
|
8
|
+
from cachetools import cachedmethod, LRUCache
|
|
7
9
|
|
|
8
10
|
# Requires at least version 3.3.3
|
|
9
11
|
from fts3 import __version__ as fts3_version
|
|
@@ -26,8 +28,9 @@ from DIRAC.Resources.Storage.StorageElement import StorageElement
|
|
|
26
28
|
|
|
27
29
|
from DIRAC.FrameworkSystem.Client.Logger import gLogger
|
|
28
30
|
from DIRAC.FrameworkSystem.Client.TokenManagerClient import gTokenManager
|
|
31
|
+
from DIRAC.FrameworkSystem.Utilities.TokenManagementUtilities import getIdProviderClient
|
|
29
32
|
|
|
30
|
-
from DIRAC.Core.Utilities.ReturnValues import S_OK, S_ERROR
|
|
33
|
+
from DIRAC.Core.Utilities.ReturnValues import S_OK, S_ERROR, returnValueOrRaise
|
|
31
34
|
from DIRAC.Core.Utilities.DErrno import cmpError
|
|
32
35
|
|
|
33
36
|
from DIRAC.Core.Utilities.JEncode import JSerializable
|
|
@@ -36,6 +39,10 @@ from DIRAC.DataManagementSystem.Client.FTS3File import FTS3File
|
|
|
36
39
|
# 3 days in seconds
|
|
37
40
|
BRING_ONLINE_TIMEOUT = 259200
|
|
38
41
|
|
|
42
|
+
# Number of IdP to keep in cache. Should correspond roughly
|
|
43
|
+
# to the number of groups performing transfers
|
|
44
|
+
IDP_CACHE_SIZE = 8
|
|
45
|
+
|
|
39
46
|
|
|
40
47
|
class FTS3Job(JSerializable):
|
|
41
48
|
"""Abstract class to represent a job to be executed by FTS. It belongs
|
|
@@ -78,6 +85,8 @@ class FTS3Job(JSerializable):
|
|
|
78
85
|
"userGroup",
|
|
79
86
|
]
|
|
80
87
|
|
|
88
|
+
_idp_cache = LRUCache(maxsize=IDP_CACHE_SIZE)
|
|
89
|
+
|
|
81
90
|
def __init__(self):
|
|
82
91
|
self.submitTime = None
|
|
83
92
|
self.lastUpdate = None
|
|
@@ -111,7 +120,12 @@ class FTS3Job(JSerializable):
|
|
|
111
120
|
# temporary used only for accounting
|
|
112
121
|
# it is set by the monitor method
|
|
113
122
|
# when a job is in a final state
|
|
114
|
-
self.
|
|
123
|
+
self.accountingDicts = None
|
|
124
|
+
|
|
125
|
+
@classmethod
|
|
126
|
+
@cachedmethod(lambda cls: cls._idp_cache)
|
|
127
|
+
def _getIdpClient(cls, group_name: str):
|
|
128
|
+
return returnValueOrRaise(getIdProviderClient(group_name, None, client_name_prefix="fts"))
|
|
115
129
|
|
|
116
130
|
def monitor(self, context=None, ftsServer=None, ucert=None):
|
|
117
131
|
"""Queries the fts server to monitor the job.
|
|
@@ -143,7 +157,6 @@ class FTS3Job(JSerializable):
|
|
|
143
157
|
|
|
144
158
|
if not self.ftsGUID:
|
|
145
159
|
return S_ERROR("FTSGUID not set, FTS job not submitted?")
|
|
146
|
-
|
|
147
160
|
if not context:
|
|
148
161
|
if not ftsServer:
|
|
149
162
|
ftsServer = self.ftsServer
|
|
@@ -170,13 +183,14 @@ class FTS3Job(JSerializable):
|
|
|
170
183
|
self.error = jobStatusDict["reason"]
|
|
171
184
|
|
|
172
185
|
if newStatus in self.FINAL_STATES:
|
|
173
|
-
self.
|
|
186
|
+
self._fillAccountingDicts(jobStatusDict)
|
|
174
187
|
|
|
175
188
|
filesInfoList = jobStatusDict["files"]
|
|
176
189
|
filesStatus = {}
|
|
177
190
|
statusSummary = {}
|
|
178
191
|
|
|
179
192
|
# Make a copy, since we are potentially
|
|
193
|
+
|
|
180
194
|
# deleting objects
|
|
181
195
|
for fileDict in list(filesInfoList):
|
|
182
196
|
file_state = fileDict["file_state"].capitalize()
|
|
@@ -231,7 +245,7 @@ class FTS3Job(JSerializable):
|
|
|
231
245
|
# so we put this back into the monitoring data such that the accounting is done properly
|
|
232
246
|
jobStatusDict["files"] = filesInfoList
|
|
233
247
|
if newStatus in self.FINAL_STATES:
|
|
234
|
-
self.
|
|
248
|
+
self._fillAccountingDicts(jobStatusDict)
|
|
235
249
|
|
|
236
250
|
total = len(filesInfoList)
|
|
237
251
|
completed = sum(statusSummary.get(state, 0) for state in FTS3File.FTS_FINAL_STATES)
|
|
@@ -509,11 +523,10 @@ class FTS3Job(JSerializable):
|
|
|
509
523
|
if not res["OK"]:
|
|
510
524
|
return res
|
|
511
525
|
srcTokenPath = res["Value"]
|
|
512
|
-
res =
|
|
513
|
-
|
|
514
|
-
requiredTimeLeft=3600,
|
|
526
|
+
res = self._getIdpClient(self.userGroup).fetchToken(
|
|
527
|
+
grant_type="client_credentials",
|
|
515
528
|
scope=[f"storage.read:/{srcTokenPath}", "offline_access"],
|
|
516
|
-
|
|
529
|
+
# TODO: add a specific audience
|
|
517
530
|
)
|
|
518
531
|
if not res["OK"]:
|
|
519
532
|
return res
|
|
@@ -528,11 +541,17 @@ class FTS3Job(JSerializable):
|
|
|
528
541
|
if not res["OK"]:
|
|
529
542
|
return res
|
|
530
543
|
dstTokenPath = res["Value"]
|
|
531
|
-
res =
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
544
|
+
res = self._getIdpClient(self.userGroup).fetchToken(
|
|
545
|
+
grant_type="client_credentials",
|
|
546
|
+
scope=[
|
|
547
|
+
f"storage.modify:/{dstTokenPath}",
|
|
548
|
+
f"storage.read:/{dstTokenPath}",
|
|
549
|
+
# Needed because CNAF
|
|
550
|
+
# https://ggus.eu/index.php?mode=ticket_info&ticket_id=165048
|
|
551
|
+
f"storage.read:/{os.path.dirname(dstTokenPath)}",
|
|
552
|
+
"offline_access",
|
|
553
|
+
],
|
|
554
|
+
# TODO: add a specific audience
|
|
536
555
|
)
|
|
537
556
|
if not res["OK"]:
|
|
538
557
|
return res
|
|
@@ -728,6 +747,7 @@ class FTS3Job(JSerializable):
|
|
|
728
747
|
retry=3,
|
|
729
748
|
metadata=job_metadata,
|
|
730
749
|
priority=self.priority,
|
|
750
|
+
unmanaged_tokens=True,
|
|
731
751
|
**dest_spacetoken,
|
|
732
752
|
)
|
|
733
753
|
|
|
@@ -882,9 +902,9 @@ class FTS3Job(JSerializable):
|
|
|
882
902
|
gLogger.exception("Error generating context", repr(e))
|
|
883
903
|
return S_ERROR(repr(e))
|
|
884
904
|
|
|
885
|
-
def
|
|
886
|
-
"""This methods generates the necessary information to create
|
|
887
|
-
accounting
|
|
905
|
+
def _fillAccountingDicts(self, jobStatusDict):
|
|
906
|
+
"""This methods generates the necessary information to create DataOperation
|
|
907
|
+
accounting records, and stores them as a instance attribute.
|
|
888
908
|
|
|
889
909
|
For it to be relevant, it should be called only when the job is in a final state.
|
|
890
910
|
|
|
@@ -893,6 +913,7 @@ class FTS3Job(JSerializable):
|
|
|
893
913
|
:returns: None
|
|
894
914
|
"""
|
|
895
915
|
|
|
916
|
+
accountingDicts = []
|
|
896
917
|
accountingDict = dict()
|
|
897
918
|
sourceSE = None
|
|
898
919
|
targetSE = None
|
|
@@ -903,16 +924,24 @@ class FTS3Job(JSerializable):
|
|
|
903
924
|
accountingDict["Protocol"] = "FTS3"
|
|
904
925
|
accountingDict["ExecutionSite"] = self.ftsServer
|
|
905
926
|
|
|
927
|
+
# Registration values must be set anyway
|
|
928
|
+
accountingDict["RegistrationTime"] = 0.0
|
|
929
|
+
accountingDict["RegistrationOK"] = 0
|
|
930
|
+
accountingDict["RegistrationTotal"] = 0
|
|
931
|
+
|
|
906
932
|
# We cannot rely on all the transient attributes (like self.filesToSubmit)
|
|
907
933
|
# because it is probably not filed by the time we monitor !
|
|
908
934
|
|
|
909
935
|
filesInfoList = jobStatusDict["files"]
|
|
910
936
|
successfulFiles = []
|
|
937
|
+
failedFiles = []
|
|
911
938
|
|
|
912
939
|
for fileDict in filesInfoList:
|
|
913
940
|
file_state = fileDict["file_state"].capitalize()
|
|
914
941
|
if file_state in FTS3File.FTS_SUCCESS_STATES:
|
|
915
942
|
successfulFiles.append(fileDict)
|
|
943
|
+
else:
|
|
944
|
+
failedFiles.append(fileDict)
|
|
916
945
|
|
|
917
946
|
job_metadata = jobStatusDict["job_metadata"]
|
|
918
947
|
# previous version of the code did not have dictionary as
|
|
@@ -921,23 +950,31 @@ class FTS3Job(JSerializable):
|
|
|
921
950
|
sourceSE = job_metadata.get("sourceSE")
|
|
922
951
|
targetSE = job_metadata.get("targetSE")
|
|
923
952
|
|
|
924
|
-
accountingDict["TransferOK"] = len(successfulFiles)
|
|
925
|
-
accountingDict["TransferTotal"] = len(filesInfoList)
|
|
926
|
-
# We need this if in the list comprehension because staging only jobs have `None` as filesize
|
|
927
|
-
accountingDict["TransferSize"] = sum(
|
|
928
|
-
fileDict["filesize"] for fileDict in successfulFiles if fileDict["filesize"]
|
|
929
|
-
)
|
|
930
|
-
accountingDict["FinalStatus"] = self.status
|
|
931
953
|
accountingDict["Source"] = sourceSE
|
|
932
954
|
accountingDict["Destination"] = targetSE
|
|
933
|
-
# We need this if in the list comprehension because staging only jobs have `None` as tx_duration
|
|
934
|
-
accountingDict["TransferTime"] = sum(
|
|
935
|
-
int(fileDict["tx_duration"]) for fileDict in successfulFiles if fileDict["tx_duration"]
|
|
936
|
-
)
|
|
937
955
|
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
956
|
+
if successfulFiles:
|
|
957
|
+
successfulDict = accountingDict.copy()
|
|
958
|
+
successfulDict["TransferOK"] = len(successfulFiles)
|
|
959
|
+
successfulDict["TransferTotal"] = len(successfulFiles)
|
|
960
|
+
# We need this if in the list comprehension because staging only jobs have `None` as filesize
|
|
961
|
+
successfulDict["TransferSize"] = sum(
|
|
962
|
+
fileDict["filesize"] for fileDict in successfulFiles if fileDict["filesize"]
|
|
963
|
+
)
|
|
964
|
+
successfulDict["FinalStatus"] = "Finished"
|
|
942
965
|
|
|
943
|
-
|
|
966
|
+
# We need this if in the list comprehension because staging only jobs have `None` as tx_duration
|
|
967
|
+
successfulDict["TransferTime"] = sum(
|
|
968
|
+
int(fileDict["tx_duration"]) for fileDict in successfulFiles if fileDict["tx_duration"]
|
|
969
|
+
)
|
|
970
|
+
accountingDicts.append(successfulDict)
|
|
971
|
+
if failedFiles:
|
|
972
|
+
failedDict = accountingDict.copy()
|
|
973
|
+
failedDict["TransferOK"] = 0
|
|
974
|
+
failedDict["TransferTotal"] = len(failedFiles)
|
|
975
|
+
failedDict["TransferSize"] = 0
|
|
976
|
+
failedDict["FinalStatus"] = "Failed"
|
|
977
|
+
failedDict["TransferTime"] = 0
|
|
978
|
+
accountingDicts.append(failedDict)
|
|
979
|
+
|
|
980
|
+
self.accountingDicts = accountingDicts
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
"""
|
|
2
|
-
|
|
1
|
+
"""Frontend to FTS3 MySQL DB. Written using sqlalchemy"""
|
|
2
|
+
|
|
3
3
|
# We disable the no-member error because
|
|
4
4
|
# they are constructed by SQLAlchemy for all
|
|
5
5
|
# the objects mapped to a table.
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import datetime
|
|
9
9
|
import errno
|
|
10
|
+
from urllib.parse import quote_plus
|
|
10
11
|
|
|
11
12
|
from sqlalchemy import (
|
|
12
13
|
BigInteger,
|
|
@@ -15,6 +16,7 @@ from sqlalchemy import (
|
|
|
15
16
|
Enum,
|
|
16
17
|
Float,
|
|
17
18
|
ForeignKey,
|
|
19
|
+
Index,
|
|
18
20
|
Integer,
|
|
19
21
|
MetaData,
|
|
20
22
|
SmallInteger,
|
|
@@ -84,6 +86,7 @@ fts3JobTable = Table(
|
|
|
84
86
|
Column("error", String(2048)),
|
|
85
87
|
Column("status", Enum(*FTS3Job.ALL_STATES), server_default=FTS3Job.INIT_STATE, index=True),
|
|
86
88
|
Column("assignment", String(255), server_default=None),
|
|
89
|
+
Index("idx_jobs_lastupdate_assignment", "lastUpdate", "assignment"),
|
|
87
90
|
mysql_engine="InnoDB",
|
|
88
91
|
)
|
|
89
92
|
|
|
@@ -109,6 +112,7 @@ fts3OperationTable = Table(
|
|
|
109
112
|
Column("error", String(1024)),
|
|
110
113
|
Column("type", String(255)),
|
|
111
114
|
Column("assignment", String(255), server_default=None),
|
|
115
|
+
Index("idx_operations_lastupdate_assignment", "lastUpdate", "assignment"),
|
|
112
116
|
mysql_engine="InnoDB",
|
|
113
117
|
)
|
|
114
118
|
|
|
@@ -184,7 +188,7 @@ class FTS3DB:
|
|
|
184
188
|
self.dbHost = dbParameters["Host"]
|
|
185
189
|
self.dbPort = dbParameters["Port"]
|
|
186
190
|
self.dbUser = dbParameters["User"]
|
|
187
|
-
self.dbPass = dbParameters["Password"]
|
|
191
|
+
self.dbPass = quote_plus(dbParameters["Password"])
|
|
188
192
|
self.dbName = dbParameters["DBName"]
|
|
189
193
|
|
|
190
194
|
def __init__(self, pool_size=15, url=None, parentLogger=None):
|
|
@@ -12,7 +12,7 @@ class DatasetManager:
|
|
|
12
12
|
_tables["FC_MetaDatasets"] = {
|
|
13
13
|
"Fields": {
|
|
14
14
|
"DatasetID": "INT AUTO_INCREMENT",
|
|
15
|
-
"DatasetName": "VARCHAR(128) CHARACTER SET
|
|
15
|
+
"DatasetName": "VARCHAR(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL",
|
|
16
16
|
"MetaQuery": "VARCHAR(512)",
|
|
17
17
|
"DirID": "INT NOT NULL DEFAULT 0",
|
|
18
18
|
"TotalSize": "BIGINT UNSIGNED NOT NULL",
|
|
@@ -23,7 +23,7 @@ CREATE TABLE FC_Files(
|
|
|
23
23
|
UID SMALLINT UNSIGNED NOT NULL,
|
|
24
24
|
GID TINYINT UNSIGNED NOT NULL,
|
|
25
25
|
Status SMALLINT UNSIGNED NOT NULL,
|
|
26
|
-
FileName VARCHAR(128) CHARACTER SET
|
|
26
|
+
FileName VARCHAR(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
|
|
27
27
|
INDEX (DirID),
|
|
28
28
|
INDEX (UID,GID),
|
|
29
29
|
INDEX (Status),
|
|
@@ -119,7 +119,7 @@ CREATE TABLE FC_Users (
|
|
|
119
119
|
|
|
120
120
|
CREATE TABLE FC_StorageElements (
|
|
121
121
|
SEID INTEGER AUTO_INCREMENT PRIMARY KEY,
|
|
122
|
-
SEName VARCHAR(127) CHARACTER SET
|
|
122
|
+
SEName VARCHAR(127) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
|
|
123
123
|
AliasName VARCHAR(127) DEFAULT '',
|
|
124
124
|
UNIQUE KEY (SEName)
|
|
125
125
|
) ENGINE = INNODB;
|
|
@@ -159,7 +159,7 @@ CREATE TABLE FC_DirectoryInfo (
|
|
|
159
159
|
|
|
160
160
|
CREATE TABLE FC_DirMeta (
|
|
161
161
|
DirID INTEGER NOT NULL,
|
|
162
|
-
MetaKey VARCHAR(31) CHARACTER SET
|
|
162
|
+
MetaKey VARCHAR(31) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL DEFAULT 'Noname',
|
|
163
163
|
MetaValue VARCHAR(31) NOT NULL DEFAULT 'Noname',
|
|
164
164
|
PRIMARY KEY (DirID,MetaKey)
|
|
165
165
|
) ENGINE = INNODB;
|
|
@@ -168,7 +168,7 @@ CREATE TABLE FC_DirMeta (
|
|
|
168
168
|
|
|
169
169
|
CREATE TABLE FC_FileMeta (
|
|
170
170
|
FileID INTEGER NOT NULL,
|
|
171
|
-
MetaKey VARCHAR(31) CHARACTER SET
|
|
171
|
+
MetaKey VARCHAR(31) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL DEFAULT 'Noname',
|
|
172
172
|
MetaValue VARCHAR(31) NOT NULL DEFAULT 'Noname',
|
|
173
173
|
PRIMARY KEY (FileID,MetaKey)
|
|
174
174
|
) ENGINE = INNODB;
|
|
@@ -177,7 +177,7 @@ CREATE TABLE FC_FileMeta (
|
|
|
177
177
|
|
|
178
178
|
CREATE TABLE FC_DirectoryTree (
|
|
179
179
|
DirID INT AUTO_INCREMENT PRIMARY KEY,
|
|
180
|
-
DirName VARCHAR(1024) CHARACTER SET
|
|
180
|
+
DirName VARCHAR(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
|
|
181
181
|
Parent INT NOT NULL DEFAULT 0,
|
|
182
182
|
INDEX (Parent),
|
|
183
183
|
INDEX (DirName)
|
|
@@ -187,7 +187,7 @@ CREATE TABLE FC_DirectoryTree (
|
|
|
187
187
|
|
|
188
188
|
CREATE TABLE FC_DirectoryTreeM (
|
|
189
189
|
DirID INT AUTO_INCREMENT PRIMARY KEY,
|
|
190
|
-
DirName VARCHAR(255) CHARACTER SET
|
|
190
|
+
DirName VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
|
|
191
191
|
Parent INT NOT NULL DEFAULT 0,
|
|
192
192
|
Level INT NOT NULL,
|
|
193
193
|
INDEX (Level),
|
|
@@ -199,7 +199,7 @@ CREATE TABLE FC_DirectoryTreeM (
|
|
|
199
199
|
|
|
200
200
|
CREATE TABLE FC_DirectoryLevelTree (
|
|
201
201
|
DirID INT AUTO_INCREMENT PRIMARY KEY,
|
|
202
|
-
DirName VARCHAR(255) CHARACTER SET
|
|
202
|
+
DirName VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
|
|
203
203
|
Parent INT NOT NULL DEFAULT 0,
|
|
204
204
|
Level INT NOT NULL,
|
|
205
205
|
LPATH1 INT NOT NULL DEFAULT 0,
|
|
@@ -240,7 +240,7 @@ CREATE TABLE FC_DirectoryUsage(
|
|
|
240
240
|
|
|
241
241
|
CREATE TABLE FC_MetaFields (
|
|
242
242
|
MetaID INT AUTO_INCREMENT PRIMARY KEY,
|
|
243
|
-
MetaName VARCHAR(64) CHARACTER SET
|
|
243
|
+
MetaName VARCHAR(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
|
|
244
244
|
MetaType VARCHAR(128) NOT NULL
|
|
245
245
|
) ENGINE = INNODB;
|
|
246
246
|
|
|
@@ -248,7 +248,7 @@ CREATE TABLE FC_MetaFields (
|
|
|
248
248
|
|
|
249
249
|
CREATE TABLE FC_FileMetaFields (
|
|
250
250
|
MetaID INT AUTO_INCREMENT PRIMARY KEY,
|
|
251
|
-
MetaName VARCHAR(64) CHARACTER SET
|
|
251
|
+
MetaName VARCHAR(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
|
|
252
252
|
MetaType VARCHAR(128) NOT NULL
|
|
253
253
|
) ENGINE = INNODB;
|
|
254
254
|
|
|
@@ -36,7 +36,7 @@ INSERT INTO FC_Statuses (StatusID, Status) values (1, 'FakeStatus');
|
|
|
36
36
|
|
|
37
37
|
CREATE TABLE FC_StorageElements (
|
|
38
38
|
SEID INTEGER AUTO_INCREMENT,
|
|
39
|
-
SEName VARCHAR(127) CHARACTER SET
|
|
39
|
+
SEName VARCHAR(127) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
|
|
40
40
|
AliasName VARCHAR(127) DEFAULT '',
|
|
41
41
|
|
|
42
42
|
PRIMARY KEY (SEID),
|
|
@@ -79,7 +79,7 @@ INSERT INTO FC_Users (UID, UserName) values (1, 'root');
|
|
|
79
79
|
--
|
|
80
80
|
-- create table FC_DirectoryList (
|
|
81
81
|
-- DirID INT NOT NULL AUTO_INCREMENT,
|
|
82
|
-
-- Name varchar(255)CHARACTER SET
|
|
82
|
+
-- Name varchar(255)CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
|
|
83
83
|
--
|
|
84
84
|
-- PRIMARY KEY (DirID),
|
|
85
85
|
--
|
|
@@ -116,7 +116,7 @@ create table FC_DirectoryList (
|
|
|
116
116
|
ModificationDate DATETIME,
|
|
117
117
|
Mode SMALLINT UNSIGNED NOT NULL DEFAULT 775,
|
|
118
118
|
Status INTEGER NOT NULL DEFAULT 0,
|
|
119
|
-
Name varchar(255)CHARACTER SET
|
|
119
|
+
Name varchar(255)CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
|
|
120
120
|
|
|
121
121
|
PRIMARY KEY (DirID),
|
|
122
122
|
FOREIGN KEY (UID) REFERENCES FC_Users(UID),
|
|
@@ -158,7 +158,7 @@ CREATE TABLE FC_Files(
|
|
|
158
158
|
Mode SMALLINT UNSIGNED NOT NULL DEFAULT 775,
|
|
159
159
|
ChecksumType ENUM('Adler32','MD5'),
|
|
160
160
|
Checksum VARCHAR(32),
|
|
161
|
-
FileName VARCHAR(128) CHARACTER SET
|
|
161
|
+
FileName VARCHAR(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
|
|
162
162
|
|
|
163
163
|
PRIMARY KEY (FileID),
|
|
164
164
|
FOREIGN KEY (DirID) REFERENCES FC_DirectoryList(DirID) ON DELETE CASCADE,
|
|
@@ -223,7 +223,7 @@ CREATE TABLE FC_DirectoryUsage(
|
|
|
223
223
|
|
|
224
224
|
CREATE TABLE FC_DirMeta (
|
|
225
225
|
DirID INTEGER NOT NULL,
|
|
226
|
-
MetaKey VARCHAR(31) CHARACTER SET
|
|
226
|
+
MetaKey VARCHAR(31) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL DEFAULT 'Noname',
|
|
227
227
|
MetaValue VARCHAR(31) NOT NULL DEFAULT 'Noname',
|
|
228
228
|
PRIMARY KEY (DirID,MetaKey)
|
|
229
229
|
) ENGINE = INNODB;
|
|
@@ -232,7 +232,7 @@ CREATE TABLE FC_DirMeta (
|
|
|
232
232
|
|
|
233
233
|
CREATE TABLE FC_FileMeta (
|
|
234
234
|
FileID INTEGER NOT NULL,
|
|
235
|
-
MetaKey VARCHAR(31) CHARACTER SET
|
|
235
|
+
MetaKey VARCHAR(31) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL DEFAULT 'Noname',
|
|
236
236
|
MetaValue VARCHAR(31) NOT NULL DEFAULT 'Noname',
|
|
237
237
|
PRIMARY KEY (FileID,MetaKey)
|
|
238
238
|
) ENGINE = INNODB;
|
|
@@ -242,7 +242,7 @@ CREATE TABLE FC_FileMeta (
|
|
|
242
242
|
|
|
243
243
|
CREATE TABLE FC_MetaFields (
|
|
244
244
|
MetaID INT AUTO_INCREMENT PRIMARY KEY,
|
|
245
|
-
MetaName VARCHAR(64) CHARACTER SET
|
|
245
|
+
MetaName VARCHAR(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
|
|
246
246
|
MetaType VARCHAR(128) NOT NULL
|
|
247
247
|
) ENGINE = INNODB;
|
|
248
248
|
|
|
@@ -250,7 +250,7 @@ CREATE TABLE FC_MetaFields (
|
|
|
250
250
|
|
|
251
251
|
CREATE TABLE FC_FileMetaFields (
|
|
252
252
|
MetaID INT AUTO_INCREMENT PRIMARY KEY,
|
|
253
|
-
MetaName VARCHAR(64) CHARACTER SET
|
|
253
|
+
MetaName VARCHAR(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
|
|
254
254
|
MetaType VARCHAR(128) NOT NULL
|
|
255
255
|
) ENGINE = INNODB;
|
|
256
256
|
|
|
@@ -280,7 +280,7 @@ CREATE TABLE FC_FileAncestors (
|
|
|
280
280
|
|
|
281
281
|
CREATE TABLE FC_MetaDatasets (
|
|
282
282
|
DatasetID INT AUTO_INCREMENT,
|
|
283
|
-
DatasetName VARCHAR(128) CHARACTER SET
|
|
283
|
+
DatasetName VARCHAR(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
|
|
284
284
|
MetaQuery VARCHAR(512),
|
|
285
285
|
DirID INT NOT NULL DEFAULT 0,
|
|
286
286
|
TotalSize BIGINT UNSIGNED NOT NULL,
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"""
|
|
2
|
-
|
|
2
|
+
This module contains helper methods for accessing operational attributes or parameters of DMS objects
|
|
3
3
|
|
|
4
4
|
"""
|
|
5
|
+
|
|
5
6
|
from collections import defaultdict
|
|
6
7
|
from DIRAC import gConfig, gLogger, S_OK, S_ERROR
|
|
7
8
|
from DIRAC.ConfigurationSystem.Client.Helpers.Path import cfgPath
|
|
@@ -17,6 +18,9 @@ sLog = gLogger.getSubLogger(__name__)
|
|
|
17
18
|
def resolveSEGroup(seGroupList, allSEs=None):
|
|
18
19
|
"""
|
|
19
20
|
Resolves recursively a (list of) SEs that can be groupSEs
|
|
21
|
+
For modules, JobWrapper or whatever runs at a given site,
|
|
22
|
+
prefer using :py:func:`~DIRAC.DataManagementSystem.Utilities.ResolveSE.getDestinationSEList`
|
|
23
|
+
|
|
20
24
|
|
|
21
25
|
:param seGroupList: list of SEs to resolve or comma-separated SEs
|
|
22
26
|
:type seGroupList: list or string
|
|
@@ -402,7 +406,7 @@ class DMSHelpers:
|
|
|
402
406
|
return sesAtSite
|
|
403
407
|
foundSEs = set(seList) & set(sesAtSite["Value"])
|
|
404
408
|
if not foundSEs:
|
|
405
|
-
sLog.
|
|
409
|
+
sLog.verbose("No SE found at that site", f"in group {seGroup} at {site}")
|
|
406
410
|
return S_OK()
|
|
407
411
|
return S_OK(sorted(foundSEs))
|
|
408
412
|
|