DIRAC 9.0.11__py3-none-any.whl → 9.0.13__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- DIRAC/AccountingSystem/Client/Types/Network.py +8 -8
- DIRAC/AccountingSystem/Client/Types/PilotSubmission.py +3 -3
- DIRAC/ConfigurationSystem/Client/CSAPI.py +11 -1
- DIRAC/ConfigurationSystem/ConfigTemplate.cfg +3 -0
- DIRAC/ConfigurationSystem/private/Modificator.py +11 -3
- DIRAC/DataManagementSystem/Client/FTS3Job.py +1 -0
- DIRAC/FrameworkSystem/DB/InstalledComponentsDB.py +3 -2
- DIRAC/FrameworkSystem/Utilities/MonitoringUtilities.py +1 -1
- DIRAC/FrameworkSystem/Utilities/diracx.py +41 -10
- DIRAC/FrameworkSystem/scripts/dirac_uninstall_component.py +1 -0
- DIRAC/MonitoringSystem/Service/WebAppHandler.py +12 -3
- DIRAC/Resources/IdProvider/IdProviderFactory.py +4 -2
- DIRAC/Resources/IdProvider/tests/Test_IdProviderFactory.py +7 -0
- DIRAC/Resources/Storage/FileStorage.py +121 -2
- {dirac-9.0.11.dist-info → dirac-9.0.13.dist-info}/METADATA +3 -2
- {dirac-9.0.11.dist-info → dirac-9.0.13.dist-info}/RECORD +20 -20
- {dirac-9.0.11.dist-info → dirac-9.0.13.dist-info}/WHEEL +0 -0
- {dirac-9.0.11.dist-info → dirac-9.0.13.dist-info}/entry_points.txt +0 -0
- {dirac-9.0.11.dist-info → dirac-9.0.13.dist-info}/licenses/LICENSE +0 -0
- {dirac-9.0.11.dist-info → dirac-9.0.13.dist-info}/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""Accounting class to stores network metrics gathered by perfSONARs.
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Filled by "Accounting/Network" agent
|
|
4
4
|
"""
|
|
5
5
|
|
|
6
6
|
from DIRAC.AccountingSystem.Client.Types.BaseAccountingType import BaseAccountingType
|
|
@@ -16,12 +16,12 @@ class Network(BaseAccountingType):
|
|
|
16
16
|
|
|
17
17
|
# IPv6 address has up to 45 chars
|
|
18
18
|
self.definitionKeyFields = [
|
|
19
|
-
("SourceIP", "VARCHAR(
|
|
20
|
-
("DestinationIP", "VARCHAR(
|
|
21
|
-
("SourceHostName", "VARCHAR(
|
|
22
|
-
("DestinationHostName", "VARCHAR(
|
|
23
|
-
("Source", "VARCHAR(
|
|
24
|
-
("Destination", "VARCHAR(
|
|
19
|
+
("SourceIP", "VARCHAR(64)"),
|
|
20
|
+
("DestinationIP", "VARCHAR(64)"),
|
|
21
|
+
("SourceHostName", "VARCHAR(255)"),
|
|
22
|
+
("DestinationHostName", "VARCHAR(255)"),
|
|
23
|
+
("Source", "VARCHAR(255)"),
|
|
24
|
+
("Destination", "VARCHAR(255)"),
|
|
25
25
|
]
|
|
26
26
|
|
|
27
27
|
self.definitionAccountingFields = [
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""Accounting Type for Pilot Submission
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Filled by the "WorkloadManagement/SiteDirector" agent(s)
|
|
4
4
|
"""
|
|
5
5
|
|
|
6
6
|
from DIRAC.AccountingSystem.Client.Types.BaseAccountingType import BaseAccountingType
|
|
@@ -13,7 +13,7 @@ class PilotSubmission(BaseAccountingType):
|
|
|
13
13
|
super().__init__()
|
|
14
14
|
|
|
15
15
|
self.definitionKeyFields = [
|
|
16
|
-
("HostName", "VARCHAR(
|
|
16
|
+
("HostName", "VARCHAR(255)"),
|
|
17
17
|
("SiteDirector", "VARCHAR(100)"),
|
|
18
18
|
("Site", "VARCHAR(100)"),
|
|
19
19
|
("CE", "VARCHAR(100)"),
|
|
@@ -456,13 +456,23 @@ class CSAPI:
|
|
|
456
456
|
gLogger.error("User is not registered: ", repr(username))
|
|
457
457
|
return S_OK(False)
|
|
458
458
|
for prop in properties:
|
|
459
|
-
if prop
|
|
459
|
+
if prop in ["Groups", "AffiliationEnds"]:
|
|
460
460
|
continue
|
|
461
461
|
prevVal = self.__csMod.getValue(f"{self.__baseSecurity}/Users/{username}/{prop}")
|
|
462
462
|
if not prevVal or prevVal != properties[prop]:
|
|
463
463
|
gLogger.info(f"Setting {prop} property for user {username} to {properties[prop]}")
|
|
464
464
|
self.__csMod.setOptionValue(f"{self.__baseSecurity}/Users/{username}/{prop}", properties[prop])
|
|
465
465
|
modifiedUser = True
|
|
466
|
+
if properties.get("AffiliationEnds", None):
|
|
467
|
+
user_affiliationends_section = f"{self.__baseSecurity}/Users/{username}/AffiliationEnds"
|
|
468
|
+
# add the section for AffiliationEnds
|
|
469
|
+
res = gConfig.getSections(user_affiliationends_section)
|
|
470
|
+
if not res["OK"]:
|
|
471
|
+
self.__csMod.createSection(user_affiliationends_section)
|
|
472
|
+
# now set value VO = end date
|
|
473
|
+
for vo, end_date in properties["AffiliationEnds"].items():
|
|
474
|
+
self.__csMod.setOptionValue(f"{user_affiliationends_section}/{vo}", end_date)
|
|
475
|
+
modifiedUser = True
|
|
466
476
|
if "Groups" in properties:
|
|
467
477
|
result = self.listGroups()
|
|
468
478
|
if not result["OK"]:
|
|
@@ -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,6 +1,7 @@
|
|
|
1
1
|
"""
|
|
2
2
|
Classes and functions for easier management of the InstalledComponents database
|
|
3
3
|
"""
|
|
4
|
+
|
|
4
5
|
import re
|
|
5
6
|
import datetime
|
|
6
7
|
|
|
@@ -90,7 +91,7 @@ class Host(componentsBase):
|
|
|
90
91
|
__table_args__ = {"mysql_engine": "InnoDB", "mysql_charset": "utf8mb4"}
|
|
91
92
|
|
|
92
93
|
hostID = Column("HostID", Integer, primary_key=True)
|
|
93
|
-
hostName = Column("HostName", String(
|
|
94
|
+
hostName = Column("HostName", String(255), nullable=False)
|
|
94
95
|
cpu = Column("CPU", String(64), nullable=False)
|
|
95
96
|
installationList = relationship("InstalledComponent", backref="installationHost")
|
|
96
97
|
|
|
@@ -219,7 +220,7 @@ class HostLogging(componentsBase):
|
|
|
219
220
|
__tablename__ = "HostLogging"
|
|
220
221
|
__table_args__ = {"mysql_engine": "InnoDB", "mysql_charset": "utf8mb4"}
|
|
221
222
|
|
|
222
|
-
hostName = Column("HostName", String(
|
|
223
|
+
hostName = Column("HostName", String(255), nullable=False, primary_key=True)
|
|
223
224
|
# status
|
|
224
225
|
DIRAC = Column("DIRACVersion", String(64))
|
|
225
226
|
Extension = Column("Extension", String(512))
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""
|
|
2
2
|
Utilities for ComponentMonitoring features
|
|
3
3
|
"""
|
|
4
|
+
|
|
4
5
|
import datetime
|
|
5
6
|
import socket
|
|
6
7
|
|
|
@@ -30,7 +31,6 @@ def monitorInstallation(componentType, system, component, module=None, cpu=None,
|
|
|
30
31
|
|
|
31
32
|
if not hostname:
|
|
32
33
|
hostname = socket.getfqdn()
|
|
33
|
-
hostname = hostname[0:64]
|
|
34
34
|
instance = component[0:32]
|
|
35
35
|
|
|
36
36
|
result = monitoringClient.installationExists(
|
|
@@ -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)
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
The WebAppHandler module provides a class to handle web requests from the DIRAC WebApp.
|
|
3
3
|
It is not indented to be used in diracx
|
|
4
4
|
"""
|
|
5
|
+
|
|
5
6
|
from DIRAC import S_ERROR, S_OK
|
|
6
7
|
from DIRAC.ConfigurationSystem.Client.Helpers.Operations import Operations
|
|
7
8
|
from DIRAC.ConfigurationSystem.Client.Helpers.Resources import getSites
|
|
@@ -527,13 +528,21 @@ class WebAppHandler(RequestHandler):
|
|
|
527
528
|
ops = Operations()
|
|
528
529
|
# Prepare the standard structure now within the resultDict dictionary
|
|
529
530
|
resultDict = {}
|
|
530
|
-
|
|
531
|
+
# Reconstruct just the values list
|
|
532
|
+
trList = [
|
|
533
|
+
[str(item) if not isinstance(item, int) else item for item in trans_dict.values()]
|
|
534
|
+
for trans_dict in res["Value"]
|
|
535
|
+
]
|
|
536
|
+
|
|
531
537
|
# Create the total records entry
|
|
532
538
|
nTrans = len(trList)
|
|
533
539
|
resultDict["TotalRecords"] = nTrans
|
|
534
540
|
# Create the ParameterNames entry
|
|
535
|
-
|
|
536
|
-
|
|
541
|
+
try:
|
|
542
|
+
resultDict["ParameterNames"] = list(res["Value"][0].keys())
|
|
543
|
+
except IndexError:
|
|
544
|
+
# As this list is a reference to the list in the DB, we cannot extend it, therefore copy it
|
|
545
|
+
resultDict["ParameterNames"] = list(cls.transformationDB.TRANSPARAMS)
|
|
537
546
|
# Add the job states to the ParameterNames entry
|
|
538
547
|
taskStateNames = TASKS_STATE_NAMES + ops.getValue("Transformations/AdditionalTaskStates", [])
|
|
539
548
|
resultDict["ParameterNames"] += ["Jobs_" + x for x in taskStateNames]
|
|
@@ -75,8 +75,10 @@ class IdProviderFactory:
|
|
|
75
75
|
|
|
76
76
|
if client_name_prefix:
|
|
77
77
|
client_name_prefix = client_name_prefix + "_"
|
|
78
|
-
|
|
79
|
-
|
|
78
|
+
if f"{client_name_prefix}client_id" in pDict:
|
|
79
|
+
pDict["client_id"] = pDict[f"{client_name_prefix}client_id"]
|
|
80
|
+
if f"{client_name_prefix}client_secret" in pDict:
|
|
81
|
+
pDict["client_secret"] = pDict[f"{client_name_prefix}client_secret"]
|
|
80
82
|
|
|
81
83
|
pDict.update(kwargs)
|
|
82
84
|
pDict["ProviderName"] = name
|
|
@@ -63,6 +63,12 @@ Resources
|
|
|
63
63
|
client_secret = IdP_client_secret
|
|
64
64
|
scope = openid+profile+offline_access+eduperson_entitlement
|
|
65
65
|
}
|
|
66
|
+
SomeIdP3.partial
|
|
67
|
+
{
|
|
68
|
+
ProviderType = OAuth2
|
|
69
|
+
issuer = https://and-another-idp.url/
|
|
70
|
+
scope = openid+profile+offline_access+eduperson_entitlement
|
|
71
|
+
}
|
|
66
72
|
}
|
|
67
73
|
}
|
|
68
74
|
"""
|
|
@@ -77,6 +83,7 @@ idps = IdProviderFactory()
|
|
|
77
83
|
("SomeIdP1.2", {"OK": True}, "https://idp.url/", "IdP_client_id2", "IdP_client_secret"),
|
|
78
84
|
("SomeIdP2", {"OK": True}, "https://another-idp.url/", "IdP_client_id1", "IdP_client_secret"),
|
|
79
85
|
("SomeIdP3", {"OK": True}, "https://and-another-idp.url/", "IdP_client_id3", "IdP_client_secret"),
|
|
86
|
+
("SomeIdP3.partial", {"OK": True}, "https://and-another-idp.url/", None, None),
|
|
80
87
|
# Try to get an unknown DIRAC client
|
|
81
88
|
("DIRACUnknown", {"OK": False, "Message": "DIRACUnknown does not exist"}, None, None, None),
|
|
82
89
|
],
|
|
@@ -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)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: DIRAC
|
|
3
|
-
Version: 9.0.
|
|
3
|
+
Version: 9.0.13
|
|
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.13
|
|
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"
|
|
@@ -12,9 +12,9 @@ DIRAC/AccountingSystem/Client/__init__.py,sha256=dT6KQbA-0PPotnu-T_ofVcW-HmuRL3Q
|
|
|
12
12
|
DIRAC/AccountingSystem/Client/Types/BaseAccountingType.py,sha256=NrH2ywkKq7vLs7voMH0XEsL7OOanbMWxeRjT-Kd9BNk,6183
|
|
13
13
|
DIRAC/AccountingSystem/Client/Types/DataOperation.py,sha256=LTklg_czWwjYMZktswD-JtnnyV8VTQ1SC_d9ejIBvRs,1224
|
|
14
14
|
DIRAC/AccountingSystem/Client/Types/Job.py,sha256=oBwd_U2HK0Ej9iEJFUcTmmdyFn1nJWQ_k4ZbAkgC6Dc,2176
|
|
15
|
-
DIRAC/AccountingSystem/Client/Types/Network.py,sha256=
|
|
15
|
+
DIRAC/AccountingSystem/Client/Types/Network.py,sha256=qrK6Wm0g4T2kuIMBiljnF_FUUOecMXge22wGnSeA7Y4,1164
|
|
16
16
|
DIRAC/AccountingSystem/Client/Types/Pilot.py,sha256=6nCIjelk2-GRUXwrakPg9l3YV20QJtrz-V52Tm8BHJ0,634
|
|
17
|
-
DIRAC/AccountingSystem/Client/Types/PilotSubmission.py,sha256=
|
|
17
|
+
DIRAC/AccountingSystem/Client/Types/PilotSubmission.py,sha256=mImBR6IV5G_usxrLBo45FEf8fF6ehQuJ4Wws9jQaXsg,1123
|
|
18
18
|
DIRAC/AccountingSystem/Client/Types/StorageOccupancy.py,sha256=8UOSUQK9xeH7ksobmQYIADyTy-_dhRSP2WYYG96qXT4,1100
|
|
19
19
|
DIRAC/AccountingSystem/Client/Types/WMSHistory.py,sha256=JI1v4BUU64sumPfSBya5v6FSZ1yLnMWura32iUqyr5A,1341
|
|
20
20
|
DIRAC/AccountingSystem/Client/Types/__init__.py,sha256=xTNU0D41kHNeg1sJOzzCTBuJdGjkw_gf3OCrJo4MYF0,52
|
|
@@ -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
|
|
@@ -52,7 +52,7 @@ DIRAC/ConfigurationSystem/Agent/RucioSynchronizerAgent.py,sha256=6gJ7MXsxkp0ig2b
|
|
|
52
52
|
DIRAC/ConfigurationSystem/Agent/VOMS2CSAgent.py,sha256=QOqFMOIfv5_g2xW_4XnMCjFeXGERLfCfB-ANyu__LYM,11520
|
|
53
53
|
DIRAC/ConfigurationSystem/Agent/__init__.py,sha256=bnNO28LCttSJYSCjB66MvfANnT4NHdWqFMe3fMXbeAM,37
|
|
54
54
|
DIRAC/ConfigurationSystem/Agent/test/Test_Bdii2CS.py,sha256=0lkJ25MooUAe0kPJRH5o2skWxx-99V1rdfzeyGZfvxc,5467
|
|
55
|
-
DIRAC/ConfigurationSystem/Client/CSAPI.py,sha256=
|
|
55
|
+
DIRAC/ConfigurationSystem/Client/CSAPI.py,sha256=Kx38hNHO95iqdnk9UOohU3-BIWFf8Hskyj3IB4BEguA,37224
|
|
56
56
|
DIRAC/ConfigurationSystem/Client/CSCLI.py,sha256=PQXYq3j7zFlKwT7k0nzlvuneBbfc_UxDUdMhS19RzdE,18739
|
|
57
57
|
DIRAC/ConfigurationSystem/Client/CSShellCLI.py,sha256=dlkGA-2-YJV8mwllJ2qG8_dvQfGsvfp953HilhkyKUs,7696
|
|
58
58
|
DIRAC/ConfigurationSystem/Client/Config.py,sha256=b8UBxKSJ3ZXVpIDGVXPR95dPs4RApEiLtqdN3fDo22k,524
|
|
@@ -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
|
|
@@ -508,7 +508,7 @@ DIRAC/FrameworkSystem/Client/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NM
|
|
|
508
508
|
DIRAC/FrameworkSystem/Client/test/Test_ComponentInstaller.py,sha256=OUIbwU5ypLpSDA-LhSlK-_Z3wPV_ZBMk5n4Y_jiipd0,505
|
|
509
509
|
DIRAC/FrameworkSystem/DB/AuthDB.py,sha256=QLotpINMq45FNoFO2AV3OH5Ij5i__HHk-p-m-b_ieaQ,11938
|
|
510
510
|
DIRAC/FrameworkSystem/DB/AuthDB.sql,sha256=tcAnRmBBEDxljAXILp8tlLzuEb7vOoN190KQK7NSbQQ,95
|
|
511
|
-
DIRAC/FrameworkSystem/DB/InstalledComponentsDB.py,sha256=
|
|
511
|
+
DIRAC/FrameworkSystem/DB/InstalledComponentsDB.py,sha256=_zVMmu9SeHiiKQH2qkuguBvQMAyrv99BPotDD3P_0AQ,43159
|
|
512
512
|
DIRAC/FrameworkSystem/DB/InstalledComponentsDB.sql,sha256=-LFjjn1gRQo7zDOclKmFwmbZi_lXXnx_B17cZPLBUak,113
|
|
513
513
|
DIRAC/FrameworkSystem/DB/ProxyDB.py,sha256=wt72y-ZtHyes1oLGgB-LiLuyZRNBelmCaEijad3raxI,39934
|
|
514
514
|
DIRAC/FrameworkSystem/DB/ProxyDB.sql,sha256=QwWe_mRX_NbZQVBo3TzA60L3FemI-oLY8G7_4uRFPzU,96
|
|
@@ -531,10 +531,10 @@ DIRAC/FrameworkSystem/Service/TornadoTokenManagerHandler.py,sha256=9DnxtK0Tam_9W
|
|
|
531
531
|
DIRAC/FrameworkSystem/Service/TornadoUserProfileManagerHandler.py,sha256=9z8Vky8YJ0reR_5E6RtxStakfg22qiGCvq-tUjojRzo,559
|
|
532
532
|
DIRAC/FrameworkSystem/Service/UserProfileManagerHandler.py,sha256=DyZFvqFeKjxVYNXqGYLkTlYgj3raUsfsb68GE4FX5x4,5707
|
|
533
533
|
DIRAC/FrameworkSystem/Service/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
534
|
-
DIRAC/FrameworkSystem/Utilities/MonitoringUtilities.py,sha256=
|
|
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
|
|
@@ -592,7 +592,7 @@ DIRAC/FrameworkSystem/scripts/dirac_start_component.py,sha256=nlCSTjG_w57t4W2vlV
|
|
|
592
592
|
DIRAC/FrameworkSystem/scripts/dirac_status_component.py,sha256=KbNYSyHLZueVNLBbFHNnl7MF5gWR2JTie13GH6tlIfQ,1658
|
|
593
593
|
DIRAC/FrameworkSystem/scripts/dirac_stop_component.py,sha256=RJJy63ilUEV5qyP_r2iXAGytt5TftAM72xgD1vZdpJs,1272
|
|
594
594
|
DIRAC/FrameworkSystem/scripts/dirac_sys_sendmail.py,sha256=lJ6OO_vkaSVhXp_p79LYTZoq9jT5qLU0qXOfFEgK9fw,2453
|
|
595
|
-
DIRAC/FrameworkSystem/scripts/dirac_uninstall_component.py,sha256=
|
|
595
|
+
DIRAC/FrameworkSystem/scripts/dirac_uninstall_component.py,sha256=LIXwHPan_xp-ewZbHPbZvoabQlvwTP4GC2PPaopGeGQ,2798
|
|
596
596
|
DIRAC/Interfaces/__init__.py,sha256=hycApm2mNnIWcdIzoOKQZLa8-LpSpfG2jdfgyKGN9Gg,34
|
|
597
597
|
DIRAC/Interfaces/API/Dirac.py,sha256=alMGB5YV2Oyo44G2k_jdSSvHRhZz0WmN3bMBeXgN11I,94619
|
|
598
598
|
DIRAC/Interfaces/API/DiracAdmin.py,sha256=PDwWl1KCckL2xhLodeWJhVS4ZondNvfdbTUEE3pukXA,28135
|
|
@@ -701,7 +701,7 @@ DIRAC/MonitoringSystem/DB/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJW
|
|
|
701
701
|
DIRAC/MonitoringSystem/DB/test/Test_monitoringdb.py,sha256=Jf4NZgb9V6U4DYk4SCLVoTqxJVBYsj49rIaYB7e6qxw,2788
|
|
702
702
|
DIRAC/MonitoringSystem/Service/MonitoringHandler.py,sha256=JGN1MUsxP8swTuIa4qdPvo-O4UoA6TkxjfDZ1sC6L2w,12332
|
|
703
703
|
DIRAC/MonitoringSystem/Service/TornadoMonitoringHandler.py,sha256=06gIHrrLJTgI-vnCHAGsDDjZrRwJaMsa8ESsdWy0Ir8,1550
|
|
704
|
-
DIRAC/MonitoringSystem/Service/WebAppHandler.py,sha256=
|
|
704
|
+
DIRAC/MonitoringSystem/Service/WebAppHandler.py,sha256=mm414IeI9hLTAQgugrqMiFVqM0kIfLYiBt93xgDuI4E,23459
|
|
705
705
|
DIRAC/MonitoringSystem/Service/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
706
706
|
DIRAC/MonitoringSystem/private/DBUtils.py,sha256=bBEJoy3KCaYi7tIAmNdCIUF5K5-oJAS3qJn0ngpo-HQ,7163
|
|
707
707
|
DIRAC/MonitoringSystem/private/MainReporter.py,sha256=a1yTBMA_wQIzohugtV_MXxiwV7Qo1e2bGrJQZFO93Go,3433
|
|
@@ -949,13 +949,13 @@ DIRAC/Resources/Computing/test/Test_SSHComputingElement.py,sha256=ahYUZ9hySaEXik
|
|
|
949
949
|
DIRAC/Resources/Computing/test/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
950
950
|
DIRAC/Resources/IdProvider/CheckInIdProvider.py,sha256=Tq8ENK6yhC7Tl6JkTF1q8mCOrFRfsN3ediF251iU4oM,1163
|
|
951
951
|
DIRAC/Resources/IdProvider/IAMIdProvider.py,sha256=kk2ty2mLevxGmJRBpLYlQXce_vy4cxp-dO2w7b1rCz0,822
|
|
952
|
-
DIRAC/Resources/IdProvider/IdProviderFactory.py,sha256=
|
|
952
|
+
DIRAC/Resources/IdProvider/IdProviderFactory.py,sha256=mt8Y9mfGXCfFZQ0hlQl4cDHB8vkR-dbFVjnxiNCPRmw,4366
|
|
953
953
|
DIRAC/Resources/IdProvider/OAuth2IdProvider.py,sha256=smoGhSD1JsyjJDot9XmMUmT7fw8kcfS3w392s2Lg9P8,23650
|
|
954
954
|
DIRAC/Resources/IdProvider/Utilities.py,sha256=bHF-aNtOapEN7Z18XKOFfAcXCHceLbEWU9dOrKeHxDo,1785
|
|
955
955
|
DIRAC/Resources/IdProvider/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
956
956
|
DIRAC/Resources/IdProvider/tests/IdProviderTestUtilities.py,sha256=dYNmgBAE1QhTXHrUX4O5yC_qCF--vg45DN4PC52ZoAA,372
|
|
957
957
|
DIRAC/Resources/IdProvider/tests/Test_IdProvider.py,sha256=8C9k5w2dsncr87sUc2hdNfOEe9DfN5-CXfUFeivtH1A,5649
|
|
958
|
-
DIRAC/Resources/IdProvider/tests/Test_IdProviderFactory.py,sha256=
|
|
958
|
+
DIRAC/Resources/IdProvider/tests/Test_IdProviderFactory.py,sha256=9zJYGrL7d8jmGUfhfD6izbiVST_iA74rOpsCCTCfAAk,5110
|
|
959
959
|
DIRAC/Resources/IdProvider/tests/Test_IdProviderUtilities.py,sha256=qqc7gaiIZs9mrHL9bq-gmH0oWkKAeLVy5D9S2_JBRG0,4861
|
|
960
960
|
DIRAC/Resources/LogBackends/AbstractBackend.py,sha256=a8CymVZ1Ew8IDDnOh_4pkO70vPNf8Of0d8cWU3gwb0Y,5269
|
|
961
961
|
DIRAC/Resources/LogBackends/ElasticSearchBackend.py,sha256=FANKSEKw21oW8aIQJ2HTYpIfqH0rFaTKBnp2fRssA1M,3113
|
|
@@ -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
|
|
@@ -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.13.dist-info/licenses/LICENSE,sha256=uyr4oV6jmjUeepXZPPjkJRwa5q5MrI7jqJz5sVXNblQ,32452
|
|
1300
|
+
dirac-9.0.13.dist-info/METADATA,sha256=Eu9YzyRmS-06O5_AZvvlySLlviqBE2p3RFezFlPqTSI,10039
|
|
1301
|
+
dirac-9.0.13.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
1302
|
+
dirac-9.0.13.dist-info/entry_points.txt,sha256=hupzIL8aVmjK3nn7RLKdhcaiPmLOiD3Kulh3CSDHKmw,16492
|
|
1303
|
+
dirac-9.0.13.dist-info/top_level.txt,sha256=RISrnN9kb_mPqmVu8_o4jF-DSX8-h6AcgfkO9cgfkHA,6
|
|
1304
|
+
dirac-9.0.13.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|