DIRAC 9.0.12__py3-none-any.whl → 9.0.14__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/ConfigurationSystem/ConfigTemplate.cfg +3 -0
- DIRAC/ConfigurationSystem/private/Modificator.py +11 -3
- DIRAC/DataManagementSystem/Client/FTS3Job.py +1 -0
- DIRAC/FrameworkSystem/Utilities/diracx.py +41 -10
- DIRAC/Resources/Storage/FileStorage.py +121 -2
- DIRAC/WorkloadManagementSystem/Agent/JobCleaningAgent.py +1 -1
- DIRAC/WorkloadManagementSystem/Agent/PilotSyncAgent.py +4 -3
- DIRAC/WorkloadManagementSystem/Agent/StalledJobAgent.py +1 -1
- DIRAC/WorkloadManagementSystem/Agent/test/Test_Agent_JobAgent.py +4 -3
- DIRAC/WorkloadManagementSystem/Agent/test/Test_Agent_PilotLoggingAgent.py +3 -3
- DIRAC/WorkloadManagementSystem/Agent/test/Test_Agent_PilotStatusAgent.py +4 -2
- DIRAC/WorkloadManagementSystem/Agent/test/Test_Agent_PushJobAgent.py +5 -4
- DIRAC/WorkloadManagementSystem/Agent/test/Test_Agent_StalledJobAgent.py +4 -2
- DIRAC/WorkloadManagementSystem/JobWrapper/JobWrapper.py +2 -3
- DIRAC/WorkloadManagementSystem/JobWrapper/JobWrapperOfflineTemplate.py +1 -1
- DIRAC/WorkloadManagementSystem/JobWrapper/JobWrapperTemplate.py +1 -2
- {dirac-9.0.12.dist-info → dirac-9.0.14.dist-info}/METADATA +3 -2
- {dirac-9.0.12.dist-info → dirac-9.0.14.dist-info}/RECORD +22 -22
- {dirac-9.0.12.dist-info → dirac-9.0.14.dist-info}/WHEEL +0 -0
- {dirac-9.0.12.dist-info → dirac-9.0.14.dist-info}/entry_points.txt +0 -0
- {dirac-9.0.12.dist-info → dirac-9.0.14.dist-info}/licenses/LICENSE +0 -0
- {dirac-9.0.12.dist-info → dirac-9.0.14.dist-info}/top_level.txt +0 -0
|
@@ -6,6 +6,9 @@ Services
|
|
|
6
6
|
{
|
|
7
7
|
HandlerPath = DIRAC/ConfigurationSystem/Service/TornadoConfigurationHandler.py
|
|
8
8
|
Port = 9135
|
|
9
|
+
# Set to True to make a DiracX model validation on commits
|
|
10
|
+
# If validation fails, commit will also failed
|
|
11
|
+
VerifyDiracXSyncOnCommit = False
|
|
9
12
|
# Subsection to configure authorization over the service
|
|
10
13
|
Authorization
|
|
11
14
|
{
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
""" This is the guy that actually modifies the content of the CS
|
|
2
2
|
"""
|
|
3
|
-
import zlib
|
|
4
|
-
import difflib
|
|
5
3
|
import datetime
|
|
4
|
+
import difflib
|
|
5
|
+
import zlib
|
|
6
6
|
|
|
7
7
|
from diraccfg import CFG
|
|
8
|
-
|
|
8
|
+
|
|
9
|
+
from DIRAC import S_ERROR
|
|
9
10
|
from DIRAC.ConfigurationSystem.Client.ConfigurationData import gConfigurationData
|
|
10
11
|
from DIRAC.Core.Security.ProxyInfo import getProxyInfo
|
|
12
|
+
from DIRAC.Core.Utilities import List
|
|
13
|
+
from DIRAC.FrameworkSystem.Utilities.diracx import diracxVerifyConfig
|
|
11
14
|
|
|
12
15
|
|
|
13
16
|
class Modificator:
|
|
@@ -239,6 +242,11 @@ class Modificator:
|
|
|
239
242
|
return str(self.cfgData)
|
|
240
243
|
|
|
241
244
|
def commit(self):
|
|
245
|
+
retOpt = self.getValue("/Systems/Configuration/Services/Server/VerifyDiracXSyncOnCommit")
|
|
246
|
+
if retOpt == "True":
|
|
247
|
+
resVerif = diracxVerifyConfig(self.cfgData)
|
|
248
|
+
if not resVerif["OK"]:
|
|
249
|
+
return S_ERROR(resVerif["Message"])
|
|
242
250
|
compressedData = zlib.compress(str(self.cfgData).encode(), 9)
|
|
243
251
|
return self.rpcClient.commitNewData(compressedData)
|
|
244
252
|
|
|
@@ -1,20 +1,25 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
from
|
|
1
|
+
import os
|
|
2
|
+
import re
|
|
3
|
+
import subprocess
|
|
4
|
+
from collections.abc import Generator
|
|
5
|
+
from contextlib import contextmanager
|
|
5
6
|
from pathlib import Path
|
|
6
7
|
from tempfile import NamedTemporaryFile
|
|
8
|
+
import tempfile
|
|
7
9
|
from typing import Any
|
|
8
|
-
from collections.abc import Generator
|
|
9
|
-
from DIRAC import gConfig
|
|
10
|
-
from DIRAC.ConfigurationSystem.Client.Helpers import Registry
|
|
11
|
-
from contextlib import contextmanager
|
|
12
10
|
|
|
11
|
+
import requests
|
|
12
|
+
from cachetools import LRUCache, TTLCache, cached
|
|
13
|
+
from cachetools.keys import hashkey
|
|
14
|
+
from diracx.cli.internal.legacy import _apply_fixes
|
|
15
|
+
from diracx.core.config.schema import Config as DiracxConfig
|
|
16
|
+
from diracx.core.models import TokenResponse
|
|
13
17
|
from diracx.core.preferences import DiracxPreferences
|
|
14
|
-
|
|
15
18
|
from diracx.core.utils import write_credentials
|
|
19
|
+
from pydantic import ValidationError
|
|
16
20
|
|
|
17
|
-
from
|
|
21
|
+
from DIRAC import S_ERROR, S_OK, gConfig
|
|
22
|
+
from DIRAC.ConfigurationSystem.Client.Helpers import Registry
|
|
18
23
|
|
|
19
24
|
try:
|
|
20
25
|
from diracx.client.sync import SyncDiracClient
|
|
@@ -104,3 +109,29 @@ def TheImpersonator(credDict: dict[str, Any], *, source: str = "") -> Generator[
|
|
|
104
109
|
client.__enter__()
|
|
105
110
|
diracx_client_cache[token_location] = client
|
|
106
111
|
yield client
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def diracxVerifyConfig(cfgData):
|
|
115
|
+
"""Verify CS config using DiracX config validation
|
|
116
|
+
|
|
117
|
+
Args:
|
|
118
|
+
cfgData: CFG data
|
|
119
|
+
|
|
120
|
+
Returns:
|
|
121
|
+
S_OK | S_ERROR: Value: diracx Config validation
|
|
122
|
+
"""
|
|
123
|
+
os.environ["DIRAC_COMPAT_ENABLE_CS_CONVERSION"] = "true"
|
|
124
|
+
with tempfile.NamedTemporaryFile() as temp_cfg:
|
|
125
|
+
with tempfile.NamedTemporaryFile() as temp_diracx_cfg:
|
|
126
|
+
cfgData.writeToFile(temp_cfg.name)
|
|
127
|
+
cmd = ["dirac", "internal", "legacy", "cs-sync", temp_cfg.name, temp_diracx_cfg.name]
|
|
128
|
+
res = subprocess.run(cmd, capture_output=True, text=True, timeout=15)
|
|
129
|
+
os.environ.pop("DIRAC_COMPAT_ENABLE_CS_CONVERSION")
|
|
130
|
+
if res.returncode == 0:
|
|
131
|
+
return S_OK(res.stdout)
|
|
132
|
+
else:
|
|
133
|
+
err = res.stderr.strip()
|
|
134
|
+
match = re.search(r"(ValidationError:.*)", err, flags=re.DOTALL)
|
|
135
|
+
if match:
|
|
136
|
+
return S_ERROR(match.group(1))
|
|
137
|
+
return S_ERROR(err)
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
"""
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
This is the File StorageClass, only meant to be used localy
|
|
3
|
+
"""
|
|
4
|
+
|
|
4
5
|
import os
|
|
5
6
|
import shutil
|
|
6
7
|
import errno
|
|
7
8
|
import stat
|
|
9
|
+
import struct
|
|
10
|
+
import time
|
|
8
11
|
|
|
9
12
|
from DIRAC import gLogger, S_OK, S_ERROR
|
|
10
13
|
from DIRAC.Resources.Storage.Utilities import checkArgumentFormat
|
|
@@ -12,6 +15,116 @@ from DIRAC.Resources.Storage.StorageBase import StorageBase
|
|
|
12
15
|
from DIRAC.Core.Utilities.Adler import fileAdler
|
|
13
16
|
|
|
14
17
|
|
|
18
|
+
def set_xattr_adler32(path, checksum):
|
|
19
|
+
"""
|
|
20
|
+
Set the adler32 checksum extended attribute on a file.
|
|
21
|
+
|
|
22
|
+
This is needed for case where you write the data on a locally mounted
|
|
23
|
+
file system, but then want to access it from outside via xroot (like the HLT farm)
|
|
24
|
+
|
|
25
|
+
Hopefully, this whole function will be part of xroot at some point
|
|
26
|
+
https://github.com/xrootd/xrootd/pull/2650
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
This function replicates the exact behavior of the C++ function fSetXattrAdler32
|
|
30
|
+
|
|
31
|
+
It writes the checksum in XrdCksData binary format with the following structure:
|
|
32
|
+
- Name[16]: Algorithm name ("adler32"), null-padded
|
|
33
|
+
- fmTime (8): File modification time (network byte order, int64)
|
|
34
|
+
- csTime (4): Time delta from mtime (network byte order, int32)
|
|
35
|
+
- Rsvd1 (2): Reserved (int16)
|
|
36
|
+
- Rsvd2 (1): Reserved (uint8)
|
|
37
|
+
- Length (1): Checksum length in bytes (uint8)
|
|
38
|
+
- Value[64]: Binary checksum value (4 bytes for adler32)
|
|
39
|
+
|
|
40
|
+
Total structure size: 96 bytes
|
|
41
|
+
|
|
42
|
+
Parameters
|
|
43
|
+
----------
|
|
44
|
+
path : str
|
|
45
|
+
Path to the file (must be a regular file on local filesystem)
|
|
46
|
+
checksum : str
|
|
47
|
+
8-character hexadecimal adler32 checksum (e.g., "deadbeef")
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
Notes
|
|
51
|
+
-----
|
|
52
|
+
- The attribute is stored as "user.XrdCks.adler32"
|
|
53
|
+
|
|
54
|
+
"""
|
|
55
|
+
# Validate checksum format
|
|
56
|
+
if not isinstance(checksum, str) or len(checksum) != 8:
|
|
57
|
+
raise ValueError("Checksum must be exactly 8 characters")
|
|
58
|
+
|
|
59
|
+
# Validate it's valid hex
|
|
60
|
+
try:
|
|
61
|
+
int(checksum, 16)
|
|
62
|
+
except ValueError:
|
|
63
|
+
raise ValueError(f"Checksum must be valid hexadecimal: {checksum}")
|
|
64
|
+
|
|
65
|
+
# Check file exists and is regular
|
|
66
|
+
|
|
67
|
+
st = os.stat(path)
|
|
68
|
+
|
|
69
|
+
# Import xattr module
|
|
70
|
+
try:
|
|
71
|
+
import xattr
|
|
72
|
+
except ImportError:
|
|
73
|
+
raise ImportError("The 'xattr' module is required. Install it with: pip install xattr")
|
|
74
|
+
|
|
75
|
+
# Build XrdCksData structure (96 bytes total)
|
|
76
|
+
# Reference: src/XrdCks/XrdCksData.hh
|
|
77
|
+
|
|
78
|
+
# 1. Name[16] - Algorithm name, null-padded
|
|
79
|
+
name = b"adler32"
|
|
80
|
+
name_field = name.ljust(16, b"\x00")
|
|
81
|
+
|
|
82
|
+
# 2. fmTime (8 bytes) - File modification time (network byte order = big-endian)
|
|
83
|
+
fm_time = int(st.st_mtime)
|
|
84
|
+
fm_time_field = struct.pack(">q", fm_time) # signed 64-bit big-endian
|
|
85
|
+
|
|
86
|
+
# 3. csTime (4 bytes) - Delta from mtime to now (network byte order)
|
|
87
|
+
cs_time = int(time.time()) - fm_time
|
|
88
|
+
cs_time_field = struct.pack(">i", cs_time) # signed 32-bit big-endian
|
|
89
|
+
|
|
90
|
+
# 4. Rsvd1 (2 bytes) - Reserved, set to 0
|
|
91
|
+
rsvd1_field = struct.pack(">h", 0) # signed 16-bit big-endian
|
|
92
|
+
|
|
93
|
+
# 5. Rsvd2 (1 byte) - Reserved, set to 0
|
|
94
|
+
rsvd2_field = struct.pack("B", 0) # unsigned 8-bit
|
|
95
|
+
|
|
96
|
+
# 6. Length (1 byte) - Checksum length in bytes
|
|
97
|
+
# Adler32 is 4 bytes (8 hex chars / 2)
|
|
98
|
+
length_field = struct.pack("B", 4) # unsigned 8-bit
|
|
99
|
+
|
|
100
|
+
# 7. Value[64] - Binary checksum value
|
|
101
|
+
# Convert hex string to 4 bytes, pad rest with zeros
|
|
102
|
+
checksum_bytes = bytes.fromhex(checksum)
|
|
103
|
+
value_field = checksum_bytes + b"\x00" * (64 - len(checksum_bytes))
|
|
104
|
+
|
|
105
|
+
# Assemble complete structure
|
|
106
|
+
xrd_cks_data = (
|
|
107
|
+
name_field # 16 bytes
|
|
108
|
+
+ fm_time_field # 8 bytes
|
|
109
|
+
+ cs_time_field # 4 bytes
|
|
110
|
+
+ rsvd1_field # 2 bytes
|
|
111
|
+
+ rsvd2_field # 1 byte
|
|
112
|
+
+ length_field # 1 byte
|
|
113
|
+
+ value_field # 64 bytes
|
|
114
|
+
) # Total: 96 bytes
|
|
115
|
+
|
|
116
|
+
assert len(xrd_cks_data) == 96, f"Structure size mismatch: {len(xrd_cks_data)}"
|
|
117
|
+
|
|
118
|
+
# Set the extended attribute
|
|
119
|
+
# XRootD uses "XrdCks.adler32" which becomes "user.XrdCks.adler32" on Linux
|
|
120
|
+
attr_name = "user.XrdCks.adler32"
|
|
121
|
+
|
|
122
|
+
try:
|
|
123
|
+
xattr.setxattr(path, attr_name, xrd_cks_data)
|
|
124
|
+
except OSError as e:
|
|
125
|
+
raise OSError(f"Failed to set extended attribute on {path}: {e}") from e
|
|
126
|
+
|
|
127
|
+
|
|
15
128
|
class FileStorage(StorageBase):
|
|
16
129
|
""".. class:: FileStorage
|
|
17
130
|
|
|
@@ -165,6 +278,12 @@ class FileStorage(StorageBase):
|
|
|
165
278
|
os.makedirs(dirname)
|
|
166
279
|
shutil.copy2(src_file, dest_url)
|
|
167
280
|
fileSize = os.path.getsize(dest_url)
|
|
281
|
+
try:
|
|
282
|
+
src_cks = fileAdler(src_file)
|
|
283
|
+
set_xattr_adler32(dest_url, src_cks)
|
|
284
|
+
except Exception as e:
|
|
285
|
+
gLogger.warn("Could not set checksum", f"{e!r}")
|
|
286
|
+
|
|
168
287
|
if sourceSize and (sourceSize != fileSize):
|
|
169
288
|
try:
|
|
170
289
|
os.unlink(dest_url)
|
|
@@ -38,8 +38,8 @@ from DIRAC.WorkloadManagementSystem.Client import JobStatus
|
|
|
38
38
|
from DIRAC.WorkloadManagementSystem.Client.WMSClient import WMSClient
|
|
39
39
|
from DIRAC.WorkloadManagementSystem.DB.JobDB import JobDB
|
|
40
40
|
from DIRAC.WorkloadManagementSystem.DB.SandboxMetadataDB import SandboxMetadataDB
|
|
41
|
-
from DIRAC.WorkloadManagementSystem.Service.JobPolicy import RIGHT_DELETE
|
|
42
41
|
from DIRAC.WorkloadManagementSystem.DB.StatusUtils import kill_delete_jobs
|
|
42
|
+
from DIRAC.WorkloadManagementSystem.Service.JobPolicy import RIGHT_DELETE
|
|
43
43
|
from DIRAC.WorkloadManagementSystem.Utilities.JobParameters import getJobParameters
|
|
44
44
|
|
|
45
45
|
|
|
@@ -8,15 +8,16 @@
|
|
|
8
8
|
|
|
9
9
|
"""
|
|
10
10
|
|
|
11
|
-
import
|
|
11
|
+
import hashlib
|
|
12
12
|
import json
|
|
13
|
+
import os
|
|
13
14
|
import shutil
|
|
14
|
-
|
|
15
|
+
|
|
15
16
|
import requests
|
|
16
17
|
|
|
17
18
|
from DIRAC import S_OK
|
|
18
19
|
from DIRAC.Core.Base.AgentModule import AgentModule
|
|
19
|
-
from DIRAC.Core.Security.Locations import
|
|
20
|
+
from DIRAC.Core.Security.Locations import getCAsLocation, getHostCertificateAndKeyLocation
|
|
20
21
|
from DIRAC.DataManagementSystem.Client.DataManager import DataManager
|
|
21
22
|
from DIRAC.WorkloadManagementSystem.Utilities.PilotCStoJSONSynchronizer import PilotCStoJSONSynchronizer
|
|
22
23
|
|
|
@@ -20,8 +20,8 @@ from DIRAC.Core.Utilities.ClassAd.ClassAdLight import ClassAd
|
|
|
20
20
|
from DIRAC.Core.Utilities.ObjectLoader import ObjectLoader
|
|
21
21
|
from DIRAC.Core.Utilities.TimeUtilities import fromString, second, toEpoch
|
|
22
22
|
from DIRAC.WorkloadManagementSystem.Client import JobMinorStatus, JobStatus
|
|
23
|
-
from DIRAC.WorkloadManagementSystem.Service.JobPolicy import RIGHT_KILL
|
|
24
23
|
from DIRAC.WorkloadManagementSystem.DB.StatusUtils import kill_delete_jobs
|
|
24
|
+
from DIRAC.WorkloadManagementSystem.Service.JobPolicy import RIGHT_KILL
|
|
25
25
|
from DIRAC.WorkloadManagementSystem.Utilities.JobParameters import getJobParameters
|
|
26
26
|
from DIRAC.WorkloadManagementSystem.Utilities.Utils import rescheduleJobs
|
|
27
27
|
|
|
@@ -2,14 +2,15 @@
|
|
|
2
2
|
"""
|
|
3
3
|
import multiprocessing
|
|
4
4
|
import os
|
|
5
|
-
from pathlib import Path
|
|
6
|
-
import pytest
|
|
7
5
|
import time
|
|
8
6
|
from concurrent.futures import ProcessPoolExecutor
|
|
9
7
|
from functools import partial
|
|
8
|
+
from pathlib import Path
|
|
10
9
|
|
|
11
|
-
|
|
10
|
+
import pytest
|
|
12
11
|
from DIRAC.Core.Security.X509Chain import X509Chain # pylint: disable=import-error
|
|
12
|
+
|
|
13
|
+
from DIRAC import S_ERROR, S_OK, gLogger
|
|
13
14
|
from DIRAC.Resources.Computing.BatchSystems.TimeLeft.TimeLeft import TimeLeft
|
|
14
15
|
from DIRAC.Resources.Computing.ComputingElementFactory import ComputingElementFactory
|
|
15
16
|
from DIRAC.Resources.Computing.test.Test_PoolComputingElement import badJobScript, jobScript
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
""" Test class for PilotLoggingAgent Agent
|
|
2
2
|
"""
|
|
3
3
|
import os
|
|
4
|
-
import time
|
|
5
4
|
import tempfile
|
|
5
|
+
import time
|
|
6
|
+
from unittest.mock import MagicMock, patch
|
|
6
7
|
|
|
7
8
|
import pytest
|
|
8
|
-
from unittest.mock import MagicMock, patch
|
|
9
9
|
|
|
10
10
|
# DIRAC Components
|
|
11
11
|
import DIRAC.WorkloadManagementSystem.Agent.PilotLoggingAgent as plaModule
|
|
12
|
+
from DIRAC import S_ERROR, S_OK, gConfig, gLogger
|
|
12
13
|
from DIRAC.WorkloadManagementSystem.Agent.PilotLoggingAgent import PilotLoggingAgent
|
|
13
|
-
from DIRAC import gLogger, gConfig, S_OK, S_ERROR
|
|
14
14
|
|
|
15
15
|
gLogger.setLevel("DEBUG")
|
|
16
16
|
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
""" Test class for Pilot Status Agent
|
|
2
2
|
"""
|
|
3
|
-
import pytest
|
|
4
3
|
from unittest.mock import MagicMock
|
|
5
4
|
|
|
5
|
+
import pytest
|
|
6
|
+
|
|
7
|
+
from DIRAC import S_OK, gLogger
|
|
8
|
+
|
|
6
9
|
# DIRAC Components
|
|
7
10
|
from DIRAC.WorkloadManagementSystem.Agent.PilotStatusAgent import PilotStatusAgent
|
|
8
|
-
from DIRAC import gLogger, S_OK
|
|
9
11
|
|
|
10
12
|
# Mock objects
|
|
11
13
|
mockReply = MagicMock()
|
|
@@ -3,18 +3,19 @@
|
|
|
3
3
|
|
|
4
4
|
# imports
|
|
5
5
|
import os
|
|
6
|
-
from pathlib import Path
|
|
7
6
|
import shutil
|
|
7
|
+
from collections import defaultdict
|
|
8
|
+
from pathlib import Path
|
|
8
9
|
from unittest.mock import Mock
|
|
10
|
+
|
|
9
11
|
import pytest
|
|
10
|
-
|
|
12
|
+
|
|
13
|
+
from DIRAC import S_ERROR, S_OK, gLogger
|
|
11
14
|
|
|
12
15
|
# DIRAC Components
|
|
13
16
|
from DIRAC.ConfigurationSystem.Client.Helpers.Operations import Operations
|
|
14
17
|
from DIRAC.WorkloadManagementSystem.Agent.PushJobAgent import PushJobAgent
|
|
15
18
|
from DIRAC.WorkloadManagementSystem.Agent.test.Test_Agent_SiteDirector import config
|
|
16
|
-
|
|
17
|
-
from DIRAC import gLogger, S_OK, S_ERROR
|
|
18
19
|
from DIRAC.WorkloadManagementSystem.Client import JobMinorStatus
|
|
19
20
|
from DIRAC.WorkloadManagementSystem.Client.JobReport import JobReport
|
|
20
21
|
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
""" Test class for Stalled Job Agent
|
|
2
2
|
"""
|
|
3
|
-
import pytest
|
|
4
3
|
from unittest.mock import MagicMock
|
|
5
4
|
|
|
5
|
+
import pytest
|
|
6
|
+
|
|
7
|
+
from DIRAC import gLogger
|
|
8
|
+
|
|
6
9
|
# DIRAC Components
|
|
7
10
|
from DIRAC.WorkloadManagementSystem.Agent.StalledJobAgent import StalledJobAgent
|
|
8
|
-
from DIRAC import gLogger
|
|
9
11
|
|
|
10
12
|
# Mock Objects
|
|
11
13
|
mockAM = MagicMock()
|
|
@@ -16,7 +16,6 @@ import datetime
|
|
|
16
16
|
import glob
|
|
17
17
|
import json
|
|
18
18
|
import os
|
|
19
|
-
from pathlib import Path
|
|
20
19
|
import re
|
|
21
20
|
import shutil
|
|
22
21
|
import stat
|
|
@@ -24,12 +23,12 @@ import sys
|
|
|
24
23
|
import tarfile
|
|
25
24
|
import threading
|
|
26
25
|
import time
|
|
26
|
+
from pathlib import Path
|
|
27
27
|
from urllib.parse import unquote
|
|
28
28
|
|
|
29
29
|
import DIRAC
|
|
30
30
|
from DIRAC import S_ERROR, S_OK, gConfig, gLogger
|
|
31
31
|
from DIRAC.AccountingSystem.Client.Types.Job import Job as AccountingJob
|
|
32
|
-
|
|
33
32
|
from DIRAC.ConfigurationSystem.Client.Helpers.Operations import Operations
|
|
34
33
|
from DIRAC.ConfigurationSystem.Client.Helpers.Registry import getVOForGroup
|
|
35
34
|
from DIRAC.Core.Utilities import DEncode, DErrno, List
|
|
@@ -1021,7 +1020,7 @@ class JobWrapper:
|
|
|
1021
1020
|
|
|
1022
1021
|
for i in outputSandbox:
|
|
1023
1022
|
if i not in okFiles:
|
|
1024
|
-
if
|
|
1023
|
+
if f"{i}.tar" not in okFiles:
|
|
1025
1024
|
if not re.search(r"\*", i):
|
|
1026
1025
|
if i not in missing:
|
|
1027
1026
|
missing.append(i)
|
|
@@ -6,9 +6,9 @@ It is executed in environment where external connections are not allowed.
|
|
|
6
6
|
We assume this script is executed in a specific environment where DIRAC is available.
|
|
7
7
|
"""
|
|
8
8
|
import hashlib
|
|
9
|
-
import sys
|
|
10
9
|
import json
|
|
11
10
|
import os
|
|
11
|
+
import sys
|
|
12
12
|
|
|
13
13
|
sitePython = os.path.realpath("@SITEPYTHON@")
|
|
14
14
|
if sitePython:
|
|
@@ -11,9 +11,9 @@
|
|
|
11
11
|
- the resolution of the inpt data failed
|
|
12
12
|
- the JobWrapper ended with the status DErrno.EWMSRESC
|
|
13
13
|
"""
|
|
14
|
-
import sys
|
|
15
14
|
import json
|
|
16
15
|
import os
|
|
16
|
+
import sys
|
|
17
17
|
|
|
18
18
|
sitePython = os.path.realpath("@SITEPYTHON@")
|
|
19
19
|
if sitePython:
|
|
@@ -35,7 +35,6 @@ from DIRAC.WorkloadManagementSystem.JobWrapper.JobWrapperUtilities import (
|
|
|
35
35
|
transferInputSandbox,
|
|
36
36
|
)
|
|
37
37
|
|
|
38
|
-
|
|
39
38
|
os.umask(0o22)
|
|
40
39
|
|
|
41
40
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: DIRAC
|
|
3
|
-
Version: 9.0.
|
|
3
|
+
Version: 9.0.14
|
|
4
4
|
Summary: DIRAC is an interware, meaning a software framework for distributed computing.
|
|
5
5
|
Home-page: https://github.com/DIRACGrid/DIRAC/
|
|
6
6
|
License: GPL-3.0-only
|
|
@@ -19,7 +19,7 @@ Requires-Dist: cachetools
|
|
|
19
19
|
Requires-Dist: certifi
|
|
20
20
|
Requires-Dist: cwltool
|
|
21
21
|
Requires-Dist: diraccfg
|
|
22
|
-
Requires-Dist: DIRACCommon==v9.0.
|
|
22
|
+
Requires-Dist: DIRACCommon==v9.0.14
|
|
23
23
|
Requires-Dist: diracx-client>=v0.0.1
|
|
24
24
|
Requires-Dist: diracx-core>=v0.0.1
|
|
25
25
|
Requires-Dist: diracx-cli>=v0.0.1
|
|
@@ -47,6 +47,7 @@ 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"
|
|
@@ -44,7 +44,7 @@ DIRAC/AccountingSystem/private/Policies/__init__.py,sha256=MZ_7JU2-hgRxx9YdvI35W
|
|
|
44
44
|
DIRAC/AccountingSystem/scripts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
45
45
|
DIRAC/AccountingSystem/scripts/dirac_accounting_decode_fileid.py,sha256=1BJXmBt0u0WuD76_mZHZvS7cQRvW4aLxa1keqLUL9wY,1251
|
|
46
46
|
DIRAC/AccountingSystem/scripts/dirac_admin_accounting_cli.py,sha256=Hhb4kxGFa5eDIv6vysQO344hBOGHNn6AIVdfTYSC2-c,627
|
|
47
|
-
DIRAC/ConfigurationSystem/ConfigTemplate.cfg,sha256=
|
|
47
|
+
DIRAC/ConfigurationSystem/ConfigTemplate.cfg,sha256=nqDjOOAjSKmRguyKzQeNE5ukr_ApIAiXTqLo4mH9zlA,4057
|
|
48
48
|
DIRAC/ConfigurationSystem/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
49
49
|
DIRAC/ConfigurationSystem/Agent/Bdii2CSAgent.py,sha256=-LyMfVhK9jee3ybmzAmDuoBCzt2j323JotthTXgKCh4,13180
|
|
50
50
|
DIRAC/ConfigurationSystem/Agent/GOCDB2CSAgent.py,sha256=TGECmSCVebg2fU115ZOXcCN1SkSnec0pki0RoYJvUy4,11384
|
|
@@ -81,7 +81,7 @@ DIRAC/ConfigurationSystem/Service/TornadoConfigurationHandler.py,sha256=Mxb64SHI
|
|
|
81
81
|
DIRAC/ConfigurationSystem/Service/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
82
82
|
DIRAC/ConfigurationSystem/private/ConfigurationClient.py,sha256=zRqHURAz2uE96fDWoccnW-pH8xHKuIOr_k0z5qM15Z4,10905
|
|
83
83
|
DIRAC/ConfigurationSystem/private/ConfigurationData.py,sha256=KaoCw6yhNTFHPYRf_gE8vllJIlOvrvTq_zI7rOQiHqo,15180
|
|
84
|
-
DIRAC/ConfigurationSystem/private/Modificator.py,sha256=
|
|
84
|
+
DIRAC/ConfigurationSystem/private/Modificator.py,sha256=I0P9Wcu75-aWJysa3OnIgMD6UmEwB_tFCgBEYnEdX34,10904
|
|
85
85
|
DIRAC/ConfigurationSystem/private/Refresher.py,sha256=bdBEp4dVtE8RBdYHmFREftrUniGbe7AwXZK-vBZnAV0,4097
|
|
86
86
|
DIRAC/ConfigurationSystem/private/RefresherBase.py,sha256=STbCWT3fJvNqyQNwsrzTQAuG6OndlBzTJfnwGrAOAnQ,6552
|
|
87
87
|
DIRAC/ConfigurationSystem/private/ServiceInterface.py,sha256=HzFWXFd6aWmlEJfcBNr5nVCG3tXuYmQunR9_xjuueX4,1919
|
|
@@ -365,7 +365,7 @@ DIRAC/DataManagementSystem/Client/DataManager.py,sha256=ME5a_0csev0X07PVXQV14BrD
|
|
|
365
365
|
DIRAC/DataManagementSystem/Client/DirectoryListing.py,sha256=CvQZ5Da5WhgwdDL8iLk0xVBjKZrBHTdwMKWwSJwzwEI,7582
|
|
366
366
|
DIRAC/DataManagementSystem/Client/FTS3Client.py,sha256=Kk1wy4YnkYuOI6IltyDYZqkzxV7Zsf7ZuoKT12_VbTw,3531
|
|
367
367
|
DIRAC/DataManagementSystem/Client/FTS3File.py,sha256=gZFN_Uxc2tblUCETb4qWPJ2M1tSmKUvTMiZUL-yJ6M0,3122
|
|
368
|
-
DIRAC/DataManagementSystem/Client/FTS3Job.py,sha256=
|
|
368
|
+
DIRAC/DataManagementSystem/Client/FTS3Job.py,sha256=58ng6XaxD-ZqbtGBpWIqTAqWc86i8Job1hBIzjAmNCc,42125
|
|
369
369
|
DIRAC/DataManagementSystem/Client/FTS3Operation.py,sha256=L3yqc0X0ziluMPegoQU6o3aYDnTYwLtujShgbGFJjsw,24455
|
|
370
370
|
DIRAC/DataManagementSystem/Client/FailoverTransfer.py,sha256=2V-dKtgAndMuw9iZHYV019V0hLwlezUNP33wvClpsaA,13373
|
|
371
371
|
DIRAC/DataManagementSystem/Client/FileCatalogClientCLI.py,sha256=sc_6mT0BCbXgj5wOEFtCxNc0AvyQ186A_yLi2lnduvw,80094
|
|
@@ -534,7 +534,7 @@ DIRAC/FrameworkSystem/Service/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5N
|
|
|
534
534
|
DIRAC/FrameworkSystem/Utilities/MonitoringUtilities.py,sha256=6KZ4lyQ4lCqiiujHJ-2gveZpb9edK2adR0mMeQY1wsQ,2557
|
|
535
535
|
DIRAC/FrameworkSystem/Utilities/TokenManagementUtilities.py,sha256=eEeKs9JMJOiokjDtDcRlyQiRWIM1TNYwcVy1C4oozuY,3034
|
|
536
536
|
DIRAC/FrameworkSystem/Utilities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
537
|
-
DIRAC/FrameworkSystem/Utilities/diracx.py,sha256=
|
|
537
|
+
DIRAC/FrameworkSystem/Utilities/diracx.py,sha256=B1MjMsfXlX4oe_WHetns8qRdQoFGf7OzWgQzJEGrcSo,4793
|
|
538
538
|
DIRAC/FrameworkSystem/Utilities/test/Test_TokenManagementUtilities.py,sha256=XIaNe18QjuBUmPvDFBmKO0UNSEiYJCzQP-XuH-JMY3s,6551
|
|
539
539
|
DIRAC/FrameworkSystem/private/SecurityFileLog.py,sha256=6pGlHaUQiqCi90TdEB0Lqjafhz1LI07U-DE_Z1yECYE,4171
|
|
540
540
|
DIRAC/FrameworkSystem/private/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -995,7 +995,7 @@ DIRAC/Resources/Storage/CTAStorage.py,sha256=EfcQDOVHDtx8cqGyxewtsnO6dYs6XfQXeQ1
|
|
|
995
995
|
DIRAC/Resources/Storage/DIPStorage.py,sha256=aKJ9XkE0uv7BcgZeAv7c6JyHYcOyaYCR44IyLxGeyhU,19811
|
|
996
996
|
DIRAC/Resources/Storage/EchoStorage.py,sha256=BwU292zxXZqjaBFBmyjDHvXlPuj-5IdvHkj9bnrxmOw,6637
|
|
997
997
|
DIRAC/Resources/Storage/FCOnlyStorage.py,sha256=msT3KhMAeeebiD5bveNfogBWIXHPKZeLETvzsr0meCc,1775
|
|
998
|
-
DIRAC/Resources/Storage/FileStorage.py,sha256=
|
|
998
|
+
DIRAC/Resources/Storage/FileStorage.py,sha256=Wi4Ci48Vq3yXG73_LfEmQeZ_jHKNxcvo-ngvX8i-fa8,26100
|
|
999
999
|
DIRAC/Resources/Storage/GFAL2_GSIFTPStorage.py,sha256=tYBZ4W_UU57PTjBEEZsfkROnYw28lKDeohK9nkpZTIk,1976
|
|
1000
1000
|
DIRAC/Resources/Storage/GFAL2_HTTPSStorage.py,sha256=FxIp3fAG9ERW_y2sqx50ScwQmP5-NlEelbyT9bx2WzE,888
|
|
1001
1001
|
DIRAC/Resources/Storage/GFAL2_SRM2Storage.py,sha256=TW5GfqMaqRt9mKiOWrmkRophiympgsrYUbVZ9nkEQvg,8844
|
|
@@ -1122,23 +1122,23 @@ DIRAC/Workflow/Utilities/test/Test_Utilities.py,sha256=DNjFPpBmpojwCWhZSUSoG3AIh
|
|
|
1122
1122
|
DIRAC/WorkloadManagementSystem/ConfigTemplate.cfg,sha256=uHa3ZiSC7cyhbJUNvWwqiL0E-m9UmBinrLIQdWmre3k,9030
|
|
1123
1123
|
DIRAC/WorkloadManagementSystem/__init__.py,sha256=9-_-HOT_8S3i-TMmTR_gFVVlNyktBRk-S2qSuOBKoIc,50
|
|
1124
1124
|
DIRAC/WorkloadManagementSystem/Agent/JobAgent.py,sha256=LzLypd3m4a6M-J5_nmUMsMqgflb_1Xm77eONDE6G1Vg,40843
|
|
1125
|
-
DIRAC/WorkloadManagementSystem/Agent/JobCleaningAgent.py,sha256=
|
|
1125
|
+
DIRAC/WorkloadManagementSystem/Agent/JobCleaningAgent.py,sha256=qoe6XQIy9HBC1rlaEG223DEx7upap5ju3eqTWtDiU3s,14708
|
|
1126
1126
|
DIRAC/WorkloadManagementSystem/Agent/PilotLoggingAgent.py,sha256=ZIgvFpasGTh76GW3G7O4hKC_Kkm31uWymlH-MTT3AXg,10541
|
|
1127
1127
|
DIRAC/WorkloadManagementSystem/Agent/PilotStatusAgent.py,sha256=qY6TbYCPOFFXhHffmRJLNEbWvZPyg5Lc5B_8BbyQ7zc,9711
|
|
1128
|
-
DIRAC/WorkloadManagementSystem/Agent/PilotSyncAgent.py,sha256=
|
|
1128
|
+
DIRAC/WorkloadManagementSystem/Agent/PilotSyncAgent.py,sha256=sns-1kUnF5kdvRhdfs_TbhXGAK_kqiosPL4_mD_tC2o,4861
|
|
1129
1129
|
DIRAC/WorkloadManagementSystem/Agent/PushJobAgent.py,sha256=IvHshnw2xN0AZrruEu86C47GDez8enBD6jjNIZd6QcA,38594
|
|
1130
1130
|
DIRAC/WorkloadManagementSystem/Agent/SiteDirector.py,sha256=ZSGWVKO64ztnv_R19I6TT7660jf7LMuYcff_aPq2xCM,45162
|
|
1131
|
-
DIRAC/WorkloadManagementSystem/Agent/StalledJobAgent.py,sha256=
|
|
1131
|
+
DIRAC/WorkloadManagementSystem/Agent/StalledJobAgent.py,sha256=mX9wxeEzBRfS63Jc0oEABCLrstPzSsbHc7SCIZTFNnA,25758
|
|
1132
1132
|
DIRAC/WorkloadManagementSystem/Agent/StatesAccountingAgent.py,sha256=iNIlWQEDBk6R1S8oHOIusZUwxOwLtgwuzR_4s32-o5w,8707
|
|
1133
1133
|
DIRAC/WorkloadManagementSystem/Agent/TaskQueuesAgent.py,sha256=ypsmo233TFXq9IC5uz6pum7_joOh2gFPUYNmmCpukAY,943
|
|
1134
1134
|
DIRAC/WorkloadManagementSystem/Agent/__init__.py,sha256=Pp2qIXA0zZxJXBQwPEDUt23Y_ct5cjs77w8ZEV6Ll6M,56
|
|
1135
|
-
DIRAC/WorkloadManagementSystem/Agent/test/Test_Agent_JobAgent.py,sha256=
|
|
1135
|
+
DIRAC/WorkloadManagementSystem/Agent/test/Test_Agent_JobAgent.py,sha256=7E2QCAfX854p8ielS6VUK0BG9E0mb2nBGzSeG0pJtO8,30723
|
|
1136
1136
|
DIRAC/WorkloadManagementSystem/Agent/test/Test_Agent_JobCleaningAgent.py,sha256=VwD3lGCEYeQuT-5wo02Yk11lR0dXmg0ObNCEvBZ-QSA,5415
|
|
1137
|
-
DIRAC/WorkloadManagementSystem/Agent/test/Test_Agent_PilotLoggingAgent.py,sha256=
|
|
1138
|
-
DIRAC/WorkloadManagementSystem/Agent/test/Test_Agent_PilotStatusAgent.py,sha256=
|
|
1139
|
-
DIRAC/WorkloadManagementSystem/Agent/test/Test_Agent_PushJobAgent.py,sha256=
|
|
1137
|
+
DIRAC/WorkloadManagementSystem/Agent/test/Test_Agent_PilotLoggingAgent.py,sha256=7rSt2IwgRBYX1-Svjx84gbtQkZuZ5BbpdKyrRkvU2i0,8611
|
|
1138
|
+
DIRAC/WorkloadManagementSystem/Agent/test/Test_Agent_PilotStatusAgent.py,sha256=0Bbcxw2AWNOjYYK12zlnLt2Y8U78iNwzWYWwvPsFImc,2808
|
|
1139
|
+
DIRAC/WorkloadManagementSystem/Agent/test/Test_Agent_PushJobAgent.py,sha256=hZzRiYivEmiJBlZZ9aiZuD77_IQT5pORDaHt47OljOU,14888
|
|
1140
1140
|
DIRAC/WorkloadManagementSystem/Agent/test/Test_Agent_SiteDirector.py,sha256=o6imUULkKrvbmkfpvER8wyg0Ncn3gxvJNTNO8xKX7_w,11670
|
|
1141
|
-
DIRAC/WorkloadManagementSystem/Agent/test/Test_Agent_StalledJobAgent.py,sha256=
|
|
1141
|
+
DIRAC/WorkloadManagementSystem/Agent/test/Test_Agent_StalledJobAgent.py,sha256=egqcddrpSMDQitJg7rR97klegBwliX4e0spPPaN6rJ0,2295
|
|
1142
1142
|
DIRAC/WorkloadManagementSystem/Client/CPUNormalization.py,sha256=txBgRfnTAY5KykpKRrK1jp5x4FInWjv-Rja4R7Dqdis,5423
|
|
1143
1143
|
DIRAC/WorkloadManagementSystem/Client/DownloadInputData.py,sha256=Ug2mhig5KbC1d4fYsVLpFhE5SvWhUJpVp7TuP8GxJxs,16285
|
|
1144
1144
|
DIRAC/WorkloadManagementSystem/Client/InputDataByProtocol.py,sha256=tjK6L8iNqWOBENcGJbG0yJsQYwGvFLRFcTMNnrusFAI,12837
|
|
@@ -1205,9 +1205,9 @@ DIRAC/WorkloadManagementSystem/FutureClient/JobMonitoringClient.py,sha256=3Mjq3h
|
|
|
1205
1205
|
DIRAC/WorkloadManagementSystem/FutureClient/JobStateUpdateClient.py,sha256=PG3JkQPgmPacjTLTCHTobZeKys4nxObs0D_Axfrl2Uw,6650
|
|
1206
1206
|
DIRAC/WorkloadManagementSystem/FutureClient/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
1207
1207
|
DIRAC/WorkloadManagementSystem/JobWrapper/JobExecutionCoordinator.py,sha256=Y64YnkrKklOkXnV5wKsgzBONFljVJ0ByFVUMFNkiGAU,2461
|
|
1208
|
-
DIRAC/WorkloadManagementSystem/JobWrapper/JobWrapper.py,sha256
|
|
1209
|
-
DIRAC/WorkloadManagementSystem/JobWrapper/JobWrapperOfflineTemplate.py,sha256=
|
|
1210
|
-
DIRAC/WorkloadManagementSystem/JobWrapper/JobWrapperTemplate.py,sha256=
|
|
1208
|
+
DIRAC/WorkloadManagementSystem/JobWrapper/JobWrapper.py,sha256=-I2BYiLsJqPOQbkcSX2ETqGydqg0IVg01UySRdHMkgA,74794
|
|
1209
|
+
DIRAC/WorkloadManagementSystem/JobWrapper/JobWrapperOfflineTemplate.py,sha256=NTt93clnLtbtlXTsBA4ecNppILYiD4s0Oxo1ywN7aqM,2490
|
|
1210
|
+
DIRAC/WorkloadManagementSystem/JobWrapper/JobWrapperTemplate.py,sha256=uVDmZ65NWTr48GHUZQ7MtUMGgfLzMG8P7ZnFXspynnA,3312
|
|
1211
1211
|
DIRAC/WorkloadManagementSystem/JobWrapper/JobWrapperUtilities.py,sha256=5w_4PMnaHhuexChADDvt1L9Ih1PstdUuYWObnlv9Dto,10072
|
|
1212
1212
|
DIRAC/WorkloadManagementSystem/JobWrapper/Watchdog.py,sha256=UWVDC_tWzlE9i5PsLycrRda4j3hWjaK1RnQVOvydg6U,38857
|
|
1213
1213
|
DIRAC/WorkloadManagementSystem/JobWrapper/__init__.py,sha256=e9Oa_ddNLweR3Lp_HOMK6WqqCWWj2SLPxF5UH4F19ic,61
|
|
@@ -1296,9 +1296,9 @@ DIRAC/tests/Workflow/Integration/exe-script.py,sha256=B_slYdTocEzqfQLRhwuPiLyYUn
|
|
|
1296
1296
|
DIRAC/tests/Workflow/Integration/helloWorld.py,sha256=tBgEHH3ZF7ZiTS57gtmm3DW-Qxgm_57HWHpM-Y8XSws,205
|
|
1297
1297
|
DIRAC/tests/Workflow/Regression/helloWorld.py,sha256=69eCgFuVSYo-mK3Dj2dw1c6g86sF5FksKCf8V2aGVoM,509
|
|
1298
1298
|
DIRAC/tests/Workflow/Regression/helloWorld.xml,sha256=xwydIcFTAHIX-YPfQfyxuQ7hzvIO3IhR3UAF7ORgkGg,5310
|
|
1299
|
-
dirac-9.0.
|
|
1300
|
-
dirac-9.0.
|
|
1301
|
-
dirac-9.0.
|
|
1302
|
-
dirac-9.0.
|
|
1303
|
-
dirac-9.0.
|
|
1304
|
-
dirac-9.0.
|
|
1299
|
+
dirac-9.0.14.dist-info/licenses/LICENSE,sha256=uyr4oV6jmjUeepXZPPjkJRwa5q5MrI7jqJz5sVXNblQ,32452
|
|
1300
|
+
dirac-9.0.14.dist-info/METADATA,sha256=Qn-KU8OTRd6X5FbEQe0094bZO7igRbHhIkukKHxKJjA,10039
|
|
1301
|
+
dirac-9.0.14.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
1302
|
+
dirac-9.0.14.dist-info/entry_points.txt,sha256=hupzIL8aVmjK3nn7RLKdhcaiPmLOiD3Kulh3CSDHKmw,16492
|
|
1303
|
+
dirac-9.0.14.dist-info/top_level.txt,sha256=RISrnN9kb_mPqmVu8_o4jF-DSX8-h6AcgfkO9cgfkHA,6
|
|
1304
|
+
dirac-9.0.14.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|