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

feat: prepare and cleanup release event hooks #349

Merged
merged 1 commit into from
Sep 21, 2018

Conversation

mumoshu
Copy link
Collaborator

@mumoshu mumoshu commented Sep 19, 2018

Resolves #295
Resolves #330
Resolves #329 (Supports templating of only releases[].hooks[].command and args right now
Resolves #324

@mumoshu mumoshu force-pushed the prepare-cleanup-release-evt-hooks branch from 0ab9eef to 5856c64 Compare September 19, 2018 09:52
README.md Outdated
@@ -593,6 +593,61 @@ mysetting: |

The possibility is endless. Try importing values from your golang app, bash script, jsonnet, or anything!

## Hooks

Hook is an per-release extension point of helmfile that is composed of:
Copy link
Contributor

Choose a reason for hiding this comment

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

What about this formulation?

A helmfile hook is a per-release extension point that is composed of:

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Sounds great!

README.md Outdated
- `args`

helmfile triggers various `events` while it is running.
One `events` are triggered, associated `hooks` are executed, by running the `command` with `args`.
Copy link
Contributor

Choose a reason for hiding this comment

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

s/One/Once/

chart: mychart
# *snip*
hooks:
- events: ["prepare", "cleanup"]
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a technical reason you didn't go with this the structure proposed in #330?:

 hooks:
    preChartLoad: # register as many commands as you want to this hook
    - command: {{` ./chartify -e {{ .Environment.Name }} {{ .Chart }} `}}

I see that you would want to register the same command for a specific hook, but that seems to be over generic (I believe it is more common to have differing calls on each event, than the same call on multiple events).

YAML anchors could come handy if you have the same command on multiple events.

The preChartLoad schema is verifiable at load time.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Good catch! Indeed my intention was to make it even more generic with (hopefully) comparable complexity to the third option in my proposal.

I believe it is more common to have differing calls on each event, than the same call on multiple events

I think so too. My intention here was to provide the most DRY way to support this use-case:

To be able to use the same script to implement multiple hooks the name of the hook should also be passed along.

See #295 (comment) for more context.

The preChartLoad schema is verifiable at load time.

Good point! I was thinking to add validation for unsupported events. That is, events: ["foo"] results in an error like unsupported event to hook: foo.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

And I wasn't sure if "eventsare the only possible hook target in helmfile. Googling around, the termhook` seems to be used for NOT only for expressing extension points associated to events. For example, something like "action hook" can be considered:

hooks:
- actions: ["lint"]
   command: ...

An event hook reacts on specific event and doesn't have ability to return data from the hook to helmfile.

An action hook, on the other hand, could be used for passing data from the hook to helmfile, in an output format helmfile expects for the specific action. In the above example, the lint action hook can return a specifically formatted json to add lint results that are integrated into the original output of helmfile lint.

Explicitly wording hook targets as events prevents ambiguity and creates future possibility like this.

@davidovich
Copy link
Contributor

small nit: (title contains a typo: faet) and one issue will not be closed: Resolevs #324

@mumoshu mumoshu force-pushed the prepare-cleanup-release-evt-hooks branch from 5856c64 to f6a9576 Compare September 19, 2018 13:52
README.md Outdated

Run `helmfile --environment staging sync` and see it results in helmfile running `kustomize build foo-kustomize/overlays/staging > foo/templates/all.yaml`.

Viola! You can mix helm releases that are backed by remote charts, local charts, and even kustomize overlays.
Copy link
Contributor

Choose a reason for hiding this comment

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

s/Viola/Voilà/

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Good catch! Thanks. Fixed in the latest commit.

@mumoshu mumoshu changed the title faet: prepare and cleanup release event hooks feat: prepare and cleanup release event hooks Sep 19, 2018
@mumoshu mumoshu force-pushed the prepare-cleanup-release-evt-hooks branch from f6a9576 to 8886038 Compare September 19, 2018 14:07

// Execute a shell command
func (shell ShellRunner) Execute(cmd string, args []string) ([]byte, error) {
preparedCmd := exec.Command(cmd, args...)
if shell.Dir != "" {
preparedCmd.Dir = shell.Dir
Copy link
Contributor

Choose a reason for hiding this comment

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

What do you think about setting preparedCmd.Dir unconditionally? It's default value is the empty string.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I believe we shouldn't, because we use it to run helm commands and it assumes Dir unspecified today.

Copy link
Contributor

Choose a reason for hiding this comment

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

What I meant is that the condition is not necessary:

if shell.Dir is empty, assign (it won't change the default of preparedCmd which is empty)
if shell.Dir is not empty, assign (as you you in the condition)

Copy link
Collaborator Author

@mumoshu mumoshu Sep 19, 2018

Choose a reason for hiding this comment

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

Ah makes sense! I'll fix it asap. Thanks for your review!

helmexec/runner.go Outdated Show resolved Hide resolved
state/hook.go Outdated
allargs := []string{}
allargs = append(allargs, command[1:]...)
allargs = append(allargs, args...)
bytes, err := state.runner.Execute(command[0], allargs)
Copy link
Contributor

Choose a reason for hiding this comment

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

command is a slice, but only the first one is executed. How does that work if the user specifies multiple commands ?

command: ["echo", "helm"]
args: ["hello", "world", "list"]

What do you think about these UIs?:

command: ["command", "arg1", "arg2"]

or

commands:
  - cmd: "helm"
    args: "list"

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Trailing items in the command array is considerd args. I made it so to make it consistent with k8s pod spec, hoping it is easy to remember along with it.

Copy link
Contributor

Choose a reason for hiding this comment

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

OK, but the podSpec is meant to override CMD and ENTRYPOINTS of containers. Not sure the model applies. Your call :-)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Good point! Maybe blindly trying to make it consistent with pod spec doesn't make sense. I'll just make it a singular value. Thanks a lot for your comments 👍

@davidovich
Copy link
Contributor

I believe this change could benefit from additional tests.

@mumoshu mumoshu force-pushed the prepare-cleanup-release-evt-hooks branch from 8886038 to 5e528c0 Compare September 20, 2018 02:32
@mumoshu
Copy link
Collaborator Author

mumoshu commented Sep 20, 2018

@davidovich I've added tests and some tweaks. Would you mind confirming? Thanks!

@davidovich
Copy link
Contributor

davidovich commented Sep 20, 2018 via email

Copy link
Contributor

@davidovich davidovich left a comment

Choose a reason for hiding this comment

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

Only one comment on the readme

LGTM!

README.md Outdated
# *snip*
hooks:
- events: ["prepare", "cleanup"]
command: ["echo"]
Copy link
Contributor

Choose a reason for hiding this comment

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

Upon your latest changes, I believe this is not an array anymore, what do you think?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Good catch! I'll fix it asap.

Resolves roboll#295
Resolves roboll#330
Resolves roboll#329 (Supports templating of only `releases[].hooks[].command` and `args` right now
Resolves roboll#324
@mumoshu mumoshu force-pushed the prepare-cleanup-release-evt-hooks branch from 5e528c0 to 5c67644 Compare September 21, 2018 01:22
@mumoshu mumoshu merged commit b9de22b into roboll:master Sep 21, 2018
@mumoshu
Copy link
Collaborator Author

mumoshu commented Sep 21, 2018

@davidovich Thanks a lot for your review ☺️

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.

2 participants