GoogleContainerTools / skaffold

Easy and Repeatable Kubernetes Development
https://skaffold.dev/
Apache License 2.0
15k stars 1.62k forks source link

Patches applied to end of empty list error out #8637

Open mattmelgard opened 1 year ago

mattmelgard commented 1 year ago

Expected behavior

When using a skaffold.yaml that looks something like this (example uses YAML anchors to define releases):

deploy:
  kubeContext: docker-desktop
  helm:
    releases: []
...

profiles:
  # The set of common services that are required by all profiles
  - name: common
    patches:
      - op: add
        path: "/deploy/helm/releases/-"
        value:
          <<: *servicedeps
      - op: add
        path: "/deploy/helm/releases/-"
        value:
          <<: *accountsapi

I would expect that a patch to add a release to the end of an empty releases list would still work.

Actual behavior

Instead I get this error output:

> skaffold run --profile common
parsing skaffold config: failed to apply profiles to config "backend" defined in file "/Users/mattmelgard/syndio/backend/skaffold.yaml": applying profile "common": invalid path: /deploy/helm/releases/-. There's an issue with one of the profiles defined in config "backend" in file "/Users/mattmelgard/syndio/backend/skaffold.yaml"; refer to the documentation on how to author valid profiles: https://skaffold.dev/docs/environment/profiles/.

The reason I know that this is because of the empty releases list is because I'm currently doing a bit of a refactor and have removed the one release I had in the default set of releases under the deploy key, and that is the only change I have made thus far to a, previously, fully working skaffold.yaml file.

Information

Steps to reproduce the behavior

  1. Add a few profiles with helm releases assigned to them that use patches to the key /deploy/helm/releases/-
  2. Set the default /deploy/helm/releases value to an empty list
  3. Try to run the profile with skaffold run --profile <profile_name>
  4. See an error like the one mentioned above
kurczynski commented 1 year ago

@mattmelgard does it work for you on a non-empty list?

I'm running into the same issue with the setValues map as well. My skaffold.yaml:

deploy:
  helm:
    releases:
      - name: my-app
        version: 0.1.0
...
  - name: minikube
    patches:
      - op: add
        path: /deploy/helm/releases/0/setValues/vault.enabled
        value: false
    activation:
      - kubeContext: minikube

Gives me:

failed to apply profiles to config "my-app" defined in file "/home/bkurczynski/workspace/my-app/skaffold.yaml": applying profile "minikube": invalid path: /deploy/helm/releases/0/setValues/vault.enabled. There's an issue with one of the profiles defined in config "my-app" in file "/home/bkurczynski/workspace/my-app/skaffold.yaml"; refer to the documentation on how to author valid profiles: https://skaffold.dev/docs/environment/profiles/.

I'm using v2.3.1 for Linux AMD64.

joebowbeer commented 1 year ago

Relates to #2741 #3446

mattmelgard commented 1 year ago

Just FYI, for anyone who runs into this problem in the future, I'm currently working around this by having a "dummy" entry in the list of releases to start with, and then overwriting that first entry with active profiles. The chart I'm using for this is the jenkins-x/empty helm chart

mattmelgard commented 1 year ago

Also, just a thought here but I wonder if this problem could be solved by just using a map type object to represent releases rather than a list of maps. I feel like that allows for more elegant values layering functionality, at least when I've needed to do something similar in my Helm chart templates. I'm not aware of the details of Skaffold's implementation though, so I don't want to assume that it would be easy to make that change.

ericzzzzzzz commented 1 year ago

tracked in #8788

taylortails commented 1 year ago

A pattern to workaround this issue is:

build:
  artifacts:
    - image: end
      context: end
profiles:
  - name: end
    patches:
      - op: remove
        path: /build/artifacts/0
  - name: frontend
    patches:
      - op: add
        path: /build/artifacts/-
        value:
          context: frontend
          image: frontend

Then you can run:

skaffold run -p frontend,end

Extending to:

skaffold run -p frontend,group1,group2,end
cmuthukumar commented 1 year ago

@taylortails above solution does not work for me ... tried with multiple profiles