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

[JUJU-573] Fix charm resolution for Juju 2.8.11 #633

Merged
merged 5 commits into from
Feb 16, 2022

Conversation

cderici
Copy link
Contributor

@cderici cderici commented Feb 9, 2022

Description

This is in response to some charm deployment issues with Juju 2.8.11. It changes two things:

1 - It patches the deployment of CharmStore charms
2 - Normally pylibjuju assumes the CharmHub when it receives a charm url without a prefix. This change adds an override for the case where the CharmsFacade version is too low to resolve the charm.

Fixes #623

QA Steps

You'll need the juju 2.8.11, and to put the following script in a file (slightly modified version of what is provided in the reporting issue #623):

import sys
import asyncio
import juju.controller

async def controller():
    c = juju.controller.Controller()
    await c.connect_current()
    return c

async def model(controller):
    return await controller.add_model('test')

loop = asyncio.get_event_loop()

try:
    c = loop.run_until_complete(controller())
    m = loop.run_until_complete(model(c))
    loop.run_until_complete(m.deploy(sys.argv[1], channel='stable'))

    loop.run_until_complete(m.disconnect())
    loop.run_until_complete(c.destroy_model('test'))
    loop.run_until_complete(c.disconnect())
    print("success")
except:
    loop.run_until_complete(c.destroy_model('test'))
    loop.run_until_complete(c.disconnect())
    raise

Bootstrap with Juju 2.8.11 and run the file containing the script above like python3 test.py ubuntu, you should see success.

Notes & Discussion

_resolve_charm method literally has a failing check for this because lower versions (such as Juju 2.8) cannot deploy from the CharmHub in the first place, so it's safe to put in this override and try to get the charm from the CharmStore instead of failing.

Copy link
Contributor

@juanmanuel-tirado juanmanuel-tirado left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Member

@SimonRichardson SimonRichardson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not fond of the URL.parse having force_v1. I think we should have URL.defaultStore that we can then pass into URL.parse. If the return type of URL.defaultStore is None, then fallback to charmhub.

@cderici
Copy link
Contributor Author

cderici commented Feb 9, 2022

I'm not fond of the URL.parse having force_v1. I think we should have URL.defaultStore that we can then pass into URL.parse. If the return type of URL.defaultStore is None, then fallback to charmhub.

Agreed, I think that's a better way of handling this, though parse being a static method doesn't help. Check out the changes. First I actually put a URL.default_store variable and changed that but I don't think modifying a global static class constant is a good idea, so I just made a new variable default_store to parse (defaulting to Schema.CHARM_HUB).

@cderici
Copy link
Contributor Author

cderici commented Feb 10, 2022

!!build!!

juju/url.py Outdated
Comment on lines 43 to 51
if Schema.LOCAL.matches(u.scheme):
c = URL(Schema.LOCAL, name=u.path)
elif Schema.CHARM_STORE.matches(u.scheme):
c = parse_v1_url(Schema.CHARM_STORE, u, s)
else:
c = parse_v2_url(u, s)
cs_match = Schema.CHARM_STORE.matches(u.scheme)
default_is_cs = Schema.CHARM_STORE.matches(default_store)

if not c.schema:
ch_match = Schema.CHARM_HUB.matches(u.scheme)
default_is_ch = Schema.CHARM_HUB.matches(default_store)

if cs_match or (not ch_match and default_is_cs):
c = parse_v1_url(Schema.CHARM_STORE, u, s)
elif ch_match or default_is_ch:
c = parse_v2_url(u, s)

if not c or not c.schema:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should write this like the following:

if Schema.LOCAL.matches(u.scheme):
            c = URL(Schema.LOCAL, name=u.path)
elif Schema.CHARM_STORE.matches(u.scheme) or (u.Scheme == "" and default_store == Schema.CHARM_STORE):
            c = parse_v1_url(Schema.CHARM_STORE, u, s)
else:
            c = parse_v2_url(u, s)

Fixes juju#623

This changes two things:

1 - It patches the deployment of CharmStore charms

2 - Normally pylibjuju assumes the CharmHub when it receives a charm
url without a prefix. This change adds an override for the case where
the CharmsFacade version is too low to resolve the charm.

_resolve_charm literally has a failing check for this because lower
versions (such as Juju 2.8) cannot deploy from the CharmHub in the
first place, so it's safe to put in this override and try to get the
charm from the CharmStore instead of failing.
@cderici cderici force-pushed the patch-for-juju-2.8.11-charm-deploy branch from ce02a4b to 64eac47 Compare February 16, 2022 18:03
@cderici
Copy link
Contributor Author

cderici commented Feb 16, 2022

$$merge$$

@jujubot jujubot merged commit b9912fc into juju:master Feb 16, 2022
@cderici cderici deleted the patch-for-juju-2.8.11-charm-deploy branch February 16, 2022 18:28
jujubot added a commit that referenced this pull request Mar 9, 2022
#647

#### Description

This is a quick fix for a bug we seem to have introduced in #633 . Empty string is not a valid CharmOrigin value.

Update: turns out in #633, I introduced a bug where I didn't realize the newer versions of Juju using the `CharmsFacade` returns a `CharmOriginResult` from an `AddCharm` call, while the `ClientFacade` in the older versions returns just a dictionary. This is why when we try to `"get"` the `charm_origin` from the object we get a `None`. (this is why people like static typing)

This also fixes [LP #1961328](https://bugs.launchpad.net/juju/+bug/1961328). We're able to reproduce the error (thanks to @sed-i ), along with confirming that this PR fixes it (see QA).

#### QA Steps

* All the CI tests should pass (modulo the intermittent CI fails).
* The following should work:
```bash
# juju @ git+https://github.com/juju/python-libjuju.git@9ef8e6ad2d4e805250265bf0a1f34a57918a3836
> git clone https://github.com/canonical/alertmanager-k8s-operator.git
> cd alertmanager-k8s-operator
> git checkout 279f4bf
> tox -e integration -- -k test_upgrade_charm
```
* Also just to make sure we're not regressing here, this QA should include the QA steps for #633. (I did qa that with this fix and it seems to be working, though it'd help whoever's QAing this do that as well)

#### Notes & Discussion
jujubot added a commit that referenced this pull request Mar 21, 2022
#655

## What's Changed
* [JUJU-567] Use ModelManager instead of ControllerFacade to list available models by @cderici in #632
* [JUJU-573] Fix charm resolution for Juju 2.8.11 by @cderici in #633
* [JUJU-704] Remove non-implemented (stuıb) functions by @cderici in #646
* [JUJU-676] Avoid defaulting to empty string for charm origin by @cderici in #647
* Charmstore compatability of deploying bundles by @addyess in #650
* [JUJU-731] Subordinate charm num unit by @cderici in #648
* [JUJU-769] Facade schemas for 2.9.27 by @cderici in #652
* [JUJU-771] Auto switch to scale from add_unit on container based models by @cderici in #653

[JUJU-567]: https://warthogs.atlassian.net/browse/JUJU-567?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
[JUJU-573]: https://warthogs.atlassian.net/browse/JUJU-573?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
[JUJU-704]: https://warthogs.atlassian.net/browse/JUJU-704?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
[JUJU-676]: https://warthogs.atlassian.net/browse/JUJU-676?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
[JUJU-731]: https://warthogs.atlassian.net/browse/JUJU-731?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
[JUJU-769]: https://warthogs.atlassian.net/browse/JUJU-769?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
[JUJU-771]: https://warthogs.atlassian.net/browse/JUJU-771?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
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

Successfully merging this pull request may close these issues.

Can't deploy charms with juju 2.8.11
4 participants