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
DIRAC/Core/Utilities/DErrno.py
CHANGED
|
@@ -37,320 +37,16 @@
|
|
|
37
37
|
DErrno.ERRX : ['An error message for ERRX that is specific to LHCb']}
|
|
38
38
|
|
|
39
39
|
"""
|
|
40
|
-
import os
|
|
41
40
|
import importlib
|
|
42
41
|
import sys
|
|
43
42
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
# To avoid conflict, the error numbers should be greater than 1000
|
|
47
|
-
# We decided to group the by range of 100 per system
|
|
48
|
-
|
|
49
|
-
# 1000: Generic
|
|
50
|
-
# 1100: Core
|
|
51
|
-
# 1200: Framework
|
|
52
|
-
# 1300: Interfaces
|
|
53
|
-
# 1400: Config
|
|
54
|
-
# 1500: WMS + Workflow
|
|
55
|
-
# 1600: DMS + StorageManagement
|
|
56
|
-
# 1700: RMS
|
|
57
|
-
# 1800: Accounting + Monitoring
|
|
58
|
-
# 1900: TS + Production
|
|
59
|
-
# 2000: Resources + RSS
|
|
60
|
-
|
|
61
|
-
# ## Generic (10XX)
|
|
62
|
-
# Python related: 0X
|
|
63
|
-
ETYPE = 1000
|
|
64
|
-
EIMPERR = 1001
|
|
65
|
-
ENOMETH = 1002
|
|
66
|
-
ECONF = 1003
|
|
67
|
-
EVALUE = 1004
|
|
68
|
-
EEEXCEPTION = 1005
|
|
69
|
-
# Files manipulation: 1X
|
|
70
|
-
ECTMPF = 1010
|
|
71
|
-
EOF = 1011
|
|
72
|
-
ERF = 1012
|
|
73
|
-
EWF = 1013
|
|
74
|
-
ESPF = 1014
|
|
75
|
-
|
|
76
|
-
# ## Core (11XX)
|
|
77
|
-
# Certificates and Proxy: 0X
|
|
78
|
-
EX509 = 1100
|
|
79
|
-
EPROXYFIND = 1101
|
|
80
|
-
EPROXYREAD = 1102
|
|
81
|
-
ECERTFIND = 1103
|
|
82
|
-
ECERTREAD = 1104
|
|
83
|
-
ENOCERT = 1105
|
|
84
|
-
ENOCHAIN = 1106
|
|
85
|
-
ENOPKEY = 1107
|
|
86
|
-
ENOGROUP = 1108
|
|
87
|
-
# DISET: 1X
|
|
88
|
-
EDISET = 1110
|
|
89
|
-
ENOAUTH = 1111
|
|
90
|
-
# 3rd party security: 2X
|
|
91
|
-
E3RDPARTY = 1120
|
|
92
|
-
EVOMS = 1121
|
|
93
|
-
# Databases : 3X
|
|
94
|
-
EDB = 1130
|
|
95
|
-
EMYSQL = 1131
|
|
96
|
-
ESQLA = 1132
|
|
97
|
-
# Message Queues: 4X
|
|
98
|
-
EMQUKN = 1140
|
|
99
|
-
EMQNOM = 1141
|
|
100
|
-
EMQCONN = 1142
|
|
101
|
-
# OpenSearch
|
|
102
|
-
EELNOFOUND = 1146
|
|
103
|
-
# Tokens
|
|
104
|
-
EATOKENFIND = 1150
|
|
105
|
-
EATOKENREAD = 1151
|
|
106
|
-
ETOKENTYPE = 1152
|
|
107
|
-
|
|
108
|
-
# config
|
|
109
|
-
ESECTION = 1400
|
|
110
|
-
|
|
111
|
-
# processes
|
|
112
|
-
EEZOMBIE = 1147
|
|
113
|
-
EENOPID = 1148
|
|
114
|
-
|
|
115
|
-
# ## WMS/Workflow
|
|
116
|
-
EWMSUKN = 1500
|
|
117
|
-
EWMSJDL = 1501
|
|
118
|
-
EWMSRESC = 1502
|
|
119
|
-
EWMSSUBM = 1503
|
|
120
|
-
EWMSJMAN = 1504
|
|
121
|
-
EWMSSTATUS = 1505
|
|
122
|
-
EWMSNOMATCH = 1510
|
|
123
|
-
EWMSPLTVER = 1511
|
|
124
|
-
EWMSNOPILOT = 1550
|
|
125
|
-
|
|
126
|
-
# ## DMS/StorageManagement (16XX)
|
|
127
|
-
EFILESIZE = 1601
|
|
128
|
-
EGFAL = 1602
|
|
129
|
-
EBADCKS = 1603
|
|
130
|
-
EFCERR = 1604
|
|
131
|
-
|
|
132
|
-
# ## RMS (17XX)
|
|
133
|
-
ERMSUKN = 1700
|
|
134
|
-
|
|
135
|
-
# ## TS (19XX)
|
|
136
|
-
ETSUKN = 1900
|
|
137
|
-
ETSDATA = 1901
|
|
138
|
-
|
|
139
|
-
# ## Resources and RSS (20XX)
|
|
140
|
-
ERESGEN = 2000
|
|
141
|
-
ERESUNA = 2001
|
|
142
|
-
ERESUNK = 2002
|
|
143
|
-
|
|
144
|
-
# This translates the integer number into the name of the variable
|
|
145
|
-
dErrorCode = {
|
|
146
|
-
# ## Generic (10XX)
|
|
147
|
-
# 100X: Python related
|
|
148
|
-
1000: "ETYPE",
|
|
149
|
-
1001: "EIMPERR",
|
|
150
|
-
1002: "ENOMETH",
|
|
151
|
-
1003: "ECONF",
|
|
152
|
-
1004: "EVALUE",
|
|
153
|
-
1005: "EEEXCEPTION",
|
|
154
|
-
# 101X: Files manipulation
|
|
155
|
-
1010: "ECTMPF",
|
|
156
|
-
1011: "EOF",
|
|
157
|
-
1012: "ERF",
|
|
158
|
-
1013: "EWF",
|
|
159
|
-
1014: "ESPF",
|
|
160
|
-
# ## Core
|
|
161
|
-
# 110X: Certificates and Proxy
|
|
162
|
-
1100: "EX509",
|
|
163
|
-
1101: "EPROXYFIND",
|
|
164
|
-
1102: "EPROXYREAD",
|
|
165
|
-
1103: "ECERTFIND",
|
|
166
|
-
1104: "ECERTREAD",
|
|
167
|
-
1105: "ENOCERT",
|
|
168
|
-
1106: "ENOCHAIN",
|
|
169
|
-
1107: "ENOPKEY",
|
|
170
|
-
1108: "ENOGROUP",
|
|
171
|
-
# 111X: DISET
|
|
172
|
-
1110: "EDISET",
|
|
173
|
-
1111: "ENOAUTH",
|
|
174
|
-
# 112X: 3rd party security
|
|
175
|
-
1120: "E3RDPARTY",
|
|
176
|
-
1121: "EVOMS",
|
|
177
|
-
# 113X: Databases
|
|
178
|
-
1130: "EDB",
|
|
179
|
-
1131: "EMYSQL",
|
|
180
|
-
1132: "ESQLA",
|
|
181
|
-
# 114X: Message Queues
|
|
182
|
-
1140: "EMQUKN",
|
|
183
|
-
1141: "EMQNOM",
|
|
184
|
-
1142: "EMQCONN",
|
|
185
|
-
# OpenSearch
|
|
186
|
-
1146: "EELNOFOUND",
|
|
187
|
-
# 115X: Tokens
|
|
188
|
-
1150: "EATOKENFIND",
|
|
189
|
-
1151: "EATOKENREAD",
|
|
190
|
-
1152: "ETOKENTYPE",
|
|
191
|
-
# Config
|
|
192
|
-
1400: "ESECTION",
|
|
193
|
-
# Processes
|
|
194
|
-
1147: "EEZOMBIE",
|
|
195
|
-
1148: "EENOPID",
|
|
196
|
-
# WMS/Workflow
|
|
197
|
-
1500: "EWMSUKN",
|
|
198
|
-
1501: "EWMSJDL",
|
|
199
|
-
1502: "EWMSRESC",
|
|
200
|
-
1503: "EWMSSUBM",
|
|
201
|
-
1504: "EWMSJMAN",
|
|
202
|
-
1505: "EWMSSTATUS",
|
|
203
|
-
1510: "EWMSNOMATCH",
|
|
204
|
-
1511: "EWMSPLTVER",
|
|
205
|
-
1550: "EWMSNOPILOT",
|
|
206
|
-
# DMS/StorageManagement
|
|
207
|
-
1601: "EFILESIZE",
|
|
208
|
-
1602: "EGFAL",
|
|
209
|
-
1603: "EBADCKS",
|
|
210
|
-
1604: "EFCERR",
|
|
211
|
-
# RMS
|
|
212
|
-
1700: "ERMSUKN",
|
|
213
|
-
# Resources and RSS
|
|
214
|
-
2000: "ERESGEN",
|
|
215
|
-
2001: "ERESUNA",
|
|
216
|
-
2002: "ERESUNK",
|
|
217
|
-
# TS
|
|
218
|
-
1900: "ETSUKN",
|
|
219
|
-
1901: "ETSDATA",
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
dStrError = { # Generic (10XX)
|
|
224
|
-
# 100X: Python related
|
|
225
|
-
ETYPE: "Object Type Error",
|
|
226
|
-
EIMPERR: "Failed to import library",
|
|
227
|
-
ENOMETH: "No such method or function",
|
|
228
|
-
ECONF: "Configuration error",
|
|
229
|
-
EVALUE: "Wrong value passed",
|
|
230
|
-
EEEXCEPTION: "runtime general exception",
|
|
231
|
-
# 101X: Files manipulation
|
|
232
|
-
ECTMPF: "Failed to create temporary file",
|
|
233
|
-
EOF: "Cannot open file",
|
|
234
|
-
ERF: "Cannot read from file",
|
|
235
|
-
EWF: "Cannot write to file",
|
|
236
|
-
ESPF: "Cannot set permissions to file",
|
|
237
|
-
# ## Core
|
|
238
|
-
# 110X: Certificates and Proxy
|
|
239
|
-
EX509: "Generic Error with X509",
|
|
240
|
-
EPROXYFIND: "Can't find proxy",
|
|
241
|
-
EPROXYREAD: "Can't read proxy",
|
|
242
|
-
ECERTFIND: "Can't find certificate",
|
|
243
|
-
ECERTREAD: "Can't read certificate",
|
|
244
|
-
ENOCERT: "No certificate loaded",
|
|
245
|
-
ENOCHAIN: "No chain loaded",
|
|
246
|
-
ENOPKEY: "No private key loaded",
|
|
247
|
-
ENOGROUP: "No DIRAC group",
|
|
248
|
-
# 111X: DISET
|
|
249
|
-
EDISET: "DISET Error",
|
|
250
|
-
ENOAUTH: "Unauthorized query",
|
|
251
|
-
# 112X: 3rd party security
|
|
252
|
-
E3RDPARTY: "3rd party security service error",
|
|
253
|
-
EVOMS: "VOMS Error",
|
|
254
|
-
# 113X: Databases
|
|
255
|
-
EDB: "Database Error",
|
|
256
|
-
EMYSQL: "MySQL Error",
|
|
257
|
-
ESQLA: "SQLAlchemy Error",
|
|
258
|
-
# 114X: Message Queues
|
|
259
|
-
EMQUKN: "Unknown MQ Error",
|
|
260
|
-
EMQNOM: "No messages",
|
|
261
|
-
EMQCONN: "MQ connection failure",
|
|
262
|
-
# 114X OpenSearch
|
|
263
|
-
EELNOFOUND: "Index not found",
|
|
264
|
-
# 115X: Tokens
|
|
265
|
-
EATOKENFIND: "Can't find a bearer access token.",
|
|
266
|
-
EATOKENREAD: "Can't read a bearer access token.",
|
|
267
|
-
ETOKENTYPE: "Unsupported access token type.",
|
|
268
|
-
# Config
|
|
269
|
-
ESECTION: "Section is not found",
|
|
270
|
-
# processes
|
|
271
|
-
EEZOMBIE: "Zombie process",
|
|
272
|
-
EENOPID: "No PID of process",
|
|
273
|
-
# WMS/Workflow
|
|
274
|
-
EWMSUKN: "Unknown WMS error",
|
|
275
|
-
EWMSJDL: "Invalid job description",
|
|
276
|
-
EWMSRESC: "Job to reschedule",
|
|
277
|
-
EWMSSUBM: "Job submission error",
|
|
278
|
-
EWMSJMAN: "Job management error",
|
|
279
|
-
EWMSSTATUS: "Job status error",
|
|
280
|
-
EWMSNOPILOT: "No pilots found",
|
|
281
|
-
EWMSPLTVER: "Pilot version does not match",
|
|
282
|
-
EWMSNOMATCH: "No match found",
|
|
283
|
-
# DMS/StorageManagement
|
|
284
|
-
EFILESIZE: "Bad file size",
|
|
285
|
-
EGFAL: "Error with the gfal call",
|
|
286
|
-
EBADCKS: "Bad checksum",
|
|
287
|
-
EFCERR: "FileCatalog error",
|
|
288
|
-
# RMS
|
|
289
|
-
ERMSUKN: "Unknown RMS error",
|
|
290
|
-
# Resources and RSS
|
|
291
|
-
ERESGEN: "Unknown Resource Failure",
|
|
292
|
-
ERESUNA: "Resource not available",
|
|
293
|
-
ERESUNK: "Unknown Resource",
|
|
294
|
-
# TS
|
|
295
|
-
ETSUKN: "Unknown Transformation System Error",
|
|
296
|
-
ETSDATA: "Invalid Input Data definition",
|
|
297
|
-
}
|
|
43
|
+
# Import all the stateless parts from DIRACCommon
|
|
44
|
+
from DIRACCommon.Core.Utilities.DErrno import * # noqa: F401, F403
|
|
298
45
|
|
|
46
|
+
from DIRAC.Core.Utilities.Extensions import extensionsByPriority
|
|
299
47
|
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
It completes it with the DIRAC specific errors.
|
|
303
|
-
"""
|
|
304
|
-
|
|
305
|
-
if code == 0:
|
|
306
|
-
return "Undefined error"
|
|
307
|
-
|
|
308
|
-
errMsg = f"Unknown error {code}"
|
|
309
|
-
|
|
310
|
-
try:
|
|
311
|
-
errMsg = dStrError[code]
|
|
312
|
-
except KeyError:
|
|
313
|
-
# It is not a DIRAC specific error, try the os one
|
|
314
|
-
try:
|
|
315
|
-
errMsg = os.strerror(code)
|
|
316
|
-
# On some system, os.strerror raises an exception with unknown code,
|
|
317
|
-
# on others, it returns a message...
|
|
318
|
-
except ValueError:
|
|
319
|
-
pass
|
|
320
|
-
|
|
321
|
-
return errMsg
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
def cmpError(inErr, candidate):
|
|
325
|
-
"""This function compares an error (in its old form (a string or dictionary) or in its int form
|
|
326
|
-
with a candidate error code.
|
|
327
|
-
|
|
328
|
-
:param inErr: a string, an integer, a S_ERROR dictionary
|
|
329
|
-
:type inErr: str or int or S_ERROR
|
|
330
|
-
:param int candidate: error code to compare with
|
|
331
|
-
|
|
332
|
-
:return: True or False
|
|
333
|
-
|
|
334
|
-
If an S_ERROR instance is passed, we compare the code with S_ERROR['Errno']
|
|
335
|
-
If it is a Integer, we do a direct comparison
|
|
336
|
-
If it is a String, we use strerror to check the error string
|
|
337
|
-
"""
|
|
338
|
-
|
|
339
|
-
if isinstance(inErr, str): # old style
|
|
340
|
-
# Compare error message strings
|
|
341
|
-
errMsg = strerror(candidate)
|
|
342
|
-
return errMsg in inErr
|
|
343
|
-
elif isinstance(inErr, dict): # if the S_ERROR structure is given
|
|
344
|
-
# Check if Errno defined in the dict
|
|
345
|
-
errorNumber = inErr.get("Errno")
|
|
346
|
-
if errorNumber:
|
|
347
|
-
return errorNumber == candidate
|
|
348
|
-
errMsg = strerror(candidate)
|
|
349
|
-
return errMsg in inErr.get("Message", "")
|
|
350
|
-
elif isinstance(inErr, int):
|
|
351
|
-
return inErr == candidate
|
|
352
|
-
else:
|
|
353
|
-
raise TypeError(f"Unknown input error type {type(inErr)}")
|
|
48
|
+
# compatErrorString is used by the extension mechanism but not in DIRACCommon
|
|
49
|
+
compatErrorString = {}
|
|
354
50
|
|
|
355
51
|
|
|
356
52
|
def includeExtensionErrors():
|
|
@@ -73,6 +73,15 @@ def findServices(modules):
|
|
|
73
73
|
return findModules(modules, "Service", "*Handler")
|
|
74
74
|
|
|
75
75
|
|
|
76
|
+
def findFutureServices(modules):
|
|
77
|
+
"""Find the legacy adapted services for one or more DIRAC extension(s)
|
|
78
|
+
|
|
79
|
+
:param list/str/module module: One or more Python modules or Python module names
|
|
80
|
+
:returns: list of tuples of the form (SystemName, ServiceName)
|
|
81
|
+
"""
|
|
82
|
+
return findModules(modules, "FutureClient")
|
|
83
|
+
|
|
84
|
+
|
|
76
85
|
@iterateThenSort
|
|
77
86
|
def findDatabases(module):
|
|
78
87
|
"""Find the DB SQL schema defintions for one or more DIRAC extension(s)
|
|
@@ -182,7 +191,7 @@ def parseArgs():
|
|
|
182
191
|
parser = argparse.ArgumentParser()
|
|
183
192
|
subparsers = parser.add_subparsers(required=True, dest="function")
|
|
184
193
|
defaultExtensions = extensionsByPriority()
|
|
185
|
-
for func in [findSystems, findAgents, findExecutors, findServices, findDatabases]:
|
|
194
|
+
for func in [findSystems, findAgents, findExecutors, findServices, findDatabases, findFutureServices]:
|
|
186
195
|
subparser = subparsers.add_parser(func.__name__)
|
|
187
196
|
subparser.add_argument("--extensions", nargs="+", default=defaultExtensions)
|
|
188
197
|
subparser.set_defaults(func=func)
|
DIRAC/Core/Utilities/File.py
CHANGED
|
@@ -273,7 +273,7 @@ def secureOpenForWrite(filename=None, *, text=True):
|
|
|
273
273
|
)
|
|
274
274
|
else:
|
|
275
275
|
fd, filename = tempfile.mkstemp(text=text)
|
|
276
|
-
with open(fd, "w" if text else "wb", encoding="
|
|
276
|
+
with open(fd, "w" if text else "wb", encoding="utf-8" if text else None) as fd:
|
|
277
277
|
yield fd, filename
|
|
278
278
|
|
|
279
279
|
|
|
@@ -411,7 +411,7 @@ class PlotData:
|
|
|
411
411
|
self.num_keys.append(next)
|
|
412
412
|
next += 1
|
|
413
413
|
elif self.key_type == "time":
|
|
414
|
-
self.num_keys = [date2num(datetime.datetime.
|
|
414
|
+
self.num_keys = [date2num(datetime.datetime.utcfromtimestamp(to_timestamp(key))) for key in self.keys]
|
|
415
415
|
elif self.key_type == "numeric":
|
|
416
416
|
self.num_keys = [float(key) for key in self.keys]
|
|
417
417
|
|
|
@@ -73,7 +73,12 @@ def convert_to_datetime(dstring):
|
|
|
73
73
|
# Use utcfromtimestamp for UTC time
|
|
74
74
|
results = datetime.datetime.utcfromtimestamp(int(results))
|
|
75
75
|
elif isinstance(results, datetime.datetime):
|
|
76
|
-
|
|
76
|
+
if results.tzinfo is not None:
|
|
77
|
+
# non-naive datetime: convert to UTC
|
|
78
|
+
results = results.astimezone(datetime.timezone.utc)
|
|
79
|
+
else:
|
|
80
|
+
# DIRAC naive datetimes are UTC everywhere: add tzinfo
|
|
81
|
+
results = results.replace(tzinfo=datetime.timezone.utc)
|
|
77
82
|
else:
|
|
78
83
|
raise ValueError("Unknown datetime type!")
|
|
79
84
|
except Exception:
|
DIRAC/Core/Utilities/JDL.py
CHANGED
|
@@ -1,203 +1,9 @@
|
|
|
1
1
|
"""Transformation classes around the JDL format."""
|
|
2
2
|
|
|
3
|
-
from
|
|
4
|
-
from pydantic import ValidationError
|
|
3
|
+
from DIRACCommon.Core.Utilities.JDL import * # noqa: F403,F401
|
|
5
4
|
|
|
6
|
-
from DIRAC import S_OK, S_ERROR
|
|
7
|
-
from DIRAC.Core.Utilities import List
|
|
8
|
-
from DIRAC.Core.Utilities.ClassAd.ClassAdLight import ClassAd
|
|
9
5
|
from DIRAC.WorkloadManagementSystem.Utilities.JobModel import BaseJobDescriptionModel
|
|
10
6
|
|
|
11
|
-
ARGUMENTS = "Arguments"
|
|
12
|
-
BANNED_SITES = "BannedSites"
|
|
13
|
-
CPU_TIME = "CPUTime"
|
|
14
|
-
EXECUTABLE = "Executable"
|
|
15
|
-
EXECUTION_ENVIRONMENT = "ExecutionEnvironment"
|
|
16
|
-
GRID_CE = "GridCE"
|
|
17
|
-
INPUT_DATA = "InputData"
|
|
18
|
-
INPUT_DATA_POLICY = "InputDataPolicy"
|
|
19
|
-
INPUT_SANDBOX = "InputSandbox"
|
|
20
|
-
JOB_CONFIG_ARGS = "JobConfigArgs"
|
|
21
|
-
JOB_TYPE = "JobType"
|
|
22
|
-
JOB_GROUP = "JobGroup"
|
|
23
|
-
LOG_LEVEL = "LogLevel"
|
|
24
|
-
NUMBER_OF_PROCESSORS = "NumberOfProcessors"
|
|
25
|
-
MAX_NUMBER_OF_PROCESSORS = "MaxNumberOfProcessors"
|
|
26
|
-
MIN_NUMBER_OF_PROCESSORS = "MinNumberOfProcessors"
|
|
27
|
-
OUTPUT_DATA = "OutputData"
|
|
28
|
-
OUTPUT_PATH = "OutputPath"
|
|
29
|
-
OUTPUT_SE = "OutputSE"
|
|
30
|
-
PLATFORM = "Platform"
|
|
31
|
-
PRIORITY = "Priority"
|
|
32
|
-
STD_ERROR = "StdError"
|
|
33
|
-
STD_OUTPUT = "StdOutput"
|
|
34
|
-
OUTPUT_SANDBOX = "OutputSandbox"
|
|
35
|
-
JOB_NAME = "JobName"
|
|
36
|
-
SITE = "Site"
|
|
37
|
-
TAGS = "Tags"
|
|
38
|
-
|
|
39
|
-
OWNER = "Owner"
|
|
40
|
-
OWNER_GROUP = "OwnerGroup"
|
|
41
|
-
VO = "VirtualOrganization"
|
|
42
|
-
|
|
43
|
-
CREDENTIALS_FIELDS = {OWNER, OWNER_GROUP, VO}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
def loadJDLAsCFG(jdl):
|
|
47
|
-
"""
|
|
48
|
-
Load a JDL as CFG
|
|
49
|
-
"""
|
|
50
|
-
|
|
51
|
-
def cleanValue(value):
|
|
52
|
-
value = value.strip()
|
|
53
|
-
if value[0] == '"':
|
|
54
|
-
entries = []
|
|
55
|
-
iPos = 1
|
|
56
|
-
current = ""
|
|
57
|
-
state = "in"
|
|
58
|
-
while iPos < len(value):
|
|
59
|
-
if value[iPos] == '"':
|
|
60
|
-
if state == "in":
|
|
61
|
-
entries.append(current)
|
|
62
|
-
current = ""
|
|
63
|
-
state = "out"
|
|
64
|
-
elif state == "out":
|
|
65
|
-
current = current.strip()
|
|
66
|
-
if current not in (",",):
|
|
67
|
-
return S_ERROR("value seems a list but is not separated in commas")
|
|
68
|
-
current = ""
|
|
69
|
-
state = "in"
|
|
70
|
-
else:
|
|
71
|
-
current += value[iPos]
|
|
72
|
-
iPos += 1
|
|
73
|
-
if state == "in":
|
|
74
|
-
return S_ERROR('value is opened with " but is not closed')
|
|
75
|
-
return S_OK(", ".join(entries))
|
|
76
|
-
else:
|
|
77
|
-
return S_OK(value.replace('"', ""))
|
|
78
|
-
|
|
79
|
-
def assignValue(key, value, cfg):
|
|
80
|
-
key = key.strip()
|
|
81
|
-
if len(key) == 0:
|
|
82
|
-
return S_ERROR("Invalid key name")
|
|
83
|
-
value = value.strip()
|
|
84
|
-
if not value:
|
|
85
|
-
return S_ERROR(f"No value for key {key}")
|
|
86
|
-
if value[0] == "{":
|
|
87
|
-
if value[-1] != "}":
|
|
88
|
-
return S_ERROR("Value '%s' seems a list but does not end in '}'" % (value))
|
|
89
|
-
valList = List.fromChar(value[1:-1])
|
|
90
|
-
for i in range(len(valList)):
|
|
91
|
-
result = cleanValue(valList[i])
|
|
92
|
-
if not result["OK"]:
|
|
93
|
-
return S_ERROR(f"Var {key} : {result['Message']}")
|
|
94
|
-
valList[i] = result["Value"]
|
|
95
|
-
if valList[i] is None:
|
|
96
|
-
return S_ERROR(f"List value '{value}' seems invalid for item {i}")
|
|
97
|
-
value = ", ".join(valList)
|
|
98
|
-
else:
|
|
99
|
-
result = cleanValue(value)
|
|
100
|
-
if not result["OK"]:
|
|
101
|
-
return S_ERROR(f"Var {key} : {result['Message']}")
|
|
102
|
-
nV = result["Value"]
|
|
103
|
-
if nV is None:
|
|
104
|
-
return S_ERROR(f"Value '{value} seems invalid")
|
|
105
|
-
value = nV
|
|
106
|
-
cfg.setOption(key, value)
|
|
107
|
-
return S_OK()
|
|
108
|
-
|
|
109
|
-
if jdl[0] == "[":
|
|
110
|
-
iPos = 1
|
|
111
|
-
else:
|
|
112
|
-
iPos = 0
|
|
113
|
-
key = ""
|
|
114
|
-
value = ""
|
|
115
|
-
action = "key"
|
|
116
|
-
insideLiteral = False
|
|
117
|
-
cfg = CFG()
|
|
118
|
-
while iPos < len(jdl):
|
|
119
|
-
char = jdl[iPos]
|
|
120
|
-
if char == ";" and not insideLiteral:
|
|
121
|
-
if key.strip():
|
|
122
|
-
result = assignValue(key, value, cfg)
|
|
123
|
-
if not result["OK"]:
|
|
124
|
-
return result
|
|
125
|
-
key = ""
|
|
126
|
-
value = ""
|
|
127
|
-
action = "key"
|
|
128
|
-
elif char == "[" and not insideLiteral:
|
|
129
|
-
key = key.strip()
|
|
130
|
-
if not key:
|
|
131
|
-
return S_ERROR("Invalid key in JDL")
|
|
132
|
-
if value.strip():
|
|
133
|
-
return S_ERROR(f"Key {key} seems to have a value and open a sub JDL at the same time")
|
|
134
|
-
result = loadJDLAsCFG(jdl[iPos:])
|
|
135
|
-
if not result["OK"]:
|
|
136
|
-
return result
|
|
137
|
-
subCfg, subPos = result["Value"]
|
|
138
|
-
cfg.createNewSection(key, contents=subCfg)
|
|
139
|
-
key = ""
|
|
140
|
-
value = ""
|
|
141
|
-
action = "key"
|
|
142
|
-
insideLiteral = False
|
|
143
|
-
iPos += subPos
|
|
144
|
-
elif char == "=" and not insideLiteral:
|
|
145
|
-
if action == "key":
|
|
146
|
-
action = "value"
|
|
147
|
-
insideLiteral = False
|
|
148
|
-
else:
|
|
149
|
-
value += char
|
|
150
|
-
elif char == "]" and not insideLiteral:
|
|
151
|
-
key = key.strip()
|
|
152
|
-
if len(key) > 0:
|
|
153
|
-
result = assignValue(key, value, cfg)
|
|
154
|
-
if not result["OK"]:
|
|
155
|
-
return result
|
|
156
|
-
return S_OK((cfg, iPos))
|
|
157
|
-
else:
|
|
158
|
-
if action == "key":
|
|
159
|
-
key += char
|
|
160
|
-
else:
|
|
161
|
-
value += char
|
|
162
|
-
if char == '"':
|
|
163
|
-
insideLiteral = not insideLiteral
|
|
164
|
-
iPos += 1
|
|
165
|
-
|
|
166
|
-
return S_OK((cfg, iPos))
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
def dumpCFGAsJDL(cfg, level=1, tab=" "):
|
|
170
|
-
indent = tab * level
|
|
171
|
-
contents = [f"{tab * (level - 1)}["]
|
|
172
|
-
sections = cfg.listSections()
|
|
173
|
-
|
|
174
|
-
for key in cfg:
|
|
175
|
-
if key in sections:
|
|
176
|
-
contents.append(f"{indent}{key} =")
|
|
177
|
-
contents.append(f"{dumpCFGAsJDL(cfg[key], level + 1, tab)};")
|
|
178
|
-
else:
|
|
179
|
-
val = List.fromChar(cfg[key])
|
|
180
|
-
# Some attributes are never lists
|
|
181
|
-
if len(val) < 2 or key in [ARGUMENTS, EXECUTABLE, STD_OUTPUT, STD_ERROR]:
|
|
182
|
-
value = cfg[key]
|
|
183
|
-
try:
|
|
184
|
-
try_value = float(value)
|
|
185
|
-
contents.append(f"{tab * level}{key} = {value};")
|
|
186
|
-
except Exception:
|
|
187
|
-
contents.append(f'{tab * level}{key} = "{value}";')
|
|
188
|
-
else:
|
|
189
|
-
contents.append(f"{indent}{key} =")
|
|
190
|
-
contents.append("%s{" % indent)
|
|
191
|
-
for iPos in range(len(val)):
|
|
192
|
-
try:
|
|
193
|
-
value = float(val[iPos])
|
|
194
|
-
except Exception:
|
|
195
|
-
val[iPos] = f'"{val[iPos]}"'
|
|
196
|
-
contents.append(",\n".join([f"{tab * (level + 1)}{value}" for value in val]))
|
|
197
|
-
contents.append("%s};" % indent)
|
|
198
|
-
contents.append(f"{tab * (level - 1)}]")
|
|
199
|
-
return "\n".join(contents)
|
|
200
|
-
|
|
201
7
|
|
|
202
8
|
def jdlToBaseJobDescriptionModel(classAd: ClassAd):
|
|
203
9
|
"""
|