Skip to content

Commit 7107442

Browse files
Robin VAN DE MERGHELRobin-Van-de-Merghel
authored andcommitted
feat: Add legacy adaptor in CI
Squashed commits: [7ae3428] fix: Fixed to support better other branches [2066814] feat: Add diracx repo choice in the integration test [7859c6b] fix: Use JobStateUpdateClient instead of deactivating it [e3b1d68] fix: Resolved dirac-proxy-init issue with multi-VO [d2f99c0] fix: Resolved bug for setJobAttributes [fe09e19] fix: Fixed ClientWMS test and reversed TEST_DIRACX flag [1447a20] fix: Use opensearch db for job parametersDB [f6116aa] fix: Made mariadb works better [c4ab3f2] fix: Fixed CI to use sandoxes [a5a02bc] fix: Activate job endpoints in CI [a1bc1b1] fix: Applied changes to the ci workflows [282efcb] refactor: Moved down diracx installation to fix auth [ac22d9d] feat: Add DiracX tests into DIRAC CI, and use only latest tag. [0ebf454] fix: Moved up futureServices argument to prevent "Missing mandatory /DiracX/URL configuration" [d98b705] fix: Fixed small bug and refactored ClientSelector [8ce234c] fix: Small fixes with docker compose cmd and removed grep [08d9eb1] fix: Add filters to remove 'Client' from services name [bc44891] fix: Remove error when a future client is not available to warn instead [a1f553d] fix: Changed to make the legacy adaptor automatic. [3fb8c4d] fix: Fixed destroy command to support MacOSX [42df58d] fix: Going back, removed CI, and going to add it to DiracX [28b9789] fix: Small fix (forgot to change to docker**compose) [61384af] feat: Add in CI new legacy adapted services. [a3a7f5b] feat: Add legacy adaptor in CI
1 parent d8de07b commit 7107442

File tree

17 files changed

+164
-58
lines changed

17 files changed

+164
-58
lines changed

.github/workflows/integration.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ jobs:
3737
ARGS: DIRAC_USE_JSON_ENCODE=NO MYSQL_VER=mysql:8.0.40
3838
- TEST_NAME: "Backward Compatibility"
3939
ARGS: CLIENT_INSTALLATION_BRANCH=rel-v8r0 PILOT_INSTALLATION_BRANCH=rel-v8r0
40+
- TEST_NAME: "Test DiracX latest"
41+
ARGS: TEST_DIRACX=Yes
4042

4143
steps:
4244
- uses: actions/checkout@v4

integration_tests.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
DEFAULT_HOST_OS = "el9"
2626
DEFAULT_MYSQL_VER = "mysql:8.4.4"
2727
DEFAULT_ES_VER = "opensearchproject/opensearch:2.18.0"
28+
DEFAULT_ES_PLATFORM = "linux/amd64"
2829
DEFAULT_IAM_VER = "indigoiam/iam-login-service:v1.10.2"
2930
FEATURE_VARIABLES = {
3031
"DIRACOSVER": "master",
@@ -71,6 +72,8 @@
7172
}
7273
LOG_PATTERN = re.compile(r"^[\d\-]{10} [\d:]{8} UTC [^\s]+ ([A-Z]+):")
7374

75+
DOCKER_COMPOSE_CMD = shlex.split(os.environ.get("DOCKER_COMPOSE_CMD", "docker compose"))
76+
7477

7578
class NaturalOrderGroup(typer.core.TyperGroup):
7679
"""Group for showing subcommands in the correct order"""
@@ -193,8 +196,8 @@ def destroy():
193196
typer.secho("Shutting down and removing containers", err=True, fg=c.GREEN)
194197
with _gen_docker_compose(DEFAULT_MODULES) as docker_compose_fn:
195198
os.execvpe(
196-
"docker",
197-
["docker", "compose", "-f", docker_compose_fn, "down", "--remove-orphans", "-t", "0", "--volumes"],
199+
DOCKER_COMPOSE_CMD[0],
200+
[*DOCKER_COMPOSE_CMD, "-f", docker_compose_fn, "down", "--remove-orphans", "-t", "0", "--volumes"],
198201
_make_env({}),
199202
)
200203

@@ -253,7 +256,7 @@ def prepare_environment(
253256
typer.secho("Running docker compose to create containers", fg=c.GREEN)
254257
with _gen_docker_compose(modules, diracx_dist_dir=diracx_dist_dir) as docker_compose_fn:
255258
subprocess.run(
256-
["docker", "compose", "-f", docker_compose_fn, "up", "-d", "dirac-server", "dirac-client", "dirac-pilot"]
259+
[*DOCKER_COMPOSE_CMD, "-f", docker_compose_fn, "up", "-d", "dirac-server", "dirac-client", "dirac-pilot"]
257260
+ extra_services,
258261
check=True,
259262
env=docker_compose_env,
@@ -360,7 +363,7 @@ def prepare_environment(
360363
subStderr = open(docker_compose_fn_final / "stderr", "w")
361364

362365
subprocess.Popen(
363-
["docker", "compose", "-f", docker_compose_fn_final / "docker-compose.yml", "up", "-d", "diracx"],
366+
[*DOCKER_COMPOSE_CMD, "-f", docker_compose_fn_final / "docker-compose.yml", "up", "-d", "diracx"],
364367
env=docker_compose_env,
365368
stdin=None,
366369
stdout=subStdout,
@@ -569,7 +572,7 @@ def _gen_docker_compose(modules, *, diracx_dist_dir=None):
569572
# Load the docker compose configuration and mount the necessary volumes
570573
input_fn = Path(__file__).parent / "tests/CI/docker-compose.yml"
571574
docker_compose = yaml.safe_load(input_fn.read_text())
572-
# diracx-wait-for-db needs the volume to be able to run the witing script
575+
# diracx-wait-for-db needs the volume to be able to run the waiting script
573576
for ctn in ("dirac-server", "dirac-client", "dirac-pilot", "diracx-wait-for-db"):
574577
if "volumes" not in docker_compose["services"][ctn]:
575578
docker_compose["services"][ctn]["volumes"] = []
@@ -619,7 +622,7 @@ def _gen_docker_compose(modules, *, diracx_dist_dir=None):
619622
def _check_containers_running(*, is_up=True):
620623
with _gen_docker_compose(DEFAULT_MODULES) as docker_compose_fn:
621624
running_containers = subprocess.run(
622-
["docker", "compose", "-f", docker_compose_fn, "ps", "-q", "-a"],
625+
[*DOCKER_COMPOSE_CMD, "-f", docker_compose_fn, "ps", "-q", "-a"],
623626
stdout=subprocess.PIPE,
624627
env=_make_env({}),
625628
# docker compose ps has a non-zero exit code when no containers are running
@@ -701,6 +704,7 @@ def _make_env(flags):
701704
else:
702705
env["MYSQL_ADMIN_COMMAND"] = "mysqladmin"
703706
env["ES_VER"] = flags.pop("ES_VER", DEFAULT_ES_VER)
707+
env["ES_PLATFORM"] = flags.pop("ES_PLATFORM", DEFAULT_ES_PLATFORM)
704708
env["IAM_VER"] = flags.pop("IAM_VER", DEFAULT_IAM_VER)
705709
if "CVMFS_DIR" not in env or not Path(env["CVMFS_DIR"]).is_dir():
706710
typer.secho(f"CVMFS_DIR environment value: {env.get('CVMFS_DIR', 'NOT SET')}", fg=c.YELLOW)

src/DIRAC/ConfigurationSystem/Client/Helpers/Registry.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,7 @@ def getVOForGroup(group):
457457
458458
:return: str
459459
"""
460-
return getVO() or gConfig.getValue(f"{gBaseRegistrySection}/Groups/{group}/VO", "")
460+
return gConfig.getValue(f"{gBaseRegistrySection}/Groups/{group}/VO", "") or getVO()
461461

462462

463463
def getIdPForGroup(group):

src/DIRAC/Core/Security/DiracX.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
def addTokenToPEM(pemPath, group):
4848
from DIRAC.Core.Base.Client import Client
4949

50-
vo = Registry.getVOMSVOForGroup(group)
50+
vo = Registry.getVOForGroup(group)
5151
if not vo:
5252
gLogger.error(f"ERROR: Could not find VO for group {group}, DiracX will not work!")
5353
disabledVOs = gConfig.getValue("/DiracX/DisabledVOs", [])

src/DIRAC/Core/Tornado/Client/ClientSelector.py

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
from DIRAC.Core.DISET.TransferClient import TransferClient
1818
from DIRAC.Core.Tornado.Client.TornadoClient import TornadoClient
1919

20-
2120
sLog = gLogger.getSubLogger(__name__)
2221

2322

@@ -66,28 +65,30 @@ def ClientSelector(disetClient, *args, **kwargs): # We use same interface as RP
6665
# If we are not already given a URL, resolve it
6766
if serviceName.startswith(("http", "dip")):
6867
completeUrl = serviceName
69-
elif useLegacyAdapter(serviceName):
70-
sLog.debug(f"Using legacy adapter for service {serviceName}")
71-
if diracxClient is None:
72-
raise NotImplementedError(
73-
"DiracX is enabled but no diracxClient is provided, do you need to update your client?"
74-
)
75-
return diracxClient()
7668
else:
69+
isServiceLegacyAdapted = useLegacyAdapter(serviceName)
70+
if isServiceLegacyAdapted and diracxClient is not None:
71+
sLog.debug(f"Using legacy adapter for service {serviceName}")
72+
return diracxClient()
73+
else:
74+
if isServiceLegacyAdapted:
75+
# Only warn to deactivate it without making the code crash.
76+
sLog.warn(
77+
f"FutureClient for {serviceName} is provided but not activated, do you need to update your client?"
78+
)
79+
7780
completeUrl = getServiceURL(serviceName)
7881
sLog.debug(f"URL resolved: {completeUrl}")
7982

8083
if completeUrl.startswith("http"):
8184
sLog.debug(f"Using HTTPS for service {serviceName}")
82-
rpc = tornadoClient(*args, **kwargs)
83-
else:
84-
rpc = disetClient(*args, **kwargs)
85+
return tornadoClient(*args, **kwargs)
8586
except Exception as e: # pylint: disable=broad-except
8687
# If anything went wrong in the resolution, we return default RPCClient
8788
# So the behaviour is exactly the same as before implementation of Tornado
8889
sLog.warn("Could not select DISET or Tornado client", f"{repr(e)}")
89-
rpc = disetClient(*args, **kwargs)
90-
return rpc
90+
sLog.exception()
91+
return disetClient(*args, **kwargs)
9192

9293

9394
# Client to use for RPC selection

src/DIRAC/Core/Utilities/Extensions.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,15 @@ def findServices(modules):
7373
return findModules(modules, "Service", "*Handler")
7474

7575

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+
7685
@iterateThenSort
7786
def findDatabases(module):
7887
"""Find the DB SQL schema defintions for one or more DIRAC extension(s)
@@ -182,7 +191,7 @@ def parseArgs():
182191
parser = argparse.ArgumentParser()
183192
subparsers = parser.add_subparsers(required=True, dest="function")
184193
defaultExtensions = extensionsByPriority()
185-
for func in [findSystems, findAgents, findExecutors, findServices, findDatabases]:
194+
for func in [findSystems, findAgents, findExecutors, findServices, findDatabases, findFutureServices]:
186195
subparser = subparsers.add_parser(func.__name__)
187196
subparser.add_argument("--extensions", nargs="+", default=defaultExtensions)
188197
subparser.set_defaults(func=func)

src/DIRAC/WorkloadManagementSystem/Client/JobMonitoringClient.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ def __init__(self, **kwargs):
1818
super().__init__(**kwargs)
1919
self.setServer("WorkloadManagement/JobMonitoring")
2020

21-
diracxClient = futureJobMonitoringClient
21+
# Set to NULL to avoid using it in ClientSelector
22+
diracxClient = None
2223

2324
@ignoreEncodeWarning
2425
def getJobsStatus(self, jobIDs):

src/DIRAC/WorkloadManagementSystem/FutureClient/JobStateUpdateClient.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,11 +77,11 @@ def setJobApplicationStatus(self, jobID: str | int, appStatus: str, source: str
7777
def setJobAttribute(self, jobID: str | int, attribute: str, value: str):
7878
with DiracXClient() as api:
7979
if attribute == "Status":
80-
api.jobs.set_job_statuses(
80+
return api.jobs.set_job_statuses(
8181
{jobID: {datetime.now(tz=timezone.utc): {"Status": value}}},
8282
)
8383
else:
84-
api.jobs.patch_metadata({jobID: {attribute: value}})
84+
return api.jobs.patch_metadata({jobID: {attribute: value}})
8585

8686
@stripValueIfOK
8787
@convertToReturnValue

tests/CI/check_db_initialized.sh

Lines changed: 40 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,43 @@
11
#!/bin/bash
2-
dbMissing=true;
3-
allDBs=(AccountingDB FTS3DB JobDB JobLoggingDB PilotAgentsDB ProductionDB ProxyDB ReqDB ResourceManagementDB ResourceStatusDB SandboxMetadataDB StorageManagementDB TaskQueueDB TransformationDB)
4-
while ${dbMissing};
5-
do
6-
dbMissing=false;
7-
allExistingDBs=$(mysql -uDirac -pDirac -h mysql -P 3306 -e "show databases;");
8-
for db in "${allDBs[@]}";
9-
do
10-
if grep -q "${db}" <<< "${allExistingDBs}";
11-
then
12-
echo "${db} OK";
13-
else
14-
echo "${db} not created";
15-
dbMissing=true;
16-
fi;
17-
done;
18-
if ${dbMissing};
19-
then
20-
sleep 1;
2+
DB_USER="Dirac"
3+
DB_PASS="Dirac"
4+
DB_HOST="mysql"
5+
DB_PORT=3306
6+
DB_CMD=""
7+
8+
# Detect available client: maria or mysql
9+
if command -v mariadb >/dev/null 2>&1; then
10+
DB_CMD="mariadb -u${DB_USER} -p${DB_PASS} -h${DB_HOST} -P${DB_PORT}"
11+
elif command -v mysql >/dev/null 2>&1; then
12+
DB_CMD="mysql -u${DB_USER} -p${DB_PASS} -h${DB_HOST} -P${DB_PORT}"
13+
else
14+
echo "❌ Neither mysql nor mariadb client found in PATH."
15+
exit 1
16+
fi
17+
18+
echo "Using client: ${DB_CMD%% *}"
19+
20+
dbMissing=true
21+
allDBs=(
22+
AccountingDB FTS3DB JobDB JobLoggingDB PilotAgentsDB ProductionDB
23+
ProxyDB ReqDB ResourceManagementDB ResourceStatusDB
24+
SandboxMetadataDB StorageManagementDB TaskQueueDB TransformationDB
25+
)
26+
27+
while $dbMissing; do
28+
dbMissing=false
29+
allExistingDBs=$($DB_CMD -e "SHOW DATABASES;" 2>/dev/null)
30+
31+
for db in "${allDBs[@]}"; do
32+
if grep -q "^${db}$" <<<"$allExistingDBs"; then
33+
echo "${db} exists"
34+
else
35+
echo "⚠️ ${db} not created yet"
36+
dbMissing=true
2137
fi
38+
done
39+
40+
$dbMissing && sleep 10
2241
done
42+
43+
echo "🎉 All databases are present."

0 commit comments

Comments
 (0)