Help: Need to create a puppet class that encompasses the functionality of base.rb and parsedfile.rb to implement a complete monit provider

46 views
Skip to first unread message

Manish Chakravarty

unread,
May 16, 2009, 8:34:28 AM5/16/09
to puppe...@googlegroups.com
This is going to be a long mail......

My requirement:
service { "thingie":
 provider   => "monit",
 start      => "/opt/thingie/start-stop-thingie start",
 stop       => "/opt/thingie/start-stop-thingie stop",
 pidfile    => "/var/thingie/pidfile.pid",
 monitextra => "group assorted_thingies\nif memory > 120 Mb then restart",
 require    => Package["thingie"],
 subscribe  => File["/etc/thingie.conf"]
}


would produce something like this in /etc/monit.d/thingie

check process thingie with pidfile /var/thingie/pidfile.pid
 start program = "/opt/thingie/start-stop-thingie start"
 stop program = "/opt/thingie/start-stop-thingie stop"
 group assorted_thingies
 if memory > 120 Mb then restart


and when it needs to stop the service will start it with

monit start thingie
or
monit stop thingie


My monit.rb type/provider:
module Puppet
    newtype(:monit) do
    @doc = "Manages monitrc"

    ensurable

    newparam(:processName, :namevar => true ) do
        desc "The process  to manage eg: mongrel_8001"
        isnamevar
    munge do |value|
        value = "check process " + value
    end
    end

    newproperty(:pidfile) do
        desc "location of the PID file"
    munge do |value|
        value = "with pidfile " + value
    end
    end

and so on.......

And the required parsedfile.rb
require 'puppet/provider/parsedfile'

Puppet::Type.type(:monit).provide(:parsed,
                    :parent => Puppet::Provider::ParsedFile,
                    :default_target => '',
                    :filetype => :flat
                    ) do

        desc "The monit provider that uses the ParsedFile class"
        text_line :comment, :match => /^#/;
        text_line :blank, :match => /^\s*$/;

        record_line :parsed, :fields => %w{name pidfile group startprogram stopprogram extracode}
end


Service type implementation:
Puppet::Type.type(:service).provide :monit, :parent => :base do
    desc "A puppet type which manages monit."


    commands :monit => "/usr/sbin/monit", :status => "status", :startall => "start all", :stopall => "stop all"

    def restartcmd
        [command(:monit), :restart, @resource[:name]]
    end

    def startcmd
        [command(:monit), :enable, @resource[:name]]
    end

    def status
    [command(:monit), :status, @resource[:name]]
    end

    def stopcmd
        [command(:monit), :disable, @resource[:name]]
    end

    def startallcmd
    [command(:monit), :startall ]
    end

    def stopallcmd
    [command(:monit), :stopall]
    end
end



Question:
How do I merge the three pieces so that I am able fulfill my requirements that I outlined earlier?

--
Manish Chakravarty
http://manish-chaks.livejournal.com/

James Turnbull

unread,
May 16, 2009, 9:03:31 AM5/16/09
to puppe...@googlegroups.com

On Sat, 16 May 2009 18:04:28 +0530, Manish Chakravarty
<manis...@gmail.com> wrote:
> This is going to be a long mail......
>
> *My requirement:
> **service { "thingie":

> provider => "monit",
> start => "/opt/thingie/start-stop-thingie start",
> stop => "/opt/thingie/start-stop-thingie stop",
> pidfile => "/var/thingie/pidfile.pid",
> monitextra => "group assorted_thingies\nif memory > 120 Mb then
restart",
> require => Package["thingie"],
> subscribe => File["/etc/thingie.conf"]

I still don't understand why you want to do this. Why embed the
functionality of the service type into another type? Just use a service
resource. I think you're going about this in entirely the wrong way.

Regards

James Turnbull

--
Author of:
* Pro Linux Systems Administration
(http://www.amazon.com/gp/product/1430219122/)
* Pulling Strings with Puppet
(http://www.amazon.com/gp/product/1590599780/)
* Pro Nagios 2.0
(http://www.amazon.com/gp/product/1590596099/)
* Hardening Linux
(http://www.amazon.com/gp/product/1590594444/)

Manish Chakravarty

unread,
May 16, 2009, 10:06:18 AM5/16/09
to Puppet Developers


On May 16, 6:03 pm, James Turnbull <ja...@lovedthanlost.net> wrote:
> On Sat, 16 May 2009 18:04:28 +0530, Manish Chakravarty
>
> <manishch...@gmail.com> wrote:
> > This is going to be a long mail......
>
> > *My requirement:
> > **service { "thingie":
> >  provider   => "monit",
> >  start      => "/opt/thingie/start-stop-thingie start",
> >  stop       => "/opt/thingie/start-stop-thingie stop",
> >  pidfile    => "/var/thingie/pidfile.pid",
> >  monitextra => "group assorted_thingies\nif memory > 120 Mb then
> restart",
> >  require    => Package["thingie"],
> >  subscribe  => File["/etc/thingie.conf"]
>
> I still don't understand why you want to do this.  Why embed the
> functionality of the service type into another type?  Just use a service
> resource.  I think you're going about this in entirely the wrong way.
We need it to be a service provider and we want to put all the code in
one place as demonstrated in my requirement code snippet.
If you have a better idea in mind, please do post it... ( Posting a
sample site.pp snippet which is what I am looking for.. it'd be
*terrific* if you can do that )

Best,
Manish Chakravarty

brandorr

unread,
May 16, 2009, 10:25:33 AM5/16/09
to Puppet Developers
James,

Let me explain what Manish is trying to do. Basically he has been
asked to write a service provider for monit. In this case we speced it
out so that the service provider can enable and disable the service,
in addition to just start/stop/restart. (Other service providers
provide this functionality)

Unfortunately two things complicate this:
1) Monit doesn't have precanned service definitions that we can just
activate or symlink to. (Thus the need to generate configs)
2) We can't inherit from both base.rb and parsefile.rb, so we are
taking this approach of using a wrapper class

Cheers,
Brian

James Turnbull

unread,
May 16, 2009, 10:50:01 AM5/16/09
to puppe...@googlegroups.com

On Sat, 16 May 2009 07:06:18 -0700 (PDT), Manish Chakravarty
<manis...@gmail.com> wrote:

> We need it to be a service provider and we want to put all the code in
> one place as demonstrated in my requirement code snippet.
> If you have a better idea in mind, please do post it... ( Posting a
> sample site.pp snippet which is what I am looking for.. it'd be
> *terrific* if you can do that )
>

I obviously don't get why it needs to be a service provider.

What's wrong with:

monit { "blah":


start => "/opt/thingie/start-stop-thingie start",
stop => "/opt/thingie/start-stop-thingie stop",
pidfile => "/var/thingie/pidfile.pid",
monitextra => "group assorted_thingies\nif memory > 120 Mb then restart",
require => Package["thingie"],
}

service { "monit":
running => true,
subscribe => Monit[blah]

Brian Gupta

unread,
May 16, 2009, 5:46:12 PM5/16/09
to puppe...@googlegroups.com

Obviously it doesn't need to be. However, we are choosing a bit of complexity in the back end in exchange for a simplified/consolidated puppet DSL code block.

On May 16, 2009 10:50 AM, "James Turnbull" <ja...@lovedthanlost.net> wrote:

On Sat, 16 May 2009 07:06:18 -0700 (PDT), Manish Chakravarty <manis...@gmail.com> wrote: > We ...

I obviously don't get why it needs to be a service provider.

What's wrong with:

monit { "blah":

start => "/opt/thingie/start-stop-thingie start", stop => "/opt/thingie/start-stop-thin...

service { "monit":
       running => true,
       subscribe => Monit[blah]

} Regards James Turnbull -- Author of: * Pro Linux Systems Administration (http://www.amazon.com...

Peter Meier

unread,
May 17, 2009, 7:57:30 AM5/17/09
to puppe...@googlegroups.com
Hi

> Obviously it doesn't need to be. However, we are choosing a bit of
> complexity in the back end in exchange for a simplified/consolidated puppet
> DSL code block.

you could combine these two afterwards with a simple define. So at the
end you're still only calling one define which is calling 2 providers.

cheers pete

Luke Kanies

unread,
May 20, 2009, 12:04:13 PM5/20/09
to puppe...@googlegroups.com
On May 16, 2009, at 9:25 AM, brandorr wrote:

>
> James,
>
> Let me explain what Manish is trying to do. Basically he has been
> asked to write a service provider for monit. In this case we speced it
> out so that the service provider can enable and disable the service,
> in addition to just start/stop/restart. (Other service providers
> provide this functionality)
>
> Unfortunately two things complicate this:
> 1) Monit doesn't have precanned service definitions that we can just
> activate or symlink to. (Thus the need to generate configs)
> 2) We can't inherit from both base.rb and parsefile.rb, so we are
> taking this approach of using a wrapper class


But wouldn't the monit service configurations be normal files,
essentially, rather than collections of records?

ParsedFile is only useful if a file is a list of records, like /etc/
passwd, /etc/hosts, things like that. If your file is essentially
just a shell script, then using a simpler system -- such as requiring
the user to use template(...) in the language, or specifying a source
-- is much better.

Probably the best approach is to use generate() to create a file
instance with its source set appropriately for the service, and then
specify that the service requires the file.

This is still complicated, a bit, but much better than what was
otherwise proposed.

--
The cure for writer's cramp is writer's block.
-- Inigo DeLeon
---------------------------------------------------------------------
Luke Kanies | http://reductivelabs.com | http://madstop.com

Reply all
Reply to author
Forward
0 new messages