diracx-cli 0.0.1a17__tar.gz → 0.0.1a19__tar.gz
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.
- {diracx_cli-0.0.1a17 → diracx_cli-0.0.1a19}/PKG-INFO +2 -2
- {diracx_cli-0.0.1a17 → diracx_cli-0.0.1a19}/pyproject.toml +11 -1
- {diracx_cli-0.0.1a17 → diracx_cli-0.0.1a19}/src/diracx/cli/__init__.py +20 -4
- {diracx_cli-0.0.1a17 → diracx_cli-0.0.1a19}/src/diracx/cli/internal/__init__.py +5 -8
- {diracx_cli-0.0.1a17 → diracx_cli-0.0.1a19}/src/diracx/cli/internal/legacy.py +8 -9
- {diracx_cli-0.0.1a17 → diracx_cli-0.0.1a19}/src/diracx/cli/jobs.py +11 -2
- {diracx_cli-0.0.1a17 → diracx_cli-0.0.1a19}/src/diracx_cli.egg-info/PKG-INFO +2 -2
- diracx_cli-0.0.1a19/src/diracx_cli.egg-info/entry_points.txt +9 -0
- {diracx_cli-0.0.1a17 → diracx_cli-0.0.1a19}/tests/legacy/cs_sync/integration_test.cfg +0 -2
- {diracx_cli-0.0.1a17 → diracx_cli-0.0.1a19}/tests/legacy/cs_sync/integration_test.yaml +0 -2
- {diracx_cli-0.0.1a17 → diracx_cli-0.0.1a19}/tests/test_jobs.py +2 -6
- diracx_cli-0.0.1a17/src/diracx_cli.egg-info/entry_points.txt +0 -2
- {diracx_cli-0.0.1a17 → diracx_cli-0.0.1a19}/README.md +0 -0
- {diracx_cli-0.0.1a17 → diracx_cli-0.0.1a19}/setup.cfg +0 -0
- {diracx_cli-0.0.1a17 → diracx_cli-0.0.1a19}/src/diracx/cli/__main__.py +0 -0
- {diracx_cli-0.0.1a17 → diracx_cli-0.0.1a19}/src/diracx/cli/config.py +0 -0
- {diracx_cli-0.0.1a17 → diracx_cli-0.0.1a19}/src/diracx/cli/py.typed +0 -0
- {diracx_cli-0.0.1a17 → diracx_cli-0.0.1a19}/src/diracx/cli/utils.py +0 -0
- {diracx_cli-0.0.1a17 → diracx_cli-0.0.1a19}/src/diracx_cli.egg-info/SOURCES.txt +0 -0
- {diracx_cli-0.0.1a17 → diracx_cli-0.0.1a19}/src/diracx_cli.egg-info/dependency_links.txt +0 -0
- {diracx_cli-0.0.1a17 → diracx_cli-0.0.1a19}/src/diracx_cli.egg-info/requires.txt +0 -0
- {diracx_cli-0.0.1a17 → diracx_cli-0.0.1a19}/src/diracx_cli.egg-info/top_level.txt +0 -0
- {diracx_cli-0.0.1a17 → diracx_cli-0.0.1a19}/tests/legacy/cs_sync/integration_test_buggy.cfg +0 -0
- {diracx_cli-0.0.1a17 → diracx_cli-0.0.1a19}/tests/legacy/cs_sync/integration_test_secret.cfg +0 -0
- {diracx_cli-0.0.1a17 → diracx_cli-0.0.1a19}/tests/legacy/cs_sync/test_cssync.py +0 -0
- {diracx_cli-0.0.1a17 → diracx_cli-0.0.1a19}/tests/legacy/test_legacy.py +0 -0
- {diracx_cli-0.0.1a17 → diracx_cli-0.0.1a19}/tests/test_internal.py +0 -0
- {diracx_cli-0.0.1a17 → diracx_cli-0.0.1a19}/tests/test_login.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: diracx-cli
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.1a19
|
|
4
4
|
Summary: TODO
|
|
5
5
|
License: GPL-3.0-only
|
|
6
6
|
Classifier: Intended Audience :: Science/Research
|
|
@@ -8,7 +8,7 @@ Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
|
|
8
8
|
Classifier: Programming Language :: Python :: 3
|
|
9
9
|
Classifier: Topic :: Scientific/Engineering
|
|
10
10
|
Classifier: Topic :: System :: Distributed Computing
|
|
11
|
-
Requires-Python: >=3.
|
|
11
|
+
Requires-Python: >=3.11
|
|
12
12
|
Description-Content-Type: text/markdown
|
|
13
13
|
Requires-Dist: diraccfg
|
|
14
14
|
Requires-Dist: diracx-api
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name = "diracx-cli"
|
|
3
3
|
description = "TODO"
|
|
4
4
|
readme = "README.md"
|
|
5
|
-
requires-python = ">=3.
|
|
5
|
+
requires-python = ">=3.11"
|
|
6
6
|
keywords = []
|
|
7
7
|
license = {text = "GPL-3.0-only"}
|
|
8
8
|
classifiers = [
|
|
@@ -36,6 +36,15 @@ types = [
|
|
|
36
36
|
[project.scripts]
|
|
37
37
|
dirac = "diracx.cli:app"
|
|
38
38
|
|
|
39
|
+
[project.entry-points."diracx.cli"]
|
|
40
|
+
jobs = "diracx.cli.jobs:app"
|
|
41
|
+
config = "diracx.cli.config:app"
|
|
42
|
+
|
|
43
|
+
[project.entry-points."diracx.cli.hidden"]
|
|
44
|
+
internal = "diracx.cli.internal:app"
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
|
|
39
48
|
[tool.setuptools.packages.find]
|
|
40
49
|
where = ["src"]
|
|
41
50
|
|
|
@@ -58,3 +67,4 @@ asyncio_mode = "auto"
|
|
|
58
67
|
markers = [
|
|
59
68
|
"enabled_dependencies: List of dependencies which should be available to the FastAPI test client",
|
|
60
69
|
]
|
|
70
|
+
asyncio_default_fixture_loop_scope = "session"
|
|
@@ -8,10 +8,10 @@ import typer
|
|
|
8
8
|
|
|
9
9
|
from diracx.client.aio import DiracClient
|
|
10
10
|
from diracx.client.models import DeviceFlowErrorResponse
|
|
11
|
+
from diracx.core.extensions import select_from_extension
|
|
11
12
|
from diracx.core.preferences import get_diracx_preferences
|
|
12
13
|
from diracx.core.utils import write_credentials
|
|
13
14
|
|
|
14
|
-
from . import config, internal, jobs
|
|
15
15
|
from .utils import AsyncTyper
|
|
16
16
|
|
|
17
17
|
app = AsyncTyper()
|
|
@@ -115,9 +115,25 @@ def callback(output_format: Optional[str] = None):
|
|
|
115
115
|
os.environ["DIRACX_OUTPUT_FORMAT"] = output_format
|
|
116
116
|
|
|
117
117
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
118
|
+
# Load all the sub commands
|
|
119
|
+
|
|
120
|
+
cli_names = set(
|
|
121
|
+
[entry_point.name for entry_point in select_from_extension(group="diracx.cli")]
|
|
122
|
+
)
|
|
123
|
+
for cli_name in cli_names:
|
|
124
|
+
entry_point = select_from_extension(group="diracx.cli", name=cli_name)[0]
|
|
125
|
+
app.add_typer(entry_point.load(), name=entry_point.name)
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
cli_hidden_names = set(
|
|
129
|
+
[
|
|
130
|
+
entry_point.name
|
|
131
|
+
for entry_point in select_from_extension(group="diracx.cli.hidden")
|
|
132
|
+
]
|
|
133
|
+
)
|
|
134
|
+
for cli_name in cli_hidden_names:
|
|
135
|
+
entry_point = select_from_extension(group="diracx.cli.hidden", name=cli_name)[0]
|
|
136
|
+
app.add_typer(entry_point.load(), name=entry_point.name, hidden=True)
|
|
121
137
|
|
|
122
138
|
|
|
123
139
|
if __name__ == "__main__":
|
|
@@ -26,7 +26,7 @@ app.add_typer(legacy.app, name="legacy")
|
|
|
26
26
|
|
|
27
27
|
@app.command()
|
|
28
28
|
def generate_cs(config_repo: str):
|
|
29
|
-
"""Generate a minimal DiracX configuration repository"""
|
|
29
|
+
"""Generate a minimal DiracX configuration repository."""
|
|
30
30
|
# TODO: The use of TypeAdapter should be moved in to typer itself
|
|
31
31
|
config_repo = TypeAdapter(ConfigSourceUrl).validate_python(config_repo)
|
|
32
32
|
if config_repo.scheme != "git+file" or config_repo.path is None:
|
|
@@ -58,8 +58,7 @@ def add_vo(
|
|
|
58
58
|
idp_url: Annotated[str, typer.Option()],
|
|
59
59
|
idp_client_id: Annotated[str, typer.Option()],
|
|
60
60
|
):
|
|
61
|
-
"""Add a registry entry (vo) to an existing configuration repository"""
|
|
62
|
-
|
|
61
|
+
"""Add a registry entry (vo) to an existing configuration repository."""
|
|
63
62
|
# TODO: The use of TypeAdapter should be moved in to typer itself
|
|
64
63
|
config_repo = TypeAdapter(ConfigSourceUrl).validate_python(config_repo)
|
|
65
64
|
if config_repo.scheme != "git+file" or config_repo.path is None:
|
|
@@ -102,8 +101,7 @@ def add_group(
|
|
|
102
101
|
group: Annotated[str, typer.Option()],
|
|
103
102
|
properties: list[str] = ["NormalUser"],
|
|
104
103
|
):
|
|
105
|
-
"""Add a group to an existing vo in the configuration repository"""
|
|
106
|
-
|
|
104
|
+
"""Add a group to an existing vo in the configuration repository."""
|
|
107
105
|
# TODO: The use of TypeAdapter should be moved in to typer itself
|
|
108
106
|
config_repo = TypeAdapter(ConfigSourceUrl).validate_python(config_repo)
|
|
109
107
|
if config_repo.scheme != "git+file" or config_repo.path is None:
|
|
@@ -139,8 +137,7 @@ def add_user(
|
|
|
139
137
|
sub: Annotated[str, typer.Option()],
|
|
140
138
|
preferred_username: Annotated[str, typer.Option()],
|
|
141
139
|
):
|
|
142
|
-
"""Add a user to an existing vo and group"""
|
|
143
|
-
|
|
140
|
+
"""Add a user to an existing vo and group."""
|
|
144
141
|
# TODO: The use of TypeAdapter should be moved in to typer itself
|
|
145
142
|
config_repo = TypeAdapter(ConfigSourceUrl).validate_python(config_repo)
|
|
146
143
|
if config_repo.scheme != "git+file" or config_repo.path is None:
|
|
@@ -184,7 +181,7 @@ def add_user(
|
|
|
184
181
|
|
|
185
182
|
|
|
186
183
|
def update_config_and_commit(repo_path: Path, config: Config, message: str):
|
|
187
|
-
"""Update the yaml file in the repo and commit it"""
|
|
184
|
+
"""Update the yaml file in the repo and commit it."""
|
|
188
185
|
repo = git.Repo(repo_path)
|
|
189
186
|
yaml_path = repo_path / "default.yml"
|
|
190
187
|
typer.echo(f"Writing back configuration to {yaml_path}", err=True)
|
|
@@ -53,7 +53,7 @@ class ConversionConfig(BaseModel):
|
|
|
53
53
|
|
|
54
54
|
@app.command()
|
|
55
55
|
def cs_sync(old_file: Path, new_file: Path):
|
|
56
|
-
"""Load the old CS and convert it to the new YAML format"""
|
|
56
|
+
"""Load the old CS and convert it to the new YAML format."""
|
|
57
57
|
if not os.environ.get("DIRAC_COMPAT_ENABLE_CS_CONVERSION"):
|
|
58
58
|
raise RuntimeError(
|
|
59
59
|
"DIRAC_COMPAT_ENABLE_CS_CONVERSION must be set for the conversion to be possible"
|
|
@@ -86,8 +86,7 @@ def cs_sync(old_file: Path, new_file: Path):
|
|
|
86
86
|
|
|
87
87
|
|
|
88
88
|
def _apply_fixes(raw):
|
|
89
|
-
"""Modify raw in place to make any layout changes between the old and new structure"""
|
|
90
|
-
|
|
89
|
+
"""Modify raw in place to make any layout changes between the old and new structure."""
|
|
91
90
|
conv_config = ConversionConfig.model_validate(raw["DiracX"]["CsSync"])
|
|
92
91
|
|
|
93
92
|
raw.pop("DiracX", None)
|
|
@@ -184,15 +183,15 @@ def generate_helm_values(
|
|
|
184
183
|
),
|
|
185
184
|
output_file: Path = Option(help="Where to dump the yam file"),
|
|
186
185
|
):
|
|
187
|
-
"""Generate an initial values.yaml to run a DiracX installation
|
|
188
|
-
compatible with a DIRAC instance. The file is not complete, and needs
|
|
189
|
-
manual editing"""
|
|
186
|
+
"""Generate an initial values.yaml to run a DiracX installation.
|
|
190
187
|
|
|
188
|
+
The file generated is not complete, and needs manual editing.
|
|
189
|
+
"""
|
|
191
190
|
helm_values = {
|
|
192
191
|
"developer": {"enabled": False},
|
|
193
|
-
"
|
|
194
|
-
"
|
|
195
|
-
"
|
|
192
|
+
"initCs": {"enabled": True},
|
|
193
|
+
"initSecrets": {"enabled": True},
|
|
194
|
+
"initSql": {"enabled": False, "env": {}},
|
|
196
195
|
"cert-manager": {"enabled": False},
|
|
197
196
|
"cert-manager-issuer": {"enabled": False},
|
|
198
197
|
"minio": {"enabled": False},
|
|
@@ -20,6 +20,12 @@ from .utils import AsyncTyper
|
|
|
20
20
|
app = AsyncTyper()
|
|
21
21
|
|
|
22
22
|
|
|
23
|
+
available_operators = (
|
|
24
|
+
f"Scalar operators: {', '.join([op.value for op in ScalarSearchOperator])}. "
|
|
25
|
+
f"Vector operators: {', '.join([op.value for op in VectorSearchOperator])}."
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
|
|
23
29
|
def parse_condition(value: str) -> SearchSpec:
|
|
24
30
|
parameter, operator, rest = value.split(" ", 2)
|
|
25
31
|
if operator in set(ScalarSearchOperator):
|
|
@@ -51,15 +57,18 @@ async def search(
|
|
|
51
57
|
"Owner",
|
|
52
58
|
"LastUpdateTime",
|
|
53
59
|
],
|
|
54
|
-
condition: Annotated[
|
|
60
|
+
condition: Annotated[
|
|
61
|
+
list[str], Option(help=f'Example: "JobID eq 1000". {available_operators}')
|
|
62
|
+
] = [],
|
|
55
63
|
all: bool = False,
|
|
56
64
|
page: int = 1,
|
|
57
65
|
per_page: int = 10,
|
|
58
66
|
):
|
|
67
|
+
search_specs = [parse_condition(cond) for cond in condition]
|
|
59
68
|
async with DiracClient() as api:
|
|
60
69
|
jobs, content_range = await api.jobs.search(
|
|
61
70
|
parameters=None if all else parameter,
|
|
62
|
-
search=
|
|
71
|
+
search=search_specs if search_specs else None,
|
|
63
72
|
page=page,
|
|
64
73
|
per_page=per_page,
|
|
65
74
|
cls=lambda _, jobs, headers: (
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: diracx-cli
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.1a19
|
|
4
4
|
Summary: TODO
|
|
5
5
|
License: GPL-3.0-only
|
|
6
6
|
Classifier: Intended Audience :: Science/Research
|
|
@@ -8,7 +8,7 @@ Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
|
|
8
8
|
Classifier: Programming Language :: Python :: 3
|
|
9
9
|
Classifier: Topic :: Scientific/Engineering
|
|
10
10
|
Classifier: Topic :: System :: Distributed Computing
|
|
11
|
-
Requires-Python: >=3.
|
|
11
|
+
Requires-Python: >=3.11
|
|
12
12
|
Description-Content-Type: text/markdown
|
|
13
13
|
Requires-Dist: diraccfg
|
|
14
14
|
Requires-Dist: diracx-api
|
|
@@ -8,7 +8,6 @@ import pytest
|
|
|
8
8
|
from pytest import raises
|
|
9
9
|
|
|
10
10
|
from diracx import cli
|
|
11
|
-
from diracx.core.models import ScalarSearchSpec
|
|
12
11
|
from diracx.core.preferences import get_diracx_preferences
|
|
13
12
|
|
|
14
13
|
TEST_JDL = """
|
|
@@ -41,7 +40,6 @@ async def jdl_file():
|
|
|
41
40
|
|
|
42
41
|
async def test_submit(with_cli_login, jdl_file, capfd):
|
|
43
42
|
"""Test submitting a job using a JDL file."""
|
|
44
|
-
|
|
45
43
|
with open(jdl_file, "r") as temp_file:
|
|
46
44
|
await cli.jobs.submit([temp_file])
|
|
47
45
|
|
|
@@ -52,7 +50,6 @@ async def test_submit(with_cli_login, jdl_file, capfd):
|
|
|
52
50
|
|
|
53
51
|
async def test_search(with_cli_login, jdl_file, capfd):
|
|
54
52
|
"""Test searching for jobs."""
|
|
55
|
-
|
|
56
53
|
# Submit 20 jobs
|
|
57
54
|
with open(jdl_file, "r") as temp_file:
|
|
58
55
|
await cli.jobs.submit([temp_file] * 20)
|
|
@@ -82,8 +79,7 @@ async def test_search(with_cli_login, jdl_file, capfd):
|
|
|
82
79
|
assert "JobGroup" in cap.out
|
|
83
80
|
|
|
84
81
|
# Search for a job that doesn't exist
|
|
85
|
-
|
|
86
|
-
await cli.jobs.search(condition=[condition])
|
|
82
|
+
await cli.jobs.search(condition=["Status eq nonexistent"])
|
|
87
83
|
cap = capfd.readouterr()
|
|
88
84
|
assert cap.err == ""
|
|
89
85
|
assert "[]" == cap.out.strip()
|
|
@@ -116,7 +112,7 @@ async def test_search(with_cli_login, jdl_file, capfd):
|
|
|
116
112
|
assert "Showing all jobs" in cap.out
|
|
117
113
|
|
|
118
114
|
# Search for a job that doesn't exist
|
|
119
|
-
await cli.jobs.search(condition=[
|
|
115
|
+
await cli.jobs.search(condition=["Status eq nonexistent"])
|
|
120
116
|
cap = capfd.readouterr()
|
|
121
117
|
assert cap.err == ""
|
|
122
118
|
assert "No jobs found" in cap.out
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{diracx_cli-0.0.1a17 → diracx_cli-0.0.1a19}/tests/legacy/cs_sync/integration_test_secret.cfg
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|