edge-containers-cli 4.3.1__tar.gz → 4.4.0__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.
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/PKG-INFO +3 -2
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/pyproject.toml +1 -1
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/src/edge_containers_cli/__main__.py +28 -20
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/src/edge_containers_cli/_version.py +2 -2
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/src/edge_containers_cli/autocomplete.py +4 -1
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/src/edge_containers_cli/backend.py +3 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/src/edge_containers_cli/cli.py +93 -32
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/src/edge_containers_cli/cmds/argo_commands.py +72 -12
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/src/edge_containers_cli/cmds/commands.py +44 -3
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/src/edge_containers_cli/cmds/helm.py +9 -2
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/src/edge_containers_cli/cmds/k8s_commands.py +14 -6
- edge_containers_cli-4.4.0/src/edge_containers_cli/git.py +236 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/src/edge_containers_cli/utils.py +62 -16
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/src/edge_containers_cli.egg-info/PKG-INFO +3 -2
- edge_containers_cli-4.4.0/src/edge_containers_cli.egg-info/entry_points.txt +2 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/tests/conftest.py +4 -1
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/tests/data/argocd.yaml +65 -0
- edge_containers_cli-4.4.0/tests/data/cli.yaml +50 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/tests/data/k8s.yaml +19 -2
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/tests/data/yaml.yaml +1 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/tests/test_argocd.py +15 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/tests/test_cli.py +4 -4
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/tests/test_k8s.py +1 -1
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/tests/test_unit.py +21 -3
- edge_containers_cli-4.3.1/src/edge_containers_cli/git.py +0 -182
- edge_containers_cli-4.3.1/src/edge_containers_cli.egg-info/entry_points.txt +0 -2
- edge_containers_cli-4.3.1/tests/data/cli.yaml +0 -24
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/.copier-answers.yml +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/.devcontainer/devcontainer.json +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/.github/CONTRIBUTING.md +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/.github/ISSUE_TEMPLATE/issue.md +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/.github/actions/install_requirements/action.yml +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/.github/dependabot.yml +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/.github/pages/index.html +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/.github/pages/make_switcher.py +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/.github/workflows/_check.yml +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/.github/workflows/_dist.yml +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/.github/workflows/_pypi.yml +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/.github/workflows/_release.yml +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/.github/workflows/_test.yml +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/.github/workflows/_tox.yml +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/.github/workflows/ci.yml +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/.gitignore +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/.pre-commit-config.yaml +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/.vscode/extensions.json +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/.vscode/launch.json +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/.vscode/settings.json +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/.vscode/tasks.json +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/Dockerfile +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/LICENSE +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/README.md +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/docs/conf.py +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/docs/developer/explanations/decisions/0001-record-architecture-decisions.rst +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/docs/developer/explanations/decisions/0002-switched-to-pip-skeleton.rst +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/docs/developer/explanations/decisions.rst +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/docs/developer/how-to/build-docs.rst +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/docs/developer/how-to/contribute.rst +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/docs/developer/how-to/lint.rst +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/docs/developer/how-to/make-release.rst +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/docs/developer/how-to/pin-requirements.rst +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/docs/developer/how-to/run-tests.rst +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/docs/developer/how-to/static-analysis.rst +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/docs/developer/how-to/test-container.rst +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/docs/developer/how-to/update-tools.rst +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/docs/developer/index.rst +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/docs/developer/reference/standards.rst +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/docs/developer/tutorials/dev-install.rst +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/docs/genindex.rst +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/docs/images/dls-favicon.ico +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/docs/images/dls-logo.svg +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/docs/images/ec-logs.png +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/docs/images/ec-web.png +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/docs/index.rst +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/docs/user/explanations/docs-structure.rst +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/docs/user/how-to/run-container.rst +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/docs/user/index.rst +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/docs/user/reference/api.rst +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/docs/user/tutorials/installation.rst +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/setup.cfg +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/src/edge_containers_cli/__init__.py +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/src/edge_containers_cli/cmds/__init__.py +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/src/edge_containers_cli/cmds/demo_commands.py +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/src/edge_containers_cli/cmds/monitor.py +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/src/edge_containers_cli/cmds/monitor.tcss +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/src/edge_containers_cli/definitions.py +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/src/edge_containers_cli/globals.py +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/src/edge_containers_cli/logging.py +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/src/edge_containers_cli/shell.py +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/src/edge_containers_cli.egg-info/SOURCES.txt +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/src/edge_containers_cli.egg-info/dependency_links.txt +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/src/edge_containers_cli.egg-info/requires.txt +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/src/edge_containers_cli.egg-info/top_level.txt +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/tests/__init__.py +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/tests/data/bl01t-deployment/apps/values.yaml +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/tests/data/bl01t-services/services/bl01t-ea-test-01/Chart.yaml +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/tests/data/bl01t-services/services/bl01t-ea-test-01/config/ioc.db +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/tests/data/bl01t-services/services/bl01t-ea-test-01/config/ioc.yaml +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/tests/data/bl01t-services/services/bl01t-ea-test-01/templates/configmap.yaml +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/tests/data/bl01t-services/services/bl01t-ea-test-01/values.yaml +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/tests/data/bl01t-services/services/bl01t-ea-test-02/Chart.yaml +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/tests/data/bl01t-services/services/bl01t-ea-test-02/values.yaml +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/tests/data/bl01t-services/services/dls-aravis/Chart.yaml +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/tests/data/bl01t-services/services/dls-aravis/config/ioc.yaml +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/tests/data/bl01t-services/services/dls-aravis/templates/configmap.yaml +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/tests/data/bl01t-services/services/dls-aravis/values.yaml +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/tests/data/bl01t-services/services/values.yaml +0 -0
- {edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/tests/test_demo.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: edge-containers-cli
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.4.0
|
|
4
4
|
Summary: CLI for deploying and managing epics containers IOCs and services
|
|
5
5
|
Author-email: Giles Knap <giles.knap@gmail.com>
|
|
6
6
|
License: Apache License
|
|
@@ -232,6 +232,7 @@ Requires-Dist: pytest-mock; extra == "dev"
|
|
|
232
232
|
Requires-Dist: ruff; extra == "dev"
|
|
233
233
|
Requires-Dist: tox-direct; extra == "dev"
|
|
234
234
|
Requires-Dist: types-mock; extra == "dev"
|
|
235
|
+
Dynamic: license-file
|
|
235
236
|
|
|
236
237
|
[](https://github.com/epics-containers/edge-containers-cli/actions/workflows/ci.yml)
|
|
237
238
|
[](https://codecov.io/gh/epics-containers/edge-containers-cli)
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import sys
|
|
1
3
|
from typing import Optional
|
|
2
4
|
|
|
3
5
|
import typer
|
|
4
6
|
|
|
5
|
-
from edge_containers_cli.cli import cli
|
|
7
|
+
from edge_containers_cli.cli import cli, drop_methods, drop_options, set_optional
|
|
6
8
|
from edge_containers_cli.definitions import ENV, ECBackends, ECContext, ECLogLevels
|
|
7
9
|
|
|
8
10
|
from . import __version__
|
|
@@ -14,6 +16,8 @@ from .utils import init_cleanup
|
|
|
14
16
|
|
|
15
17
|
__all__ = ["main"]
|
|
16
18
|
|
|
19
|
+
DEFAULT_BACKEND = ECBackends.ARGOCD
|
|
20
|
+
|
|
17
21
|
|
|
18
22
|
def version_callback(value: bool):
|
|
19
23
|
if value:
|
|
@@ -23,27 +27,14 @@ def version_callback(value: bool):
|
|
|
23
27
|
|
|
24
28
|
def backend_callback(ctx: typer.Context, backend: ECBackends):
|
|
25
29
|
init_backend(backend)
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
mthd.replace("_", "-") for mthd in ec_backend.get_notimplemented_cmds()
|
|
30
|
-
]
|
|
31
|
-
typer_commands = ctx.command.commands # type: ignore
|
|
32
|
-
for command in not_implemented:
|
|
33
|
-
if command in typer_commands:
|
|
34
|
-
typer_commands.pop(command)
|
|
35
|
-
|
|
36
|
-
# Dynamically drop any cli options as specified
|
|
37
|
-
for cmd_name, drop_params in ec_backend.get_notimplemented_params().items():
|
|
38
|
-
for index, param in enumerate(typer_commands[cmd_name].params):
|
|
39
|
-
if param.name in drop_params:
|
|
40
|
-
typer_commands[cmd_name].params.pop(index)
|
|
41
|
-
|
|
30
|
+
drop_methods(ctx, ec_backend.get_notimplemented_cmds())
|
|
31
|
+
drop_options(ctx, ec_backend.get_notimplemented_params())
|
|
32
|
+
set_optional(ctx, ec_backend.get_optional_params())
|
|
42
33
|
return backend.value
|
|
43
34
|
|
|
44
35
|
|
|
45
36
|
@cli.callback()
|
|
46
|
-
def
|
|
37
|
+
def _main(
|
|
47
38
|
ctx: typer.Context,
|
|
48
39
|
version: Optional[bool] = typer.Option(
|
|
49
40
|
None,
|
|
@@ -67,7 +58,7 @@ def main(
|
|
|
67
58
|
envvar=ENV.target.value,
|
|
68
59
|
),
|
|
69
60
|
backend: ECBackends = typer.Option(
|
|
70
|
-
|
|
61
|
+
DEFAULT_BACKEND,
|
|
71
62
|
"-b",
|
|
72
63
|
"--backend",
|
|
73
64
|
callback=backend_callback,
|
|
@@ -123,7 +114,24 @@ def main(
|
|
|
123
114
|
ec_backend.set_context(context)
|
|
124
115
|
|
|
125
116
|
|
|
117
|
+
def force_backend_callback():
|
|
118
|
+
"""
|
|
119
|
+
Typer does not execute option callbacks before running --help unless the
|
|
120
|
+
option is explicitly provided
|
|
121
|
+
"""
|
|
122
|
+
if "--help" in sys.argv:
|
|
123
|
+
if "-b" not in sys.argv:
|
|
124
|
+
backend = os.environ.get("EC_CLI_BACKEND", DEFAULT_BACKEND)
|
|
125
|
+
sys.argv.insert(1, backend)
|
|
126
|
+
sys.argv.insert(1, "-b")
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def main():
|
|
130
|
+
force_backend_callback()
|
|
131
|
+
cli()
|
|
132
|
+
|
|
133
|
+
|
|
126
134
|
# test with:
|
|
127
135
|
# python -m edge_containers_cli
|
|
128
136
|
if __name__ == "__main__":
|
|
129
|
-
|
|
137
|
+
main()
|
{edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/src/edge_containers_cli/autocomplete.py
RENAMED
|
@@ -33,7 +33,10 @@ def fetch_service_graph(repo: str) -> dict:
|
|
|
33
33
|
if not version_map:
|
|
34
34
|
with new_workdir() as path:
|
|
35
35
|
version_map = create_version_map(
|
|
36
|
-
repo,
|
|
36
|
+
repo,
|
|
37
|
+
Path(globals.SERVICES_DIR),
|
|
38
|
+
path,
|
|
39
|
+
shared_files=[globals.SHARED_VALUES],
|
|
37
40
|
)
|
|
38
41
|
cache_dict(
|
|
39
42
|
globals.CACHE_ROOT / url_encode(repo),
|
|
@@ -40,7 +40,10 @@ cli = ErrorHandlingTyper(pretty_exceptions_show_locals=False)
|
|
|
40
40
|
@cli.command()
|
|
41
41
|
def attach(
|
|
42
42
|
service_name: str = typer.Argument(
|
|
43
|
-
...,
|
|
43
|
+
...,
|
|
44
|
+
help="Name of the service to attach to",
|
|
45
|
+
autocompletion=running_svc,
|
|
46
|
+
show_default=False,
|
|
44
47
|
),
|
|
45
48
|
):
|
|
46
49
|
"""
|
|
@@ -52,15 +55,18 @@ def attach(
|
|
|
52
55
|
@cli.command()
|
|
53
56
|
def delete(
|
|
54
57
|
service_name: str = typer.Argument(
|
|
55
|
-
...,
|
|
58
|
+
...,
|
|
59
|
+
help="Name of the service to delete",
|
|
60
|
+
autocompletion=all_svc,
|
|
61
|
+
show_default=False,
|
|
56
62
|
),
|
|
57
63
|
yes: bool = typer.Option(False, "-y", "--yes", help="Skip confirmation prompt"),
|
|
58
64
|
):
|
|
59
65
|
"""
|
|
60
|
-
Remove a
|
|
66
|
+
Remove a service from the cluster
|
|
61
67
|
"""
|
|
62
68
|
confirmation(
|
|
63
|
-
f"Remove
|
|
69
|
+
f"Remove {service_name} from the target `{backend.commands.target}`",
|
|
64
70
|
yes,
|
|
65
71
|
)
|
|
66
72
|
backend.commands.delete(service_name)
|
|
@@ -69,12 +75,16 @@ def delete(
|
|
|
69
75
|
@cli.command()
|
|
70
76
|
def deploy(
|
|
71
77
|
service_name: str = typer.Argument(
|
|
72
|
-
...,
|
|
78
|
+
...,
|
|
79
|
+
help="Name of the service to deploy",
|
|
80
|
+
autocompletion=avail_services,
|
|
81
|
+
show_default=False,
|
|
73
82
|
),
|
|
74
83
|
version: str = typer.Argument(
|
|
75
|
-
|
|
76
|
-
help="Version tag of the service to deploy",
|
|
84
|
+
"latest tag",
|
|
85
|
+
help="Version tag or branch of the service to deploy",
|
|
77
86
|
autocompletion=avail_versions,
|
|
87
|
+
show_default=False,
|
|
78
88
|
),
|
|
79
89
|
wait: bool = typer.Option(False, "--wait", help="Waits for readiness"),
|
|
80
90
|
yes: bool = typer.Option(False, "-y", "--yes", help="Skip confirmation prompt"),
|
|
@@ -83,15 +93,19 @@ def deploy(
|
|
|
83
93
|
),
|
|
84
94
|
):
|
|
85
95
|
"""
|
|
86
|
-
|
|
96
|
+
Add a service to the cluster from its source repository
|
|
87
97
|
"""
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
98
|
+
|
|
99
|
+
def confirm_callback(svc_version):
|
|
100
|
+
confirmation(
|
|
101
|
+
f"Deploy {service_name.lower()} "
|
|
102
|
+
f"of version `{svc_version}` to target `{backend.commands.target}`",
|
|
103
|
+
yes,
|
|
104
|
+
)
|
|
105
|
+
|
|
93
106
|
args = args if not wait else args + " --wait"
|
|
94
|
-
|
|
107
|
+
version = version if version != "latest tag" else ""
|
|
108
|
+
backend.commands.deploy(service_name, version, args, confirm_callback)
|
|
95
109
|
|
|
96
110
|
|
|
97
111
|
@cli.command()
|
|
@@ -103,19 +117,23 @@ def deploy_local(
|
|
|
103
117
|
file_okay=False,
|
|
104
118
|
resolve_path=True,
|
|
105
119
|
autocompletion=force_plain_completion,
|
|
120
|
+
show_default=False,
|
|
106
121
|
),
|
|
107
122
|
yes: bool = typer.Option(False, "-y", "--yes", help="Skip confirmation prompt"),
|
|
108
123
|
args: str = typer.Option("", help="Additional args for helm, 'must be quoted'"),
|
|
109
124
|
):
|
|
110
125
|
"""
|
|
111
|
-
|
|
126
|
+
Add a local service helm chart directly to the cluster with dated beta version
|
|
112
127
|
"""
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
128
|
+
|
|
129
|
+
def confirm_callback(svc_version):
|
|
130
|
+
confirmation(
|
|
131
|
+
f"Deploy local {svc_instance.name.lower()} of version `{svc_version}` "
|
|
132
|
+
f"from {svc_instance} to target `{backend.commands.target}`",
|
|
133
|
+
yes,
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
backend.commands.deploy_local(svc_instance, args, confirm_callback)
|
|
119
137
|
|
|
120
138
|
|
|
121
139
|
@cli.command()
|
|
@@ -131,6 +149,7 @@ def exec(
|
|
|
131
149
|
...,
|
|
132
150
|
help="Name of the service container to run in",
|
|
133
151
|
autocompletion=running_svc,
|
|
152
|
+
show_default=False,
|
|
134
153
|
),
|
|
135
154
|
):
|
|
136
155
|
"""Execute a bash prompt in a running container"""
|
|
@@ -140,7 +159,10 @@ def exec(
|
|
|
140
159
|
@cli.command()
|
|
141
160
|
def instances(
|
|
142
161
|
service_name: str = typer.Argument(
|
|
143
|
-
...,
|
|
162
|
+
...,
|
|
163
|
+
help="Name of the service to inspect",
|
|
164
|
+
autocompletion=avail_services,
|
|
165
|
+
show_default=False,
|
|
144
166
|
),
|
|
145
167
|
):
|
|
146
168
|
"""List all versions of the specified service in the repository"""
|
|
@@ -149,19 +171,19 @@ def instances(
|
|
|
149
171
|
service_name,
|
|
150
172
|
backend.commands.repo,
|
|
151
173
|
Path(globals.SERVICES_DIR),
|
|
152
|
-
|
|
174
|
+
shared_files=[globals.SHARED_VALUES],
|
|
153
175
|
)
|
|
154
176
|
)
|
|
155
177
|
|
|
156
178
|
|
|
157
|
-
@cli.command()
|
|
158
|
-
def
|
|
179
|
+
@cli.command(name="list")
|
|
180
|
+
def _list():
|
|
159
181
|
"""List all services available in the service repository"""
|
|
160
182
|
print(
|
|
161
183
|
list_all(
|
|
162
184
|
backend.commands.repo,
|
|
163
185
|
Path(globals.SERVICES_DIR),
|
|
164
|
-
|
|
186
|
+
shared_files=[globals.SHARED_VALUES],
|
|
165
187
|
)
|
|
166
188
|
)
|
|
167
189
|
|
|
@@ -172,16 +194,20 @@ def log_history(
|
|
|
172
194
|
...,
|
|
173
195
|
help="Name of the service to inspect",
|
|
174
196
|
autocompletion=all_svc,
|
|
197
|
+
show_default=False,
|
|
175
198
|
),
|
|
176
199
|
):
|
|
177
|
-
"""Open historical logs for
|
|
200
|
+
"""Open historical logs for a service"""
|
|
178
201
|
backend.commands.log_history(service_name)
|
|
179
202
|
|
|
180
203
|
|
|
181
204
|
@cli.command()
|
|
182
205
|
def logs(
|
|
183
206
|
service_name: str = typer.Argument(
|
|
184
|
-
...,
|
|
207
|
+
...,
|
|
208
|
+
help="Name of the service to inspect",
|
|
209
|
+
autocompletion=running_svc,
|
|
210
|
+
show_default=False,
|
|
185
211
|
),
|
|
186
212
|
prev: bool = typer.Option(
|
|
187
213
|
False,
|
|
@@ -190,7 +216,7 @@ def logs(
|
|
|
190
216
|
help="Show log from the previous instance of the service",
|
|
191
217
|
),
|
|
192
218
|
):
|
|
193
|
-
"""Show logs for current and previous instances of
|
|
219
|
+
"""Show logs for current and previous instances of a service"""
|
|
194
220
|
backend.commands.logs(service_name, prev)
|
|
195
221
|
|
|
196
222
|
|
|
@@ -200,7 +226,7 @@ def monitor(
|
|
|
200
226
|
False, "-r", "--running-only", help="list only services that are running"
|
|
201
227
|
),
|
|
202
228
|
):
|
|
203
|
-
"""Open monitor TUI
|
|
229
|
+
"""Open monitor TUI"""
|
|
204
230
|
from edge_containers_cli.cmds.monitor import (
|
|
205
231
|
MonitorApp, # Lazy import for performace
|
|
206
232
|
)
|
|
@@ -222,7 +248,10 @@ def ps(
|
|
|
222
248
|
@cli.command()
|
|
223
249
|
def restart(
|
|
224
250
|
service_name: str = typer.Argument(
|
|
225
|
-
...,
|
|
251
|
+
...,
|
|
252
|
+
help="Name of the container to restart",
|
|
253
|
+
autocompletion=running_svc,
|
|
254
|
+
show_default=False,
|
|
226
255
|
),
|
|
227
256
|
):
|
|
228
257
|
"""Restart a service"""
|
|
@@ -232,7 +261,10 @@ def restart(
|
|
|
232
261
|
@cli.command()
|
|
233
262
|
def start(
|
|
234
263
|
service_name: str = typer.Argument(
|
|
235
|
-
...,
|
|
264
|
+
...,
|
|
265
|
+
help="Name of the service container to start",
|
|
266
|
+
autocompletion=all_svc,
|
|
267
|
+
show_default=False,
|
|
236
268
|
),
|
|
237
269
|
commit: bool = typer.Option(False, help="Commits the values to the git repo"),
|
|
238
270
|
):
|
|
@@ -250,6 +282,7 @@ def stop(
|
|
|
250
282
|
...,
|
|
251
283
|
help="Name of the service container to stop",
|
|
252
284
|
autocompletion=running_svc,
|
|
285
|
+
show_default=False,
|
|
253
286
|
),
|
|
254
287
|
commit: bool = typer.Option(False, help="Commits the values to the git repo"),
|
|
255
288
|
):
|
|
@@ -270,6 +303,7 @@ def template(
|
|
|
270
303
|
file_okay=False,
|
|
271
304
|
resolve_path=True,
|
|
272
305
|
autocompletion=force_plain_completion,
|
|
306
|
+
show_default=False,
|
|
273
307
|
),
|
|
274
308
|
args: str = typer.Option("", help="Additional args for helm, 'must be quoted'"),
|
|
275
309
|
):
|
|
@@ -278,3 +312,30 @@ def template(
|
|
|
278
312
|
"""
|
|
279
313
|
args = f"{args} --debug"
|
|
280
314
|
backend.commands.template(svc_instance, args)
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
def drop_methods(ctx: typer.Context, to_drop: list[str]):
|
|
318
|
+
"""Dynamically drop any method not implemented"""
|
|
319
|
+
not_implemented = [mthd.replace("_", "-") for mthd in to_drop]
|
|
320
|
+
typer_commands = ctx.command.commands # type: ignore
|
|
321
|
+
for command in not_implemented:
|
|
322
|
+
if command in typer_commands:
|
|
323
|
+
typer_commands.pop(command)
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
def drop_options(ctx: typer.Context, to_drop: dict[str, list[str]]):
|
|
327
|
+
"""Dynamically drop any cli options as specified"""
|
|
328
|
+
typer_commands = ctx.command.commands # type: ignore
|
|
329
|
+
for cmd_name, drop_params in to_drop.items():
|
|
330
|
+
for i, param in enumerate(typer_commands[cmd_name].params):
|
|
331
|
+
if param.name in drop_params:
|
|
332
|
+
typer_commands[cmd_name].params.pop(i)
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
def set_optional(ctx: typer.Context, to_set: dict[str, list[str]]):
|
|
336
|
+
"""Dynamically set any cli options optional as specified"""
|
|
337
|
+
typer_commands = ctx.command.commands # type: ignore
|
|
338
|
+
for cmd_name, optional_params in to_set.items():
|
|
339
|
+
for i, param in enumerate(typer_commands[cmd_name].params):
|
|
340
|
+
if param.name in optional_params:
|
|
341
|
+
typer_commands[cmd_name].params[i].required = False
|
|
@@ -4,6 +4,7 @@ implements commands for deploying and managing service instances suing argocd
|
|
|
4
4
|
Relies on the Helm class for deployment aspects.
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
|
+
import re
|
|
7
8
|
import webbrowser
|
|
8
9
|
from datetime import datetime
|
|
9
10
|
from pathlib import Path
|
|
@@ -12,6 +13,7 @@ from time import sleep
|
|
|
12
13
|
import polars
|
|
13
14
|
from ruamel.yaml import YAML
|
|
14
15
|
|
|
16
|
+
from edge_containers_cli import globals
|
|
15
17
|
from edge_containers_cli.cmds.commands import (
|
|
16
18
|
CommandError,
|
|
17
19
|
Commands,
|
|
@@ -19,10 +21,10 @@ from edge_containers_cli.cmds.commands import (
|
|
|
19
21
|
ServicesSchema,
|
|
20
22
|
)
|
|
21
23
|
from edge_containers_cli.definitions import ECContext
|
|
22
|
-
from edge_containers_cli.git import
|
|
23
|
-
from edge_containers_cli.globals import TIME_FORMAT
|
|
24
|
+
from edge_containers_cli.git import del_key, set_value
|
|
24
25
|
from edge_containers_cli.logging import log
|
|
25
26
|
from edge_containers_cli.shell import ShellError, shell
|
|
27
|
+
from edge_containers_cli.utils import YamlTypes
|
|
26
28
|
|
|
27
29
|
|
|
28
30
|
def extract_ns_app(target: str) -> tuple[str, str]:
|
|
@@ -30,6 +32,18 @@ def extract_ns_app(target: str) -> tuple[str, str]:
|
|
|
30
32
|
return namespace, app
|
|
31
33
|
|
|
32
34
|
|
|
35
|
+
def get_patches(target) -> dict:
|
|
36
|
+
app_resp = shell.run_command(
|
|
37
|
+
f"argocd app get --show-params {target} -o json",
|
|
38
|
+
)
|
|
39
|
+
app_dicts = YAML(typ="safe").load(app_resp)
|
|
40
|
+
try:
|
|
41
|
+
patch_dict = app_dicts["spec"]["source"]["helm"]["parameters"]
|
|
42
|
+
except KeyError:
|
|
43
|
+
patch_dict = {}
|
|
44
|
+
return patch_dict
|
|
45
|
+
|
|
46
|
+
|
|
33
47
|
def do_retry(cmd):
|
|
34
48
|
def _do_retry(*args, **kwargs):
|
|
35
49
|
max_attempts = 5
|
|
@@ -52,14 +66,14 @@ def do_retry(cmd):
|
|
|
52
66
|
|
|
53
67
|
|
|
54
68
|
@do_retry
|
|
55
|
-
def patch_value(target: str, key: str, value:
|
|
69
|
+
def patch_value(target: str, key: str, value: YamlTypes):
|
|
56
70
|
cmd_temp_ = f"argocd app set {target} -p {key}={value}"
|
|
57
71
|
shell.run_command(cmd_temp_, skip_on_dryrun=True)
|
|
58
72
|
# Rely on argocd autosync to get the cluster into the right state
|
|
59
73
|
|
|
60
74
|
|
|
61
75
|
@do_retry
|
|
62
|
-
def push_value(target: str, key: str, value:
|
|
76
|
+
def push_value(target: str, key: str, value: YamlTypes):
|
|
63
77
|
# Get source details
|
|
64
78
|
app_resp = shell.run_command(
|
|
65
79
|
f"argocd app get {target} -o yaml",
|
|
@@ -68,12 +82,7 @@ def push_value(target: str, key: str, value: str | bool | int):
|
|
|
68
82
|
repo_url = app_dicts["spec"]["source"]["repoURL"]
|
|
69
83
|
path = Path(app_dicts["spec"]["source"]["path"])
|
|
70
84
|
|
|
71
|
-
|
|
72
|
-
repo_url,
|
|
73
|
-
path / "values.yaml",
|
|
74
|
-
key,
|
|
75
|
-
value,
|
|
76
|
-
)
|
|
85
|
+
set_value(repo_url, path / "values.yaml", key, value)
|
|
77
86
|
|
|
78
87
|
# Free a possible patched value & refresh repo
|
|
79
88
|
cmd_unset = f"argocd app unset {target} -p {key}"
|
|
@@ -83,17 +92,65 @@ def push_value(target: str, key: str, value: str | bool | int):
|
|
|
83
92
|
# Rely on argocd autosync to get the cluster into the right state
|
|
84
93
|
|
|
85
94
|
|
|
95
|
+
@do_retry
|
|
96
|
+
def push_remove_key(target: str, key: str):
|
|
97
|
+
# Get source details
|
|
98
|
+
app_resp = shell.run_command(
|
|
99
|
+
f"argocd app get {target} -o yaml",
|
|
100
|
+
)
|
|
101
|
+
app_dicts = YAML(typ="safe").load(app_resp)
|
|
102
|
+
repo_url = app_dicts["spec"]["source"]["repoURL"]
|
|
103
|
+
path = Path(app_dicts["spec"]["source"]["path"])
|
|
104
|
+
|
|
105
|
+
del_key(repo_url, path / "values.yaml", key)
|
|
106
|
+
|
|
107
|
+
# Free a possible patched value, its children & refresh repo
|
|
108
|
+
cmd_unset = f"argocd app unset {target} -p {key}"
|
|
109
|
+
shell.run_command(cmd_unset, skip_on_dryrun=True)
|
|
110
|
+
app_patches = get_patches(target)
|
|
111
|
+
for patch in app_patches:
|
|
112
|
+
if re.match(rf"{key}\..*", patch["name"]):
|
|
113
|
+
cmd_unset_child = f"argocd app unset {target} -p {patch['name']}"
|
|
114
|
+
shell.run_command(cmd_unset_child, skip_on_dryrun=True)
|
|
115
|
+
cmd_refresh = f"argocd app get {target} --refresh"
|
|
116
|
+
shell.run_command(cmd_refresh, skip_on_dryrun=True)
|
|
117
|
+
# Rely on argocd autosync to get the cluster into the right state
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def get_services_repo(deployment_repo_url: str) -> str:
|
|
121
|
+
services_repo_url = ""
|
|
122
|
+
return services_repo_url
|
|
123
|
+
|
|
124
|
+
|
|
86
125
|
class ArgoCommands(Commands):
|
|
87
126
|
"""
|
|
88
127
|
A class for implementing the Kubernetes based commands
|
|
89
128
|
"""
|
|
90
129
|
|
|
130
|
+
params_opt_out = {
|
|
131
|
+
"deploy": ["args", "wait"],
|
|
132
|
+
}
|
|
133
|
+
|
|
91
134
|
def __init__(
|
|
92
135
|
self,
|
|
93
136
|
ctx: ECContext,
|
|
94
137
|
):
|
|
95
138
|
super().__init__(ctx)
|
|
96
139
|
|
|
140
|
+
def delete(self, service_name: str) -> None:
|
|
141
|
+
self._check_service(service_name)
|
|
142
|
+
push_remove_key(self.target, f"ec_services.{service_name}")
|
|
143
|
+
|
|
144
|
+
def deploy(self, service_name, version, args, confirm_callback=None) -> None:
|
|
145
|
+
latest_version = self._get_latest_version(service_name)
|
|
146
|
+
if not version:
|
|
147
|
+
version = latest_version
|
|
148
|
+
if confirm_callback:
|
|
149
|
+
confirm_callback(version)
|
|
150
|
+
deploy_dict: YamlTypes = {"enabled": True, "targetRevision": version}
|
|
151
|
+
|
|
152
|
+
push_value(self.target, f"ec_services.{service_name}", deploy_dict)
|
|
153
|
+
|
|
97
154
|
def logs(self, service_name, prev):
|
|
98
155
|
self._logs(service_name, prev)
|
|
99
156
|
|
|
@@ -153,7 +210,10 @@ class ArgoCommands(Commands):
|
|
|
153
210
|
|
|
154
211
|
if app_dicts:
|
|
155
212
|
for app in app_dicts:
|
|
156
|
-
|
|
213
|
+
try:
|
|
214
|
+
resources_dict = app["status"]["resources"]
|
|
215
|
+
except KeyError:
|
|
216
|
+
continue
|
|
157
217
|
|
|
158
218
|
for resource in resources_dict:
|
|
159
219
|
is_ready = False
|
|
@@ -188,7 +248,7 @@ class ArgoCommands(Commands):
|
|
|
188
248
|
)
|
|
189
249
|
service_data["ready"].append(is_ready)
|
|
190
250
|
service_data["deployed"].append(
|
|
191
|
-
datetime.strftime(time_stamp, TIME_FORMAT)
|
|
251
|
+
datetime.strftime(time_stamp, globals.TIME_FORMAT)
|
|
192
252
|
)
|
|
193
253
|
|
|
194
254
|
services_df = polars.from_dict(service_data, schema=ServicesSchema)
|
{edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/src/edge_containers_cli/cmds/commands.py
RENAMED
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
from abc import ABC, abstractmethod
|
|
2
|
+
from collections.abc import Callable
|
|
2
3
|
from pathlib import Path
|
|
3
4
|
|
|
4
5
|
import polars
|
|
6
|
+
from natsort import natsorted
|
|
5
7
|
|
|
8
|
+
from edge_containers_cli import globals
|
|
6
9
|
from edge_containers_cli.definitions import ENV, ECContext
|
|
10
|
+
from edge_containers_cli.git import create_version_map
|
|
7
11
|
from edge_containers_cli.logging import log
|
|
12
|
+
from edge_containers_cli.utils import new_workdir
|
|
8
13
|
|
|
9
14
|
|
|
10
15
|
class CommandError(Exception):
|
|
@@ -39,7 +44,8 @@ class Commands(ABC):
|
|
|
39
44
|
Methods not exposed to the CLI should be private
|
|
40
45
|
"""
|
|
41
46
|
|
|
42
|
-
params_opt_out: dict[str, list[str]] = {} #
|
|
47
|
+
params_opt_out: dict[str, list[str]] = {} # Drop parameters from the CLI
|
|
48
|
+
params_optional: dict[str, list[str]] = {} # Set optional parameters from the CLI
|
|
43
49
|
|
|
44
50
|
def __init__(self, ctx: ECContext):
|
|
45
51
|
self._target = ctx.target
|
|
@@ -108,10 +114,21 @@ class Commands(ABC):
|
|
|
108
114
|
def delete(self, service_name: str) -> None:
|
|
109
115
|
raise NotImplementedError
|
|
110
116
|
|
|
111
|
-
def deploy(
|
|
117
|
+
def deploy(
|
|
118
|
+
self,
|
|
119
|
+
service_name: str,
|
|
120
|
+
version: str,
|
|
121
|
+
args: str,
|
|
122
|
+
confirm_callback: Callable[[str], None] | None = None,
|
|
123
|
+
) -> None:
|
|
112
124
|
raise NotImplementedError
|
|
113
125
|
|
|
114
|
-
def deploy_local(
|
|
126
|
+
def deploy_local(
|
|
127
|
+
self,
|
|
128
|
+
svc_instance: Path,
|
|
129
|
+
args: str,
|
|
130
|
+
confirm_callback: Callable[[str], None] | None = None,
|
|
131
|
+
) -> None:
|
|
115
132
|
raise NotImplementedError
|
|
116
133
|
|
|
117
134
|
def exec(self, service_name: str) -> None:
|
|
@@ -171,3 +188,27 @@ class Commands(ABC):
|
|
|
171
188
|
pass
|
|
172
189
|
else:
|
|
173
190
|
raise CommandError(f"Service '{service_name}' not found in {self.target}")
|
|
191
|
+
|
|
192
|
+
def _get_latest_version(self, service_name) -> str:
|
|
193
|
+
with new_workdir() as path:
|
|
194
|
+
version_map = create_version_map(
|
|
195
|
+
self.repo,
|
|
196
|
+
Path(globals.SERVICES_DIR),
|
|
197
|
+
path,
|
|
198
|
+
shared_files=[globals.SHARED_VALUES],
|
|
199
|
+
)
|
|
200
|
+
svc_list = version_map.keys()
|
|
201
|
+
log.debug(f"Found the following services: {svc_list}")
|
|
202
|
+
if service_name not in svc_list:
|
|
203
|
+
raise CommandError(f"Service '{service_name}' not found in {self.repo}")
|
|
204
|
+
|
|
205
|
+
version_list = natsorted(version_map[service_name])
|
|
206
|
+
log.debug(f"Found the following versions of {service_name}: {version_list}")
|
|
207
|
+
try:
|
|
208
|
+
version = version_list[-1]
|
|
209
|
+
except IndexError as err:
|
|
210
|
+
raise CommandError(
|
|
211
|
+
f"No versions of '{service_name}' found in {self.repo}"
|
|
212
|
+
) from err
|
|
213
|
+
|
|
214
|
+
return version
|
{edge_containers_cli-4.3.1 → edge_containers_cli-4.4.0}/src/edge_containers_cli/cmds/helm.py
RENAMED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from collections.abc import Callable
|
|
1
2
|
from pathlib import Path
|
|
2
3
|
from typing import Optional
|
|
3
4
|
|
|
@@ -50,19 +51,25 @@ class Helm:
|
|
|
50
51
|
for package in service_path.glob("*.tgz"):
|
|
51
52
|
package.unlink(missing_ok=True)
|
|
52
53
|
|
|
53
|
-
def deploy_local(
|
|
54
|
+
def deploy_local(
|
|
55
|
+
self, service_path: Path, confirm_callback: Callable[[str], None] | None = None
|
|
56
|
+
):
|
|
54
57
|
"""
|
|
55
58
|
Deploy a local helm chart directly to the cluster with dated beta version
|
|
56
59
|
"""
|
|
57
60
|
|
|
61
|
+
if confirm_callback:
|
|
62
|
+
confirm_callback(self.version)
|
|
58
63
|
validate_instance_path(service_path)
|
|
59
64
|
self.cleanup_chart(service_path)
|
|
60
65
|
self._do_deploy(service_path)
|
|
61
66
|
|
|
62
|
-
def deploy(self):
|
|
67
|
+
def deploy(self, confirm_callback: Callable[[str], None] | None = None):
|
|
63
68
|
"""
|
|
64
69
|
Clone a helm chart and deploy it to the cluster
|
|
65
70
|
"""
|
|
71
|
+
if confirm_callback:
|
|
72
|
+
confirm_callback(self.version)
|
|
66
73
|
shell.run_command(
|
|
67
74
|
f"git clone {self.repo} {self.tmp} --depth=1 "
|
|
68
75
|
f"--single-branch --branch={self.version}",
|