Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

show-relation fails on surbordinate applications #179

Open
gboutry opened this issue Aug 20, 2024 · 7 comments
Open

show-relation fails on surbordinate applications #179

gboutry opened this issue Aug 20, 2024 · 7 comments

Comments

@gboutry
Copy link

gboutry commented Aug 20, 2024

Trying to show relation of subordinate charm fails.

I tried to read the peer data of a surbordinate charm:

$ jhack show-relation ntp:ntp-peers
...
| /snap/jhack/387/lib/python3.8/site-packages/jhack/utils/show_relation.py:304 in                  │
│ get_metadata_from_status                                                                         │
│                                                                                                  │
│    301 ):                                                                                        │
│    302 │   status = _juju_status(model=model, json=True)                                         │
│    303 │   # machine status json output apparently has no 'scale'... -_-                         │
│ ❱  304 │   app_status = status["applications"][endpoint.app_name]                                │
│    305 │   if app_status.get("subordinate-to"):                                                  │
│    306 │   │   units = {}                                                                        │
│    307 │   │   # todo: need to scavenge unit names from OTHER units' .subordinates field         │
│                                                                                                  │
│ ╭────────── locals ──────────╮                                                                   │
│ │ endpoint = 'ntp:ntp-peers' │                                                                   │
│ │    model = None            │                                                                   │
│ │   status = {}              │                                                                   │
│ ╰────────────────────────────╯                                                                   │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
KeyError: 'applications'

I tried reading juju-info:

$ jhack show-relation ntp:juju-info sunbeam-charms:juju-info
...
│ /snap/jhack/387/lib/python3.8/site-packages/jhack/utils/show_relation.py:725 in                  │
│ _coalesce_endpoint_and_n                                                                         │
│                                                                                                  │
│    722 │   │   # if either provider or requirer are not apps in this model, OR either one have   │
│    723 │   │   # suspect a malformed CMR request                                                 │
│    724 │   │   status = _juju_status(model=model, json=True)                                     │
│ ❱  725 │   │   apps = status["applications"]                                                     │
│    726 │   │   app1 = apps.get(ep_url_1.app_name)                                                │
│    727 │   │   app2 = apps.get(ep_url_2.app_name)                                                │
│    728 │   │   app_not_found = (                                                                 │
│                                                                                                  │
│ ╭─────────────────────────────────────────── locals ───────────────────────────────────────────╮ │
│ │ endpoint1 = 'ntp:juju-info'                                                                  │ │
│ │ endpoint2 = 'sunbeam-charms:juju-info'                                                       │ │
│ │  ep_url_1 = 'ntp:juju-info'                                                                  │ │
│ │  ep_url_2 = 'sunbeam-charms:juju-info'                                                       │ │
│ │      flip = False                                                                            │ │
│ │     found = []                                                                               │ │
│ │     match = False                                                                            │ │
│ │     model = None                                                                             │ │
│ │       msg = "No relation found with endpoints 'ntp:juju-info' -> 'sunbeam-charms:juju-info'  │ │
│ │             i"+30                                                                            │ │
│ │         n = None                                                                             │ │
│ │  relation = Relation(                                                                        │ │
│ │             │   provider='sunbeam-machine',                                                  │ │
│ │             │   provider_endpoint='juju-info',                                               │ │
│ │             │   requirer='ntp',                                                              │ │
│ │             │   requirer_endpoint='juju-info',                                               │ │
│ │             │   interface='juju-info',                                                       │ │
│ │             │   raw_type='subordinate'                                                       │ │
│ │             )                                                                                │ │
│ │ relations = [                                                                                │ │
│ │             │   Relation(                                                                    │ │
│ │             │   │   provider='mysql',                                                        │ │
│ │             │   │   provider_endpoint='database-peers',                                      │ │
│ │             │   │   requirer='mysql',                                                        │ │
│ │             │   │   requirer_endpoint='database-peers',                                      │ │
│ │             │   │   interface='mysql_peers',                                                 │ │
│ │             │   │   raw_type='peer'                                                          │ │
│ │             │   ),                                                                           │ │
│ │             │   Relation(                                                                    │ │
│ │             │   │   provider='mysql',                                                        │ │
│ │             │   │   provider_endpoint='restart',                                             │ │
│ │             │   │   requirer='mysql',                                                        │ │
│ │             │   │   requirer_endpoint='restart',                                             │ │
│ │             │   │   interface='rolling_op',                                                  │ │
│ │             │   │   raw_type='peer'                                                          │ │
│ │             │   ),                                                                           │ │
│ │             │   Relation(                                                                    │ │
│ │             │   │   provider='mysql',                                                        │ │
│ │             │   │   provider_endpoint='upgrade',                                             │ │
│ │             │   │   requirer='mysql',                                                        │ │
│ │             │   │   requirer_endpoint='upgrade',                                             │ │
│ │             │   │   interface='upgrade',                                                     │ │
│ │             │   │   raw_type='peer'                                                          │ │
│ │             │   ),                                                                           │ │
│ │             │   Relation(                                                                    │ │
│ │             │   │   provider='ntp',                                                          │ │
│ │             │   │   provider_endpoint='ntp-peers',                                           │ │
│ │             │   │   requirer='ntp',                                                          │ │
│ │             │   │   requirer_endpoint='ntp-peers',                                           │ │
│ │             │   │   interface='ntp',                                                         │ │
│ │             │   │   raw_type='peer'                                                          │ │
│ │             │   ),                                                                           │ │
│ │             │   Relation(                                                                    │ │
│ │             │   │   provider='sunbeam-machine',                                              │ │
│ │             │   │   provider_endpoint='juju-info',                                           │ │
│ │             │   │   requirer='ntp',                                                          │ │
│ │             │   │   requirer_endpoint='juju-info',                                           │ │
│ │             │   │   interface='juju-info',                                                   │ │
│ │             │   │   raw_type='subordinate'                                                   │ │
│ │             │   )                                                                            │ │
│ │             ]                                                                                │ │
│ │    status = {}                                                                               │ │
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
KeyError: 'applications'

Status output:

$ juju status --relations
Model   Controller  Cloud/Region         Version  SLA          Timestamp
testos  lxd         localhost/localhost  3.5.3    unsupported  14:42:54+02:00

App              Version  Status  Scale  Charm            Channel        Rev  Exposed  Message
ntp              4.2      active      5  ntp              latest/stable   50  no       chrony: Ready
sunbeam-machine           active      5  sunbeam-machine  2024.1/edge     36  no       

Unit                Workload  Agent  Machine  Public address                          Ports    Message
sunbeam-machine/0*  active    idle   1        fd00:56ad:9f7a:9800:216:3eff:fe8f:5914           
  ntp/5             active    idle            fd00:56ad:9f7a:9800:216:3eff:fe8f:5914  123/udp  chrony: Ready
sunbeam-machine/1   active    idle   2        fd00:56ad:9f7a:9800:216:3eff:fe39:b945           
  ntp/0             active    idle            fd00:56ad:9f7a:9800:216:3eff:fe39:b945  123/udp  chrony: Ready
sunbeam-machine/2   active    idle   3        fd00:56ad:9f7a:9800:216:3eff:fe74:b927           
  ntp/1*            active    idle            fd00:56ad:9f7a:9800:216:3eff:fe74:b927  123/udp  chrony: Ready
sunbeam-machine/3   active    idle   4        fd00:56ad:9f7a:9800:216:3eff:fe3c:37ca           
  ntp/4             active    idle            fd00:56ad:9f7a:9800:216:3eff:fe3c:37ca  123/udp  chrony: Ready
sunbeam-machine/4   active    idle   5        fd00:56ad:9f7a:9800:216:3eff:febe:90a5           
  ntp/3             active    idle            fd00:56ad:9f7a:9800:216:3eff:febe:90a5  123/udp  chrony: Ready

Machine  State    Address                                 Inst id        Base          AZ  Message
1        started  fd00:56ad:9f7a:9800:216:3eff:fe8f:5914  juju-a1d33d-1  ubuntu@22.04      Running
2        started  fd00:56ad:9f7a:9800:216:3eff:fe39:b945  juju-a1d33d-2  ubuntu@22.04      Running
3        started  fd00:56ad:9f7a:9800:216:3eff:fe74:b927  juju-a1d33d-3  ubuntu@22.04      Running
4        started  fd00:56ad:9f7a:9800:216:3eff:fe3c:37ca  juju-a1d33d-4  ubuntu@22.04      Running
5        started  fd00:56ad:9f7a:9800:216:3eff:febe:90a5  juju-a1d33d-5  ubuntu@22.04      Running

Integration provider       Requirer       Interface  Type         Message
ntp:ntp-peers              ntp:ntp-peers  ntp        peer         
sunbeam-machine:juju-info  ntp:juju-info  juju-info  subordinate        

jhack version: jhack 0.4.3.2.1 --DEVMODE--
juju version: 3.5.3


Note: if trying to reproduce with these 2 specific charms, know that sunbeam-machine and ntp won't work in a container, they need to be deployed on a VM (--constraints virt-type=virtual-machine to get a LXD vm on a LXD cloud)

@PietroPasotti
Copy link
Collaborator

Yeah in some situations juju status seems to be returning nothing, but I find it very hard to reproduce.
I assume you retried soon after and didn't see changes, it wasn't a transient thing?

@PietroPasotti
Copy link
Collaborator

can you check if running the command with the LOGLEVEL=DEBUG envvar set gives you any more hints?

@gboutry
Copy link
Author

gboutry commented Aug 20, 2024

I have a 100% failure rate until now

With the debug level:

LOGLEVEL=DEBUG jhack show-relation -m testos ntp:ntp-peers                         
INFO:jhack:jhack running in snapped mode. Checking configuration...
INFO:jhack:juju command is b'/snap/jhack/387/bin/juju\n'
DEBUG:parse:format '{_}: {timestamp:ti} {_}' -> '(.+?): (?P<timestamp>(\\d{4}-\\d\\d-\\d\\d)((\\s+|T)(\\d{1,2}:\\d{1,2}(:\\d{1,2}(\\.\\d+)?)?))?(Z|\\s*[-+]\\d\\d:?\\d\\d)?) (.+?)'
DEBUG:parse:format '{_}: {timestamp:tt} {_}' -> '(.+?): (?P<timestamp>(\\d{1,2}:\\d{1,2}(:\\d{1,2}(\\.\\d+)?)?)?(\\s+[AP]M)?(\\s+[-+]\\d\\d?:?\\d\\d)?) (.+?)'
::= Verbose mode (DEBUG). =::
DEBUG:asyncio:Using selector: EpollSelector
╭─────────────────────────────── Traceback (most recent call last) ────────────────────────────────╮
│ /snap/jhack/387/lib/python3.8/site-packages/jhack/utils/show_relation.py:1023 in                 │
│ sync_show_relation                                                                               │
│                                                                                                  │
│   1020 │   - ``$ jhack utils show-relation my_app:peers`` - peer relation\n                      │
│   1021 │   - ``$ jhack utils show-relation my_app:foo cross_model_app:bar`` - CMRs\n             │
│   1022 │   """                                                                                   │
│ ❱ 1023 │   return _sync_show_relation(                                                           │
│   1024 │   │   endpoint1=endpoint1,                                                              │
│   1025 │   │   endpoint2=endpoint2,                                                              │
│   1026 │   │   n=n,                                                                              │
│                                                                                                  │
│ ╭────────────────── locals ───────────────────╮                                                  │
│ │               color = 'auto'                │                                                  │
│ │           endpoint1 = 'ntp:ntp-peers'       │                                                  │
│ │           endpoint2 = None                  │                                                  │
│ │              format = <Format.auto: 'auto'> │                                                  │
│ │ hide_empty_databags = False                 │                                                  │
│ │               model = 'testos'              │                                                  │
│ │                   n = None                  │                                                  │
│ │      show_juju_keys = False                 │                                                  │
│ │               watch = False                 │                                                  │
│ ╰─────────────────────────────────────────────╯                                                  │
│                                                                                                  │
│ /snap/jhack/387/lib/python3.8/site-packages/jhack/utils/show_relation.py:1062 in                 │
│ _sync_show_relation                                                                              │
│                                                                                                  │
│   1059 │   while True:                                                                           │
│   1060 │   │   start = time.time()                                                               │
│   1061 │   │                                                                                     │
│ ❱ 1062 │   │   table = asyncio.run(                                                              │
│   1063 │   │   │   render_relation(                                                              │
│   1064 │   │   │   │   endpoint1,                                                                │
│   1065 │   │   │   │   endpoint2,                                                                │
│                                                                                                  │
│ ╭─────────────────────────────────────────── locals ───────────────────────────────────────────╮ │
│ │               color = 'auto'                                                                 │ │
│ │             Console = <class 'rich.console.Console'>                                         │ │
│ │             console = <console width=249 ColorSystem.TRUECOLOR>                              │ │
│ │           endpoint1 = 'ntp:ntp-peers'                                                        │ │
│ │           endpoint2 = None                                                                   │ │
│ │              format = <Format.auto: 'auto'>                                                  │ │
│ │ hide_empty_databags = False                                                                  │ │
│ │               model = 'testos'                                                               │ │
│ │                   n = None                                                                   │ │
│ │                rich = <module 'rich' from                                                    │ │
│ │                       '/snap/jhack/387/lib/python3.8/site-packages/rich/__init__.py'>        │ │
│ │      show_juju_keys = False                                                                  │ │
│ │               start = 1724160271.643747                                                      │ │
│ │               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 0x70c74b6e7340>           │                       │
│ ╰────────────────────────────────────────────────────────────────────────╯                       │
│                                                                                                  │
│ /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/387/lib/python3.8/site-packages/jhack/utils/show_relation.py:789>     │ │
│ │            exception=KeyError('applications')>                                               │ │
│ │ new_task = True                                                                              │ │
│ │     self = <_UnixSelectorEventLoop running=False closed=True debug=False>                    │ │
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │
│                                                                                                  │
│ /snap/jhack/387/lib/python3.8/site-packages/jhack/utils/show_relation.py:814 in render_relation  │
│                                                                                                  │
│    811 │   │   if endpoint1.app_name in saas or (endpoint2 and endpoint2.app_name in saas):      │
│    812 │   │   │   relation.raw_type = "cross_model"                                             │
│    813 │                                                                                         │
│ ❱  814 │   entities = _gather_entities(                                                          │
│    815 │   │   endpoint1,                                                                        │
│    816 │   │   endpoint2,                                                                        │
│    817 │   │   relation,                                                                         │
│                                                                                                  │
│ ╭──────────────────────────── locals ────────────────────────────╮                               │
│ │                 endpoint1 = 'ntp:ntp-peers'                    │                               │
│ │                 endpoint2 = None                               │                               │
│ │                    format = <Format.auto: 'auto'>              │                               │
│ │       hide_empty_databags = False                              │                               │
│ │ include_default_juju_keys = False                              │                               │
│ │                     model = 'testos'                           │                               │
│ │                         n = None                               │                               │
│ │                  relation = Relation(                          │                               │
│ │                             │   provider='ntp',                │                               │
│ │                             │   provider_endpoint='ntp-peers', │                               │
│ │                             │   requirer='ntp',                │                               │
│ │                             │   requirer_endpoint='ntp-peers', │                               │
│ │                             │   interface='ntp',               │                               │
│ │                             │   raw_type='peer'                │                               │
│ │                             )                                  │                               │
│ ╰────────────────────────────────────────────────────────────────╯                               │
│                                                                                                  │
│ /snap/jhack/387/lib/python3.8/site-packages/jhack/utils/show_relation.py:765 in _gather_entities │
│                                                                                                  │
│    762 ) -> Tuple[AppRelationData, ...]:                                                         │
│    763 │   if relation.type == RelationType.peer:                                                │
│    764 │   │   return (                                                                          │
│ ❱  765 │   │   │   get_peer_relation_data(                                                       │
│    766 │   │   │   │   endpoint=endpoint1,                                                       │
│    767 │   │   │   │   include_default_juju_keys=include_default_juju_keys,                      │
│    768 │   │   │   │   model=model,                                                              │
│                                                                                                  │
│ ╭──────────────────────────── locals ────────────────────────────╮                               │
│ │                 endpoint1 = 'ntp:ntp-peers'                    │                               │
│ │                 endpoint2 = None                               │                               │
│ │ include_default_juju_keys = False                              │                               │
│ │                     model = 'testos'                           │                               │
│ │                  relation = Relation(                          │                               │
│ │                             │   provider='ntp',                │                               │
│ │                             │   provider_endpoint='ntp-peers', │                               │
│ │                             │   requirer='ntp',                │                               │
│ │                             │   requirer_endpoint='ntp-peers', │                               │
│ │                             │   interface='ntp',               │                               │
│ │                             │   raw_type='peer'                │                               │
│ │                             )                                  │                               │
│ ╰────────────────────────────────────────────────────────────────╯                               │
│                                                                                                  │
│ /snap/jhack/387/lib/python3.8/site-packages/jhack/utils/show_relation.py:546 in                  │
│ get_peer_relation_data                                                                           │
│                                                                                                  │
│    543 │   include_default_juju_keys: bool = False,                                              │
│    544 │   model: str = None,                                                                    │
│    545 ) -> AppRelationData:                                                                     │
│ ❱  546 │   return get_content(                                                                   │
│    547 │   │   endpoint,                                                                         │
│    548 │   │   endpoint,                                                                         │
│    549 │   │   relation,                                                                         │
│                                                                                                  │
│ ╭──────────────────────────── locals ────────────────────────────╮                               │
│ │                  endpoint = 'ntp:ntp-peers'                    │                               │
│ │ include_default_juju_keys = False                              │                               │
│ │                     model = 'testos'                           │                               │
│ │                  relation = Relation(                          │                               │
│ │                             │   provider='ntp',                │                               │
│ │                             │   provider_endpoint='ntp-peers', │                               │
│ │                             │   requirer='ntp',                │                               │
│ │                             │   requirer_endpoint='ntp-peers', │                               │
│ │                             │   interface='ntp',               │                               │
│ │                             │   raw_type='peer'                │                               │
│ │                             )                                  │                               │
│ ╰────────────────────────────────────────────────────────────────╯                               │
│                                                                                                  │
│ /snap/jhack/387/lib/python3.8/site-packages/jhack/utils/show_relation.py:374 in get_content      │
│                                                                                                  │
│    371 │   # so even though we need 'any' remote unit name, we still need to query the status    │
│    372 │   # to find out what units there are.                                                   │
│    373 │   status = _juju_status(model=model, json=True)                                         │
│ ❱  374 │   units, meta = get_units_and_meta(obj, model)                                          │
│    375 │                                                                                         │
│    376 │   if other_model != model:                                                              │
│    377 │   │   logger.info(f"other app is in model {other_model!r}. Pulling status...")          │
│                                                                                                  │
│ ╭──────────────────────────── locals ────────────────────────────╮                               │
│ │ include_default_juju_keys = False                              │                               │
│ │                     model = 'testos'                           │                               │
│ │                       obj = 'ntp:ntp-peers'                    │                               │
│ │               other_model = None                               │                               │
│ │                 other_obj = 'ntp:ntp-peers'                    │                               │
│ │                  relation = Relation(                          │                               │
│ │                             │   provider='ntp',                │                               │
│ │                             │   provider_endpoint='ntp-peers', │                               │
│ │                             │   requirer='ntp',                │                               │
│ │                             │   requirer_endpoint='ntp-peers', │                               │
│ │                             │   interface='ntp',               │                               │
│ │                             │   raw_type='peer'                │                               │
│ │                             )                                  │                               │
│ │                    status = {}                                 │                               │
│ ╰────────────────────────────────────────────────────────────────╯                               │
│                                                                                                  │
│ /snap/jhack/387/lib/python3.8/site-packages/jhack/utils/show_relation.py:353 in                  │
│ get_units_and_meta                                                                               │
│                                                                                                  │
│    350 │   model: str = None,                                                                    │
│    351 ):                                                                                        │
│    352 │   """Get app name and unit count from url; url is either `app_name/0` or `app_name`.""  │
│ ❱  353 │   meta = get_metadata_from_status(endpoint, model=model)                                │
│    354 │   if endpoint.unit_id is not None:                                                      │
│    355 │   │   units = (int(endpoint.unit_id),)                                                  │
│    356 │   else:                                                                                 │
│                                                                                                  │
│ ╭────────── locals ──────────╮                                                                   │
│ │ endpoint = 'ntp:ntp-peers' │                                                                   │
│ │    model = 'testos'        │                                                                   │
│ ╰────────────────────────────╯                                                                   │
│                                                                                                  │
│ /snap/jhack/387/lib/python3.8/site-packages/jhack/utils/show_relation.py:304 in                  │
│ get_metadata_from_status                                                                         │
│                                                                                                  │
│    301 ):                                                                                        │
│    302 │   status = _juju_status(model=model, json=True)                                         │
│    303 │   # machine status json output apparently has no 'scale'... -_-                         │
│ ❱  304 │   app_status = status["applications"][endpoint.app_name]                                │
│    305 │   if app_status.get("subordinate-to"):                                                  │
│    306 │   │   units = {}                                                                        │
│    307 │   │   # todo: need to scavenge unit names from OTHER units' .subordinates field         │
│                                                                                                  │
│ ╭────────── locals ──────────╮                                                                   │
│ │ endpoint = 'ntp:ntp-peers' │                                                                   │
│ │    model = 'testos'        │                                                                   │
│ │   status = {}              │                                                                   │
│ ╰────────────────────────────╯                                                                   │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
KeyError: 'applications'

@PietroPasotti
Copy link
Collaborator

could you post the output of running the above after installing jhack from this branch? #180

@gboutry
Copy link
Author

gboutry commented Aug 20, 2024

Of course:

$ LOGLEVEL=DEBUG jhack show-relation -m testos ntp:ntp-peers
INFO:jhack:jhack running in unsnapped mode. Skipping .local/share/juju configuration.
DEBUG:parse:format '{_}: {timestamp:ti} {_}' -> '(.+?): (?P<timestamp>(\\d{4}-\\d\\d-\\d\\d)((\\s+|T)(\\d{1,2}:\\d{1,2}(:\\d{1,2}(\\.\\d+)?)?))?(Z|\\s*[-+]\\d\\d:?\\d\\d)?) (.+?)'
DEBUG:parse:format '{_}: {timestamp:tt} {_}' -> '(.+?): (?P<timestamp>(\\d{1,2}:\\d{1,2}(:\\d{1,2}(\\.\\d+)?)?)?(\\s+[AP]M)?(\\s+[-+]\\d\\d?:?\\d\\d)?) (.+?)'
::= Verbose mode (DEBUG). =::
DEBUG:asyncio:Using selector: EpollSelector
DEBUG:jhack:Fetching status with: 'juju status --relations -m testos'
DEBUG:jhack:Fetching status with: 'juju status --relations -m testos --format json'
DEBUG:jhack:Fetching status with: 'juju status --relations -m testos --format json'
ERROR:jhack./home/gboutry/Documents/canonical/projects/jhack/jhack/utils/show_relation.py:juju status returned nothing!
DEBUG:jhack:Fetching status with: 'juju status --relations -m testos --format json'
ERROR:jhack./home/gboutry/Documents/canonical/projects/jhack/jhack/utils/show_relation.py:juju status returned nothing!
╭─────────────────────────────── Traceback (most recent call last) ────────────────────────────────╮
│ /home/gboutry/Documents/canonical/projects/jhack/jhack/utils/show_relation.py:1028 in            │
│ sync_show_relation                                                                               │
│                                                                                                  │
│   1025 │   - ``$ jhack utils show-relation my_app:peers`` - peer relation\n                      │
│   1026 │   - ``$ jhack utils show-relation my_app:foo cross_model_app:bar`` - CMRs\n             │
│   1027 │   """                                                                                   │
│ ❱ 1028 │   return _sync_show_relation(                                                           │
│   1029 │   │   endpoint1=endpoint1,                                                              │
│   1030 │   │   endpoint2=endpoint2,                                                              │
│   1031 │   │   n=n,                                                                              │
│                                                                                                  │
│ ╭────────────────── locals ───────────────────╮                                                  │
│ │               color = 'auto'                │                                                  │
│ │           endpoint1 = 'ntp:ntp-peers'       │                                                  │
│ │           endpoint2 = None                  │                                                  │
│ │              format = <Format.auto: 'auto'> │                                                  │
│ │ hide_empty_databags = False                 │                                                  │
│ │               model = 'testos'              │                                                  │
│ │                   n = None                  │                                                  │
│ │      show_juju_keys = False                 │                                                  │
│ │               watch = False                 │                                                  │
│ ╰─────────────────────────────────────────────╯                                                  │
│                                                                                                  │
│ /home/gboutry/Documents/canonical/projects/jhack/jhack/utils/show_relation.py:1067 in            │
│ _sync_show_relation                                                                              │
│                                                                                                  │
│   1064 │   while True:                                                                           │
│   1065 │   │   start = time.time()                                                               │
│   1066 │   │                                                                                     │
│ ❱ 1067 │   │   table = asyncio.run(                                                              │
│   1068 │   │   │   render_relation(                                                              │
│   1069 │   │   │   │   endpoint1,                                                                │
│   1070 │   │   │   │   endpoint2,                                                                │
│                                                                                                  │
│ ╭─────────────────────────────────────────── locals ───────────────────────────────────────────╮ │
│ │               color = 'auto'                                                                 │ │
│ │             Console = <class 'rich.console.Console'>                                         │ │
│ │             console = <console width=249 ColorSystem.TRUECOLOR>                              │ │
│ │           endpoint1 = 'ntp:ntp-peers'                                                        │ │
│ │           endpoint2 = None                                                                   │ │
│ │              format = <Format.auto: 'auto'>                                                  │ │
│ │ hide_empty_databags = False                                                                  │ │
│ │               model = 'testos'                                                               │ │
│ │                   n = None                                                                   │ │
│ │                rich = <module 'rich' from                                                    │ │
│ │                       '/home/gboutry/Documents/canonical/projects/jhack/venv/lib/python3.10… │ │
│ │      show_juju_keys = False                                                                  │ │
│ │               start = 1724161940.095359                                                      │ │
│ │               watch = False                                                                  │ │
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │
│                                                                                                  │
│ /home/gboutry/.rye/py/cpython@3.10.13/install/lib/python3.10/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 0x754d8492f290>           │                       │
│ ╰────────────────────────────────────────────────────────────────────────╯                       │
│                                                                                                  │
│ /home/gboutry/.rye/py/cpython@3.10.13/install/lib/python3.10/asyncio/base_events.py:649 in       │
│ run_until_complete                                                                               │
│                                                                                                  │
│    646 │   │   if not future.done():                                                             │
│    647 │   │   │   raise RuntimeError('Event loop stopped before Future completed.')             │
│    648 │   │                                                                                     │
│ ❱  649 │   │   return future.result()                                                            │
│    650 │                                                                                         │
│    651 │   def stop(self):                                                                       │
│    652 │   │   """Stop running the event loop.                                                   │
│                                                                                                  │
│ ╭─────────────────────────────────────────── locals ───────────────────────────────────────────╮ │
│ │   future = <Task finished name='Task-1' coro=<render_relation() done, defined at             │ │
│ │            /home/gboutry/Documents/canonical/projects/jhack/jhack/utils/show_relation.py:79… │ │
│ │            exception=KeyError('applications')>                                               │ │
│ │ new_task = True                                                                              │ │
│ │     self = <_UnixSelectorEventLoop running=False closed=True debug=False>                    │ │
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │
│                                                                                                  │
│ /home/gboutry/Documents/canonical/projects/jhack/jhack/utils/show_relation.py:819 in             │
│ render_relation                                                                                  │
│                                                                                                  │
│    816 │   │   if endpoint1.app_name in saas or (endpoint2 and endpoint2.app_name in saas):      │
│    817 │   │   │   relation.raw_type = "cross_model"                                             │
│    818 │                                                                                         │
│ ❱  819 │   entities = _gather_entities(                                                          │
│    820 │   │   endpoint1,                                                                        │
│    821 │   │   endpoint2,                                                                        │
│    822 │   │   relation,                                                                         │
│                                                                                                  │
│ ╭──────────────────────────── locals ────────────────────────────╮                               │
│ │                 endpoint1 = 'ntp:ntp-peers'                    │                               │
│ │                 endpoint2 = None                               │                               │
│ │                    format = <Format.auto: 'auto'>              │                               │
│ │       hide_empty_databags = False                              │                               │
│ │ include_default_juju_keys = False                              │                               │
│ │                     model = 'testos'                           │                               │
│ │                         n = None                               │                               │
│ │                  relation = Relation(                          │                               │
│ │                             │   provider='ntp',                │                               │
│ │                             │   provider_endpoint='ntp-peers', │                               │
│ │                             │   requirer='ntp',                │                               │
│ │                             │   requirer_endpoint='ntp-peers', │                               │
│ │                             │   interface='ntp',               │                               │
│ │                             │   raw_type='peer'                │                               │
│ │                             )                                  │                               │
│ ╰────────────────────────────────────────────────────────────────╯                               │
│                                                                                                  │
│ /home/gboutry/Documents/canonical/projects/jhack/jhack/utils/show_relation.py:770 in             │
│ _gather_entities                                                                                 │
│                                                                                                  │
│    767 ) -> Tuple[AppRelationData, ...]:                                                         │
│    768 │   if relation.type == RelationType.peer:                                                │
│    769 │   │   return (                                                                          │
│ ❱  770 │   │   │   get_peer_relation_data(                                                       │
│    771 │   │   │   │   endpoint=endpoint1,                                                       │
│    772 │   │   │   │   include_default_juju_keys=include_default_juju_keys,                      │
│    773 │   │   │   │   model=model,                                                              │
│                                                                                                  │
│ ╭──────────────────────────── locals ────────────────────────────╮                               │
│ │                 endpoint1 = 'ntp:ntp-peers'                    │                               │
│ │                 endpoint2 = None                               │                               │
│ │ include_default_juju_keys = False                              │                               │
│ │                     model = 'testos'                           │                               │
│ │                  relation = Relation(                          │                               │
│ │                             │   provider='ntp',                │                               │
│ │                             │   provider_endpoint='ntp-peers', │                               │
│ │                             │   requirer='ntp',                │                               │
│ │                             │   requirer_endpoint='ntp-peers', │                               │
│ │                             │   interface='ntp',               │                               │
│ │                             │   raw_type='peer'                │                               │
│ │                             )                                  │                               │
│ ╰────────────────────────────────────────────────────────────────╯                               │
│                                                                                                  │
│ /home/gboutry/Documents/canonical/projects/jhack/jhack/utils/show_relation.py:551 in             │
│ get_peer_relation_data                                                                           │
│                                                                                                  │
│    548 │   include_default_juju_keys: bool = False,                                              │
│    549 │   model: str = None,                                                                    │
│    550 ) -> AppRelationData:                                                                     │
│ ❱  551 │   return get_content(                                                                   │
│    552 │   │   endpoint,                                                                         │
│    553 │   │   endpoint,                                                                         │
│    554 │   │   relation,                                                                         │
│                                                                                                  │
│ ╭──────────────────────────── locals ────────────────────────────╮                               │
│ │                  endpoint = 'ntp:ntp-peers'                    │                               │
│ │ include_default_juju_keys = False                              │                               │
│ │                     model = 'testos'                           │                               │
│ │                  relation = Relation(                          │                               │
│ │                             │   provider='ntp',                │                               │
│ │                             │   provider_endpoint='ntp-peers', │                               │
│ │                             │   requirer='ntp',                │                               │
│ │                             │   requirer_endpoint='ntp-peers', │                               │
│ │                             │   interface='ntp',               │                               │
│ │                             │   raw_type='peer'                │                               │
│ │                             )                                  │                               │
│ ╰────────────────────────────────────────────────────────────────╯                               │
│                                                                                                  │
│ /home/gboutry/Documents/canonical/projects/jhack/jhack/utils/show_relation.py:379 in get_content │
│                                                                                                  │
│    376 │   # so even though we need 'any' remote unit name, we still need to query the status    │
│    377 │   # to find out what units there are.                                                   │
│    378 │   status = _juju_status(model=model, json=True)                                         │
│ ❱  379 │   units, meta = get_units_and_meta(obj, model)                                          │
│    380 │                                                                                         │
│    381 │   if other_model != model:                                                              │
│    382 │   │   logger.info(f"other app is in model {other_model!r}. Pulling status...")          │
│                                                                                                  │
│ ╭──────────────────────────── locals ────────────────────────────╮                               │
│ │ include_default_juju_keys = False                              │                               │
│ │                     model = 'testos'                           │                               │
│ │                       obj = 'ntp:ntp-peers'                    │                               │
│ │               other_model = None                               │                               │
│ │                 other_obj = 'ntp:ntp-peers'                    │                               │
│ │                  relation = Relation(                          │                               │
│ │                             │   provider='ntp',                │                               │
│ │                             │   provider_endpoint='ntp-peers', │                               │
│ │                             │   requirer='ntp',                │                               │
│ │                             │   requirer_endpoint='ntp-peers', │                               │
│ │                             │   interface='ntp',               │                               │
│ │                             │   raw_type='peer'                │                               │
│ │                             )                                  │                               │
│ │                    status = {}                                 │                               │
│ ╰────────────────────────────────────────────────────────────────╯                               │
│                                                                                                  │
│ /home/gboutry/Documents/canonical/projects/jhack/jhack/utils/show_relation.py:358 in             │
│ get_units_and_meta                                                                               │
│                                                                                                  │
│    355 │   model: str = None,                                                                    │
│    356 ):                                                                                        │
│    357 │   """Get app name and unit count from url; url is either `app_name/0` or `app_name`.""  │
│ ❱  358 │   meta = get_metadata_from_status(endpoint, model=model)                                │
│    359 │   if endpoint.unit_id is not None:                                                      │
│    360 │   │   units = (int(endpoint.unit_id),)                                                  │
│    361 │   else:                                                                                 │
│                                                                                                  │
│ ╭────────── locals ──────────╮                                                                   │
│ │ endpoint = 'ntp:ntp-peers' │                                                                   │
│ │    model = 'testos'        │                                                                   │
│ ╰────────────────────────────╯                                                                   │
│                                                                                                  │
│ /home/gboutry/Documents/canonical/projects/jhack/jhack/utils/show_relation.py:309 in             │
│ get_metadata_from_status                                                                         │
│                                                                                                  │
│    306 ):                                                                                        │
│    307 │   status = _juju_status(model=model, json=True)                                         │
│    308 │   # machine status json output apparently has no 'scale'... -_-                         │
│ ❱  309 │   app_status = status["applications"][endpoint.app_name]                                │
│    310 │   if app_status.get("subordinate-to"):                                                  │
│    311 │   │   units = {}                                                                        │
│    312 │   │   # todo: need to scavenge unit names from OTHER units' .subordinates field         │
│                                                                                                  │
│ ╭────────── locals ──────────╮                                                                   │
│ │ endpoint = 'ntp:ntp-peers' │                                                                   │
│ │    model = 'testos'        │                                                                   │
│ │   status = {}              │                                                                   │
│ ╰────────────────────────────╯                                                                   │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
KeyError: 'applications'

(I trust you, but still read the code before haha)

@gboutry
Copy link
Author

gboutry commented Aug 20, 2024

Ok, after some more testing, I had no errors in the status cli, until I added --format json

juju status --relations -m testos --format json
provided relations option is always enabled in non tabular formats
{}
ERROR cannot process storage instances: cannot convert storage details for storage-database-0: filesystem for storage instance "database/0" not found (not found)

This seems to be the root issue.

@PietroPasotti
Copy link
Collaborator

huh
that sounds like a juju bug?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants