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

Add preapply hook #79

Merged
merged 19 commits into from
Sep 19, 2022
Merged

Add preapply hook #79

merged 19 commits into from
Sep 19, 2022

Conversation

Sajfer
Copy link
Contributor

@Sajfer Sajfer commented Apr 30, 2022

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
Copy link
Member

yxxhero commented May 1, 2022

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

@Sajfer
Copy link
Contributor Author

Sajfer commented May 1, 2022

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
Copy link
Member

yxxhero commented May 1, 2022

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
Copy link

gakesson commented May 1, 2022

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
Copy link
Contributor Author

Sajfer commented May 4, 2022

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
Copy link
Contributor Author

Sajfer commented May 9, 2022

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

@Sajfer
Copy link
Contributor Author

Sajfer commented May 18, 2022

@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
pkg/event/bus.go Outdated
@@ -69,6 +71,10 @@ func (bus *Bus) Trigger(evt string, evtErr error, context map[string]interface{}
}
}

if slices.Contains(hook.Events, "preapply") && evt == "presync" && hook.Executed {
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 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
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
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

Copy link
Contributor Author

@Sajfer Sajfer Jun 6, 2022

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

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.

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
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
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
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
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.

Copy link
Contributor

@mumoshu mumoshu left a comment

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
Copy link
Contributor Author

Sajfer commented Jun 11, 2022

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

@yxxhero
Copy link
Member

yxxhero commented Jun 11, 2022

@Sajfer I will review this PR together.

pkg/app/app.go Outdated Show resolved Hide resolved
pkg/app/app.go Outdated
@@ -1352,6 +1352,14 @@ Do you really want to apply?
if !interactive || interactive && r.askForConfirmation(confMsg) {
r.helm.SetExtraArgs(argparser.GetArgs(c.Args(), r.state)...)

for _, release := range st.Releases {
Copy link
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
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.

Sajfer and others added 14 commits September 19, 2022 08:55
Signed-off-by: Anton Bretting <sajfer@gmail.com>
Signed-off-by: Anton Bretting <sajfer@gmail.com>
Signed-off-by: Anton Bretting <sajfer@gmail.com>
Signed-off-by: Anton Bretting <sajfer@gmail.com>
Signed-off-by: Anton Bretting <sajfer@gmail.com>
Signed-off-by: Anton Bretting <sajfer@gmail.com>
Signed-off-by: Anton Bretting <sajfer@gmail.com>
Signed-off-by: Anton Bretting <sajfer@gmail.com>
Signed-off-by: Anton Bretting <sajfer@gmail.com>
Signed-off-by: Anton Bretting <sajfer@gmail.com>
Signed-off-by: Anton Bretting <sajfer@gmail.com>
Signed-off-by: Anton Bretting <sajfer@gmail.com>
Signed-off-by: Anton Bretting <sajfer@gmail.com>
Signed-off-by: Yusuke Kuoka <ykuoka@gmail.com>
Signed-off-by: Yusuke Kuoka <ykuoka@gmail.com>
Signed-off-by: Yusuke Kuoka <ykuoka@gmail.com>
})
})

t.Run("apply release with preapply hook", func(t *testing.T) {
Copy link
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
Copy link
Member

yxxhero commented Sep 19, 2022

@mumoshu Ready?

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

mumoshu commented Sep 19, 2022

@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!

Copy link
Contributor

@mumoshu mumoshu left a comment

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.

None yet

4 participants