summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuke Kanies <luke@madstop.com>2008-07-15 21:34:33 -0500
committerLuke Kanies <luke@madstop.com>2009-02-06 18:08:39 -0600
commit1afb8216f166dc375dec5778890985a6635aa54f (patch)
tree6e2b56b781622ab2eebdf63903dabdd3ea659e38
parent2afff60abe430dc1e2660fa82807e131e1dc71aa (diff)
downloadpuppet-1afb8216f166dc375dec5778890985a6635aa54f.tar.gz
puppet-1afb8216f166dc375dec5778890985a6635aa54f.tar.xz
puppet-1afb8216f166dc375dec5778890985a6635aa54f.zip
Adding the first bits of an Agent class.
This class replaces the existing, all-knowing Client::Master class, and it will hopefully be more reasonable in scope. Signed-off-by: Luke Kanies <luke@madstop.com>
-rw-r--r--lib/puppet/agent.rb107
-rwxr-xr-xspec/unit/agent.rb117
2 files changed, 224 insertions, 0 deletions
diff --git a/lib/puppet/agent.rb b/lib/puppet/agent.rb
new file mode 100644
index 000000000..095a2942b
--- /dev/null
+++ b/lib/puppet/agent.rb
@@ -0,0 +1,107 @@
+class Puppet::Agent
+ # enable/disable
+
+ # storage
+
+ # locking
+
+ # config timeout
+
+ # setclasses
+
+ # Retrieve our catalog, possibly from the cache.
+ def catalog
+ unless c = Puppet::Node::Catalog.find(name, :use_cache => (!Puppet[:ignorecache]))
+ raise "Could not retrieve catalog"
+ end
+ c.host_config = true
+ c
+ end
+
+ def initialize(options = {})
+ options.each do |param, value|
+ if respond_to?(param.to_s + "=")
+ send(param.to_s + "=", value)
+ else
+ raise ArgumentError, "%s is not a valid option for Agents" % param
+ end
+ end
+ end
+
+ def name
+ Puppet[:certname]
+ end
+
+ # Is this a onetime agent?
+ attr_accessor :onetime
+ def onetime?
+ onetime
+ end
+
+ def run
+ splay()
+
+ download_plugins()
+
+ upload_facts()
+
+ catalog = download_catalog()
+
+ apply(catalog)
+ end
+
+ # Sleep for a random but consistent period of time if configured to
+ # do so.
+ def splay
+ return unless Puppet[:splay]
+
+ time = splay_time()
+
+ Puppet.info "Sleeping for %s seconds (splay is enabled)" % time
+ sleep(time)
+ end
+
+ def start
+# # Create our timer. Puppet will handle observing it and such.
+# timer = Puppet.newtimer(
+# :interval => Puppet[:runinterval],
+# :tolerance => 1,
+# :start? => true
+# ) do
+# begin
+# self.runnow if self.scheduled?
+# rescue => detail
+# puts detail.backtrace if Puppet[:trace]
+# Puppet.err "Could not run client; got otherwise uncaught exception: %s" % detail
+# end
+# end
+#
+# # Run once before we start following the timer
+# self.runnow
+ end
+
+ def download_catalog
+ # LAK:NOTE This needs to handle skipping cached configs
+ # if configured to do so.
+ Puppet::Node::Catalog.find name
+ end
+
+ def download_plugins
+ raise "Plugin downloads not implemented"
+ end
+
+ def upload_facts
+ end
+
+ def splay_time
+ limit = Integer(Puppet[:splaylimit])
+
+ # Pick a splay time and then cache it.
+ unless time = Puppet::Util::Storage.cache(:configuration)[:splay_time]
+ time = rand(limit)
+ Puppet::Util::Storage.cache(:configuration)[:splay_time] = time
+ end
+
+ time
+ end
+end
diff --git a/spec/unit/agent.rb b/spec/unit/agent.rb
new file mode 100755
index 000000000..63914c3a3
--- /dev/null
+++ b/spec/unit/agent.rb
@@ -0,0 +1,117 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../spec_helper'
+
+require 'puppet/agent'
+
+describe Puppet::Agent do
+ it "should have a start method" do
+ Puppet::Agent.new.should respond_to(:start)
+ end
+
+ it "should be able to download a catalog" do
+ Puppet::Agent.new.should respond_to(:download_catalog)
+ end
+
+ it "should set its name to the certname" do
+ Puppet.settings.expects(:value).with(:certname).returns "myname"
+ Puppet::Agent.new.name.should == "myname"
+ end
+
+ it "should be configurable to only run once" do
+ Puppet::Agent.new(:onetime => true).should be_onetime
+ end
+
+ it "should be able to splay" do
+ Puppet::Agent.new.should respond_to(:splay)
+ end
+
+ describe "when splaying" do
+ before do
+ @agent = Puppet::Agent.new
+ @agent.stubs(:name).returns "foo"
+
+ Puppet.settings.stubs(:value).with(:splaylimit).returns "1800"
+ Puppet.settings.stubs(:value).with(:splaylimit).returns "1800"
+ end
+
+ it "should do nothing if splay is disabled" do
+ Puppet.settings.expects(:value).with(:splay).returns false
+ @agent.expects(:sleep).never
+ @agent.splay
+ end
+
+ it "should sleep if splay is enabled" do
+ Puppet.settings.expects(:value).with(:splay).returns true
+ @agent.expects(:sleep)
+ @agent.splay
+ end
+
+ it "should log when splay is enabled" do
+ Puppet.settings.expects(:value).with(:splay).returns true
+ @agent.stubs(:sleep)
+
+ Puppet.expects(:info)
+
+ @agent.splay
+ end
+ end
+
+ it "should default to using splay time"
+
+ it "should be able to ignore splay time"
+
+ it "should be able to retrieve facts"
+
+ describe "when running" do
+ it "should download plugins"
+
+ it "should download facts"
+
+ it "should retrieve the facts and save them to the server"
+
+ it "should retrieve the catalog"
+
+ it "should apply the catalog"
+ end
+
+ describe "when retrieving the catalog" do
+ before do
+ @agent = Puppet::Agent.new
+ @agent.stubs(:name).returns "me"
+
+ @catalog = stub("catalog", :host_config= => true)
+ end
+
+ it "should use the Catalog class to find the catalog" do
+ Puppet::Node::Catalog.expects(:find).with { |name, options| name == "me" }.returns @catalog
+
+ @agent.catalog.should equal(@catalog)
+ end
+
+ it "should default to allowing use of the cache" do
+ Puppet::Node::Catalog.expects(:find).with { |name, options| options[:use_cache] == true }.returns @catalog
+
+ @agent.catalog
+ end
+
+ it "should ignore a cached catalog if configured to do so" do
+ Puppet.settings.expects(:value).with(:ignorecache).returns true
+ Puppet::Node::Catalog.expects(:find).with { |name, options| options[:use_cache] == false }.returns @catalog
+
+ @agent.catalog
+ end
+
+ it "should mark the catalog as a host catalog" do
+ @catalog.expects(:host_config=).with true
+ Puppet::Node::Catalog.expects(:find).returns @catalog
+
+ @agent.catalog
+ end
+
+ it "should fail if a catalog can not be retrieved" do
+ Puppet::Node::Catalog.expects(:find).returns nil
+ lambda { @agent.catalog }.should raise_error(RuntimeError)
+ end
+ end
+end