edge-containers-cli 4.2.1__tar.gz → 4.3.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.2.1 → edge_containers_cli-4.3.0}/.copier-answers.yml +1 -1
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/.devcontainer/devcontainer.json +4 -4
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/.github/CONTRIBUTING.md +1 -1
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/.github/workflows/_pypi.yml +2 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/.github/workflows/_release.yml +1 -1
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/.github/workflows/_test.yml +1 -1
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/.vscode/launch.json +13 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/Dockerfile +1 -1
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/PKG-INFO +3 -3
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/README.md +1 -1
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/src/edge_containers_cli/_version.py +9 -4
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/src/edge_containers_cli/cli.py +2 -2
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/src/edge_containers_cli/cmds/argo_commands.py +80 -49
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/src/edge_containers_cli/cmds/commands.py +30 -2
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/src/edge_containers_cli/cmds/demo_commands.py +29 -12
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/src/edge_containers_cli/cmds/helm.py +1 -1
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/src/edge_containers_cli/cmds/k8s_commands.py +33 -21
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/src/edge_containers_cli/cmds/monitor.py +245 -178
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/src/edge_containers_cli/cmds/monitor.tcss +12 -8
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/src/edge_containers_cli/definitions.py +9 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/src/edge_containers_cli/git.py +3 -1
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/src/edge_containers_cli/logging.py +1 -1
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/src/edge_containers_cli/shell.py +1 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/src/edge_containers_cli/utils.py +22 -5
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/src/edge_containers_cli.egg-info/PKG-INFO +3 -3
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/tests/data/argocd.yaml +4 -8
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/tests/data/yaml.yaml +1 -1
- edge_containers_cli-4.3.0/tests/test_demo.py +37 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/tests/test_unit.py +9 -4
- edge_containers_cli-4.2.1/tests/test_demo.py +0 -32
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/.github/ISSUE_TEMPLATE/issue.md +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/.github/actions/install_requirements/action.yml +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/.github/dependabot.yml +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/.github/pages/index.html +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/.github/pages/make_switcher.py +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/.github/workflows/_check.yml +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/.github/workflows/_dist.yml +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/.github/workflows/_tox.yml +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/.github/workflows/ci.yml +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/.gitignore +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/.pre-commit-config.yaml +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/.vscode/extensions.json +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/.vscode/settings.json +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/.vscode/tasks.json +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/LICENSE +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/docs/conf.py +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/docs/developer/explanations/decisions/0001-record-architecture-decisions.rst +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/docs/developer/explanations/decisions/0002-switched-to-pip-skeleton.rst +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/docs/developer/explanations/decisions.rst +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/docs/developer/how-to/build-docs.rst +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/docs/developer/how-to/contribute.rst +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/docs/developer/how-to/lint.rst +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/docs/developer/how-to/make-release.rst +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/docs/developer/how-to/pin-requirements.rst +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/docs/developer/how-to/run-tests.rst +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/docs/developer/how-to/static-analysis.rst +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/docs/developer/how-to/test-container.rst +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/docs/developer/how-to/update-tools.rst +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/docs/developer/index.rst +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/docs/developer/reference/standards.rst +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/docs/developer/tutorials/dev-install.rst +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/docs/genindex.rst +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/docs/images/dls-favicon.ico +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/docs/images/dls-logo.svg +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/docs/images/ec-logs.png +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/docs/images/ec-web.png +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/docs/index.rst +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/docs/user/explanations/docs-structure.rst +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/docs/user/how-to/run-container.rst +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/docs/user/index.rst +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/docs/user/reference/api.rst +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/docs/user/tutorials/installation.rst +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/pyproject.toml +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/setup.cfg +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/src/edge_containers_cli/__init__.py +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/src/edge_containers_cli/__main__.py +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/src/edge_containers_cli/autocomplete.py +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/src/edge_containers_cli/backend.py +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/src/edge_containers_cli/cmds/__init__.py +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/src/edge_containers_cli/globals.py +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/src/edge_containers_cli.egg-info/SOURCES.txt +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/src/edge_containers_cli.egg-info/dependency_links.txt +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/src/edge_containers_cli.egg-info/entry_points.txt +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/src/edge_containers_cli.egg-info/requires.txt +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/src/edge_containers_cli.egg-info/top_level.txt +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/tests/__init__.py +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/tests/conftest.py +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/tests/data/bl01t-deployment/apps/values.yaml +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/tests/data/bl01t-services/services/bl01t-ea-test-01/Chart.yaml +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/tests/data/bl01t-services/services/bl01t-ea-test-01/config/ioc.db +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/tests/data/bl01t-services/services/bl01t-ea-test-01/config/ioc.yaml +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/tests/data/bl01t-services/services/bl01t-ea-test-01/templates/configmap.yaml +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/tests/data/bl01t-services/services/bl01t-ea-test-01/values.yaml +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/tests/data/bl01t-services/services/bl01t-ea-test-02/Chart.yaml +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/tests/data/bl01t-services/services/bl01t-ea-test-02/values.yaml +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/tests/data/bl01t-services/services/dls-aravis/Chart.yaml +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/tests/data/bl01t-services/services/dls-aravis/config/ioc.yaml +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/tests/data/bl01t-services/services/dls-aravis/templates/configmap.yaml +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/tests/data/bl01t-services/services/dls-aravis/values.yaml +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/tests/data/bl01t-services/services/values.yaml +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/tests/data/cli.yaml +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/tests/data/k8s.yaml +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/tests/test_argocd.py +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/tests/test_cli.py +0 -0
- {edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/tests/test_k8s.py +0 -0
|
@@ -28,11 +28,11 @@
|
|
|
28
28
|
}
|
|
29
29
|
},
|
|
30
30
|
"features": {
|
|
31
|
-
//
|
|
32
|
-
"ghcr.io/
|
|
33
|
-
"upgradePackages": false
|
|
34
|
-
}
|
|
31
|
+
// add in eternal history and other bash features
|
|
32
|
+
"ghcr.io/diamondlightsource/devcontainer-features/bash-config:1.0.0": {}
|
|
35
33
|
},
|
|
34
|
+
// Create the config folder for the bash-config feature
|
|
35
|
+
"initializeCommand": "mkdir -p ${localEnv:HOME}/.config/bash-config",
|
|
36
36
|
"runArgs": [
|
|
37
37
|
// Allow the container to access the host X11 display and EPICS CA
|
|
38
38
|
"--net=host",
|
|
@@ -24,4 +24,4 @@ It is recommended that developers use a [vscode devcontainer](https://code.visua
|
|
|
24
24
|
|
|
25
25
|
This project was created using the [Diamond Light Source Copier Template](https://github.com/DiamondLightSource/python-copier-template) for Python projects.
|
|
26
26
|
|
|
27
|
-
For more information on common tasks like setting up a developer environment, running the tests, and setting a pre-commit hook, see the template's [How-to guides](https://diamondlightsource.github.io/python-copier-template/2.
|
|
27
|
+
For more information on common tasks like setting up a developer environment, running the tests, and setting a pre-commit hook, see the template's [How-to guides](https://diamondlightsource.github.io/python-copier-template/2.6.0/how-to.html).
|
|
@@ -23,7 +23,7 @@ jobs:
|
|
|
23
23
|
- name: Create GitHub Release
|
|
24
24
|
# We pin to the SHA, not the tag, for security reasons.
|
|
25
25
|
# https://docs.github.com/en/actions/learn-github-actions/security-hardening-for-github-actions#using-third-party-actions
|
|
26
|
-
uses: softprops/action-gh-release@
|
|
26
|
+
uses: softprops/action-gh-release@c95fe1489396fe8a9eb87c0abf8aa5b2ef267fda # v2.2.1
|
|
27
27
|
with:
|
|
28
28
|
prerelease: ${{ contains(github.ref_name, 'a') || contains(github.ref_name, 'b') || contains(github.ref_name, 'rc') }}
|
|
29
29
|
files: "*"
|
|
@@ -18,6 +18,19 @@
|
|
|
18
18
|
// Enable break on exception when debugging tests (see: tests/conftest.py)
|
|
19
19
|
"PYTEST_RAISE": "1",
|
|
20
20
|
},
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"name": "Debug Monitor",
|
|
24
|
+
"type": "debugpy",
|
|
25
|
+
"request": "launch",
|
|
26
|
+
"module": "edge_containers_cli",
|
|
27
|
+
"args": [
|
|
28
|
+
"monitor"
|
|
29
|
+
],
|
|
30
|
+
"console": "integratedTerminal",
|
|
31
|
+
"env": {
|
|
32
|
+
"EC_CLI_BACKEND": "DEMO",
|
|
33
|
+
},
|
|
21
34
|
}
|
|
22
35
|
]
|
|
23
36
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# The devcontainer should use the developer target and run as root with podman
|
|
2
2
|
# or docker with user namespaces.
|
|
3
3
|
ARG PYTHON_VERSION=3.11
|
|
4
|
-
FROM python:${PYTHON_VERSION}
|
|
4
|
+
FROM python:${PYTHON_VERSION} AS developer
|
|
5
5
|
|
|
6
6
|
# Add any system dependencies for the developer/build environment here
|
|
7
7
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: edge-containers-cli
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.3.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
|
|
@@ -236,7 +236,7 @@ Requires-Dist: types-mock; extra == "dev"
|
|
|
236
236
|
[](https://github.com/epics-containers/edge-containers-cli/actions/workflows/ci.yml)
|
|
237
237
|
[](https://codecov.io/gh/epics-containers/edge-containers-cli)
|
|
238
238
|
[](https://pypi.org/project/edge-containers-cli)
|
|
239
|
-
[](https://
|
|
239
|
+
[](https://www.apache.org/licenses/LICENSE-2.0)
|
|
240
240
|
|
|
241
241
|
# edge_containers_cli
|
|
242
242
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
[](https://github.com/epics-containers/edge-containers-cli/actions/workflows/ci.yml)
|
|
2
2
|
[](https://codecov.io/gh/epics-containers/edge-containers-cli)
|
|
3
3
|
[](https://pypi.org/project/edge-containers-cli)
|
|
4
|
-
[](https://
|
|
4
|
+
[](https://www.apache.org/licenses/LICENSE-2.0)
|
|
5
5
|
|
|
6
6
|
# edge_containers_cli
|
|
7
7
|
|
|
@@ -1,8 +1,13 @@
|
|
|
1
|
-
# file generated by
|
|
1
|
+
# file generated by setuptools-scm
|
|
2
2
|
# don't change, don't track in version control
|
|
3
|
+
|
|
4
|
+
__all__ = ["__version__", "__version_tuple__", "version", "version_tuple"]
|
|
5
|
+
|
|
3
6
|
TYPE_CHECKING = False
|
|
4
7
|
if TYPE_CHECKING:
|
|
5
|
-
from typing import Tuple
|
|
8
|
+
from typing import Tuple
|
|
9
|
+
from typing import Union
|
|
10
|
+
|
|
6
11
|
VERSION_TUPLE = Tuple[Union[int, str], ...]
|
|
7
12
|
else:
|
|
8
13
|
VERSION_TUPLE = object
|
|
@@ -12,5 +17,5 @@ __version__: str
|
|
|
12
17
|
__version_tuple__: VERSION_TUPLE
|
|
13
18
|
version_tuple: VERSION_TUPLE
|
|
14
19
|
|
|
15
|
-
__version__ = version = '4.
|
|
16
|
-
__version_tuple__ = version_tuple = (4,
|
|
20
|
+
__version__ = version = '4.3.0'
|
|
21
|
+
__version_tuple__ = version_tuple = (4, 3, 0)
|
|
@@ -238,7 +238,7 @@ def start(
|
|
|
238
238
|
):
|
|
239
239
|
"""Start a service"""
|
|
240
240
|
try:
|
|
241
|
-
backend.commands.start(service_name, commit)
|
|
241
|
+
backend.commands.start(service_name, commit=commit)
|
|
242
242
|
except GitError as e:
|
|
243
243
|
msg = f"{str(e)} - Commit failed. Try 'ec start <service> --no-commit to set values without updating git"
|
|
244
244
|
raise GitError(msg) from e
|
|
@@ -255,7 +255,7 @@ def stop(
|
|
|
255
255
|
):
|
|
256
256
|
"""Stop a service"""
|
|
257
257
|
try:
|
|
258
|
-
backend.commands.stop(service_name, commit)
|
|
258
|
+
backend.commands.stop(service_name, commit=commit)
|
|
259
259
|
except GitError as e:
|
|
260
260
|
msg = f"{str(e)} - Commit failed. Try ec stop <service> --no-commit to set values without updating git"
|
|
261
261
|
raise GitError(msg) from e
|
|
@@ -7,14 +7,21 @@ Relies on the Helm class for deployment aspects.
|
|
|
7
7
|
import webbrowser
|
|
8
8
|
from datetime import datetime
|
|
9
9
|
from pathlib import Path
|
|
10
|
+
from time import sleep
|
|
10
11
|
|
|
11
12
|
import polars
|
|
12
13
|
from ruamel.yaml import YAML
|
|
13
14
|
|
|
14
|
-
from edge_containers_cli.cmds.commands import
|
|
15
|
+
from edge_containers_cli.cmds.commands import (
|
|
16
|
+
CommandError,
|
|
17
|
+
Commands,
|
|
18
|
+
ServicesDataFrame,
|
|
19
|
+
ServicesSchema,
|
|
20
|
+
)
|
|
15
21
|
from edge_containers_cli.definitions import ECContext
|
|
16
22
|
from edge_containers_cli.git import set_values
|
|
17
23
|
from edge_containers_cli.globals import TIME_FORMAT
|
|
24
|
+
from edge_containers_cli.logging import log
|
|
18
25
|
from edge_containers_cli.shell import ShellError, shell
|
|
19
26
|
|
|
20
27
|
|
|
@@ -23,13 +30,35 @@ def extract_ns_app(target: str) -> tuple[str, str]:
|
|
|
23
30
|
return namespace, app
|
|
24
31
|
|
|
25
32
|
|
|
33
|
+
def do_retry(cmd):
|
|
34
|
+
def _do_retry(*args, **kwargs):
|
|
35
|
+
max_attempts = 5
|
|
36
|
+
attempt = 1
|
|
37
|
+
sleep_time = 1
|
|
38
|
+
while attempt <= max_attempts:
|
|
39
|
+
try:
|
|
40
|
+
cmd(*args, **kwargs)
|
|
41
|
+
return None
|
|
42
|
+
except ShellError:
|
|
43
|
+
if attempt == max_attempts:
|
|
44
|
+
log.debug(f"Retry failed after {max_attempts} attempts")
|
|
45
|
+
raise
|
|
46
|
+
else:
|
|
47
|
+
log.debug(f"Retry attempt {attempt} failed. Retrying...")
|
|
48
|
+
sleep(sleep_time)
|
|
49
|
+
attempt += 1
|
|
50
|
+
|
|
51
|
+
return _do_retry
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
@do_retry
|
|
26
55
|
def patch_value(target: str, key: str, value: str | bool | int):
|
|
27
56
|
cmd_temp_ = f"argocd app set {target} -p {key}={value}"
|
|
28
57
|
shell.run_command(cmd_temp_, skip_on_dryrun=True)
|
|
29
|
-
|
|
30
|
-
shell.run_command(cmd_sync, skip_on_dryrun=True)
|
|
58
|
+
# Rely on argocd autosync to get the cluster into the right state
|
|
31
59
|
|
|
32
60
|
|
|
61
|
+
@do_retry
|
|
33
62
|
def push_value(target: str, key: str, value: str | bool | int):
|
|
34
63
|
# Get source details
|
|
35
64
|
app_resp = shell.run_command(
|
|
@@ -46,11 +75,12 @@ def push_value(target: str, key: str, value: str | bool | int):
|
|
|
46
75
|
value,
|
|
47
76
|
)
|
|
48
77
|
|
|
49
|
-
#
|
|
50
|
-
cmd_sync = f"argocd app sync {target} --apply-out-of-sync-only"
|
|
51
|
-
shell.run_command(cmd_sync, skip_on_dryrun=True)
|
|
78
|
+
# Free a possible patched value & refresh repo
|
|
52
79
|
cmd_unset = f"argocd app unset {target} -p {key}"
|
|
53
80
|
shell.run_command(cmd_unset, skip_on_dryrun=True)
|
|
81
|
+
cmd_refresh = f"argocd app get {target} --refresh"
|
|
82
|
+
shell.run_command(cmd_refresh, skip_on_dryrun=True)
|
|
83
|
+
# Rely on argocd autosync to get the cluster into the right state
|
|
54
84
|
|
|
55
85
|
|
|
56
86
|
class ArgoCommands(Commands):
|
|
@@ -79,19 +109,18 @@ class ArgoCommands(Commands):
|
|
|
79
109
|
self._check_service(service_name)
|
|
80
110
|
namespace, app = extract_ns_app(self.target)
|
|
81
111
|
cmd = (
|
|
82
|
-
f"argocd app delete-resource {namespace}/{service_name} "
|
|
83
|
-
f"--kind StatefulSet"
|
|
112
|
+
f"argocd app delete-resource {namespace}/{service_name} --kind StatefulSet"
|
|
84
113
|
)
|
|
85
114
|
shell.run_command(cmd, skip_on_dryrun=True)
|
|
86
115
|
|
|
87
|
-
def start(self, service_name, commit):
|
|
116
|
+
def start(self, service_name, commit=False):
|
|
88
117
|
self._check_service(service_name)
|
|
89
118
|
if commit:
|
|
90
119
|
push_value(self.target, f"ec_services.{service_name}.enabled", True)
|
|
91
120
|
else:
|
|
92
121
|
patch_value(self.target, f"ec_services.{service_name}.enabled", True)
|
|
93
122
|
|
|
94
|
-
def stop(self, service_name, commit):
|
|
123
|
+
def stop(self, service_name, commit=False):
|
|
95
124
|
self._check_service(service_name)
|
|
96
125
|
if commit:
|
|
97
126
|
push_value(self.target, f"ec_services.{service_name}.enabled", False)
|
|
@@ -122,45 +151,47 @@ class ArgoCommands(Commands):
|
|
|
122
151
|
)
|
|
123
152
|
app_dicts = YAML(typ="safe").load(app_resp)
|
|
124
153
|
|
|
125
|
-
if
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
154
|
+
if app_dicts:
|
|
155
|
+
for app in app_dicts:
|
|
156
|
+
resources_dict = app["status"]["resources"]
|
|
157
|
+
|
|
158
|
+
for resource in resources_dict:
|
|
159
|
+
is_ready = False
|
|
160
|
+
if resource["kind"] == "StatefulSet":
|
|
161
|
+
name = app["metadata"]["name"]
|
|
162
|
+
|
|
163
|
+
# check if replicas ready
|
|
164
|
+
mani_resp = shell.run_command(
|
|
165
|
+
f"argocd app manifests {namespace}/{name} --source live",
|
|
166
|
+
)
|
|
167
|
+
for resource_manifest in mani_resp.split("---")[1:]:
|
|
168
|
+
manifest = YAML(typ="safe").load(resource_manifest)
|
|
169
|
+
if not manifest:
|
|
170
|
+
continue
|
|
171
|
+
kind = manifest["kind"]
|
|
172
|
+
resource_name = manifest["metadata"]["name"]
|
|
173
|
+
if kind == "StatefulSet" and resource_name == name:
|
|
174
|
+
try:
|
|
175
|
+
is_ready = bool(manifest["status"]["readyReplicas"])
|
|
176
|
+
except (
|
|
177
|
+
KeyError,
|
|
178
|
+
TypeError,
|
|
179
|
+
): # Not ready if doesnt exist
|
|
180
|
+
is_ready = False
|
|
181
|
+
time_stamp = datetime.strptime(
|
|
182
|
+
manifest["metadata"]["creationTimestamp"],
|
|
183
|
+
"%Y-%m-%dT%H:%M:%SZ",
|
|
184
|
+
)
|
|
185
|
+
service_data["name"].append(name)
|
|
186
|
+
service_data["version"].append(
|
|
187
|
+
app["spec"]["source"]["targetRevision"]
|
|
188
|
+
)
|
|
189
|
+
service_data["ready"].append(is_ready)
|
|
190
|
+
service_data["deployed"].append(
|
|
191
|
+
datetime.strftime(time_stamp, TIME_FORMAT)
|
|
192
|
+
)
|
|
193
|
+
|
|
194
|
+
services_df = polars.from_dict(service_data, schema=ServicesSchema)
|
|
164
195
|
|
|
165
196
|
if running_only:
|
|
166
197
|
services_df = services_df.filter(polars.col("ready").eq(True))
|
{edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/src/edge_containers_cli/cmds/commands.py
RENAMED
|
@@ -47,6 +47,34 @@ class Commands(ABC):
|
|
|
47
47
|
self._repo = ctx.repo
|
|
48
48
|
self._log_url = ctx.log_url
|
|
49
49
|
|
|
50
|
+
def __getattribute__(self, attr_name):
|
|
51
|
+
"""Override to wrap each abstract method"""
|
|
52
|
+
attr = super().__getattribute__(attr_name)
|
|
53
|
+
if callable(attr):
|
|
54
|
+
if attr_name[0] == "_":
|
|
55
|
+
log_f = log.debug
|
|
56
|
+
else:
|
|
57
|
+
log_f = log.info
|
|
58
|
+
|
|
59
|
+
def wrapper(*args, **kwargs):
|
|
60
|
+
call_msg = (
|
|
61
|
+
f"Calling: {attr_name} {', '.join(str(item) for item in args)}"
|
|
62
|
+
)
|
|
63
|
+
return_msg = (
|
|
64
|
+
f"Returned: {attr_name} {', '.join(str(item) for item in args)}"
|
|
65
|
+
)
|
|
66
|
+
if kwargs:
|
|
67
|
+
call_msg = f"{call_msg} [{', '.join(f'{k}={v}' for k, v in kwargs.items())}]"
|
|
68
|
+
return_msg = f"{return_msg} [{', '.join(f'{k}={v}' for k, v in kwargs.items())}]"
|
|
69
|
+
log_f(call_msg)
|
|
70
|
+
result = attr(*args, **kwargs)
|
|
71
|
+
log_f(return_msg)
|
|
72
|
+
return result
|
|
73
|
+
|
|
74
|
+
return wrapper
|
|
75
|
+
else:
|
|
76
|
+
return attr
|
|
77
|
+
|
|
50
78
|
@property
|
|
51
79
|
def target(self):
|
|
52
80
|
if not self._target_valid: # Only validate once
|
|
@@ -103,11 +131,11 @@ class Commands(ABC):
|
|
|
103
131
|
raise NotImplementedError
|
|
104
132
|
|
|
105
133
|
@abstractmethod
|
|
106
|
-
def start(self, service_name: str, commit: bool) -> None:
|
|
134
|
+
def start(self, service_name: str, commit: bool = False) -> None:
|
|
107
135
|
raise NotImplementedError
|
|
108
136
|
|
|
109
137
|
@abstractmethod
|
|
110
|
-
def stop(self, service_name: str, commit: bool) -> None:
|
|
138
|
+
def stop(self, service_name: str, commit: bool = False) -> None:
|
|
111
139
|
raise NotImplementedError
|
|
112
140
|
|
|
113
141
|
def template(self, svc_instance: Path, args: str) -> None:
|
|
@@ -6,6 +6,7 @@ Relies on the Helm class for deployment aspects.
|
|
|
6
6
|
|
|
7
7
|
import time
|
|
8
8
|
from datetime import datetime
|
|
9
|
+
from random import randrange, seed
|
|
9
10
|
|
|
10
11
|
import polars
|
|
11
12
|
|
|
@@ -13,7 +14,9 @@ from edge_containers_cli.cmds.commands import CommandError, Commands, ServicesDa
|
|
|
13
14
|
from edge_containers_cli.definitions import ECContext
|
|
14
15
|
from edge_containers_cli.globals import TIME_FORMAT
|
|
15
16
|
|
|
16
|
-
DELAY =
|
|
17
|
+
DELAY = 2.0
|
|
18
|
+
NUM_SERVICES = 8
|
|
19
|
+
seed(237)
|
|
17
20
|
|
|
18
21
|
|
|
19
22
|
def process_t(time_string) -> str:
|
|
@@ -22,13 +25,12 @@ def process_t(time_string) -> str:
|
|
|
22
25
|
|
|
23
26
|
|
|
24
27
|
sample_data = {
|
|
25
|
-
"name": ["demo-ea-
|
|
26
|
-
"version": ["
|
|
27
|
-
"ready": [True
|
|
28
|
+
"name": [f"demo-ea-0{cnt}" for cnt in range(NUM_SERVICES)],
|
|
29
|
+
"version": ["1.0." + str(25 - cnt) for cnt in range(NUM_SERVICES)],
|
|
30
|
+
"ready": [True] * NUM_SERVICES,
|
|
28
31
|
"deployed": [
|
|
29
|
-
process_t("2024-10-22T11:23:
|
|
30
|
-
|
|
31
|
-
process_t("2024-10-22T12:51:50Z"),
|
|
32
|
+
process_t(f"2024-10-22T11:23:0{randrange(1, 9)}Z")
|
|
33
|
+
for cnt in range(NUM_SERVICES)
|
|
32
34
|
],
|
|
33
35
|
}
|
|
34
36
|
sample_ServicesDataFrame = ServicesDataFrame(polars.from_dict(sample_data))
|
|
@@ -69,6 +71,11 @@ class DemoCommands(Commands):
|
|
|
69
71
|
self._target_valid = False
|
|
70
72
|
self._stateDF = sample_ServicesDataFrame
|
|
71
73
|
|
|
74
|
+
self.lorem_min = 10
|
|
75
|
+
self.lorem_max = 50
|
|
76
|
+
self.lorem_step = 5
|
|
77
|
+
self.lorem_count = self.lorem_min
|
|
78
|
+
|
|
72
79
|
@demo_message
|
|
73
80
|
def logs(self, service_name, prev):
|
|
74
81
|
self._logs(service_name, prev)
|
|
@@ -83,11 +90,14 @@ class DemoCommands(Commands):
|
|
|
83
90
|
|
|
84
91
|
@demo_message
|
|
85
92
|
def restart(self, service_name):
|
|
86
|
-
self.
|
|
87
|
-
self.
|
|
93
|
+
self._stop(service_name, commit=False)
|
|
94
|
+
self._start(service_name, commit=False)
|
|
88
95
|
|
|
89
96
|
@demo_message
|
|
90
|
-
def start(self, service_name, commit):
|
|
97
|
+
def start(self, service_name, commit=False):
|
|
98
|
+
self._start(service_name, commit=commit)
|
|
99
|
+
|
|
100
|
+
def _start(self, service_name, commit=False):
|
|
91
101
|
self._check_service(service_name)
|
|
92
102
|
time.sleep(DELAY)
|
|
93
103
|
self._stateDF = self._stateDF.with_columns(
|
|
@@ -98,7 +108,10 @@ class DemoCommands(Commands):
|
|
|
98
108
|
)
|
|
99
109
|
|
|
100
110
|
@demo_message
|
|
101
|
-
def stop(self, service_name, commit):
|
|
111
|
+
def stop(self, service_name, commit=False):
|
|
112
|
+
self._stop(service_name, commit=commit)
|
|
113
|
+
|
|
114
|
+
def _stop(self, service_name, commit=False):
|
|
102
115
|
self._check_service(service_name)
|
|
103
116
|
time.sleep(DELAY)
|
|
104
117
|
self._stateDF = self._stateDF.with_columns(
|
|
@@ -110,7 +123,11 @@ class DemoCommands(Commands):
|
|
|
110
123
|
|
|
111
124
|
def _get_logs(self, service_name, prev) -> str:
|
|
112
125
|
self._check_service(service_name)
|
|
113
|
-
|
|
126
|
+
if self.lorem_count < self.lorem_max:
|
|
127
|
+
self.lorem_count += self.lorem_step
|
|
128
|
+
else:
|
|
129
|
+
self.lorem_count = self.lorem_min
|
|
130
|
+
logs_list = ["Lorem ipsum dolor sit amet"] * self.lorem_count
|
|
114
131
|
return "\n".join(logs_list)
|
|
115
132
|
|
|
116
133
|
def _get_services(self, running_only) -> ServicesDataFrame:
|
{edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/src/edge_containers_cli/cmds/helm.py
RENAMED
|
@@ -87,7 +87,7 @@ class Helm:
|
|
|
87
87
|
with open("Chart.yaml") as fp:
|
|
88
88
|
chart_yaml = YAML(typ="safe").load(fp)
|
|
89
89
|
package_path = (
|
|
90
|
-
service_folder / f
|
|
90
|
+
service_folder / f"{chart_yaml['name']}-{chart_yaml['version']}.tgz"
|
|
91
91
|
)
|
|
92
92
|
|
|
93
93
|
# use helm to install the chart
|
{edge_containers_cli-4.2.1 → edge_containers_cli-4.3.0}/src/edge_containers_cli/cmds/k8s_commands.py
RENAMED
|
@@ -89,14 +89,14 @@ class K8sCommands(Commands):
|
|
|
89
89
|
f"kubectl delete -n {self.target} {pod_name}", skip_on_dryrun=True
|
|
90
90
|
)
|
|
91
91
|
|
|
92
|
-
def start(self, service_name, commit):
|
|
92
|
+
def start(self, service_name, commit=False):
|
|
93
93
|
self._check_service(service_name)
|
|
94
94
|
shell.run_command(
|
|
95
95
|
f"kubectl scale -n {self.target} statefulset {service_name} --replicas=1",
|
|
96
96
|
skip_on_dryrun=True,
|
|
97
97
|
)
|
|
98
98
|
|
|
99
|
-
def stop(self, service_name, commit):
|
|
99
|
+
def stop(self, service_name, commit=False):
|
|
100
100
|
self._check_service(service_name)
|
|
101
101
|
shell.run_command(
|
|
102
102
|
f"kubectl scale -n {self.target} statefulset {service_name} --replicas=0 ",
|
|
@@ -124,34 +124,46 @@ class K8sCommands(Commands):
|
|
|
124
124
|
f'kubectl get statefulset -l "is_ioc==true" -n {self.target} -o yaml',
|
|
125
125
|
)
|
|
126
126
|
sts_dicts = YAML(typ="safe").load(kubectl_res)
|
|
127
|
-
if not sts_dicts["items"]:
|
|
128
|
-
raise CommandError(f"No ec-services found in {self.target}")
|
|
129
127
|
service_data = {
|
|
130
128
|
"name": [], # type: ignore
|
|
131
129
|
"ready": [],
|
|
132
130
|
"deployed": [],
|
|
133
131
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
132
|
+
if sts_dicts["items"]:
|
|
133
|
+
for sts in sts_dicts["items"]:
|
|
134
|
+
name = sts["metadata"]["name"]
|
|
135
|
+
time_stamp = datetime.strptime(
|
|
136
|
+
sts["metadata"]["creationTimestamp"], "%Y-%m-%dT%H:%M:%SZ"
|
|
137
|
+
)
|
|
138
|
+
try:
|
|
139
|
+
is_ready = bool(sts["status"]["readyReplicas"])
|
|
140
|
+
except KeyError: # Not ready if doesnt exist
|
|
141
|
+
is_ready = False
|
|
142
|
+
|
|
143
|
+
# Fill app data
|
|
144
|
+
service_data["name"].append(name)
|
|
145
|
+
service_data["ready"].append(is_ready)
|
|
146
|
+
service_data["deployed"].append(
|
|
147
|
+
datetime.strftime(time_stamp, TIME_FORMAT)
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
services_df = polars.from_dict(
|
|
151
|
+
service_data,
|
|
152
|
+
schema=polars.Schema(
|
|
153
|
+
{
|
|
154
|
+
"name": polars.String,
|
|
155
|
+
"ready": polars.Boolean,
|
|
156
|
+
"deployed": polars.String,
|
|
157
|
+
}
|
|
158
|
+
),
|
|
159
|
+
)
|
|
150
160
|
|
|
151
161
|
# Adds the version for all services
|
|
152
162
|
helm_out = str(shell.run_command(f"helm list -n {self.target} -o json"))
|
|
153
163
|
if helm_out == "[]\n":
|
|
154
|
-
helm_df = polars.DataFrame(
|
|
164
|
+
helm_df = polars.DataFrame(
|
|
165
|
+
schema=polars.Schema({"name": polars.String, "version": polars.String})
|
|
166
|
+
)
|
|
155
167
|
else:
|
|
156
168
|
helm_df = polars.read_json(StringIO(str(helm_out)))
|
|
157
169
|
helm_df = helm_df.rename({"app_version": "version"})
|