edge-containers-cli 4.2.0__tar.gz → 4.2.2__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.
Files changed (107) hide show
  1. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/.copier-answers.yml +1 -1
  2. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/.github/CONTRIBUTING.md +1 -1
  3. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/.github/workflows/_pypi.yml +2 -0
  4. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/.github/workflows/_release.yml +1 -1
  5. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/.vscode/launch.json +13 -0
  6. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/Dockerfile +1 -1
  7. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/PKG-INFO +26 -4
  8. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/README.md +25 -3
  9. edge_containers_cli-4.2.2/docs/images/ec-logs.png +0 -0
  10. edge_containers_cli-4.2.2/docs/images/ec-web.png +0 -0
  11. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/src/edge_containers_cli/_version.py +2 -2
  12. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/src/edge_containers_cli/cli.py +2 -2
  13. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/src/edge_containers_cli/cmds/argo_commands.py +21 -4
  14. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/src/edge_containers_cli/cmds/commands.py +30 -2
  15. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/src/edge_containers_cli/cmds/demo_commands.py +29 -12
  16. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/src/edge_containers_cli/cmds/k8s_commands.py +2 -2
  17. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/src/edge_containers_cli/cmds/monitor.py +196 -96
  18. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/src/edge_containers_cli/cmds/monitor.tcss +12 -8
  19. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/src/edge_containers_cli/definitions.py +8 -0
  20. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/src/edge_containers_cli/shell.py +1 -0
  21. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/src/edge_containers_cli.egg-info/PKG-INFO +26 -4
  22. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/src/edge_containers_cli.egg-info/SOURCES.txt +2 -0
  23. edge_containers_cli-4.2.2/tests/test_demo.py +37 -0
  24. edge_containers_cli-4.2.0/tests/test_demo.py +0 -32
  25. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/.devcontainer/devcontainer.json +0 -0
  26. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  27. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/.github/ISSUE_TEMPLATE/issue.md +0 -0
  28. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md +0 -0
  29. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/.github/actions/install_requirements/action.yml +0 -0
  30. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/.github/dependabot.yml +0 -0
  31. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/.github/pages/index.html +0 -0
  32. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/.github/pages/make_switcher.py +0 -0
  33. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/.github/workflows/_check.yml +0 -0
  34. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/.github/workflows/_dist.yml +0 -0
  35. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/.github/workflows/_test.yml +0 -0
  36. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/.github/workflows/_tox.yml +0 -0
  37. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/.github/workflows/ci.yml +0 -0
  38. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/.gitignore +0 -0
  39. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/.pre-commit-config.yaml +0 -0
  40. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/.vscode/extensions.json +0 -0
  41. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/.vscode/settings.json +0 -0
  42. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/.vscode/tasks.json +0 -0
  43. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/LICENSE +0 -0
  44. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/docs/conf.py +0 -0
  45. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/docs/developer/explanations/decisions/0001-record-architecture-decisions.rst +0 -0
  46. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/docs/developer/explanations/decisions/0002-switched-to-pip-skeleton.rst +0 -0
  47. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/docs/developer/explanations/decisions.rst +0 -0
  48. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/docs/developer/how-to/build-docs.rst +0 -0
  49. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/docs/developer/how-to/contribute.rst +0 -0
  50. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/docs/developer/how-to/lint.rst +0 -0
  51. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/docs/developer/how-to/make-release.rst +0 -0
  52. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/docs/developer/how-to/pin-requirements.rst +0 -0
  53. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/docs/developer/how-to/run-tests.rst +0 -0
  54. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/docs/developer/how-to/static-analysis.rst +0 -0
  55. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/docs/developer/how-to/test-container.rst +0 -0
  56. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/docs/developer/how-to/update-tools.rst +0 -0
  57. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/docs/developer/index.rst +0 -0
  58. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/docs/developer/reference/standards.rst +0 -0
  59. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/docs/developer/tutorials/dev-install.rst +0 -0
  60. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/docs/genindex.rst +0 -0
  61. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/docs/images/dls-favicon.ico +0 -0
  62. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/docs/images/dls-logo.svg +0 -0
  63. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/docs/index.rst +0 -0
  64. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/docs/user/explanations/docs-structure.rst +0 -0
  65. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/docs/user/how-to/run-container.rst +0 -0
  66. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/docs/user/index.rst +0 -0
  67. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/docs/user/reference/api.rst +0 -0
  68. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/docs/user/tutorials/installation.rst +0 -0
  69. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/pyproject.toml +0 -0
  70. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/setup.cfg +0 -0
  71. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/src/edge_containers_cli/__init__.py +0 -0
  72. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/src/edge_containers_cli/__main__.py +0 -0
  73. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/src/edge_containers_cli/autocomplete.py +0 -0
  74. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/src/edge_containers_cli/backend.py +0 -0
  75. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/src/edge_containers_cli/cmds/__init__.py +0 -0
  76. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/src/edge_containers_cli/cmds/helm.py +0 -0
  77. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/src/edge_containers_cli/git.py +0 -0
  78. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/src/edge_containers_cli/globals.py +0 -0
  79. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/src/edge_containers_cli/logging.py +0 -0
  80. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/src/edge_containers_cli/utils.py +0 -0
  81. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/src/edge_containers_cli.egg-info/dependency_links.txt +0 -0
  82. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/src/edge_containers_cli.egg-info/entry_points.txt +0 -0
  83. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/src/edge_containers_cli.egg-info/requires.txt +0 -0
  84. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/src/edge_containers_cli.egg-info/top_level.txt +0 -0
  85. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/tests/__init__.py +0 -0
  86. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/tests/conftest.py +0 -0
  87. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/tests/data/argocd.yaml +0 -0
  88. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/tests/data/bl01t-deployment/apps/values.yaml +0 -0
  89. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/tests/data/bl01t-services/services/bl01t-ea-test-01/Chart.yaml +0 -0
  90. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/tests/data/bl01t-services/services/bl01t-ea-test-01/config/ioc.db +0 -0
  91. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/tests/data/bl01t-services/services/bl01t-ea-test-01/config/ioc.yaml +0 -0
  92. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/tests/data/bl01t-services/services/bl01t-ea-test-01/templates/configmap.yaml +0 -0
  93. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/tests/data/bl01t-services/services/bl01t-ea-test-01/values.yaml +0 -0
  94. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/tests/data/bl01t-services/services/bl01t-ea-test-02/Chart.yaml +0 -0
  95. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/tests/data/bl01t-services/services/bl01t-ea-test-02/values.yaml +0 -0
  96. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/tests/data/bl01t-services/services/dls-aravis/Chart.yaml +0 -0
  97. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/tests/data/bl01t-services/services/dls-aravis/config/ioc.yaml +0 -0
  98. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/tests/data/bl01t-services/services/dls-aravis/templates/configmap.yaml +0 -0
  99. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/tests/data/bl01t-services/services/dls-aravis/values.yaml +0 -0
  100. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/tests/data/bl01t-services/services/values.yaml +0 -0
  101. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/tests/data/cli.yaml +0 -0
  102. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/tests/data/k8s.yaml +0 -0
  103. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/tests/data/yaml.yaml +0 -0
  104. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/tests/test_argocd.py +0 -0
  105. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/tests/test_cli.py +0 -0
  106. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/tests/test_k8s.py +0 -0
  107. {edge_containers_cli-4.2.0 → edge_containers_cli-4.2.2}/tests/test_unit.py +0 -0
@@ -1,5 +1,5 @@
1
1
  # Changes here will be overwritten by Copier
2
- _commit: 2.3.0
2
+ _commit: 2.5.0
3
3
  _src_path: gh:DiamondLightSource/python-copier-template
4
4
  author_email: giles.knap@gmail.com
5
5
  author_name: Giles Knap
@@ -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.3.0/how-to.html).
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.5.0/how-to.html).
@@ -15,3 +15,5 @@ jobs:
15
15
 
16
16
  - name: Publish to PyPI using trusted publishing
17
17
  uses: pypa/gh-action-pypi-publish@release/v1
18
+ with:
19
+ attestations: false
@@ -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@c062e08bd532815e2082a85e87e3ef29c3e6d191 # v2.0.8
26
+ uses: softprops/action-gh-release@e7a8f85e1c67a31e6ed99a94b41bd0b71bbee6b8 # v2.0.9
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} as developer
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
1
  Metadata-Version: 2.1
2
2
  Name: edge-containers-cli
3
- Version: 4.2.0
3
+ Version: 4.2.2
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,12 +236,16 @@ Requires-Dist: types-mock; extra == "dev"
236
236
  [![CI](https://github.com/epics-containers/edge-containers-cli/actions/workflows/ci.yml/badge.svg)](https://github.com/epics-containers/edge-containers-cli/actions/workflows/ci.yml)
237
237
  [![Coverage](https://codecov.io/gh/epics-containers/edge-containers-cli/branch/main/graph/badge.svg)](https://codecov.io/gh/epics-containers/edge-containers-cli)
238
238
  [![PyPI](https://img.shields.io/pypi/v/edge-containers-cli.svg)](https://pypi.org/project/edge-containers-cli)
239
- [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
239
+ [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0)
240
240
 
241
241
  # edge_containers_cli
242
242
 
243
+ ## About
244
+
243
245
  Edge containers command line interface: a tool for deploying and managing
244
- IOCs and services in a beamline or accelerator cluster.
246
+ IOCs in a beamline or accelerator cluster. The tool is a thin wrapper around
247
+ familiar command line tools such as git, kubectl, helm and argocd - and can
248
+ be used to learn the underlying commands being used.
245
249
 
246
250
  For detailed documentation on the framework that this supports see:
247
251
  https://epics-containers.github.io/
@@ -254,7 +258,25 @@ Releases | <https://github.com/epics-containers/edge-containers-cli/relea
254
258
 
255
259
 
256
260
  To discover the CLI commands, create a python virtual environment,
257
- and perform the following::
261
+ and perform the following:
258
262
 
259
263
  pip install edge-containers-cli
260
264
  ec --version
265
+
266
+ ## Monitor
267
+
268
+ Some commands of the tool are also exposed as a TUI which can additionally be served as
269
+ a web application.
270
+
271
+ To demo the TUI as a web application:
272
+
273
+ pip install textual-dev
274
+ textual serve "ec -b DEMO monitor"
275
+
276
+ Dashboard:
277
+
278
+ ![screenshot](docs/images/ec-web.png)
279
+
280
+ IOC logs:
281
+
282
+ ![screenshot](docs/images/ec-logs.png)
@@ -1,12 +1,16 @@
1
1
  [![CI](https://github.com/epics-containers/edge-containers-cli/actions/workflows/ci.yml/badge.svg)](https://github.com/epics-containers/edge-containers-cli/actions/workflows/ci.yml)
2
2
  [![Coverage](https://codecov.io/gh/epics-containers/edge-containers-cli/branch/main/graph/badge.svg)](https://codecov.io/gh/epics-containers/edge-containers-cli)
3
3
  [![PyPI](https://img.shields.io/pypi/v/edge-containers-cli.svg)](https://pypi.org/project/edge-containers-cli)
4
- [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
4
+ [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0)
5
5
 
6
6
  # edge_containers_cli
7
7
 
8
+ ## About
9
+
8
10
  Edge containers command line interface: a tool for deploying and managing
9
- IOCs and services in a beamline or accelerator cluster.
11
+ IOCs in a beamline or accelerator cluster. The tool is a thin wrapper around
12
+ familiar command line tools such as git, kubectl, helm and argocd - and can
13
+ be used to learn the underlying commands being used.
10
14
 
11
15
  For detailed documentation on the framework that this supports see:
12
16
  https://epics-containers.github.io/
@@ -19,7 +23,25 @@ Releases | <https://github.com/epics-containers/edge-containers-cli/relea
19
23
 
20
24
 
21
25
  To discover the CLI commands, create a python virtual environment,
22
- and perform the following::
26
+ and perform the following:
23
27
 
24
28
  pip install edge-containers-cli
25
29
  ec --version
30
+
31
+ ## Monitor
32
+
33
+ Some commands of the tool are also exposed as a TUI which can additionally be served as
34
+ a web application.
35
+
36
+ To demo the TUI as a web application:
37
+
38
+ pip install textual-dev
39
+ textual serve "ec -b DEMO monitor"
40
+
41
+ Dashboard:
42
+
43
+ ![screenshot](docs/images/ec-web.png)
44
+
45
+ IOC logs:
46
+
47
+ ![screenshot](docs/images/ec-logs.png)
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '4.2.0'
16
- __version_tuple__ = version_tuple = (4, 2, 0)
15
+ __version__ = version = '4.2.2'
16
+ __version_tuple__ = version_tuple = (4, 2, 2)
@@ -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,6 +7,7 @@ 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
@@ -15,6 +16,7 @@ from edge_containers_cli.cmds.commands import CommandError, Commands, ServicesDa
15
16
  from edge_containers_cli.definitions import ECContext
16
17
  from edge_containers_cli.git import set_values
17
18
  from edge_containers_cli.globals import TIME_FORMAT
19
+ from edge_containers_cli.logging import log
18
20
  from edge_containers_cli.shell import ShellError, shell
19
21
 
20
22
 
@@ -26,8 +28,23 @@ def extract_ns_app(target: str) -> tuple[str, str]:
26
28
  def patch_value(target: str, key: str, value: str | bool | int):
27
29
  cmd_temp_ = f"argocd app set {target} -p {key}={value}"
28
30
  shell.run_command(cmd_temp_, skip_on_dryrun=True)
29
- cmd_sync = f"argocd app sync {target} --apply-out-of-sync-only"
30
- shell.run_command(cmd_sync, skip_on_dryrun=True)
31
+ max_attempts = 3
32
+ attempt = 1
33
+ sleep_time = 2
34
+ while attempt <= max_attempts:
35
+ try:
36
+ # Sync may conflict with autosync "another operation is already in progress"
37
+ cmd_sync = f"argocd app sync {target} --apply-out-of-sync-only"
38
+ shell.run_command(cmd_sync, skip_on_dryrun=True)
39
+ return None
40
+ except ShellError:
41
+ if attempt == max_attempts:
42
+ log.debug(f"Argo patch failed after {max_attempts} attempts")
43
+ raise
44
+ else:
45
+ log.debug(f"Argo patch attempt {attempt} failed. Retrying...")
46
+ sleep(sleep_time)
47
+ attempt += 1
31
48
 
32
49
 
33
50
  def push_value(target: str, key: str, value: str | bool | int):
@@ -84,14 +101,14 @@ class ArgoCommands(Commands):
84
101
  )
85
102
  shell.run_command(cmd, skip_on_dryrun=True)
86
103
 
87
- def start(self, service_name, commit):
104
+ def start(self, service_name, commit=False):
88
105
  self._check_service(service_name)
89
106
  if commit:
90
107
  push_value(self.target, f"ec_services.{service_name}.enabled", True)
91
108
  else:
92
109
  patch_value(self.target, f"ec_services.{service_name}.enabled", True)
93
110
 
94
- def stop(self, service_name, commit):
111
+ def stop(self, service_name, commit=False):
95
112
  self._check_service(service_name)
96
113
  if commit:
97
114
  push_value(self.target, f"ec_services.{service_name}.enabled", False)
@@ -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 = 0.0
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-01", "demo-ea-02", "demo-ea-03"], # type: ignore
26
- "version": ["2024.10.1", "2024.10.1b", "2024.10.1"],
27
- "ready": [True, True, False],
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:10Z"),
30
- process_t("2024-10-28T14:53:55Z"),
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.stop(service_name, False)
87
- self.start(service_name, False)
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
- logs_list = ["Lorem ipsum dolor sit amet"] * 25
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:
@@ -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 ",