canonical / jhack

Chock-full of Juju hackery.
Apache License 2.0
51 stars 24 forks source link

"show-relation" doesn't seem to work on subordinate relations #60

Closed Vultaire closed 1 year ago

Vultaire commented 1 year ago

I did a quick test of jhack locally on LXD, using an ubuntu unit and an nrpe subordinate.

My invocation of jhack was: jhack show-relation ubuntu:juju-info nrpe:general-info

This gives the following traceback:

Traceback (most recent call last):
  File "/snap/jhack/120/bin/jhack", line 8, in <module>
    sys.exit(main())
  File "/snap/jhack/120/lib/python3.8/site-packages/jhack/main.py", line 134, in main
    app()
  File "/snap/jhack/120/lib/python3.8/site-packages/typer/main.py", line 214, in __call__
    return get_command(self)(*args, **kwargs)
  File "/snap/jhack/120/lib/python3.8/site-packages/click/core.py", line 1130, in __call__
    return self.main(*args, **kwargs)
  File "/snap/jhack/120/lib/python3.8/site-packages/click/core.py", line 1055, in main
    rv = self.invoke(ctx)
  File "/snap/jhack/120/lib/python3.8/site-packages/click/core.py", line 1657, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/snap/jhack/120/lib/python3.8/site-packages/click/core.py", line 1404, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/snap/jhack/120/lib/python3.8/site-packages/click/core.py", line 760, in invoke
    return __callback(*args, **kwargs)
  File "/snap/jhack/120/lib/python3.8/site-packages/typer/main.py", line 500, in wrapper
    return callback(**use_params)  # type: ignore
  File "/snap/jhack/120/lib/python3.8/site-packages/jhack/utils/show_relation.py", line 572, in sync_show_relation
    return _sync_show_relation(
  File "/snap/jhack/120/lib/python3.8/site-packages/jhack/utils/show_relation.py", line 609, in _sync_show_relation
    table = asyncio.run(
  File "/usr/lib/python3.8/asyncio/runners.py", line 44, in run
    return loop.run_until_complete(main)
  File "/usr/lib/python3.8/asyncio/base_events.py", line 616, in run_until_complete
    return future.result()
  File "/snap/jhack/120/lib/python3.8/site-packages/jhack/utils/show_relation.py", line 459, in render_relation
    data = get_relation_data(
  File "/snap/jhack/120/lib/python3.8/site-packages/jhack/utils/show_relation.py", line 325, in get_relation_data
    provider_data = get_content(
  File "/snap/jhack/120/lib/python3.8/site-packages/jhack/utils/show_relation.py", line 238, in get_content
    other_unit_name = next(iter(status["applications"][other_app_name]["units"]))
KeyError: 'units'

I suspect the above issue is happening because juju status output for subordinate applications doesn't include a "units" dictionary; you'd have to go into the principal unit to find those subordinate units.

Reproduction steps:

PietroPasotti commented 1 year ago

Ummm, I was convinced I'd fixed this one. Will repro tomorrow. Thanks!

Vultaire commented 1 year ago

Actually, I missed an important detail; maybe this is resolved in later version?

Was running latest/stable, i.e. version 0.3.2.

PietroPasotti commented 1 year ago

yeah if you have time to check from edge that'd be great

Vultaire commented 1 year ago

Yeah, we still have errors.

Here is the output I get with edge (0.3.14):

paul-goins@dell2018:~$ jhack show-relation ubuntu:juju-info nrpe:general-info
╭─────────────────────────────── Traceback (most recent call last) ────────────────────────────────╮
│ /snap/jhack/198/lib/python3.8/site-packages/jhack/utils/show_relation.py:594 in                  │
│ sync_show_relation                                                                               │
│                                                                                                  │
│   591 │                                                                                          │
│   592 │   $ jhack utils show-relation my_app:relation_name other_app:other_name                  │
│   593 │   """                                                                                    │
│ ❱ 594 │   return _sync_show_relation(                                                            │
│   595 │   │   endpoint1=endpoint1,                                                               │
│   596 │   │   endpoint2=endpoint2,                                                               │
│   597 │   │   n=n,                                                                               │
│                                                                                                  │
│ ╭───────────────── locals ──────────────────╮                                                    │
│ │               color = 'auto'              │                                                    │
│ │           endpoint1 = 'ubuntu:juju-info'  │                                                    │
│ │           endpoint2 = 'nrpe:general-info' │                                                    │
│ │ hide_empty_databags = False               │                                                    │
│ │               model = None                │                                                    │
│ │                   n = None                │                                                    │
│ │      show_juju_keys = False               │                                                    │
│ │               watch = False               │                                                    │
│ ╰───────────────────────────────────────────╯                                                    │
│                                                                                                  │
│ /snap/jhack/198/lib/python3.8/site-packages/jhack/utils/show_relation.py:631 in                  │
│ _sync_show_relation                                                                              │
│                                                                                                  │
│   628 │   while True:                                                                            │
│   629 │   │   start = time.time()                                                                │
│   630 │   │                                                                                      │
│ ❱ 631 │   │   table = asyncio.run(                                                               │
│   632 │   │   │   render_relation(                                                               │
│   633 │   │   │   │   endpoint1,                                                                 │
│   634 │   │   │   │   endpoint2,                                                                 │
│                                                                                                  │
│ ╭─────────────────────────────────────────── locals ───────────────────────────────────────────╮ │
│ │               color = 'auto'                                                                 │ │
│ │             Console = <class 'rich.console.Console'>                                         │ │
│ │             console = <console width=195 ColorSystem.TRUECOLOR>                              │ │
│ │           endpoint1 = 'ubuntu:juju-info'                                                     │ │
│ │           endpoint2 = 'nrpe:general-info'                                                    │ │
│ │ hide_empty_databags = False                                                                  │ │
│ │               model = None                                                                   │ │
│ │                   n = None                                                                   │ │
│ │                rich = <module 'rich' from                                                    │ │
│ │                       '/snap/jhack/198/lib/python3.8/site-packages/rich/__init__.py'>        │ │
│ │      show_juju_keys = False                                                                  │ │
│ │               start = 1678382891.3614984                                                     │ │
│ │               watch = False                                                                  │ │
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │
│                                                                                                  │
│ /usr/lib/python3.8/asyncio/runners.py:44 in run                                                  │
│                                                                                                  │
│   41 │   │   events.set_event_loop(loop)                                                         │
│   42 │   │   if debug is not None:                                                               │
│   43 │   │   │   loop.set_debug(debug)                                                           │
│ ❱ 44 │   │   return loop.run_until_complete(main)                                                │
│   45 │   finally:                                                                                │
│   46 │   │   try:                                                                                │
│   47 │   │   │   _cancel_all_tasks(loop)                                                         │
│                                                                                                  │
│ ╭──────────────────────────────── locals ────────────────────────────────╮                       │
│ │ debug = None                                                           │                       │
│ │  loop = <_UnixSelectorEventLoop running=False closed=True debug=False> │                       │
│ │  main = <coroutine object render_relation at 0x7f98288b90c0>           │                       │
│ ╰────────────────────────────────────────────────────────────────────────╯                       │
│                                                                                                  │
│ /usr/lib/python3.8/asyncio/base_events.py:616 in run_until_complete                              │
│                                                                                                  │
│    613 │   │   if not future.done():                                                             │
│    614 │   │   │   raise RuntimeError('Event loop stopped before Future completed.')             │
│    615 │   │                                                                                     │
│ ❱  616 │   │   return future.result()                                                            │
│    617 │                                                                                         │
│    618 │   def stop(self):                                                                       │
│    619 │   │   """Stop running the event loop.                                                   │
│                                                                                                  │
│ ╭─────────────────────────────────────────── locals ───────────────────────────────────────────╮ │
│ │   future = <Task finished name='Task-1' coro=<render_relation() done, defined at             │ │
│ │            /snap/jhack/198/lib/python3.8/site-packages/jhack/utils/show_relation.py:422>     │ │
│ │            exception=KeyError('units')>                                                      │ │
│ │ new_task = True                                                                              │ │
│ │     self = <_UnixSelectorEventLoop running=False closed=True debug=False>                    │ │
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │
│                                                                                                  │
│ /snap/jhack/198/lib/python3.8/site-packages/jhack/utils/show_relation.py:481 in render_relation  │
│                                                                                                  │
│   478 │   │   if not (endpoint1 and endpoint2):                                                  │
│   479 │   │   │   raise RuntimeError("invalid usage: provide two endpoints.")                    │
│   480 │   │                                                                                      │
│ ❱ 481 │   │   data = get_relation_data(                                                          │
│   482 │   │   │   provider_endpoint=endpoint1,                                                   │
│   483 │   │   │   requirer_endpoint=endpoint2,                                                   │
│   484 │   │   │   include_default_juju_keys=include_default_juju_keys,                           │
│                                                                                                  │
│ ╭──────────────────── locals ─────────────────────╮                                              │
│ │                 endpoint1 = 'ubuntu:juju-info'  │                                              │
│ │                 endpoint2 = 'nrpe:general-info' │                                              │
│ │       hide_empty_databags = False               │                                              │
│ │ include_default_juju_keys = False               │                                              │
│ │                   is_peer = False               │                                              │
│ │                     model = None                │                                              │
│ │                         n = None                │                                              │
│ ╰─────────────────────────────────────────────────╯                                              │
│                                                                                                  │
│ /snap/jhack/198/lib/python3.8/site-packages/jhack/utils/show_relation.py:347 in                  │
│ get_relation_data                                                                                │
│                                                                                                  │
│   344 │                                                                                          │
│   345 │   >>> get_relation_data('prometheus/0:ingress', 'traefik/1:ingress-per-unit')            │
│   346 │   """                                                                                    │
│ ❱ 347 │   provider_data = get_content(                                                           │
│   348 │   │   provider_endpoint, requirer_endpoint, include_default_juju_keys, model=model       │
│   349 │   )                                                                                      │
│   350 │   requirer_data = get_content(                                                           │
│                                                                                                  │
│ ╭──────────────────── locals ─────────────────────╮                                              │
│ │ include_default_juju_keys = False               │                                              │
│ │                     model = None                │                                              │
│ │         provider_endpoint = 'ubuntu:juju-info'  │                                              │
│ │         requirer_endpoint = 'nrpe:general-info' │                                              │
│ ╰─────────────────────────────────────────────────╯                                              │
│                                                                                                  │
│ /snap/jhack/198/lib/python3.8/site-packages/jhack/utils/show_relation.py:245 in get_content      │
│                                                                                                  │
│   242 │   # so even though we need 'any' remote unit name, we still need to query the status     │
│   243 │   # to find out what units there are.                                                    │
│   244 │   status = _juju_status(other_app_name, model=model, json=True)                          │
│ ❱ 245 │   other_unit_name = next(iter(status["applications"][other_app_name]["units"]))          │
│   246 │   # we might have a different number of units and other units, and it doesn't            │
│   247 │   # matter which 'other' we pass to get the databags for 'this one'.                     │
│   248                                                                                            │
│                                                                                                  │
│ ╭─────────────────────────────────────────── locals ───────────────────────────────────────────╮ │
│ │                         _ = None                                                             │ │
│ │                  app_name = 'ubuntu'                                                         │ │
│ │                  endpoint = 'juju-info'                                                      │ │
│ │ include_default_juju_keys = False                                                            │ │
│ │                      meta = Metadata(                                                        │ │
│ │                             │   scale=1,                                                     │ │
│ │                             │   units=(0,),                                                  │ │
│ │                             │   leader_id=0,                                                 │ │
│ │                             │   interface='juju-info'                                        │ │
│ │                             )                                                                │ │
│ │                     model = None                                                             │ │
│ │                       obj = 'ubuntu:juju-info'                                               │ │
│ │            other_app_name = 'nrpe'                                                           │ │
│ │            other_endpoint = 'general-info'                                                   │ │
│ │                 other_obj = 'nrpe:general-info'                                              │ │
│ │                 other_url = 'nrpe'                                                           │ │
│ │                      peer = False                                                            │ │
│ │                    status = {                                                                │ │
│ │                             │   'model': {                                                   │ │
│ │                             │   │   'name': 'test',                                          │ │
│ │                             │   │   'type': 'iaas',                                          │ │
│ │                             │   │   'controller': 'lxd',                                     │ │
│ │                             │   │   'cloud': 'localhost',                                    │ │
│ │                             │   │   'region': 'localhost',                                   │ │
│ │                             │   │   'version': '2.9.38',                                     │ │
│ │                             │   │   'model-status': {                                        │ │
│ │                             │   │   │   'current': 'available',                              │ │
│ │                             │   │   │   'since': '08 Mar 2023 10:20:25-08:00'                │ │
│ │                             │   │   },                                                       │ │
│ │                             │   │   'sla': 'unsupported'                                     │ │
│ │                             │   },                                                           │ │
│ │                             │   'machines': {                                                │ │
│ │                             │   │   '0': {                                                   │ │
│ │                             │   │   │   'juju-status': {                                     │ │
│ │                             │   │   │   │   'current': 'started',                            │ │
│ │                             │   │   │   │   'since': '08 Mar 2023 10:24:47-08:00',           │ │
│ │                             │   │   │   │   'version': '2.9.38'                              │ │
│ │                             │   │   │   },                                                   │ │
│ │                             │   │   │   'hostname': 'juju-b229b0-0',                         │ │
│ │                             │   │   │   'dns-name': '10.29.120.99',                          │ │
│ │                             │   │   │   'ip-addresses': ['10.29.120.99'],                    │ │
│ │                             │   │   │   'instance-id': 'juju-b229b0-0',                      │ │
│ │                             │   │   │   'machine-status': {                                  │ │
│ │                             │   │   │   │   'current': 'running',                            │ │
│ │                             │   │   │   │   'message': 'Running',                            │ │
│ │                             │   │   │   │   'since': '08 Mar 2023 10:23:01-08:00'            │ │
│ │                             │   │   │   },                                                   │ │
│ │                             │   │   │   'modification-status': {                             │ │
│ │                             │   │   │   │   'current': 'applied',                            │ │
│ │                             │   │   │   │   'since': '09 Mar 2023 07:59:27-08:00'            │ │
│ │                             │   │   │   },                                                   │ │
│ │                             │   │   │   'base': {'name': 'ubuntu', 'channel': '20.04'},      │ │
│ │                             │   │   │   'network-interfaces': {                              │ │
│ │                             │   │   │   │   'eth0': {                                        │ │
│ │                             │   │   │   │   │   'ip-addresses': ['10.29.120.99'],            │ │
│ │                             │   │   │   │   │   'mac-address': '00:16:3e:62:8a:7b',          │ │
│ │                             │   │   │   │   │   'gateway': '10.29.120.1',                    │ │
│ │                             │   │   │   │   │   'space': 'alpha',                            │ │
│ │                             │   │   │   │   │   'is-up': True                                │ │
│ │                             │   │   │   │   }                                                │ │
│ │                             │   │   │   },                                                   │ │
│ │                             │   │   │   'constraints': 'arch=amd64',                         │ │
│ │                             │   │   │   ... +1                                               │ │
│ │                             │   │   }                                                        │ │
│ │                             │   },                                                           │ │
│ │                             │   'applications': {                                            │ │
│ │                             │   │   'nrpe': {                                                │ │
│ │                             │   │   │   'charm': 'nrpe',                                     │ │
│ │                             │   │   │   'base': {'name': 'ubuntu', 'channel': '22.04'},      │ │
│ │                             │   │   │   'charm-origin': 'charmhub',                          │ │
│ │                             │   │   │   'charm-name': 'nrpe',                                │ │
│ │                             │   │   │   'charm-rev': 97,                                     │ │
│ │                             │   │   │   'charm-channel': 'stable',                           │ │
│ │                             │   │   │   'exposed': False,                                    │ │
│ │                             │   │   │   'application-status': {                              │ │
│ │                             │   │   │   │   'current': 'active',                             │ │
│ │                             │   │   │   │   'message': 'Ready',                              │ │
│ │                             │   │   │   │   'since': '09 Mar 2023 08:44:58-08:00'            │ │
│ │                             │   │   │   },                                                   │ │
│ │                             │   │   │   'relations': {'general-info': ['ubuntu']},           │ │
│ │                             │   │   │   'subordinate-to': ['ubuntu'],                        │ │
│ │                             │   │   │   ... +1                                               │ │
│ │                             │   │   },                                                       │ │
│ │                             │   │   'ubuntu': {                                              │ │
│ │                             │   │   │   'charm': 'ubuntu',                                   │ │
│ │                             │   │   │   'base': {'name': 'ubuntu', 'channel': '20.04'},      │ │
│ │                             │   │   │   'charm-origin': 'charmhub',                          │ │
│ │                             │   │   │   'charm-name': 'ubuntu',                              │ │
│ │                             │   │   │   'charm-rev': 21,                                     │ │
│ │                             │   │   │   'charm-channel': 'stable',                           │ │
│ │                             │   │   │   'exposed': False,                                    │ │
│ │                             │   │   │   'application-status': {                              │ │
│ │                             │   │   │   │   'current': 'active',                             │ │
│ │                             │   │   │   │   'since': '08 Mar 2023 10:24:50-08:00'            │ │
│ │                             │   │   │   },                                                   │ │
│ │                             │   │   │   'relations': {'juju-info': ['nrpe']},                │ │
│ │                             │   │   │   'units': {                                           │ │
│ │                             │   │   │   │   'ubuntu/0': {                                    │ │
│ │                             │   │   │   │   │   'workload-status': {                         │ │
│ │                             │   │   │   │   │   │   'current': 'active',                     │ │
│ │                             │   │   │   │   │   │   'since': '08 Mar 2023 10:24:50-08:00'    │ │
│ │                             │   │   │   │   │   },                                           │ │
│ │                             │   │   │   │   │   'juju-status': {                             │ │
│ │                             │   │   │   │   │   │   'current': 'idle',                       │ │
│ │                             │   │   │   │   │   │   'since': '09 Mar 2023 07:59:30-08:00',   │ │
│ │                             │   │   │   │   │   │   'version': '2.9.38'                      │ │
│ │                             │   │   │   │   │   },                                           │ │
│ │                             │   │   │   │   │   'leader': True,                              │ │
│ │                             │   │   │   │   │   'machine': '0',                              │ │
│ │                             │   │   │   │   │   'public-address': '10.29.120.99',            │ │
│ │                             │   │   │   │   │   'subordinates': {                            │ │
│ │                             │   │   │   │   │   │   'nrpe/0': {                              │ │
│ │                             │   │   │   │   │   │   │   'workload-status': {                 │ │
│ │                             │   │   │   │   │   │   │   │   'current': 'active',             │ │
│ │                             │   │   │   │   │   │   │   │   'message': 'Ready',              │ │
│ │                             │   │   │   │   │   │   │   │   'since': '09 Mar 2023            │ │
│ │                             08:44:58-08:00'                                                  │ │
│ │                             │   │   │   │   │   │   │   },                                   │ │
│ │                             │   │   │   │   │   │   │   'juju-status': {                     │ │
│ │                             │   │   │   │   │   │   │   │   'current': 'idle',               │ │
│ │                             │   │   │   │   │   │   │   │   'since': '09 Mar 2023            │ │
│ │                             08:42:22-08:00',                                                 │ │
│ │                             │   │   │   │   │   │   │   │   'version': '2.9.38'              │ │
│ │                             │   │   │   │   │   │   │   },                                   │ │
│ │                             │   │   │   │   │   │   │   'leader': True,                      │ │
│ │                             │   │   │   │   │   │   │   'open-ports': ['icmp', '5666/tcp'],  │ │
│ │                             │   │   │   │   │   │   │   'public-address': '10.29.120.99'     │ │
│ │                             │   │   │   │   │   │   }                                        │ │
│ │                             │   │   │   │   │   }                                            │ │
│ │                             │   │   │   │   }                                                │ │
│ │                             │   │   │   },                                                   │ │
│ │                             │   │   │   ... +1                                               │ │
│ │                             │   │   }                                                        │ │
│ │                             │   },                                                           │ │
│ │                             │   'storage': {},                                               │ │
│ │                             │   'controller': {'timestamp': '09:28:11-08:00'}                │ │
│ │                             }                                                                │ │
│ │                     units = (0,)                                                             │ │
│ │                       url = 'ubuntu'                                                         │ │
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
KeyError: 'units'