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

new helm operator from existing chart with local subcharts fails with "directory X not found" #2942

Closed
tmckayus opened this issue Apr 29, 2020 · 5 comments
Assignees
Labels
area/dependency Issues or PRs related to dependency changes language/helm Issue is related to a Helm operator project lifecycle/rotten Denotes an issue or PR that has aged beyond stale and will be auto-closed. triage/support Indicates an issue that is a support question.
Milestone

Comments

@tmckayus
Copy link

tmckayus commented Apr 29, 2020

Bug Report

What did you do?

Generated a helm operator from an existing chart with an expanded local subchart, no repository defined in Chart.yaml. This is a valid chart that deploys with "helm install . --generate-name"

$ tree alpine
alpine/
├── Chart.lock
├── charts
│ └── mysql
│ ├── Chart.yaml
│ ├── README.md
│ ├── templates
│ │ ├── configurationFiles-configmap.yaml
│ │ ├── deployment.yaml
│ │ ├── _helpers.tpl
│ │ ├── initializationFiles-configmap.yaml
│ │ ├── NOTES.txt
│ │ ├── pvc.yaml
│ │ ├── secrets.yaml
│ │ ├── serviceaccount.yaml
│ │ ├── servicemonitor.yaml
│ │ ├── svc.yaml
│ │ └── tests
│ │ ├── test-configmap.yaml
│ │ └── test.yaml
│ └── values.yaml
├── Chart.yaml
├── README.md
├── templates
│ └── alpine-pod.yaml
└── values.yaml

$ operator-sdk new alpine-test --api-version=alpine.io/v1alpha1 --kind=Alpine --type=helm --helm-chart=alpine

alpine.zip
 
What did you expect to see?

Successful scaffolding of the new helm operator, including a copy of the charts directory

What did you see instead? Under which circumstances?
EBU[0000] Debug logging is set
INFO[0000] Creating new Helm operator 'alpine-test'.

FATA[0000] failed to create helm chart: failed to fetch chart dependencies: directory /helm/alpine-test/helm-charts/alpine/charts/mysql not found

Environment

  • operator-sdk version:

operator-sdk version: "v0.17.0", commit: "2fd7019f856cdb6f6618e2c3c80d15c3c79d1b6c", kubernetes version: "unknown", go version: "go1.13.10 linux/amd64"

  • go version:

go version go1.13.1 linux/amd64

  • Kubernetes version information:

Client Version: version.Info{Major:"1", Minor:"13+", GitVersion:"v1.13.4+72d1bea", GitCommit:"72d1bea", GitTreeState:"clean", BuildDate:"2019-09-21T02:11:40Z", GoVersion:"go1.11.13", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"16+", GitVersion:"v1.16.2", GitCommit:"94e669a", GitTreeState:"clean", BuildDate:"2020-02-03T23:11:39Z", GoVersion:"go1.12.12", Compiler:"gc", Platform:"linux/amd64"}

oc version:

Client Version: version.Info{Major:"4", Minor:"1+", GitVersion:"v4.1.18-201909201915+72d1bea-dirty", GitCommit:"72d1bea", GitTreeState:"dirty", BuildDate:"2019-09-21T02:11:40Z", GoVersion:"go1.11.13", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"16+", GitVersion:"v1.16.2", GitCommit:"94e669a", GitTreeState:"clean", BuildDate:"2020-02-03T23:11:39Z", GoVersion:"go1.12.12", Compiler:"gc", Platform:"linux/amd64"}

  • Kubernetes cluster kind:

OpenShift (CRC)

  • Are you writing your operator in ansible, helm, or go?

helm

Possible Solution

Not a helm/sdk expert, but here's what I found :)

Solution: when copying expanded subcharts for which there is no repository defined, expand the corresponding tarballs under the helm-charts directory of the newly created operator.
(I tried this with a modified operator-sdk which included a call out to a bash script to expand the tarballs after the copy, and the "new" operation succeeded)

The trouble seems to be that the operator-sdk uses helm subroutines to copy the charts directory, resulting in charts/mysql-1.6.3.tgz

However, internally the operator-sdk calls the helm downloader manager Build routine, which in turn invokes the download manager Update routine (specifically because there is no Charts.lock file in the newly generated dir, but Build would probably fail anyway )

https://github.com/operator-framework/operator-sdk/blob/master/internal/scaffold/helm/chart.go#L259
https://github.com/helm/helm/blob/master/pkg/downloader/manager.go#L76

The downloader manager Update routine fails for local charts with no repository if the tarball is not expanded. This can be seen by just running "helm dependency update", which calls the same internal routine as shown here

https://github.com/helm/helm/blob/master/cmd/helm/dependency_update.go#L73

$ cd alpine-test/helm-charts/alpine
$ helm dependency update
Error: directory charts/mysql not found
$ ls charts/
mysql-1.6.3.tgz
$ tar -C charts -xzf charts/mysql-1.6.3.tgz
$ helm dependency update
Saving 1 charts
Dependency mysql did not declare a repository. Assuming it exists in the charts directory
Deleting outdated charts

Additional context

There is a longish workaround for this, but a bug fix would be better. The workaround is essentially

  1. make a copy of the original helm chart
  2. package all of the subcharts and upload them to an instance of chartmuseum with local storage
  3. modify the Chart.yaml and add the local url for chartmuseum as the repository for each subchart
  4. run the operator-sdk new comand to create the operator from the modified helm chart
  5. edit the Chart.yaml in the newly created operator and remove the repository definitions
  6. expand all of the .tgz files in the helm-charts/somename/charts dir in the new operator
  7. remove all of the .tgz files in the helm-charts/somename/charts dir in the new operator
  8. run "helm dependency update" in the helm-charts/somename/ dir in the new operator

This should leave the helm-charts directory in the correct state as far as I can tell, with local expanded charts and a matching Chart.lock file.

@joelanford joelanford self-assigned this May 4, 2020
@joelanford joelanford added this to the v0.18.0 milestone May 4, 2020
@joelanford joelanford added language/helm Issue is related to a Helm operator project area/dependency Issues or PRs related to dependency changes triage/support Indicates an issue that is a support question. labels May 4, 2020
@joelanford
Copy link
Member

@tmckayus Sorry it took me so long to get back to this. It looks like loading and then saving is not round-trippable, which is maybe a bug in Helm. I posted an issue (helm/helm#8120) asking about this. We'll see what the outcome of that is.

I think in the worst case, we can copy the SaveDir code into the SDK repo and tweak it to save without tgz'ing the subcharts, and I think that will solve the problem.

In the meantime, there are a couple of other tweaks you can make to the chart prior to loading it with operator-sdk new. These seemed to work for me:

  1. Remove the declared mysql dependency from Chart.yaml:

    apiVersion: v2
    appVersion: 3.9.6
    description: Deploy a basic Alpine Linux pod
    name: alpine
    version: 0.1.0
    type: application
    dependencies: []
  2. Add the repository field to the mysql dependency in Chart.yaml:

    apiVersion: v2
    appVersion: 3.9.6
    description: Deploy a basic Alpine Linux pod
    name: alpine
    version: 0.1.0
    type: application
    dependencies:
    - name: mysql
      version: 1.6.3
      repository: https://kubernetes-charts.storage.googleapis.com    

@openshift-bot
Copy link

Issues go stale after 90d of inactivity.

Mark the issue as fresh by commenting /remove-lifecycle stale.
Stale issues rot after an additional 30d of inactivity and eventually close.
Exclude this issue from closing by commenting /lifecycle frozen.

If this issue is safe to close now please do so with /close.

/lifecycle stale

@openshift-ci-robot openshift-ci-robot added the lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale. label Oct 27, 2020
@openshift-bot
Copy link

Stale issues rot after 30d of inactivity.

Mark the issue as fresh by commenting /remove-lifecycle rotten.
Rotten issues close after an additional 30d of inactivity.
Exclude this issue from closing by commenting /lifecycle frozen.

If this issue is safe to close now please do so with /close.

/lifecycle rotten
/remove-lifecycle stale

@openshift-ci-robot openshift-ci-robot added lifecycle/rotten Denotes an issue or PR that has aged beyond stale and will be auto-closed. and removed lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale. labels Nov 26, 2020
@openshift-bot
Copy link

Rotten issues close after 30d of inactivity.

Reopen the issue by commenting /reopen.
Mark the issue as fresh by commenting /remove-lifecycle rotten.
Exclude this issue from closing again by commenting /lifecycle frozen.

/close

@openshift-ci-robot
Copy link

@openshift-bot: Closing this issue.

In response to this:

Rotten issues close after 30d of inactivity.

Reopen the issue by commenting /reopen.
Mark the issue as fresh by commenting /remove-lifecycle rotten.
Exclude this issue from closing again by commenting /lifecycle frozen.

/close

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/dependency Issues or PRs related to dependency changes language/helm Issue is related to a Helm operator project lifecycle/rotten Denotes an issue or PR that has aged beyond stale and will be auto-closed. triage/support Indicates an issue that is a support question.
Projects
None yet
Development

No branches or pull requests

4 participants