juju / python-libjuju

Python library for the Juju API
Apache License 2.0
60 stars 101 forks source link

Broken APIs after Charmhub cutover #634

Closed genet022 closed 2 years ago

genet022 commented 2 years ago

Previously supported APIs have broke after the switch from Charmstore to Charmhub. Presumably due to Charmhub not supporting the old APIs.

A simple reproducible example:

>>> model = Model()
>>> do(model.connect_current())
>>> do(model.deploy("cs:~containers/easyrsa"))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in do
  File "/usr/lib/python3.8/asyncio/base_events.py", line 616, in run_until_complete
    return future.result()
  File "/usr/local/lib/python3.8/dist-packages/juju/model.py", line 1614, in deploy
    res = await self.deploy_types[str(url.schema)].resolve(url, architecture, application_name, channel, series, entity_url)
  File "/usr/local/lib/python3.8/dist-packages/juju/model.py", line 513, in resolve
    app_name = result['Meta']['charm-metadata']['Name']
KeyError: 'charm-metadata'

A bit more granular:

$ curl "https://api.jujucharms.com/charmstore/v5/containers/coredns/meta/any?channel=edge"
{"Code":"not found","Message":"No matching charm or bundle for cs:containers/coredns; for channel: 'edge'"}
$ curl "https://api.jujucharms.com/charmstore/v5/~containers/coredns/meta/any"
{"Id":"cs:~containers/coredns-20"}
addyess commented 2 years ago

please note I provided one of these granular details. Note that in the first example containers is missing a tilda (~)

curling the correct endpoint yields a response rather than the 404 Response. However, this missing metadata still could be an issue

❯ curl "https://api.jujucharms.com/charmstore/v5/~containers/coredns/meta/any?channel=edge"
{"Id":"cs:~containers/coredns-21"}
addyess commented 2 years ago

running this locally, here's the URL that's generated in charmstore.py line 127

https://api.jujucharms.com/charmstore/v5/~containers/easyrsa/meta/any?include=bundle-machine-count&include=bundle-metadata&include=bundle-unit-count&include=charm-actions&include=charm-config&include=charm-metadata&include=common-info&include=extra-info&include=owner&include=published&include=resources&include=supported-series&include=terms

❯ curl https://api.jujucharms.com/charmstore/v5/\~containers/easyrsa/meta/any\?include\=bundle-machine-count\&include\=bundle-metadata\&include\=bundle-unit-count\&include\=charm-actions\&include\=charm-config\&include\=charm-metadata\&include\=common-info\&include\=extra-info\&include\=owner\&include\=published\&include\=resources\&include\=supported-series\&include\=terms | jq
{
  "Id": "cs:~containers/easyrsa-441",
  "Meta": {
    "published": {
      "Info": [
        {
          "Channel": "stable",
          "Current": true
        },
        {
          "Channel": "candidate",
          "Current": false
        },
        {
          "Channel": "beta",
          "Current": true
        },
        {
          "Channel": "edge",
          "Current": false
        }
      ]
    },
    "supported-series": {
      "SupportedSeries": [
        "focal",
        "bionic",
        "xenial",
        "trusty"
      ]
    }
  }
}
Roadmaster commented 2 years ago

By design, charmhub does NOT implement all of the old charmstore APIs, that was never the goal/intent. It's enough of a subset to allow Juju to deploy a charm.

I see a "Name" value provided e.g. here:

$ curl -s "https://api.jujucharms.com/charmstore/v5/~containers/easyrsa/meta/any?channel=stable&include=id&include=supported-series&include=published" | jq .
{
  "Id": "cs:~containers/easyrsa-441",
  "Meta": {
    "id": {
      "Id": "cs:~containers/easyrsa-441",
      "Name": "easyrsa",
      "Revision": 441,
      "User": "containers"
    },
    "published": {
      "Info": [
        {
          "Channel": "stable",
          "Current": true
        }
      ]
    },
    "supported-series": {
      "SupportedSeries": [
        "focal",
        "bionic",
        "xenial",
        "trusty"
      ]
    }
  }
}

so maybe it now lives under Meta.id.Name. A change to Python-libjuju to use that might work. I don't know whether that's the field you need, though.

addyess commented 2 years ago

the url to query actually is generated by another pip package theblues

since the url generated here doesn't have the query parameters include=id, this isn't returned to python-libjuju

this section is missing

    "id": {
      "Id": "cs:~containers/easyrsa-441",
      "Name": "easyrsa",
      "Revision": 441,
      "User": "containers"
    },
juanmanuel-tirado commented 2 years ago

Fixed after #635