Skip to content

Commit 4db5094

Browse files
authored
Merge pull request #382 from chaen/lhcbdiracx
Lhcbdiracx
2 parents 19913ec + 0eee11a commit 4db5094

File tree

22 files changed

+306
-202
lines changed

22 files changed

+306
-202
lines changed

diracx-api/src/diracx/api/jobs.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import tarfile
99
import tempfile
1010
from pathlib import Path
11+
from typing import Literal
1112

1213
import httpx
1314

@@ -19,7 +20,8 @@
1920
logger = logging.getLogger(__name__)
2021

2122
SANDBOX_CHECKSUM_ALGORITHM = "sha256"
22-
SANDBOX_COMPRESSION = "bz2"
23+
SANDBOX_COMPRESSION: Literal["bz2"] = "bz2"
24+
SANDBOX_OPEN_MODE: Literal["w|bz2"] = "w|bz2"
2325

2426

2527
@with_client
@@ -31,7 +33,7 @@ async def create_sandbox(paths: list[Path], *, client: DiracClient) -> str:
3133
be used to submit jobs.
3234
"""
3335
with tempfile.TemporaryFile(mode="w+b") as tar_fh:
34-
with tarfile.open(fileobj=tar_fh, mode=f"w|{SANDBOX_COMPRESSION}") as tf:
36+
with tarfile.open(fileobj=tar_fh, mode=SANDBOX_OPEN_MODE) as tf:
3537
for path in paths:
3638
logger.debug("Adding %s to sandbox as %s", path.resolve(), path.name)
3739
tf.add(path.resolve(), path.name, recursive=True)

diracx-cli/src/diracx/cli/internal/legacy.py

Lines changed: 114 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import hashlib
55
import json
66
import os
7+
import re
78
from pathlib import Path
89
from typing import TYPE_CHECKING, cast
910
from urllib.parse import urljoin, urlparse
@@ -26,6 +27,12 @@
2627
app = AsyncTyper()
2728

2829

30+
BASE_64_URL_SAFE_PATTERN = (
31+
r"(?:[A-Za-z0-9\-_]{4})*(?:[A-Za-z0-9\-_]{2}==|[A-Za-z0-9\-_]{3}=)?"
32+
)
33+
LEGACY_EXCHANGE_PATTERN = rf"diracx:legacy:({BASE_64_URL_SAFE_PATTERN})"
34+
35+
2936
class IdPConfig(BaseModel):
3037
URL: str
3138
ClientID: str
@@ -182,12 +189,13 @@ def generate_helm_values(
182189
"developer": {"enabled": False},
183190
"initCs": {"enabled": True},
184191
"initSecrets": {"enabled": True},
185-
"initSql": {"enabled": False, "env": {}},
192+
"initSql": {"enabled": False},
186193
"cert-manager": {"enabled": False},
187194
"cert-manager-issuer": {"enabled": False},
188195
"minio": {"enabled": False},
189196
"dex": {"enabled": False},
190197
"opensearch": {"enabled": False},
198+
# This is Openshift specific, change it maybe
191199
"ingress": {
192200
"enabled": True,
193201
"className": None,
@@ -199,12 +207,7 @@ def generate_helm_values(
199207
},
200208
"rabbitmq": {"enabled": False},
201209
"mysql": {"enabled": False},
202-
"diracx": {
203-
"manageOSIndices": False,
204-
"mysqlDatabases": [],
205-
"osDatabases": [],
206-
"settings": {},
207-
},
210+
"global": {"images": {"services": "FILL ME"}, "storageClassName": "FILL ME"},
208211
}
209212

210213
cfg = diraccfg.CFG().loadFromBuffer(public_cfg.read_text())
@@ -216,15 +219,13 @@ def generate_helm_values(
216219

217220
diracx_url = cfg["DiracX"]["URL"]
218221
diracx_hostname = urlparse(diracx_url).netloc.split(":", 1)[0]
219-
# Remove the port
220-
diracx_config = {
221-
"manageOSIndices": False,
222-
"mysqlDatabases": [],
223-
"osDatabases": [],
224-
"settings": {},
222+
223+
diracx_config: dict = {
224+
"sqlDbs": {},
225+
"osDbs": {},
225226
}
226227

227-
diracx_settings: dict[str, str] = {}
228+
diracx_settings: dict[str, str] = {"DIRACX_CONFIG_BACKEND_URL": "FILL ME"}
228229
diracx_config["settings"] = diracx_settings
229230
helm_values["diracx"] = diracx_config
230231
diracx_config["hostname"] = diracx_hostname
@@ -236,47 +237,122 @@ def generate_helm_values(
236237
]
237238
)
238239

240+
### SQL DBs
241+
239242
default_db_user = cfg["Systems"].get("Databases", {}).get("User")
240243
default_db_password = cfg["Systems"].get("Databases", {}).get("Password")
241-
242-
default_setup = cfg["DIRAC"]["Setup"]
244+
default_db_host = cfg["Systems"].get("Databases", {}).get("Host", "FILL ME")
245+
default_db_port = cfg["Systems"].get("Databases", {}).get("Port", "FILL ME")
243246

244247
all_db_configs = {}
245-
for system, system_config in cfg["Systems"].items():
246-
system_setup = cfg["DIRAC"]["Setups"][default_setup].get(system, None)
247-
if system_setup:
248-
all_db_configs.update(system_config[system_setup].get("Databases", {}))
248+
sql_dbs = {
249+
"dbs": {},
250+
"default": {
251+
"host": f"{default_db_host}:{default_db_port}",
252+
"password": default_db_password,
253+
"rootPassword": "FILL ME",
254+
"rootUser": "FILL ME",
255+
"user": default_db_user,
256+
},
257+
}
258+
for _system, system_config in cfg["Systems"].items():
259+
all_db_configs.update(system_config.get("Databases", {}))
249260

250261
from diracx.core.extensions import select_from_extension
251262

252263
for entry_point in select_from_extension(group="diracx.db.sql"):
264+
253265
db_name = entry_point.name
266+
db_config = all_db_configs.get(db_name, {})
267+
268+
sql_dbs["dbs"][db_name] = {}
254269
# There is a DIRAC AuthDB, but it is not the same
255270
# as the DiracX one
256271
if db_name == "AuthDB":
257-
url_name = "DIRACX_DB_URL_AUTHDB"
258-
connection_string = "FILL ME: I am a new DB, create me"
259-
else:
260-
db_config = all_db_configs[db_name]
261-
url_name = f"DIRACX_DB_URL_{entry_point.name.upper()}"
262-
db_user = db_config.get("User", default_db_user)
263-
db_password = db_config.get("Password", default_db_password)
264-
db_host = db_config["Host"]
265-
db_port = db_config["Port"]
272+
sql_dbs["dbs"]["AuthDB"] = {"internalName": "DiracXAuthDB"}
273+
274+
if "DBName" in db_config:
266275
indb_name = db_config["DBName"]
276+
if indb_name != db_name:
277+
sql_dbs["dbs"]["internalName"] = indb_name
278+
if "User" in db_config:
279+
sql_dbs["dbs"][db_name]["user"] = db_config.get("User")
280+
if "Password" in db_config:
281+
sql_dbs["dbs"][db_name]["password"] = db_config.get("Password")
282+
if "Host" in db_config or "Port" in db_config:
283+
sql_dbs["dbs"][db_name][
284+
"host"
285+
] = f"{db_config.get('Host', default_db_host)}:{db_config.get('Port', default_db_port)}"
286+
if not sql_dbs["dbs"][db_name]:
287+
sql_dbs["dbs"][db_name] = None
288+
289+
diracx_config["sqlDbs"] = sql_dbs
290+
291+
#### END SQL DB
292+
293+
# #### OS DBs
294+
295+
default_os_db_user = cfg["Systems"].get("NoSQLDatabases", {}).get("User")
296+
default_os_db_password = cfg["Systems"].get("NoSQLDatabases", {}).get("Password")
297+
default_os_db_host = cfg["Systems"].get("NoSQLDatabases", {}).get("Host", "FILL ME")
298+
299+
os_dbs = {
300+
"dbs": {},
301+
"default": {
302+
"host": f"{default_os_db_host}",
303+
"password": default_os_db_password,
304+
"rootPassword": "FILL ME",
305+
"rootUser": "FILL ME",
306+
"user": default_os_db_user,
307+
},
308+
}
267309

268-
connection_string = f"mysql+aiomysql://{db_user}:{db_password}@{db_host}:{db_port}/{indb_name}"
269-
diracx_settings[url_name] = connection_string
310+
for entry_point in select_from_extension(group="diracx.db.os"):
311+
db_name = entry_point.name
312+
db_config = all_db_configs.get(db_name, {})
313+
314+
os_dbs["dbs"][db_name] = {}
315+
# There is a DIRAC AuthDB, but it is not the same
316+
# as the DiracX one
317+
318+
if "DBName" in db_config:
319+
indb_name = db_config["DBName"]
320+
if indb_name != db_name:
321+
os_dbs["dbs"]["internalName"] = indb_name
322+
if "User" in db_config:
323+
os_dbs["dbs"][db_name]["user"] = db_config["User"]
324+
if "Password" in db_config:
325+
os_dbs["dbs"][db_name]["password"] = db_config["Password"]
326+
if "Host" in db_config:
327+
os_dbs["dbs"][db_name]["host"] = db_config["Host"]
328+
329+
if not os_dbs["dbs"][db_name]:
330+
os_dbs["dbs"][db_name] = None
331+
332+
diracx_config["osDbs"] = os_dbs
333+
334+
#### End OS DBs
270335

271336
# Settings for the legacy
272337
try:
338+
if match := re.fullmatch(
339+
LEGACY_EXCHANGE_PATTERN, cfg["DiracX"]["LegacyExchangeApiKey"]
340+
):
341+
raw_token = base64.urlsafe_b64decode(match.group(1))
342+
else:
343+
raise ValueError(
344+
"Invalid authorization header",
345+
)
346+
273347
diracx_settings["DIRACX_LEGACY_EXCHANGE_HASHED_API_KEY"] = hashlib.sha256(
274-
base64.urlsafe_b64decode(cfg["DiracX"]["LegacyExchangeApiKey"])
348+
raw_token
275349
).hexdigest()
276350
except KeyError:
277-
typer.echo(
278-
"ERROR: you must have '/DiracX/LegacyExchangeApiKey' already set", err=True
279-
)
351+
error_msg = """
352+
ERROR: you must have '/DiracX/LegacyExchangeApiKey' already set.
353+
See the `legacy_exchange` function definition for how to generate it in python
354+
"""
355+
typer.echo(error_msg, err=True)
280356
raise typer.Exit(1) from None
281357
# Sandboxstore settings
282358
# TODO: Integrate minio for production use (ingress, etc)
@@ -295,3 +371,6 @@ def generate_helm_values(
295371
diracx_settings["DIRACX_SERVICE_JOBS_ENABLED"] = "true"
296372
diracx_settings["DIRACX_SANDBOX_STORE_AUTO_CREATE_BUCKET"] = "true"
297373
output_file.write_text(yaml.safe_dump(helm_values))
374+
typer.echo(
375+
"The file is incomplete and needs manual editing (grep for 'FILL ME')", err=True
376+
)

diracx-cli/tests/legacy/cs_sync/test_cssync.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
def test_cs_sync(tmp_path, monkeypatch):
1717
monkeypatch.setenv("DIRAC_COMPAT_ENABLE_CS_CONVERSION", "Yes")
1818

19-
output_file = tmp_path / "default.yaml"
19+
output_file = tmp_path / "default.yml"
2020

2121
result = runner.invoke(
2222
app,
@@ -40,7 +40,7 @@ def test_disabled_vos_empty(tmp_path, monkeypatch):
4040
# # DisabledVOs cannot be set if any Legacy clients are enabled
4141
monkeypatch.setenv("DIRAC_COMPAT_ENABLE_CS_CONVERSION", "Yes")
4242

43-
output_file = tmp_path / "default.yaml"
43+
output_file = tmp_path / "default.yml"
4444

4545
result = runner.invoke(
4646
app,

diracx-client/src/diracx/client/generated/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# coding=utf-8
22
# --------------------------------------------------------------------------
3-
# Code generated by Microsoft (R) AutoRest Code Generator (autorest: 3.10.3, generator: @autorest/python@6.28.0)
3+
# Code generated by Microsoft (R) AutoRest Code Generator (autorest: 3.10.2, generator: @autorest/python@6.28.3)
44
# Changes may cause incorrect behavior and will be lost if the code is regenerated.
55
# --------------------------------------------------------------------------
66
# pylint: disable=wrong-import-position

diracx-client/src/diracx/client/generated/_client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# coding=utf-8
22
# --------------------------------------------------------------------------
3-
# Code generated by Microsoft (R) AutoRest Code Generator (autorest: 3.10.3, generator: @autorest/python@6.28.0)
3+
# Code generated by Microsoft (R) AutoRest Code Generator (autorest: 3.10.2, generator: @autorest/python@6.28.3)
44
# Changes may cause incorrect behavior and will be lost if the code is regenerated.
55
# --------------------------------------------------------------------------
66

diracx-client/src/diracx/client/generated/_configuration.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# coding=utf-8
22
# --------------------------------------------------------------------------
3-
# Code generated by Microsoft (R) AutoRest Code Generator (autorest: 3.10.3, generator: @autorest/python@6.28.0)
3+
# Code generated by Microsoft (R) AutoRest Code Generator (autorest: 3.10.2, generator: @autorest/python@6.28.3)
44
# Changes may cause incorrect behavior and will be lost if the code is regenerated.
55
# --------------------------------------------------------------------------
66

0 commit comments

Comments
 (0)