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

Fix preapply hooks are not called on no diff when run apply subcommand #522

Merged
merged 2 commits into from
Dec 10, 2022

Conversation

xiaomudk
Copy link
Contributor

Fix: #518
Signed-off-by: xiaomudk xiaomudk@gmail.com

2 default//bar

invoking preapply hooks for releases in group 1/2: default//foo
invoking preapply hooks for releases in group 2/2: default//bar
Copy link
Contributor Author

@xiaomudk xiaomudk Nov 15, 2022

Choose a reason for hiding this comment

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

In this case, is this the expected value? @mumoshu

Copy link
Contributor

@mumoshu mumoshu Nov 16, 2022

Choose a reason for hiding this comment

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

Yeah probably. I think this is an example of what we call "Release ID" in helmfile code. The first part is the kubecontext and the second part is a K8s namespace, followed by the release name. // looks like there were no namespace specified. Try setting namespace: whatever in the release so that the release ID would become default/whatever/bar.

Note that making it appear like default/bar when you omitted the release namespace doesn't look right, because then you have no way to distinguish a release whose namespace is omitted vs another release whose kubecontext is omitted.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There is also a preapply problem. In this case, the chart has been declared not to be installed.
case

releases:
- name: bar
  chart: stable/mychart2
- name: foo
  chart: stable/mychart1
  installed: false
  needs:
  - bar

before
preapply will not be executed, I think it is reasonable

processing file "helmfile.yaml" in directory "."
changing working directory to "/path/to"
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
first-pass uses: &{default map[] map[]}
first-pass rendering output of "helmfile.yaml.part.0":
 0: 
 1: releases:
 2: - name: bar
 3:   chart: stable/mychart2
 4: - name: foo
 5:   chart: stable/mychart1
 6:   installed: false
 7:   needs:
 8:   - bar
 9: 

first-pass produced: &{default map[] map[]}
first-pass rendering result of "helmfile.yaml.part.0": {default map[] map[]}
vals:
map[]
defaultVals:[]
second-pass rendering result of "helmfile.yaml.part.0":
 0: 
 1: releases:
 2: - name: bar
 3:   chart: stable/mychart2
 4: - name: foo
 5:   chart: stable/mychart1
 6:   installed: false
 7:   needs:
 8:   - bar
 9: 

merged environment: &{default map[] map[]}
2 release(s) found in helmfile.yaml

changing working directory back to "/path/to"

now
preapply will be executed, which is dangerous

more reasonable
Detect a release that needs to be installed and execute preapply. Whether this release needs to be updated or not.

@mumoshu @yxxhero @itscaro WDYT?

Copy link
Contributor

@mumoshu mumoshu Nov 16, 2022

Choose a reason for hiding this comment

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

In this PR, we opted to make preapply happen even for releases that have no diff, right?
Then I'd guess it would also be reasonable to trigger preapply also for releases with installed: false, as the setting is intended to mean that "it's going to be deleted", not "exclude from the targeted releases". In other words, the release is going to be uninstalled as a part of the apply operation, hence the preapply hook should also be triggered.

In addition to that- could you elaborate a bit more on how it can be "dangerous"? Depending on the use case you had in your mind, we could discuss how to address it in another way. (Like, exposing a specified envvar to the hook command so that it can know the operation Helmfile is going to conduct on the release, for example delete, install, or upgrade)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

environments:
  test01:
  test02:

releases:
- name: bar
  chart: stable/mychart2
- name: foo
  chart: stable/mychart1
  installed: {{ eq .Environment.Name "production" test01 }}
  hooks:
    - events: ["preapply"]
      showlogs: true
      command: "echo"
      args: ["Hello from preapply"]

In this case, helmfile -e test02 apply will not install foo, but will execute preapply in foo, which is very dangerous if preapply has modifications to the cluster environment

Copy link
Contributor

@mumoshu mumoshu Nov 20, 2022

Choose a reason for hiding this comment

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

Even the prepare hook is dangerous if you made it to conduct a "dangerous" operation on a cluster. The original motivation to add preapply was to add another extension point that is superior to existing hooks. presync doesn't get triggered on unmodified releases. Still, we needed preapply for use cases where you need it to be triggered on unmodified releases.

Copy link
Contributor

@mumoshu mumoshu Nov 20, 2022

Choose a reason for hiding this comment

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

My advice would be to design your preapply hook command not to break your cluster when it's called on unmodified releases. Same for prepare.
Note also that whatever hook command should be made "idempotent", so that it is safe for rerunning. Helmfile doesn't guarantee that e.g. preapply is called only once for your release. For example, if helm-upgdate command failed after a preapply hook, you'd need to rerun the whole helmfile command and it would result in rerunning your preapply hook. If you've designed your preapply to do any dangerous operation, it would fail for the second time. That's an issue in your preapply hook, not Helmfile's preapply design.

Copy link
Member

Choose a reason for hiding this comment

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

@xiaomudk @mumoshu when a release will not be installed, should we auto-disable the hooks?

Copy link
Contributor

Choose a reason for hiding this comment

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

I think we'd better NOT disable hooks in that case. preapply is supposed to get triggered even on unmodified releases. It should work the same for releases with installed: false. installed: false declares the release to be deleted, unlike when you filtered out the release by using a label selector so that it is ever installed.
Indeed, we shouldn't call hooks for releases that are filtered out by using a label selector. But I think that's already implemented.

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 very much agree that hook command should be made "idempotent", I think it would be better to state this in the docs, I'll do it.

@xiaomudk xiaomudk changed the title Fix presync hooks are not called on no diff when run apply subcommand Fix preapply hooks are not called on no diff when run apply subcommand Nov 17, 2022
@xiaomudk xiaomudk force-pushed the patch-8 branch 5 times, most recently from 46baf30 to f5bd748 Compare November 27, 2022 16:24
@yxxhero
Copy link
Member

yxxhero commented Nov 28, 2022

@xiaomudk adding more docs about pre-apply will be better.

@yxxhero yxxhero added this to the 0.149.0 milestone Dec 4, 2022
@yxxhero
Copy link
Member

yxxhero commented Dec 5, 2022

@mumoshu WDYT?

@mumoshu
Copy link
Contributor

mumoshu commented Dec 5, 2022

@yxxhero Thanks for the reminder! Aren't we waiting for @xiaomudk to update the docs, or should I?

@xiaomudk
Copy link
Contributor Author

xiaomudk commented Dec 5, 2022

@mumoshu @yxxhero Sorry, I will update the docs today

yxxhero
yxxhero previously approved these changes Dec 6, 2022
@yxxhero
Copy link
Member

yxxhero commented Dec 7, 2022

@mumoshu @itscaro WDYT?

@itscaro
Copy link
Contributor

itscaro commented Dec 7, 2022

@yxxhero I need to check the behaviours in case of installed: false. I will get back to you ASAP.

docs/index.md Outdated Show resolved Hide resolved
@yxxhero
Copy link
Member

yxxhero commented Dec 7, 2022

@xiaomudk DCO

Co-authored-by: Yusuke Kuoka <ykuoka@gmail.com>
Signed-off-by: xiaomudk <xiaomudk@gmail.com>
Copy link
Contributor

@itscaro itscaro left a comment

Choose a reason for hiding this comment

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

Something is not consistent here:

When the chart is not installed and installed: false. No hook is called but preapply is, IMO, I not attend this. If preapply is called, prepare is attended to.

When the chart is installed, and we change installed: true to installed: false, prepare hook is not called, is it normal? since the document says

Hooks associated to prepare events are triggered after each release in your helmfile is loaded from YAML, before execution. prepare hooks are triggered on the release as long as it is not excluded by the helmfile selector(e.g. helmfile -l key=value).

I think when no action should be done, no hook should be called at all. I have cases that I only use installed to include or exclude a release and I do not use condition in combination with installed for the sake of ease.

@yxxhero
Copy link
Member

yxxhero commented Dec 8, 2022

Something is not consistent here:

When the chart is not installed and installed: false. No hook is called but preapply is, IMO, I not attend this. If preapply is called, prepare is attended to.

When the chart is installed, and we change installed: true to installed: false, prepare hook is not called, is it normal? since the document says

Hooks associated to prepare events are triggered after each release in your helmfile is loaded from YAML, before execution. prepare hooks are triggered on the release as long as it is not excluded by the helmfile selector(e.g. helmfile -l key=value).

I think when no action should be done, no hook should be called at all. I have cases that I only use installed to include or exclude a release and I do not use condition in combination with installed for the sake of ease.

see: #522 (comment)

@mumoshu

@itscaro
Copy link
Contributor

itscaro commented Dec 8, 2022

@yxxhero I read the comment of mumoshu, I am partly OK. in the case, installed: false is not use to delete the chart but to not install the release, I feel something wrong to run hooks. Btw may be we should improve the documents on hooks to add some sequence diagrams, wdyt?

@yxxhero
Copy link
Member

yxxhero commented Dec 9, 2022

@yxxhero I read the comment of mumoshu, I am partly OK. in the case, installed: false is not use to delete the chart but to not install the release, I feel something wrong to run hooks. Btw may be we should improve the documents on hooks to add some sequence diagrams, wdyt?

good ieda.

@yxxhero
Copy link
Member

yxxhero commented Dec 9, 2022

@mumoshu So would we merge this PR?

@mumoshu
Copy link
Contributor

mumoshu commented Dec 10, 2022

installed: false is not use to delete the chart but to not install the release, I feel something wrong to run hooks

@itscaro I think I have similar sentiment as yours, but the behavior should be good in terms of consistency if we think carefully- it triggers the preapply hook regardless of whether there are any changes to be synced or not. Helmfile does diff between the missing(already uninstalled, not yet installed) release vs the desired state of the release installed: false. It syncs nothing due to there's no diff between the desired and the current states. But it does trigger the preapply hook because that's when preapply hook is supposed to be called.
I'm afraid my comment turned out to be a repetition of the previous one, but anyway, I hope it clarifies things a bit!

And yeah, any documentation enhancement should be welcomed if there's anything unclear.

@mumoshu
Copy link
Contributor

mumoshu commented Dec 10, 2022

I'm going to merge this anyway- but let's keep discussing! We should be able to freely change it to not get triggered for the installed: false + missing release case if we ended up having a consensus that's the desired behavior until this new preapply hook becomes popular.

@mumoshu mumoshu merged commit 94381c1 into helmfile:main Dec 10, 2022
yxxhero pushed a commit that referenced this pull request Dec 10, 2022
#522)

* Fix presync hooks are not called on no diff when run apply subcommand

Signed-off-by: xiaomudk <xiaomudk@gmail.com>

* Update docs/index.md

Co-authored-by: Yusuke Kuoka <ykuoka@gmail.com>
Signed-off-by: xiaomudk <xiaomudk@gmail.com>

Signed-off-by: xiaomudk <xiaomudk@gmail.com>
Co-authored-by: Yusuke Kuoka <ykuoka@gmail.com>
yxxhero pushed a commit that referenced this pull request Dec 10, 2022
#522)

* Fix presync hooks are not called on no diff when run apply subcommand

Signed-off-by: xiaomudk <xiaomudk@gmail.com>

* Update docs/index.md

Co-authored-by: Yusuke Kuoka <ykuoka@gmail.com>
Signed-off-by: xiaomudk <xiaomudk@gmail.com>

Signed-off-by: xiaomudk <xiaomudk@gmail.com>
Co-authored-by: Yusuke Kuoka <ykuoka@gmail.com>
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Dec 12, 2022
@xiaomudk xiaomudk deleted the patch-8 branch January 1, 2023 09:07
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

preapply not working
4 participants