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

feat: add support for v2 fields in CharmMeta #1106

Merged
merged 29 commits into from
Jan 16, 2024

Conversation

tonyandrewmeyer
Copy link
Contributor

@tonyandrewmeyer tonyandrewmeyer commented Jan 10, 2024

Extends the CharmMeta and related objects to handle all fields in the current specification, both loading from metadata.yaml and from charmcraft.yaml (which is likely to happen when running unit tests).

New fields:

  • links:
    • websites
    • sources
    • issues
    • documentation (this is "docs" in metadata.yaml, but "documentation" in charmcraft.yaml, and is a single string unlike the above, so "docs" seems misleading)
  • assumes

metadata.yaml allows arbitrary fields, so leaving in fields that are not in the current specification (e.g. "tags", "series") seems ok and provides the most backwards compatibility.

Also fleshes out ContainerMeta and adds properties to StorageMeta.

Fixes #498.

@tonyandrewmeyer
Copy link
Contributor Author

@benhoyt this needs the new classes added to __init__.py, tests, and a few other bits of cleanup (including whatever is failing in the CI, likely formatting). Before I do those, could you quickly check that this is more-or-less what you intended for #498? No need for a full review - that can be done when I've finished everything.

Copy link
Collaborator

@benhoyt benhoyt left a comment

Choose a reason for hiding this comment

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

Yep, this looks like the basic idea, thanks! I haven't gone over in detail.

What spec were you working against?

ops/charm.py Outdated Show resolved Hide resolved
@tonyandrewmeyer
Copy link
Contributor Author

Yep, this looks like the basic idea, thanks! I haven't gone over in detail.

Thanks! Just needed a santy check 😄. You can go over in detail when I finish it off 😄.

What spec were you working against?

The one linked in the description: https://juju.is/docs/sdk/metadata-yaml - the Discourse post linked from the issue says that it should be used rather than the Discourse post.

ops/charm.py Outdated Show resolved Hide resolved
raise AttributeError(
f"{self.__class__.__name__} has no such attribute: {name}!"
)
@property
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is a backwards-incompatible change in that you can no longer assign to .location, but it seems like that would surely always be a bug anyway, since it wouldn't actually change the location, just make the metadata incorrect.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Excellent, thanks for this fix.

@tonyandrewmeyer
Copy link
Contributor Author

FYI, I did a basic sanity check across the ~150 charms I have locally, and loading the metadata doesn't crash:

import pathlib

import ops

root = pathlib.Path(...)

for charm in root.iterdir():
    meta = charm / 'metadata.yaml'
    if meta.exists():
        assert ops.CharmMeta.from_yaml(meta.open()).name

@tonyandrewmeyer tonyandrewmeyer marked this pull request as ready for review January 11, 2024 02:33
Copy link
Collaborator

@benhoyt benhoyt left a comment

Choose a reason for hiding this comment

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

Looking good, just some small questions and minor nits.

ops/charm.py Outdated
self.min_juju_version = raw_.get('min-juju-version')
if self.min_juju_version:
# Add in an implied 'assumes'.
self.assumes.features.append(f'juju >= {self.min_juju_version}')
Copy link
Collaborator

Choose a reason for hiding this comment

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

Are we sure we want to add this in? Why? It would seem better to me to have this reflect the metadata as is, rather than try to be smart about things.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I definitely agree that the code I had earlier that tried to be smart in the other direction (populating min_juju_version from assumes) was a bad idea (on the positive side, it helped me really dig into how assumes works, so I could be more sure I had the class correct 😄).

This direction (populating assumes from min_juju_version) is vastly simpler, just these 2-3 lines, and more obviously correct.

My thinking was that if someone is using this in code, and they want to support both versions of metadata (e.g. in a lib where you don't have as much control over the metadata), they have to do something like:

min_version = meta.min_juju_version or find_minimum_juju_version(meta.assumes)

instead of just find_minimum_juju_version(meta.assumes).

However, writing this out I think I have rubber-ducked my way into agreeing that it's too small to be worthwhile 😄.

ops/charm.py Outdated Show resolved Hide resolved
ops/charm.py Outdated Show resolved Hide resolved
ops/charm.py Outdated Show resolved Hide resolved
raise AttributeError(
f"{self.__class__.__name__} has no such attribute: {name}!"
)
@property
Copy link
Collaborator

Choose a reason for hiding this comment

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

Excellent, thanks for this fix.

test/test_charm.py Show resolved Hide resolved
Copy link
Collaborator

@benhoyt benhoyt left a comment

Choose a reason for hiding this comment

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

Looks good to me, thanks!

Copy link

@wallyworld wallyworld left a comment

Choose a reason for hiding this comment

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

The assumes stuff looks good (consistent with how juju parses it).
juju reads bases from manifest.yaml and what's here looks consistent with that.

Can we defer adding Devices until we are sure it's actually used somewhere?
Otherwise looks ok to me except for the properties bit.

ops/charm.py Outdated Show resolved Hide resolved
ops/charm.py Outdated Show resolved Hide resolved
@benhoyt benhoyt merged commit dc47640 into canonical:main Jan 16, 2024
26 checks passed
@tonyandrewmeyer tonyandrewmeyer deleted the metav2-498 branch January 17, 2024 03:48
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.

CharmMeta class needs to be updated for Metadata v2
3 participants