epics-containers / edge-containers-cli

command line shortcuts for epics containers developers
Apache License 2.0
3 stars 1 forks source link

Handling deploy of services which dont exist #111

Open marcelldls opened 3 months ago

marcelldls commented 3 months ago

Currently when trying to deploy a service that does not exist:

(.venv) [esq51579@pc0146 epics-containers-cli]$ ec deploy no-service 2024.2.1
╭─────────────────────────────── Traceback (most recent call last) ────────────────────────────────╮
│ /home/esq51579/WIP/edge-containers-cli/src/edge_containers_cli/cmds/cli.py:152 in deploy         │
│                                                                                                  │
│   149 │   if ctx.obj.namespace == globals.LOCAL_NAMESPACE:                                       │
│   150 │   │   LocalCommands(ctx.obj, service_name).deploy(service_name, version, args)           │
│   151 │   else:                                                                                  │
│ ❱ 152 │   │   K8sCommands(ctx.obj, service_name, check=False).deploy(                            │
│   153 │   │   │   service_name, version, args                                                    │
│   154 │   │   )                                                                                  │
│   155                                                                                            │
│                                                                                                  │
│ /home/esq51579/WIP/edge-containers-cli/src/edge_containers_cli/cmds/k8s_commands.py:129 in       │
│ deploy                                                                                           │
│                                                                                                  │
│   126 │   │   │   version,                                                                       │
│   127 │   │   │   repo=self.beamline_repo,                                                       │
│   128 │   │   )                                                                                  │
│ ❱ 129 │   │   chart.deploy()                                                                     │
│   130 │                                                                                          │
│   131 │   def exec(self):                                                                        │
│   132 │   │   shell.run_command(                                                                 │
│                                                                                                  │
│ /home/esq51579/WIP/edge-containers-cli/src/edge_containers_cli/cmds/helm.py:76 in deploy         │
│                                                                                                  │
│    73 │   │   │   interactive=False,                                                             │
│    74 │   │   )                                                                                  │
│    75 │   │                                                                                      │
│ ❱  76 │   │   self._do_deploy(self.tmp / "services" / self.service_name)                         │
│    77 │                                                                                          │
│    78 │   def _do_deploy(self, service_folder: Path):                                            │
│    79 │   │   """                                                                                │
│                                                                                                  │
│ /home/esq51579/WIP/edge-containers-cli/src/edge_containers_cli/cmds/helm.py:90 in _do_deploy     │
│                                                                                                  │
│    87 │   │   for chart in chart_paths:                                                          │
│    88 │   │   │   shell.run_command(f"helm dependency update {chart}", interactive=False)        │
│    89 │   │                                                                                      │
│ ❱  90 │   │   with chdir(service_folder):                                                        │
│    91 │   │   │   shell.run_command(                                                             │
│    92 │   │   │   │   f"helm dependency update {service_folder}; "                               │
│    93 │   │   │   │   f"helm package {service_folder} --app-version {self.version}",             │
│                                                                                                  │
│ /dls_sw/apps/python/miniforge/4.10.0-0/envs/python3.11/lib/python3.11/contextlib.py:137 in       │
│ __enter__                                                                                        │
│                                                                                                  │
│   134 │   │   # they are only needed for recreation, which is not possible anymore               │
│   135 │   │   del self.args, self.kwds, self.func                                                │
│   136 │   │   try:                                                                               │
│ ❱ 137 │   │   │   return next(self.gen)                                                          │
│   138 │   │   except StopIteration:                                                              │
│   139 │   │   │   raise RuntimeError("generator didn't yield") from None                         │
│   140                                                                                            │
│                                                                                                  │
│ /home/esq51579/WIP/edge-containers-cli/src/edge_containers_cli/utils.py:91 in chdir              │
│                                                                                                  │
│    88 │   upon entering and restores the old one on exit.                                        │
│    89 │   """                                                                                    │
│    90 │   curdir = os.getcwd()                                                                   │
│ ❱  91 │   os.chdir(path)                                                                         │
│    92 │   try:                                                                                   │
│    93 │   │   yield                                                                              │
│    94 │   finally:                                                                               │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
FileNotFoundError: [Errno 2] No such file or directory: '/tmp/tmpgw9bqeed/services/no-service'

Perhaps a more informative message would be that the service is not found in the repo.

Following a similar thought, if the version does not exist in the tags we get

(.venv) [esq51579@pc0146 epics-containers-cli]$ ec deploy bl01c-ea-test-02 any-version

Command Failed:
git clone git@gitlab.diamond.ac.uk:controls/containers/beamline/bl01c.git /tmp/tmp0xtra4ah --depth=1 --single-branch --branch=any-version

Cloning into '/tmp/tmp0xtra4ah'...
warning: Could not find remote branch any-version to clone.
fatal: Remote branch any-version not found in upstream origin
fatal: the remote end hung up unexpectedly
remote: 
remote: ========================================================================
remote: 
remote: rpc error: code = Canceled desc = running upload-pack: user canceled the request
remote: 
remote: ========================================================================
remote: 

Additionally if the version tag does exist but is before committing the service:

(.venv) [esq51579@pc0146 epics-containers-cli]$ ec deploy bl01c-ea-test-03 2024.2.6
╭─────────────────────────────── Traceback (most recent call last) ────────────────────────────────╮
│ /home/esq51579/WIP/edge-containers-cli/src/edge_containers_cli/cmds/cli.py:152 in deploy         │
│                                                                                                  │
│   149 │   if ctx.obj.namespace == globals.LOCAL_NAMESPACE:                                       │
│   150 │   │   LocalCommands(ctx.obj, service_name).deploy(service_name, version, args)           │
│   151 │   else:                                                                                  │
│ ❱ 152 │   │   K8sCommands(ctx.obj, service_name, check=False).deploy(                            │
│   153 │   │   │   service_name, version, args                                                    │
│   154 │   │   )                                                                                  │
│   155                                                                                            │
│                                                                                                  │
│ /home/esq51579/WIP/edge-containers-cli/src/edge_containers_cli/cmds/k8s_commands.py:129 in       │
│ deploy                                                                                           │
│                                                                                                  │
│   126 │   │   │   version,                                                                       │
│   127 │   │   │   repo=self.beamline_repo,                                                       │
│   128 │   │   )                                                                                  │
│ ❱ 129 │   │   chart.deploy()                                                                     │
│   130 │                                                                                          │
│   131 │   def exec(self):                                                                        │
│   132 │   │   shell.run_command(                                                                 │
│                                                                                                  │
│ /home/esq51579/WIP/edge-containers-cli/src/edge_containers_cli/cmds/helm.py:76 in deploy         │
│                                                                                                  │
│    73 │   │   │   interactive=False,                                                             │
│    74 │   │   )                                                                                  │
│    75 │   │                                                                                      │
│ ❱  76 │   │   self._do_deploy(self.tmp / "services" / self.service_name)                         │
│    77 │                                                                                          │
│    78 │   def _do_deploy(self, service_folder: Path):                                            │
│    79 │   │   """                                                                                │
│                                                                                                  │
│ /home/esq51579/WIP/edge-containers-cli/src/edge_containers_cli/cmds/helm.py:90 in _do_deploy     │
│                                                                                                  │
│    87 │   │   for chart in chart_paths:                                                          │
│    88 │   │   │   shell.run_command(f"helm dependency update {chart}", interactive=False)        │
│    89 │   │                                                                                      │
│ ❱  90 │   │   with chdir(service_folder):                                                        │
│    91 │   │   │   shell.run_command(                                                             │
│    92 │   │   │   │   f"helm dependency update {service_folder}; "                               │
│    93 │   │   │   │   f"helm package {service_folder} --app-version {self.version}",             │
│                                                                                                  │
│ /dls_sw/apps/python/miniforge/4.10.0-0/envs/python3.11/lib/python3.11/contextlib.py:137 in       │
│ __enter__                                                                                        │
│                                                                                                  │
│   134 │   │   # they are only needed for recreation, which is not possible anymore               │
│   135 │   │   del self.args, self.kwds, self.func                                                │
│   136 │   │   try:                                                                               │
│ ❱ 137 │   │   │   return next(self.gen)                                                          │
│   138 │   │   except StopIteration:                                                              │
│   139 │   │   │   raise RuntimeError("generator didn't yield") from None                         │
│   140                                                                                            │
│                                                                                                  │
│ /home/esq51579/WIP/edge-containers-cli/src/edge_containers_cli/utils.py:91 in chdir              │
│                                                                                                  │
│    88 │   upon entering and restores the old one on exit.                                        │
│    89 │   """                                                                                    │
│    90 │   curdir = os.getcwd()                                                                   │
│ ❱  91 │   os.chdir(path)                                                                         │
│    92 │   try:                                                                                   │
│    93 │   │   yield                                                                              │
│    94 │   finally:                                                                               │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
FileNotFoundError: [Errno 2] No such file or directory: '/tmp/tmp6uk08ajr/services/bl01c-ea-test-03'

Finally, it is possible to deploy a service using any tag which does not correspond to changes in the service.

(.venv) [esq51579@pc0146 epics-containers-cli]$ ec deploy bl01c-ea-test-02 202
2023.3.2  2024.2.3  
(.venv) [esq51579@pc0146 epics-containers-cli]$ ec deploy bl01c-ea-test-02 2024.2.4
Release "bl01c-ea-test-02" has been upgraded. Happy Helming!
NAME: bl01c-ea-test-02
LAST DEPLOYED: Wed Mar 13 15:03:35 2024
NAMESPACE: b01-1-iocs
STATUS: deployed
REVISION: 2
TEST SUITE: None

(.venv) [esq51579@pc0146 epics-containers-cli]$ ec ps
| name             | version  | running | restarts | deployed            |
|------------------|----------|---------|----------|---------------------|
| epics-opis       | 2024.2.9 | true    | 0        | 2024-02-28 15:44:42 |
| bl01c-di-dcam-01 | 2024.2.4 | true    | 0        | 2024-03-13 13:45:38 |
| bl01c-di-dcam-02 | 2024.2.5 | true    | 0        | 2024-03-13 13:46:03 |
| bl01c-ea-test-01 | 2024.2.1 | true    | 0        | 2024-03-13 13:47:03 |
| bl01c-ea-test-02 | 2024.2.4 | true    | 0        | 2024-03-13 15:03:35 |
| bl01c-ea-test-03 | 2024.2.7 | true    | 0        | 2024-03-13 14:53:13 |
| bl01c-mo-ioc-01  | 2024.3.1 | true    | 0        | 2024-03-04 12:17:03 |

Since we already have a process to generate a dictionary of services and corresponding versions - perhaps we should filter the deploy arguments and give neater user feedback?

gilesknap commented 3 months ago

Yes this is something we should do. The current errors are confusing.

stan-dot commented 1 month ago

ran into this with blueapi https://gitlab.diamond.ac.uk/controls/containers/beamline/bl01c/-/merge_requests/2#note_88602