canonical / charmcraft

Collaborate, build and publish charmed operators for Kubernetes, Linux and Windows.
Apache License 2.0
66 stars 69 forks source link

error message is unhelpful when parsing charmcraft.yaml fails because `charm-libs[*].version` is an integer #1954

Open ca-scribner opened 3 hours ago

ca-scribner commented 3 hours ago

Bug Description

charmcraft.yaml's charm-libs[*].version fields (I think?) require string inputs. If set to an integer when invoking charmcraft fetch-libs, we see the error:

charmcraft fetch-libs
charmcraft internal error: AttributeError("'int' object has no attribute 'partition'")                                    
Full execution log: '/home/scribs/.local/state/charmcraft/log/charmcraft-20241011-144937.257724.log'      

The error message and log are not very instructive about the root cause. It would be great to have a more helpful error message here.

To Reproduce

Set charmcraft.yaml's charm-libs versions to an integer, eg:

charm-libs:
  - lib: "tls_certificates_interface.tls_certificates"
    version: 3

then run charmcraft fetch-libs

Environment

charmcraft 3.2.1 (I think 3.1.x did not have this behaviour)

charmcraft.yaml

name: istio-ingress-k8s
type: charm
title: Istio Ingress
summary: A Juju charm to deploy and manage ingresses
description: |
  Istio Ingress is a Juju charm for managing Istio ingress gateways in Kubernetes clusters.
  It automates deployment and configuration, providing secure and reliable traffic routing.
assumes:
  - k8s-api

bases:
  - build-on:
    - name: ubuntu
      channel: "22.04"
      architectures: ["amd64"]
    run-on:
    - name: ubuntu
      channel: "22.04"
      architectures: ["amd64"]
  - build-on:
    - name: ubuntu
      channel: "22.04"
      architectures: ["arm64"]
    run-on:
    - name: ubuntu
      channel: "22.04"
      architectures: ["arm64"]

charm-libs:
  - lib: "tls_certificates_interface.tls_certificates"
    version: 3
  - lib: "observability-libs.cert_handler"
    version: 1

parts:
  charm:
    build-packages: [ git ]
    charm-binary-python-packages:
      # TODO after https://github.com/canonical/istio-ingress-k8s-operator/issues/7 closed:
      #      remove rpds-py from this list
      - "rpds-py"
      - "pydantic>=2"
      - "cryptography"
      - "jsonschema"

config:
  options:
    ready-timeout:
      type: int
      default: 100
      description: >
        The maximum time (in seconds) to wait for the gateway deployment to be 
        ready. This applies specifically to the deployment/LB created for the Istio 
        gateway controller. If the deployment does not become ready within this time, 
        charm will go into blocked state.
    external_hostname:
      description: |
        The DNS name to be used by Istio ingress.
        If unspecified, the gateway ingress ip address will be used, e.g,
        as provided by MetalLB. This needs to be a `bare` hostname: i.e. 
        no schema prefix and no port.
        Hostname can be “precise” which is a domain name without the terminating dot of a network host (e.g. “foo.example.com”).
        It's also important to note that domain name prefixed with a single wildcard label (e.g. *.example.com) isn't supported for now.
      type: string

peers:
  peers:
    interface: istio_k8s_peers

provides:
  ingress:
    interface: ingress
    description: |
      Provides ingress-like routing to the related Juju application, load-balancing across all units

requires:
  certificates:
    interface: tls-certificates
    limit: 1
    description: |
      Send a CSR to- and obtain a signed certificate from an external CA.

Relevant log output

charmcraft fetch-libs
charmcraft internal error: AttributeError("'int' object has no attribute 'partition'")                                    
Full execution log: '/home/scribs/.local/state/charmcraft/log/charmcraft-20241011-144937.257724.log'

---

2024-10-11 14:49:37.258 Starting charmcraft, version 3.2.1
2024-10-11 14:49:37.258 Log verbosity level set to BRIEF
2024-10-11 14:49:37.258 Configuring application...
2024-10-11 14:49:37.258 Preparing application...
2024-10-11 14:49:37.273 Build plan: platform=None, build_for=None
2024-10-11 14:49:37.273 Loading project file '/home/scribs/code/canonical/istio-ingress-k8s-operator/openg-2525/charmcraft.yaml'
2024-10-11 14:49:37.278 Processing grammar (on amd64 for amd64)
2024-10-11 14:49:37.278 Processing grammar for build-packages: ['git']
2024-10-11 14:49:37.278 Not processing grammar for non-grammar enabled keyword charm-binary-python-packages
2024-10-11 14:49:37.280 charmcraft internal error: AttributeError("'int' object has no attribute 'partition'")
2024-10-11 14:49:37.280 Traceback (most recent call last):
2024-10-11 14:49:37.280   File "/snap/charmcraft/4914/lib/python3.10/site-packages/craft_application/application.py", line 531, in run
2024-10-11 14:49:37.280     self.services.project = self.get_project(
2024-10-11 14:49:37.280   File "/snap/charmcraft/4914/lib/python3.10/site-packages/craft_application/application.py", line 314, in get_project
2024-10-11 14:49:37.280     self.__project = self.app.ProjectClass.from_yaml_data(yaml_data, project_path)
2024-10-11 14:49:37.280   File "/snap/charmcraft/4914/lib/python3.10/site-packages/craft_application/models/base.py", line 77, in from_yaml_data
2024-10-11 14:49:37.280     return cls.unmarshal(data)
2024-10-11 14:49:37.280   File "/snap/charmcraft/4914/lib/python3.10/site-packages/charmcraft/models/project.py", line 444, in unmarshal
2024-10-11 14:49:37.280     return BasesCharm.unmarshal(data)
2024-10-11 14:49:37.280   File "/snap/charmcraft/4914/lib/python3.10/site-packages/charmcraft/models/project.py", line 440, in unmarshal
2024-10-11 14:49:37.280     return cls.model_validate(data)
2024-10-11 14:49:37.280   File "/snap/charmcraft/4914/lib/python3.10/site-packages/pydantic/main.py", line 568, in model_validate
2024-10-11 14:49:37.280     return cls.__pydantic_validator__.validate_python(
2024-10-11 14:49:37.280   File "/snap/charmcraft/4914/lib/python3.10/site-packages/charmcraft/models/project.py", line 127, in _validate_patch_version
2024-10-11 14:49:37.280     api, separator, patch = value.partition(".")
2024-10-11 14:49:37.280 AttributeError: 'int' object has no attribute 'partition'
2024-10-11 14:49:37.280 Full execution log: '/home/scribs/.local/state/charmcraft/log/charmcraft-20241011-144937.257724.log'
lengau commented 2 hours ago

Hi! Thanks for the report. I've fixed the error message in https://github.com/canonical/charmcraft/pull/1955.

It should now correctly give an error like:

1 validation error for CharmLib
  version
    Input should be a valid string [type=string_type, input_value=1.1, input_type=float]
      For further information visit https://errors.pydantic.dev/2.9/v/string_type