can I pass a class or type to be executed into another class?

32 views
Skip to first unread message

Joshua Chaitin-Pollak

unread,
Nov 26, 2013, 1:31:33 AM11/26/13
to puppet...@googlegroups.com
Hello, I have a module "mywebapp" which calls the tomcat::war module with specific parameters, to upgrade the war file and restart tomcat. This works great. What I would like to do is modify the code so that if, and only if tomcat needs to be restarted, BEFORE it is restarted, I want to perform a file operation. I want to do this because the operation will tell our load balancer the server is about to go offline, and not to direct any traffic to the server. I don't want to do this unless the war file is actually going to be upgraded, which only the tomcat::war type knows.

The tomcat::war module which looks roughly like this (I'm simplifying for brevity):

define tomcat7::war (
    ... params
) {

  ... variable definitions ...

  file { "${tomcat7::sites_dir}/${destFile}":
    notify      => Exec["clean_${tomcat7::sites_dir}/${contextPath}"],
  }

  exec { "clean_${tomcat7::sites_dir}/${contextPath}":
    command     => "rm -rf ${contextPath} ; mkdir ${contextPath} ; unzip ${contextPath}.war -d ${contextPath}/",
    cwd         => "${tomcat7::sites_dir}",
    notify      => Class['tomcat7::service'],
  }
}

what I would like to do is pass a parameter into tomcat::war so that if that the parameter is set, the class (or type) referenced in the parameter is Notified instead of Exec["clean_${tomcat7::sites_dir}/${contextPath}"], and then Exec["clean_${tomcat7::sites_dir}/${contextPath}"] would be notified AFTER my code.

This would allow my code a chance to notify the load balancer and pause before cleaning and restarting tomcat. I don't want the special load-balancer code in tomcat::war, because it is unique to 'mywebapp'. 

Is there a way to do this at all?

Felix Frank

unread,
Nov 27, 2013, 5:25:55 AM11/27/13
to puppet...@googlegroups.com
Hi,

I think you're overcomplicating.

I suppose you have something like

class mywebapp {
tomcat7::war { "mywebapp": ... }
}

You can wrench your code inbetween if you slightly modify your defined
type like so:

define tomcat7::war(...) {
file { "tomcat7-war-file-$name":
path => "${tomcat7::sites_dir}/${destFile}",
notify => Exec["clean-tomcat7-war-$name"],
}
exec { "clean-tomcat7-war-$name":
...
}
}

to make the interface more transparent. Then add to class mywebapp:

exec { "notify-loadbalancer":
command => ...
suscribe => File["tomcat7-war-file-mywebapp"],
before => Exec["clean-tomcat7-war-mywebapp"],
}

This is not exactly clean design, of course (use this pattern in enough
places and you've got a maintenance nightmare right on hand).

If you *want* to make it clean, you will have little choice but to
include the code in tomcat7::war after all, along with a new parameter
to explicitly enable it (e.g. $do_notify_loadbalancer = false).

If a compromise is acceptable, you may get away with making it somewhat
generic like

define tomcat7::war(
...
$pre_cleanup_hook = "") {

...

if $pre_cleanup_hook {
exec { "tomcat7-war-pch-$name":
command => "$pre_cleanup_hook",
subscribe => File[...],
before => Exec[...],
}
}
...
}

HTH,
Felix
Reply all
Reply to author
Forward
0 new messages