rhtconsulting / puppet-jboss_admin

Puppet module for runtime configuration of a JBoss container
MIT License
15 stars 12 forks source link

How are you handling operations that you only need to run once? #90

Closed jairojunior closed 8 years ago

jairojunior commented 8 years ago

The title is self explanatory, but I'd like to know how are you handling operations like restart, reload, deploy, flush-all-connection-in-pool and etc

With domain operation mode you could be doing this with JBoss Web Console, but what if you have multiple domain controllers or multiple standalone instances?

I know that there are a lot of JBoss users here and just released a MCollective JBoss Agent Plugin that might help: https://github.com/jairojunior/mcollective-jboss-agent

itewk commented 8 years ago

@jairojunior

One of the important things to remember about Puppet is there is no such thing as "an action you only do once". Every action must be idempotent. The way I typically think of it is that anything Puppet is controlling has to have four things.

  1. A current state, as read from the machine Puppet is running on
  2. a desired state, as defined by a puppet resource
  3. a mechanism for comparing current state to desired state
  4. a mechanism for changing the current state to match the desired state.

For examples of how I handle restarts and deployments you can see my sample puppet module that uses the jboss_admin module here, https://github.com/itewk/puppet-jboss_eap_server

The closest thing I have done to "flush-all-connections-in-pool", is a validate connection call on a datasource, and the way I did that was to hook it up as a refresh only resource after a datasource is initially configured. This does have the down side that if something breaks on the database side of the connection Puppet and JBoss won't know about it because I do not run the validate on every Puppet run. But I don't do that on purpose for two reasons. The overhead of validating the connection every 30 miutes, and secondly the Puppet run would never be stable then and would always report a change happening every 30 minutes making for an unstable Puppet environment.

For your "flush-all-connection-in-pool" example you first have to deside what is the "current state" that would dictate that you need to take that action, then figure out how to detect that state, then use the jboss_exec resource to invoke that action. If the "current state" that dictates that flush-all-connections-in-pool should be performed is along the lines of "once every night between 1:00am and 2:00am then you could create a jboss_exec resource that does the flush but with a Puppet schedule that only allows the flush to happen during those hours. If the "current state" that dictates that flush-all-connections-in-pool should be preformed is "on-demand" rather then some detectable state. Then you should be thinking about using Jenkins (or similar automation orchestration software) to allow users to invoke this on demand action.

I hope all of this helps. I will wait to close this question until you have responded with any more questions.

Blue Skies, ~Ian

jairojunior commented 8 years ago

Thank you @itewk, that's exactly the kind of feedback I was expecting. =)

Regarding Puppet idempotency and eventual consistency (https://puppetlabs.com/presentations/puppetizing-multitier-architecture-reid-vandewiele-puppet-labs), they are both desirable - most of the the time.

Let's talk about the three scenarios you suggested:

1 - Reload/Restart

if (result == reload-required) of read-attribute server-state
  reload

Which we will translate to:

exec_cli { 'Reload if necessary':
  command => 'reload',
  onlyif  => '(result == reload-required) of read-attribute server-state'
}

So, what's the problem with this approach? Reload/Restart is not a resource/state, it's an operation.

2 - Deploy

Deploy is a funny guy because it's look like both a state and an operation. And if you pay attention to JBoss configuration XML after a deploy you'll find something like:

<deployment name="MyApp.ear" runtime-name="MyApp.ear">
    <content sha1="e067140a5f0696faaad7b981b36b5b34033a1f19"/>
</deployment>

Hence, deployment is a resource and deploy is the operation that creates this resource.

3 - flush-all-connection-in-pool

This guy is clearly an operation, but more important, it's an operation that you may want to execute right now (i.e. you did not want to wait for a puppet run);

TL;DR: There are resources and operations. Operations doesn't look natural in your node roles and profiles because they are imperative and Puppet DSL is declarative.

Among operations, you have ones that you can afford to wait for the next Puppet run, but you also have others that you want to perform in a specific time in a synchronous/more consistency way.

I'm not sure if my point was clear in the first comment, but what I want to say is that there are space for both resources and operations and we should try to find one solution for each case.

itewk commented 8 years ago

@jairojunior

I would think that the difference between jboss_resource and jboss_exec is exactly the difference you are thinking about when you reference Operations vs Resources, but I maybe misunderstanding.

Did you take a look at my sample project for how I handle deployments? The relevant files are:

https://github.com/itewk/puppet-jboss_eap_server/blob/master/manifests/deploy.pp https://github.com/itewk/puppet-jboss_eap_server/blob/master/manifests/artifact.pp

Blue Skies, ~Ian

itewk commented 8 years ago

@jairojunior

As for the restart/reload, did you already take a look at https://github.com/cpitman/puppet-jboss_admin/blob/master/manifests/cleanup.pp? That does exactly what you put in pseudo code. This is an example using jboss_admin::clean up, https://github.com/itewk/puppet-jboss_eap_server/blob/master/manifests/cleanup.pp

Blue Skies, ~Ian

jairojunior commented 8 years ago

I'm not arguing whether it's feasible or not. As a matter of fact, I already did the same thing you did in your repository and just don't feel it's the best way to handle this. (i.e. just because you can doesn't mean you should)

jmarley commented 8 years ago

Good points.

I'm wondering if what you're looking for isn't something for another tool. As this puppet model is meant to keep a particular state constant. You're looking for a 1 off solution when say the JVM goes awry or something funky happens with your controllers, but have a repeatable, stable solution.

This type of thing might be better for a simple script that targets a subset of servers and bounces them, logs info and reports back. Anisble, python or some other scripting tool would do the trick.

2c, Jason

Jason

----- Original Message ----- I'm not arguing whether it's feasible or not. As a matter of fact, I already did the same thing you did in your repository and just don't feel it's the best way to handle this. (i.e. just because you can doesn't mean you should)
---
Reply to this email directly or view it on GitHub:
https://github.com/cpitman/puppet-jboss_admin/issues/90#issuecomment-144053801
itewk commented 8 years ago

@jairojunior

I guess I am still confused as to what you are trying to do that isn't covered by what we already have and what you feel isn't the best about it? Maybe a concrete example of how you would do a deployment differently then I handle it in my example module?

Of course, my use case, is as Jason mentioned, consistent state. Which in the case of deployment means if it is a SNAPSHOT deployed, be sure the latest SNAPSHOT is deployed at all times, or in the case of a release, ensure a given release is deployed at all times. That way if someone accidentally un-deployed the application Puppet can automatically detect this and re-deploy.

I played with doing deployments outside of puppet, with scripts orchestrated from Jenkins, but ultimate scrapped the idea. There were multiple reasons for this. One of the primary reasons being the previously mentioned protecting against an accidental undeployment. Secondly I wanted the ability to completely uninstall JBoss EAP from a VM, run Puppet and have it back at exactly the same state it was before I did the uninstall, and that would include the deployment, which meant Puppet controlling the deployment. Similarly I want the ability to spin up new VMs in a cluster and the only action I need to do is add the VM to a hostgroup in Foreman and run puppet and it makes the VM look just like all other VMs in that hostgroup. Which again, means Puppet controlling the deployment.

Circling back to my original question, in the case of the actions you are talking about, where are the triggers for them? Whether it be deployment or a datasource flush, or some other action, what is the trigger for those actions? Manual? Timmer? The mechanism for what kicks off your action would dictate the best way to implement. If its all manual then @jmarley suggestions are good. If its a timer or consistent state then Puppet is likely better.

itewk commented 8 years ago

I am closing this question. If you still have questions please re-open or start a new thread.