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

Kap 09 #701

Merged
merged 12 commits into from
Aug 1, 2021
Merged

Kap 09 #701

merged 12 commits into from
Aug 1, 2021

Conversation

Jean-Daniel
Copy link
Contributor

Implementation of kap-9: Bring your own Helm.

fixes: #368 #647

Proposed Changes

  • Replace helm cffi by Helm CLI invocation. This greatly simplify the helm logic and make adoption of new capabilities easier (just add a flag to the command line invocation)

This PR takes care of both helm_fetch and helm input. It completely removes the need for golang and cffi to build and install Kapitan.

It is based on and tested Helm 3 only as Helm 2 support ended the November 13, 2020.

@ademariag
Copy link
Contributor

Thank you @Jean-Daniel, this is a great idea.

I know that @simu and @srueg are also interested in this and would also like to get their opinion.

Personally I like the idea of moving away from helm cffi, although we need to consider other angles.

@srueg
Copy link
Contributor

srueg commented Mar 5, 2021

That's great, thanks!
I don't think there's any downside to this (at least from our side) and it would solve a lot of problems indeed 👍

I'll do some tests and review this PR 🎉

Copy link
Contributor

@srueg srueg left a comment

Choose a reason for hiding this comment

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

LGTM, I ran tests with some of our setups and apart from the app.kubernetes.io/managed-by=Helm label change and some reordered RBAC, all compiled output stays the same 👍

# uses absolute path to make sure helm interpret it as a
# local dir and not a chart_name that it should download.
args.append(os.path.abspath(chart_dir))

Copy link
Contributor

Choose a reason for hiding this comment

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

Should we add --include-crds or make it configurable?

Copy link
Contributor

Choose a reason for hiding this comment

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

And probably --skip-tests?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, this is both 2 reasonable flags to add by defaults.
Should we add skip_crds and include_tests configuration flags then.

The only drawback I see with this names, is that helm already has an unrelated --skip-crds flags.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'd suggest to add include_crds and skip_tests just with a default of true to name them after the flags.

@srueg
Copy link
Contributor

srueg commented Mar 8, 2021

I tried to get rid of some of the debug output in this PR: helm/helm#8992
Maybe if you add your vote there?

Or should we try to filter the stdout of the helm cli to remove the wrote [...] debug logs?

@Jean-Daniel
Copy link
Contributor Author

I tried to get rid of some of the debug output in this PR: helm/helm#8992
Maybe if you add your vote there?

Or should we try to filter the stdout of the helm cli to remove the wrote [...] debug logs?

As the Kapitan debug output already print the generated files names, we can probably disable helm stdout completely (stdout=subprocess.DEVNULL).

Or enable it only when debug log is enabled.

@srueg srueg mentioned this pull request Mar 12, 2021
@ramaro
Copy link
Member

ramaro commented Mar 12, 2021

Btw @sebradloff you might want to have a look at this 😄

args.append("--output-dir")
args.append(output_path)

if self.kube_version:
Copy link
Contributor

Choose a reason for hiding this comment

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

This is an amazing PR! I would recommend however to take helm_params as an input for all the additional flags like api-versions, validate, etc. I think it makes it a little more flexible.

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 pushed a new version that supports most helm flags. There is just a bunch of flags that are disabled because they either affect the output, or are useless for templating and only relevant on install.

Note that helm template has a --release-name flag that conflicts with the release_name helm_params. This version now recommend to use name instead of release_name. To supports inventory that keep using release_name, the helm input check if the release_name value is a bool. If not, it prints a deprecation warning and keep using the release_name value as name.

Copy link
Contributor

Choose a reason for hiding this comment

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

In regards to the conflict of name and release_name, I think your solution make sense of printing the warning makes sense.


if param in HELM_DENIED_FLAGS:
logger.warning("helm flag '%s' is not supported and will be ignored.", param)
continue
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we maybe abort here? Warning output might be missed and lead to unexpected behavior if the flags are just dropped.

&& pip install .

# Install Helm
RUN apt-get install --no-install-recommends -y curl \
&& curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 \
Copy link
Contributor

@sebradloff sebradloff Mar 16, 2021

Choose a reason for hiding this comment

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

should we be pinning the version of helm3 that gets downloaded? I believe if I'm reading the get_helm.sh script correctly, we could technically set a DESIRED_VERSION to control the helm3 version being downloaded instead of defaulting to latest.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

get_helm.sh supports --version flag. What would be the benefit of pinning the version ?

Copy link
Contributor

Choose a reason for hiding this comment

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

I feel like in general there are bug fixes here and there that happen with any software. I feel like since we directly depend on the helm binary and we have an "open" interface with helm_params it might be worth being methodical on upgrading versions. Just a thought, don't think it's required.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The get_helm.sh script is design to fetch only v3 version. So, all updates should be backward compatible.

Just like this image is using latest python3.7, git or gnupg binaries, I don't think it should cause issues using the latest helm 3 release.

@ramaro
Copy link
Member

ramaro commented Apr 27, 2021

@Jean-Daniel @srueg @sebradloff are we happy with the state of this?

@Jean-Daniel
Copy link
Contributor Author

I'm using it for some times now and haven't encounter any issue yet. So I'm fine with it.

try:
logger.debug("launching helm with arguments: %s", args)
res = subprocess.run(
args=["helm"] + args, stderr=PIPE, stdout=stdout or (PIPE if verbose else DEVNULL)
Copy link

Choose a reason for hiding this comment

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

I think it would make sense if we can somehow configure which helm binary to use instead of relying on a hardcoded value. Some users might have a dual-helm setup with helm v2 and v3 and their helm binary might be called helm3 or so. Maybe try to use the binary in an env var like "HELM_BIN" (or whatever appropriate) and default to helm if not defined?

e.g. https://github.com/roboll/helmfile allows to set the "helmBinary" config.

Copy link
Member

Choose a reason for hiding this comment

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

For that, I think it would be best to support a helm_path option along the other ones

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Both use cases are valid IMHO. Some people may need to set the path globally (if they want to use a specific helm for everything), and some will need to set it per compile action (to compile a helm2 chart for instance).

Copy link

Choose a reason for hiding this comment

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

yeah, sure. being able to specify it globally or per compilation should give enough flexibility

@sebradloff
Copy link
Contributor

@Jean-Daniel @srueg @sebradloff are we happy with the state of this?

I think this PR is great. Helm2 binary as an option sounds like a good idea, since some people might be stuck with old open source charts.

@zstoth
Copy link

zstoth commented Jun 9, 2021

@Jean-Daniel is anything blocking this?

@ramaro
Copy link
Member

ramaro commented Jun 18, 2021

Hey @Jean-Daniel do you wanna master rebase this? It should fix the failed binary tests as we discontinued the binary in #740

Jean-Daniel Dupas and others added 9 commits June 18, 2021 13:22
An actually difference with the cffi implementation is that  if something goes wrong,
it raises a HelmFetchingError instead of silently failing.

It is consistent with Git and Http behaviour which raise errors too if the fetch operation fails.
It mostly matches the cffi implementation with one difference:
- release_name is required when using Helm CLI. This implementation uses —generate-name flag if neither release_name nor template_name are specified, which may cause different output.

This commit also add `validate` flag support, which is required to compile some templates that rely on cluster Capabilities (cilium with ServiceMonitor for instance).
- reduce denied flags list to the bare minimum. No need to raise error when using an irrelevant flag like atomic.
- raise an error if flags contains a '-' instead of '_'. Allowing both may cause subtle bugs if both syntaxes are used in the same target for the same flag.
Co-authored-by: Simon Rüegg <[email protected]>
When specified, run helm template without specifying --output-dir and pipe the result into a single file.
All helm invocation will try to use the value set in the env var KAPITAN_HELM_PATH.
Fetch and compile action takes a helm_path parameter to specify per target helm binary.
@Jean-Daniel
Copy link
Contributor Author

Jean-Daniel commented Jun 18, 2021

Hey @Jean-Daniel do you wanna master rebase this? It should fix the failed binary tests as we discontinued the binary in #740

Done. Note that #741 erroneously remove the build_helm_binding target in the Makefile, which breaks helm support (until this PR is merged).

@ademariag
Copy link
Contributor

I did a quick test with my repo, and this pretty much doubles the compile speed (for prometeus chart) in my case

before

time kapitan compile -t intranet-cluster-infra
Compiled intranet-cluster-infra (8.97s)
real    0m12.099s
user    0m11.563s
sys     0m1.508s

after

time kapitan compile -t intranet-cluster-infra
Compiled intranet-cluster-infra (3.41s)
real    0m6.199s
user    0m8.038s
sys     0m1.285s

@ademariag
Copy link
Contributor

A tiny issue I have found, is that the produced files have a different formatting (which we already experienced in #360) so that replacing the old helm support for the new one will make the review process tedious (because we will have lots of formatting diffs)

Do you know whether it is possible to still prettify the helm output even with this new input type?

@ramaro
Copy link
Member

ramaro commented Jul 12, 2021

We can do the same we've done before here https://github.com/kapicorp/kapitan/pull/385/files @ademariag

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.

Add support for helm bindings in OSX
7 participants