Skip to content

Add preapply hook#79

Merged
yxxhero merged 19 commits into
helmfile:mainfrom
Sajfer:preapply
Sep 19, 2022
Merged

Add preapply hook#79
yxxhero merged 19 commits into
helmfile:mainfrom
Sajfer:preapply

Conversation

@Sajfer

@Sajfer Sajfer commented Apr 30, 2022

Copy link
Copy Markdown
Contributor

As discussed in roboll/helmfile#1940 this PR adds a preapply hook that will run every time the release is applied, even if there is no changes to the release.

@yxxhero

yxxhero commented May 1, 2022

Copy link
Copy Markdown
Member

@Sajfer Can you add some unittest? Thanks very much.

@Sajfer

Sajfer commented May 1, 2022

Copy link
Copy Markdown
Contributor Author

I am working on unittests, but I have ran into a problem.

--- FAIL: TestApply_2 (0.04s)
    --- FAIL: TestApply_2/apply_release_with_preapply_hook (0.00s)
        /home/sajfer/code/helmfile/pkg/app/app_apply_test.go:1286: unexpected log: want (-), got (+):   strings.Join({
              	... // 1131 identical bytes
              	"ing preapply hook for foo:\nhook[echo]: stateFilePath=helmfile.ya",
              	"ml, basePath=.\n\nhook[echo]: triggered by event \"preapply\"\n\necho:",
            - 	"DKdXX",
            + 	"pFGpk",
              	"> foo\nhook[echo]: foo\n\n\n\nhook[preapply] logs | foo\nhook[preapply",
              	"] logs | \nprocessing 1 groups of releases in this order:\nGROUP R",
              	... // 299 identical bytes
              }, "")

The hook output contains a random 6 letter string that changes every run.

@yxxhero

yxxhero commented May 1, 2022

Copy link
Copy Markdown
Member

I am working on unittests, but I have ran into a problem.

--- FAIL: TestApply_2 (0.04s)
    --- FAIL: TestApply_2/apply_release_with_preapply_hook (0.00s)
        /home/sajfer/code/helmfile/pkg/app/app_apply_test.go:1286: unexpected log: want (-), got (+):   strings.Join({
              	... // 1131 identical bytes
              	"ing preapply hook for foo:\nhook[echo]: stateFilePath=helmfile.ya",
              	"ml, basePath=.\n\nhook[echo]: triggered by event \"preapply\"\n\necho:",
            - 	"DKdXX",
            + 	"pFGpk",
              	"> foo\nhook[echo]: foo\n\n\n\nhook[preapply] logs | foo\nhook[preapply",
              	"] logs | \nprocessing 1 groups of releases in this order:\nGROUP R",
              	... // 299 identical bytes
              }, "")

The hook output contains a random 6 letter string that changes every run.

@Sajfer try to use regex?

@gakesson

gakesson commented May 1, 2022

Copy link
Copy Markdown

Is there a need to document the defined behavior when specifying below hook events?
events: ["presync", "preapply"]

I would expect/want the hook to only be executed once for the release in question in above scenario but I think it is good if we establish and document a well-known behavior.

@Sajfer Sajfer changed the title Add preapply hook Draft: Add preapply hook May 1, 2022
@Sajfer Sajfer marked this pull request as draft May 1, 2022 09:53
@Sajfer Sajfer force-pushed the preapply branch 4 times, most recently from a02d4d8 to 733eb60 Compare May 4, 2022 20:03
@Sajfer Sajfer marked this pull request as ready for review May 4, 2022 20:17
@Sajfer

Sajfer commented May 4, 2022

Copy link
Copy Markdown
Contributor Author

The current implementation only allows one of preapply and presync to run.
I have added some tests that checks that as well.

@Sajfer Sajfer changed the title Draft: Add preapply hook Add preapply hook May 5, 2022
@Sajfer

Sajfer commented May 9, 2022

Copy link
Copy Markdown
Contributor Author

@itscaro @mumoshu Any chanse for a review? :)

@Sajfer

Sajfer commented May 18, 2022

Copy link
Copy Markdown
Contributor Author

@itscaro @mumoshu can you review?

@Sajfer Sajfer force-pushed the preapply branch 2 times, most recently from 3f922a5 to 25484df Compare May 25, 2022 17:45
Comment thread pkg/event/bus.go Outdated
}
}

if slices.Contains(hook.Events, "preapply") && evt == "presync" && hook.Executed {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think this special handling is unnecessary- when one included a hook for both events preapply and presync, almost probably it's what they wanted, for e.g. notifying the timing helmfile triggered respective events. There shouldn't be a hard-coded logic to block such usage.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Or could you clarify the context behind this guard a bit more? 🙏

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@yxxhero @itscaro Do you have any insights on this? I'm wondering if I'm missing any practical use-cases of this feature that might make this special handling necessary

@Sajfer Sajfer Jun 6, 2022

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@mumoshu I added it as a response to @gakesson, it felt reasonable, but I can remove it if not wanted.

The reasoning was that we can add both preapply and presync to make sure that the hook is run both if apply or sync is used, but that it only should run once. Since the presync hook is called when running apply as well, if there is any changes that will be synced to the cluster.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@Sajfer @mumoshu it was mostly that to me it is not intuitive that if I run "helmfile apply" and have events as ["presync", "preapply"] that the hook would be executed twice (in case sync is invoked for the release), but perhaps this type of special handling is not consistent how events and hooks work today.
But I'm fine either way, as long as we have a well-defined and documented behavior.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@mumoshu The use-case I was thinking of was that the hook execution would behave same (=execute once always) irrespective of our users use sync or apply (we deliver our helmfile to other parts of company org). In that case we would specify ["preapply", "presync"] to cover both rollout commands, but obviously this can instead be solved by simply instructing users to only use apply and never sync if we use the preapply event. And at least for us it is not a problem to execute the hook twice, only a bit redundant.
But for consistency I think it is fine to not have this special handling. Sorry for the confusion on this discussion. :)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If we only have the preapply hook set and run helmfile sync then that hook would not run right?

@Sajfer Ah, good point! And that's how it's implemented in this PR now, right? I'd say the new hook should be triggered also on helmfile sync.

It's unfortunately that presync and preapply doesn't correspond 1:1 to helmfile sync and helmfile apply respectively. But still, to better reflect how it's supposed to work:

preapply hooks will trigger everytime a release is applied, indifferent if there is changes to the release or not.

we'd better make it triggered also on helmfile-sync.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Correct, the current implementation only runs on apply and not on sync.

Just to be clear so there is no more changes after:

  • we want the preapply hook to run both on apply and sync.
  • We do not want to have a prevention for the hook to run twice if both preapply and presync is added.

Is this correct?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@Sajfer Yes, you're absolutely correct. I think the combination of those two changes makes the new preapplly hook more consistent with other hooks(Each hook is run only once per release on a lifecycle event of each release, regardless of which helmfile sub-command you're using). Does it make sense to you?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, that sounds good.
I will see if I can get some time to make the changes this week.

@mumoshu mumoshu left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@Sajfer Sorry for the delayed review! Just one comment regarding the guard for preventing double-running a hook in case it was targeted both presync and preapply. WDYT?

@Sajfer Sajfer requested a review from yxxhero as a code owner June 11, 2022 11:52
@Sajfer Sajfer force-pushed the preapply branch 2 times, most recently from 1252f45 to 12bb46c Compare June 11, 2022 11:54
@Sajfer

Sajfer commented Jun 11, 2022

Copy link
Copy Markdown
Contributor Author

@mumoshu I pushed an update that removes the prevention of double execution now.

@yxxhero

yxxhero commented Jun 11, 2022

Copy link
Copy Markdown
Member

@Sajfer I will review this PR together.

Comment thread pkg/app/app.go Outdated
Comment thread pkg/app/app.go Outdated
if !interactive || interactive && r.askForConfirmation(confMsg) {
r.helm.SetExtraArgs(argparser.GetArgs(c.Args(), r.state)...)

for _, release := range st.Releases {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@Sajfer Thanks a lot for the fix! Juts to be extra sure, you're triggering preapply events also for unprocessed(=not-deleted and not-updated releases without any changes to be applied) releases. Is it intentional? If not, I'm prepared for fixing it in a way I've summarized in my previous comment.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Sure, go ahead, it was not intended.

})
})

t.Run("apply release with preapply hook", func(t *testing.T) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@Sajfer I've never realized that you were able to use the same test title multiple times like this (you have three of them in this file) and the framework still differentiates those by appending suffixes like #2 and #3. Great finding!

@yxxhero

yxxhero commented Sep 19, 2022

Copy link
Copy Markdown
Member

@mumoshu Ready?

@mumoshu

mumoshu commented Sep 19, 2022

Copy link
Copy Markdown
Contributor

@Sajfer I've added documentation about this feature in 385c3e8. It would be great if you could take a look and leave any comments if any!

@mumoshu mumoshu left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I've added a few more test cases for verification and it turned out to be working well! This LGTM now.
Thanks a lot for your patience and awesome work @Sajfer!

@yxxhero yxxhero merged commit 24810a4 into helmfile:main Sep 19, 2022
@Sajfer Sajfer deleted the preapply branch September 19, 2022 07:52
@github-actions github-actions Bot locked as resolved and limited conversation to collaborators Sep 21, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants