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

Unable to build multi-base subordinate charms on 24.04 #1789

Closed
carlcsaposs-canonical opened this issue Aug 6, 2024 · 12 comments · Fixed by #2054
Closed

Unable to build multi-base subordinate charms on 24.04 #1789

carlcsaposs-canonical opened this issue Aug 6, 2024 · 12 comments · Fixed by #2054
Labels
Bug Something isn't working triaged

Comments

@carlcsaposs-canonical
Copy link
Contributor

Bug Description

Subordinate charms use the base of the principal charm. Therefore, subordinate charms such as MySQL Router need to support multiple bases, since we can't enforce the principal charm to use a particular base. Currently MySQL Router supports 20.04 and 22.04 and plans to support 24.04.

However, with the new base and platforms syntax in charmcraft 3, it is not possible to build a subordinate charm on 20.04, 22.04, and 24.04 with a single charmcraft.yaml and git branch

Additional context:
I believe @jnsgruk and @sergiusens were/are discussing this. Created an issue to track officially per @taurus-forever's request

To Reproduce

  1. Create charmcraft.yaml with
bases:
  - name: ubuntu
    channel: "20.04"
    architectures: [amd64]
  - name: ubuntu
    channel: "22.04"
    architectures: [amd64]
  - name: ubuntu
    channel: "22.04"
    architectures: [arm64]
  - name: ubuntu
    channel: "24.04"
    architectures: [amd64]
  - name: ubuntu
    channel: "24.04"
    architectures: [arm64]
  1. charmcraft pack

Environment

Ubuntu 22.04

charmcraft.yaml

# Copyright 2022 Canonical Ltd.
# See LICENSE file for licensing details.

type: charm
bases:
  # Whenever "bases" is changed:
  # - Update tests/conftest.py::pytest_configure()
  # - Update .github/workflow/ci.yaml integration-test matrix
  - name: ubuntu
    channel: "20.04"
    architectures: [amd64]
  - name: ubuntu
    channel: "22.04"
    architectures: [amd64]
  - name: ubuntu
    channel: "22.04"
    architectures: [arm64]
  - name: ubuntu
    channel: "24.04"
    architectures: [amd64]
  - name: ubuntu
    channel: "24.04"
    architectures: [arm64]
parts:
  charm:
    override-pull: |
      craftctl default
      if [[ ! -f requirements.txt ]]
      then
          echo 'ERROR: Use "tox run -e build-dev" instead of calling "charmcraft pack" directly' >&2
          exit 1
      fi
    # TODO: enable after https://github.com/canonical/charmcraft/issues/1456 fixed
    charm-strict-dependencies: false
    charm-entrypoint: src/machine_charm.py
    prime:
      - charm_version
      - workload_version
    build-packages:
      - libffi-dev
      - libssl-dev
      - pkg-config
      - rustc
      - cargo

Relevant log output

Bad charmcraft.yaml content:
- base requires 'platforms' definition: {'name': 'ubuntu', 'channel': '24.04', 'architectures': ['amd64']} (in field 'bases[3]')
- base requires 'platforms' definition: {'name': 'ubuntu', 'channel': '24.04', 'architectures': ['arm64']} (in field 'bases[4]')
@carlcsaposs-canonical carlcsaposs-canonical added the Bug Something isn't working label Aug 6, 2024
@jnsgruk
Copy link
Member

jnsgruk commented Aug 6, 2024

Yes, I have discussed this with @sergiusens and briefly with @niemeyer. The current design isn't set in stone, and Sergio is going to have a bit of a think about what alternatives may look like.

For the sake of transparency, one area that could be quite problematic for "multi-base" charms is where many Python libraries have transitioned to building certain parts of their CPython code with Rust - this is increasingly popular (pydantic, cryptography, etc.).

The issue is not that the code is built in Rust, but rather that more and more core Python libraries are including dynamically-linked object files, where we could see incompatibilities across LTS versions of Ubuntu.

The current design indeed means that you must have one charmcraft.yaml per base, which is actually consistent with how snapcraft.yaml and rockcraft.yaml work. It also means that the base can become the definition of when breaking changes are permitted in the DSL, rather than just the version of Charmcraft itself - i.e. we could commit to no more breaking changes in the DSL for charmcraft.yaml until ubuntu@26.04 is used.

I definitely think we should investigate this, even if we do in fact end up with one artefact per base, we might be able to ease the developer experience slightly - and perhaps even introduce a bare base where there is no CPython code present and the subordinate is all just "plain python" that's LTS-agnostic.

@jnsgruk
Copy link
Member

jnsgruk commented Aug 6, 2024

For the reader, the proposed new syntax is:

name: some-charm
type: charm

# Here is the biggest difference - a single base per charmcraft.yaml
base: ubuntu@22.04

platforms:
  amd64:
  arm64:
  armhf:

# ...

@carlcsaposs-canonical
Copy link
Contributor Author

The issue is not that the code is built in Rust, but rather that more and more core Python libraries are including dynamically-linked object files, where we could see incompatibilities across LTS versions of Ubuntu.

FYI, we already have this problem (and we already need to build on the same Ubuntu base that we're running on)
Many wheels in our charms are specific to the python version (python virtual environments and their wheels are not designed to be portable across architectures or minor python versions)

Here are the wheels that are affected just for MySQL Router:

  • pyyaml
  • cffi
  • cryptography
  • markupsafe
  • rdps-py
  • wrapt

Here are some other wheels used by our other charms that are specific to minor python version:

  • bcrypt
  • cython
  • maturin
  • protobuf
  • psycopg2
  • psycopg
  • pydantic-core
  • ruamel

@dragomirp
Copy link

Python requirements are specified outside of charmcraft.yaml (in requirements.txt), so dealing with dependency incompatibilities between bases will have to be handled elsewhere either way. IMHO removing multiple bases will not help with managing those, but will add another moving part to deal with when trying to support multiple bases.

@carlcsaposs-canonical
Copy link
Contributor Author

so dealing with dependency incompatibilities between bases will have to be handled elsewhere either way

If we're talking about incompatibilities of versions, poetry already handles that for us. When creating poetry.lock, poetry respects syntax (in our direct & indirect dependencies) that specifies different versions (or different dependencies entirely) across different python versions and different architectures. The poetry.lock file resolves dependencies for each python version & architecture into poetry.lock (or will raise an error telling you what is incompatible). When we export requirements.txt from poetry.lock, this requirements.txt contains resolved dependencies for each python version & architecture

But I think we might be talking about incompatibilities of wheels/virtual environments across bases—e.g. a pyyaml wheel built on ubuntu 20.04 (python 3.8) will not work on 22.04 (python 3.10). By building on the same base that we run on (with charmcraft), we are no longer concerned about these incompatibilities

@jnsgruk
Copy link
Member

jnsgruk commented Aug 6, 2024

But I think we might be talking about incompatibilities of wheels/virtual environments across bases—e.g. a pyyaml wheel built on ubuntu 20.04 (python 3.8) will not work on 22.04 (python 3.10). By building on the same base that we run on (with charmcraft), we are no longer concerned about these incompatibilities

Yes, indeed - that is what I'm referring to here 🙂

@ca-scribner
Copy link

What are we doing to prevent code duplication with this change? The naive next step for charmers will be keeping one branch or charm directory per base (since charmcraft doesn't cater to multiple charmcraft files in one dir). That's a lot of code duplication we're forcing them to handle. The issue is a bit worse for libraries too, where its unclear which instance of the code owns the library.

If we're requiring a different charmcraft.yaml per base, charmcraft should make that easy to administer.

@jnsgruk
Copy link
Member

jnsgruk commented Aug 8, 2024

That's precisely the problem I'm working to solve with @sergiusens and @niemeyer - though we've not yet reached any conclusion. To be continued :)

@hloeung
Copy link

hloeung commented Sep 26, 2024

With having a different charmcraft.yaml per base, how does one tell charmcraft pack to use a specific charmcraft.yaml?

@lengau lengau added the triaged label Sep 26, 2024
Copy link

Thank you for reporting us your feedback!

The internal ticket has been created: https://warthogs.atlassian.net/browse/CRAFT-3481.

This message was autogenerated

@ca-scribner
Copy link

Is there any update on this issue?

@simskij
Copy link
Member

simskij commented Nov 27, 2024

For anyone who, like me, did not feel that it was clear how to use these new constructs, see the core24 reference in the following article from the snapcraft docs. However, as of right now, latest/stable of charmcraft does not produce valid charm files.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Something isn't working triaged
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants