Azure / draft-classic

A tool for developers to create cloud-native applications on Kubernetes.
https://draft.sh
MIT License
3.92k stars 396 forks source link

A plugin hook for `draft up` #565

Open mumoshu opened 6 years ago

mumoshu commented 6 years ago

Hi, thanks as always for maintaining great products 👍

Assuming we already have a plugin system, I hope draft to support a plugin hook for draft up, so that I can set up runtime dependencies for my app.

Runtime dependencies may include, for example, a RDBMS, but the implementation may differ according to DRAFT_ENV: An AWS RDS MySQL instance, mysql from the stable/mysql helm chart, mysql installed in process of another tool like helmfile...

As I don't want bloat up the codebase, I prefer adding draft only the hook. This way, we can redirect any user like me, wanting draft rather than e.g. make to be an entry-point of ones development workflow, to use the plugin hook to organize their workflows.

Would this make sense within the scope of draft? Thanks!

mumoshu commented 6 years ago

This request differs from #370, which seems to be intended for hooks from draft packs, rather than plugins.

mumoshu commented 6 years ago

This request differs from #100, which seems to be intended for customizing build.

bacongobbler commented 6 years ago

Hey! I think this sounds like something that would make sense within the scope of Draft, but I'd love to pick your brain a bit on the desired feature set first just to make sure we're on the same page.

One thing we thought about in #370 is the difference between client-side and server-side hooks. #370 talks specifically about pre and post draft up stages, but there are similar client/server tools (like git for example) that have both client and server-side hooks. Is that something along your lines of thinking, or were you thinking of something else?

mumoshu commented 6 years ago

Hi @bacongobbler, thanks again for your response!

I'm still not very confident if this answers your question, but I'm considering this as a client-side hook, just because I don't have specific requirement to do it server-side.

More concretely, I have been considering to exploit the current plugin hook system from within maybe draft up. draft up calls context.RunPluginHook("up") to call plugin.runHook(p, "up") for each draft plugin impl p.

Probably this isn't what the current plugin hook is intended to be used for, but wanted to explore if it makes sense to implement things this way.

bacongobbler commented 6 years ago

That sounds interesting! The current plugin system is modeled heavily against helm's plugin system, which is that there are hooks for post-install, post-update and post-delete events. We could definitely adopt that to draft.toml using the same format:

[environments]

    [environments.development]
    name = "draft"
    namespace = "kube-system"
    wait = false
    hooks.pre-up = ["echo", "hi!"]
    hooks.post-up = ["echo", "bye!"]

Or (both are acceptable formats in TOML):

[environments]

    [environments.development]
    name = "draft"
    namespace = "kube-system"
    wait = false
    [hooks]
    pre-up = ["echo", "hi!"]
    post-up = ["echo", "bye!"]

How does that look?

bacongobbler commented 6 years ago

cc @michelleN, might be a new way to emit events to inspire #370

mumoshu commented 6 years ago

@bacongobbler Thanks for the response!

Your explanation and the link to #370 made me come up with an alternative implementation to support my use-case.

Anyway, .draft/hooks would contain pre-up which in my case run helmfile sync according to maybe DRAFT_ENV passed from draft.

That being said, we'd better implement an another hook system other than we have for draft plugins, not to mix up plugin hooks vs lifecycle hooks. Not sure I'm explaining this concisely enough but you'll see what I mean after reading over 😉

Basically, we can choose to implement the lifecycle hook system (1)natively inside draft, or (2)as a draft plugin. (1) was almost the same thing I would have done without knowing #370.

But now, I slightly prefer (2) because it provides us a more customizability and keep the draft core smaller compared to (1).

If I were going to implement (2), I would firstly enhance the current plugin system to support plugin.runHook(p, "pre-up"). On top of it, a lifecyclehook plugin, which is bundled and enabled by default in draft, does the job of (1)reading .draft/hooks/pre-up and invoking it on plugin.runHook(p, "pre-up").

michelleN commented 6 years ago

Hey @mumoshu - I'm highly in favor of supporting lifecycle hooks in the way you described. I'm a little confused on why we want to support lifecycle hooks in plugins specifically (not against it, just want to understand). If a pre-up hook is defined in /.draft/hooks/pre-up, I would assume that the pre-up hook would be invoked before any up command regardless of it being explicitly called by a plugin.

Are you suggesting we re-write draft up to be a plugin itself and then build support for lifecycle hooks on plugins and invoke them via plugin.runHook(p, "pre-up") like you mentioned?

+1 to a lifecyclehook plugin that is installed/enabled by default btw

michelleN commented 6 years ago

hey @mumoshu I've taken a stab at #370 via PR #642 -- it's very much in progress right now but I'll put in some documentation and cleanup in the morning. Basically, it allows you to define tasks to handle runtime dependencies like setting up a database or other service for your app. It also allows you to define tasks that you'd want to run in your container to set up your application and cleanup tasks like things you'd want to do when you're done iterating on an app like deleting the database service. Would love your feedback.

mumoshu commented 6 years ago

@michelleN Hi. Sounds awesome! I'll try it a sap. Thanks for your efforts :tada: