Skip to content
14 changes: 11 additions & 3 deletions src/DIRAC/ConfigurationSystem/private/Modificator.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
""" This is the guy that actually modifies the content of the CS
"""
import zlib
import difflib
import datetime
import difflib
import zlib

from diraccfg import CFG
from DIRAC.Core.Utilities import List

from DIRAC import S_ERROR
from DIRAC.ConfigurationSystem.Client.ConfigurationData import gConfigurationData
from DIRAC.Core.Security.ProxyInfo import getProxyInfo
from DIRAC.Core.Utilities import List
from DIRAC.FrameworkSystem.Utilities.diracx import diracxVerifyConfig


class Modificator:
Expand Down Expand Up @@ -239,6 +242,11 @@ def __str__(self):
return str(self.cfgData)

def commit(self):
retOpt = self.getValue("/Systems/Configuration/Services/Server/VerifyDiracXSyncOnCommit")
if retOpt == "True":
resVerif = diracxVerifyConfig(self.cfgData)
if not resVerif["OK"]:
return S_ERROR(resVerif["Message"])
compressedData = zlib.compress(str(self.cfgData).encode(), 9)
return self.rpcClient.commitNewData(compressedData)

Expand Down
51 changes: 41 additions & 10 deletions src/DIRAC/FrameworkSystem/Utilities/diracx.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,25 @@
import requests

from cachetools import TTLCache, LRUCache, cached
from cachetools.keys import hashkey
import os
import re
import subprocess
from collections.abc import Generator
from contextlib import contextmanager
from pathlib import Path
from tempfile import NamedTemporaryFile
import tempfile
from typing import Any
from collections.abc import Generator
from DIRAC import gConfig
from DIRAC.ConfigurationSystem.Client.Helpers import Registry
from contextlib import contextmanager

import requests
from cachetools import LRUCache, TTLCache, cached
from cachetools.keys import hashkey
from diracx.cli.internal.legacy import _apply_fixes
from diracx.core.config.schema import Config as DiracxConfig
from diracx.core.models import TokenResponse
from diracx.core.preferences import DiracxPreferences

from diracx.core.utils import write_credentials
from pydantic import ValidationError

from diracx.core.models import TokenResponse
from DIRAC import S_ERROR, S_OK, gConfig
from DIRAC.ConfigurationSystem.Client.Helpers import Registry

try:
from diracx.client.sync import SyncDiracClient
Expand Down Expand Up @@ -104,3 +109,29 @@ def TheImpersonator(credDict: dict[str, Any], *, source: str = "") -> Generator[
client.__enter__()
diracx_client_cache[token_location] = client
yield client


def diracxVerifyConfig(cfgData):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This won't work for converting the CS, see https://diracx.diracgrid.org/en/latest/admin/how-to/install/convert-cs/ for the procedure.

Running it in a subproces with a timeout is probably a good idea.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah indeed. Then I will call the diracx cli to validate the config.

"""Verify CS config using DiracX config validation

Args:
cfgData: CFG data

Returns:
S_OK | S_ERROR: Value: diracx Config validation
"""
os.environ["DIRAC_COMPAT_ENABLE_CS_CONVERSION"] = "true"
with tempfile.NamedTemporaryFile() as temp_cfg:
with tempfile.NamedTemporaryFile() as temp_diracx_cfg:
cfgData.writeToFile(temp_cfg.name)
cmd = ["dirac", "internal", "legacy", "cs-sync", temp_cfg.name, temp_diracx_cfg.name]
res = subprocess.run(cmd, capture_output=True, text=True, timeout=15)
os.environ.pop("DIRAC_COMPAT_ENABLE_CS_CONVERSION")
if res.returncode == 0:
return S_OK(res.stdout)
else:
err = res.stderr.strip()
match = re.search(r"(ValidationError:.*)", err, flags=re.DOTALL)
if match:
return S_ERROR(match.group(1))
return S_ERROR(err)
Loading