Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[9.0] Support selecting legacy adaptor client #7258

Merged
merged 2 commits into from
Nov 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions dirac.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,8 @@ DiracX
URL = https://diracx.invalid:8000
# A key used to have priviledged interactions with diracx. see
LegacyExchangeApiKey = diracx:legacy:InsecureChangeMe
# List of VOs which should use DiracX via the legacy compatibility mechanism
EnabledVOs = gridpp,cta
# List of VOs which should not use DiracX via the legacy compatibility mechanism
DisabledVOs = dteam,cta
}
### Registry section:
# Sections to register VOs, groups, users and hosts
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@ DIRAC_DEPRECATED_FAIL
If set, the use of functions or objects that are marked ``@deprecated`` will fail. Useful for example in continuous
integration tests against future versions of DIRAC

DIRAC_ENABLE_DIRACX_JOB_MONITORING
If set, calls the diracx job monitoring service. Off by default.

DIRAC_FEWER_CFG_LOCKS
If ``true`` or ``yes`` or ``on`` or ``1`` or ``y`` or ``t``, DIRAC will reduce the number of locks used when accessing the CS for better performance (default, ``no``).

Expand Down
2 changes: 1 addition & 1 deletion integration_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
"DIRAC_USE_JSON_ENCODE": None,
"INSTALLATION_BRANCH": "",
}
DIRACX_OPTIONS = ("DIRAC_ENABLE_DIRACX_JOB_MONITORING",)
DIRACX_OPTIONS = ()
DEFAULT_MODULES = {"DIRAC": Path(__file__).parent.absolute()}

# Static configuration
Expand Down
19 changes: 19 additions & 0 deletions src/DIRAC/ConfigurationSystem/Client/PathFinder.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,19 @@ def getServiceURLs(system, service=None, setup=False, failover=False):
return resList


def useLegacyAdapter(system, service=None) -> bool:
"""Should DiracX be used for this service via the legacy adapter mechanism

:param str system: system name or full name e.g.: Framework/ProxyManager
:param str service: service name, like 'ProxyManager'.

:return: bool -- True if DiracX should be used
"""
system, service = divideFullName(system, service)
value = gConfigurationData.extractOptionFromCFG(f"/DiracX/LegacyClientEnabled/{system}/{service}")
return (value or "no").lower() in ("y", "yes", "true", "1")


def getServiceURL(system, service=None, setup=False):
"""Generate url.

Expand Down Expand Up @@ -297,3 +310,9 @@ def getGatewayURLs(system="", service=None):
return False
gateways = List.randomize(List.fromChar(gateways, ","))
return [checkComponentURL(u, system, service) for u in gateways if u] if system and service else gateways


def getDisabledDiracxVOs() -> list[str]:
"""Get the list of VOs for which DiracX is enabled"""
vos = gConfigurationData.extractOptionFromCFG("/DiracX/DisabledVOs")
return List.fromChar(vos or "", ",")
fstagni marked this conversation as resolved.
Show resolved Hide resolved
5 changes: 4 additions & 1 deletion src/DIRAC/Core/Base/Client.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,10 @@ def _getRPC(self, rpc=None, url="", timeout=None):
timeout = self.timeout

self.__kwargs["timeout"] = timeout
rpc = RPCClientSelector(url, httpsClient=self.httpsClient, **self.__kwargs)

rpc = RPCClientSelector(
url, httpsClient=self.httpsClient, diracxClient=getattr(self, "diracxClient", None), **self.__kwargs
)
return rpc


Expand Down
10 changes: 9 additions & 1 deletion src/DIRAC/Core/Tornado/Client/ClientSelector.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import functools

from DIRAC import gLogger
from DIRAC.ConfigurationSystem.Client.PathFinder import getServiceURL
from DIRAC.ConfigurationSystem.Client.PathFinder import getServiceURL, useLegacyAdapter
from DIRAC.Core.DISET.RPCClient import RPCClient
from DIRAC.Core.DISET.TransferClient import TransferClient
from DIRAC.Core.Tornado.Client.TornadoClient import TornadoClient
Expand Down Expand Up @@ -54,6 +54,7 @@ def ClientSelector(disetClient, *args, **kwargs): # We use same interface as RP
# We detect if we need to use a specific class for the HTTPS client

tornadoClient = kwargs.pop("httpsClient", TornadoClient)
diracxClient = kwargs.pop("diracxClient", None)

# We have to make URL resolution BEFORE the RPCClient or TornadoClient to determine which one we want to use
# URL is defined as first argument (called serviceName) in RPCClient
Expand All @@ -65,6 +66,13 @@ def ClientSelector(disetClient, *args, **kwargs): # We use same interface as RP
# If we are not already given a URL, resolve it
if serviceName.startswith(("http", "dip")):
completeUrl = serviceName
elif useLegacyAdapter(serviceName):
sLog.debug(f"Using legacy adapter for service {serviceName}")
if diracxClient is None:
raise NotImplementedError(
"DiracX is enabled but no diracxClient is provided, do you need to update your client?"
)
return diracxClient()
else:
completeUrl = getServiceURL(serviceName)
sLog.debug(f"URL resolved: {completeUrl}")
Expand Down
4 changes: 2 additions & 2 deletions src/DIRAC/FrameworkSystem/scripts/dirac_login.py
Original file line number Diff line number Diff line change
Expand Up @@ -315,8 +315,8 @@ def loginWithCertificate(self):

# Get a token for use with diracx
vo = getVOMSVOForGroup(self.group)
enabledVOs = gConfig.getValue("/DiracX/EnabledVOs", [])
if vo in enabledVOs:
disabledVOs = gConfig.getValue("/DiracX/DisabledVOs", [])
if vo not in disabledVOs:
from diracx.core.utils import write_credentials # pylint: disable=import-error
from diracx.core.models import TokenResponse # pylint: disable=import-error
from diracx.core.preferences import DiracxPreferences # pylint: disable=import-error
Expand Down
4 changes: 2 additions & 2 deletions src/DIRAC/FrameworkSystem/scripts/dirac_proxy_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,8 +239,8 @@ def doTheMagic(self):
return resultProxyUpload

vo = Registry.getVOMSVOForGroup(self.__piParams.diracGroup)
enabledVOs = gConfig.getValue("/DiracX/EnabledVOs", [])
if vo in enabledVOs:
disabledVOs = gConfig.getValue("/DiracX/DisabledVOs", [])
if vo not in disabledVOs:
from diracx.core.utils import write_credentials # pylint: disable=import-error
from diracx.core.models import TokenResponse # pylint: disable=import-error
from diracx.core.preferences import DiracxPreferences # pylint: disable=import-error
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,21 @@
from DIRAC.Core.Utilities.DEncode import ignoreEncodeWarning
from DIRAC.Core.Utilities.JEncode import strToIntDict

try:
from DIRAC.WorkloadManagementSystem.FutureClient.JobMonitoringClient import (
JobMonitoringClient as futureJobMonitoringClient,
)
except ImportError:
futureJobMonitoringClient = None


@createClient("WorkloadManagement/JobMonitoring")
class JobMonitoringClient(Client):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.setServer("WorkloadManagement/JobMonitoring")

if os.getenv("DIRAC_ENABLE_DIRACX_JOB_MONITORING", "No").lower() in ("yes", "true"):
from DIRAC.WorkloadManagementSystem.FutureClient.JobMonitoringClient import (
JobMonitoringClient as futureJobMonitoringClient,
)

httpsClient = futureJobMonitoringClient
diracxClient = futureJobMonitoringClient

@ignoreEncodeWarning
def getJobsStatus(self, jobIDs):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,8 @@ def _getFromClient(self, fileId, token, fileSize, fileHelper=None, data=""):
credDict = self.getRemoteCredentials()
vo = Registry.getVOForGroup(credDict["group"])

enabledVOs = gConfig.getValue("/DiracX/EnabledVOs", [])
if self._useDiracXBackend and vo in enabledVOs:
disabledVOs = gConfig.getValue("/DiracX/DisabledVOs", [])
if self._useDiracXBackend and vo not in disabledVOs:
from DIRAC.FrameworkSystem.Utilities.diracx import TheImpersonator
from diracx.client.models import SandboxInfo # pylint: disable=import-error

Expand Down
43 changes: 43 additions & 0 deletions tests/Jenkins/dirac-cfg-setup-diracx.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#!/usr/bin/env python
import argparse
import os

import DIRAC
from DIRAC.Core.Utilities.ReturnValues import returnValueOrRaise


def parse_args():
parser = argparse.ArgumentParser(description="Setup DIRAC CS for running integration tests with DiracX")
parser.add_argument("--disable-vo", nargs="+", help="Disable a VO", default=[])
parser.add_argument("--url", help="URL of the DiracX services")
parser.add_argument("--credentials-dir", help="Directory where hostcert.pem/hostkey.pem can be found")
args = parser.parse_args()

DIRAC.initialize(
host_credentials=(
f"{args.credentials_dir}/hostcert.pem",
f"{args.credentials_dir}/hostkey.pem",
)
)

main(args.url, args.disable_vo)


def main(url: str, disabled_vos: list[str]):
from DIRAC.ConfigurationSystem.Client.CSAPI import CSAPI

csAPI = CSAPI()

returnValueOrRaise(csAPI.createSection("DiracX"))

if url:
returnValueOrRaise(csAPI.setOption("DiracX/URL", url))

if disabled_vos:
returnValueOrRaise(csAPI.setOption("DiracX/DisabledVOs", ",".join(disabled_vos)))

returnValueOrRaise(csAPI.commit())


if __name__ == "__main__":
parse_args()
15 changes: 13 additions & 2 deletions tests/Jenkins/dirac_ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -136,9 +136,8 @@ installSite() {
echo "==> Done installing, now configuring"
source "${SERVERINSTALLDIR}/bashrc"
configureArgs=()
if [[ -n "${TEST_DIRACX:-}" ]]; then
if [[ "${TEST_DIRACX:-}" = "Yes" ]]; then
configureArgs+=("--LegacyExchangeApiKey=diracx:legacy:InsecureChangeMe")
configureArgs+=("--DiracxUrl=${DIRACX_URL}")
fi
if ! dirac-configure --cfg "${SERVERINSTALLDIR}/install.cfg" "${configureArgs[@]}" "${DEBUG}"; then
echo "ERROR: dirac-configure failed" >&2
Expand All @@ -150,6 +149,18 @@ installSite() {
exit 1
fi

echo "==> Setting up DiracX"
diracxSetupArgs=("--credentials-dir" "$SERVERINSTALLDIR/etc/grid-security")
if [[ "${TEST_DIRACX:-}" = "Yes" ]]; then
diracxSetupArgs+=("--url=${DIRACX_URL}")
else
diracxSetupArgs+=("--disable-vo" "vo")
fi
if ! python "${TESTCODE}/DIRAC/tests/Jenkins/dirac-cfg-setup-diracx.py" "${diracxSetupArgs[@]}"; then
echo "ERROR: dirac-cfg-setup-diracx.py failed" >&2
exit 1
fi

echo "==> Completed installation"

}
Expand Down
2 changes: 1 addition & 1 deletion tests/Jenkins/utilities.sh
Original file line number Diff line number Diff line change
Expand Up @@ -614,7 +614,7 @@ diracProxies() {
# And make sure it was synced
if [[ -n $TEST_DIRACX ]]; then
echo "Waiting for for DiracX to be available" >&2
for i in {1..100}; do
for i in {1..10}; do
if dirac-login -C "${SERVERINSTALLDIR}/user/client.pem" -K "${SERVERINSTALLDIR}/user/client.key" -T 72 "${DEBUG}"; then
break
fi
Expand Down
Loading