Home

Awesome

What?

While doing some prototype work of a new MCollective agent to manage Puppet version 3 I needed to write a bunch of code to wrap the lock files, json files, pid files and yaml files that makes up the combined status of the Puppet Agent.

The object of this library is to make it easier for external processes like monitoring scripts, mcollective etc to interface with all the locks and status files for the Puppet Agent. Puppet sometimes change how it behaves wrt these files so this API is versioned and returns a version specific manager instance that represents a consistant API. Currently it understands Puppet 2.7.x and Puppet 3.0.x.

Additionally it interacts directly with the files in question and not via the Puppet libraries so it should be a bit faster, I do not know the Puppet libraries around locking and these files using the Puppet libraries directly might be isolated enough that there could be scope to DRY this up.

It does require the puppet libraries and fetches the settings from the Puppet library. At present it makes no effort to ensure it parses the right file or right section out of the file, this is a major short coming but I am not familiar enough with the Puppet settings classes to figure out the run_mode and so forth in the time I had.

This is a work in progress specifically a few outstanding questions remain:

Available Methods?

Using?

You can obtain basic status, this is a convenience wrapper around all the status behavior in the library:

>> require 'puppet_agent_mgr'
=> true
>> m = PuppetAgentMgr.manager
=> #<PuppetAgentMgr::V2::Manager:0x7fe2edf76070>
>> m.status
{:status=>"disabled", :applying=>false, :lastrun=>1347897634,
 :message=>"Currently disabled; last completed run 18 hours 59 minutes 17 seconds ago",
 :disable_message=>"", :enabled=>false, :since_lastrun=>68357, :daemon_present=>false}

You can enable/disable:

>> m.enabled?
false
>> m.enable!
=> 1
>> m.enabled?
=> true

You can find out if there is currently a daemon in the process list and if it's busy applying a catalog:

>> m.daemon_present?
=> false
>> m.applying?
=> false
>> m.idling?
=> false

You can find out when last it applied a catalog:

>> m.lastrun
=> 1347897634
>> m.since_lastrun
=> 68615

And you can load the summary, it will make some effort to normalize the data so you'll always get at least some sanely structured content:

>> m.load_summary
=> {"events"=>{"total"=>0, "success"=>0, "failure"=>0},
    "resources"=>{"restarted"=>0, "total"=>7, "failed"=>0, "skipped"=>6, "scheduled"=>0,
                  "failed_to_restart"=>0, "changed"=>0, "out_of_sync"=>0},
    "changes"=>{"total"=>0}, "time"=>{"total"=>0.040585, "last_run"=>1347897634,
                                      "config_retrieval"=>0.040399, "filebucket"=>0.000186},
    "version"=>{"puppet"=>"2.7.17", "config"=>1347897634}}

Puppet records which resources it is managing, this information is available:

>> m.managed_resources_count
=> 569
>> m.managed_resources
=> [ .........]
>> m.managing_resource?("File[/srv/www]")
=> false

And finally you can kick off a run:

>> m.runonce :foreground_run => true
=> "..full puppet run output here"
>> m.runonce
=> ""

You can limit it to specific tags:

>> m.runonce(:tags => ["foo", "bar"])
=> ""

You can do a noop run:

>> m.runonce(:noop => true)
=> ""

And specify an environment:

>> m.runonce(:environment => "development")
=> ""

And even a custom master and port:

>> m.runonce(:server => "dev-puppet.example.com:1234")
=> ""

You can force splaying:

>> m.runonce(:splay => true)
=> ""

...or force disable it

>> m.runonce(:splay => false)
=> ""

...with a custom time limit

>> m.runonce(:splay => true, :splaylimit=100)
=> ""

If you have an application that wants to do its own executing of puppet but just want to use this lib to do option parsing etc you can get the run mode and command line options by passing :options_only => true, the first argument is one of :run_in_background, :signal_running_daemon, :run_in_background:

>> p.runonce!(:options_only => true, :noop => true, :environment => "production")
=> [:run_in_background, ["--noop", "--environment production"]]

When doing noop, tags limited, specific host or specific environment runs it will raise an exception if the daemon is already present as the only option available then is to trigger an immediate run

Contact?

R.I.Pienaar / rip@devco.net / @ripienaar / http://devco.net/