[Pkg-puppet-devel] [SCM] Puppet packaging for Debian branch, upstream, updated. 2.6.1rc1-141-gcdb2b90
James Turnbull
james at lovedthanlost.net
Mon Aug 16 12:47:45 UTC 2010
The following commit has been merged in the upstream branch:
commit 97936c6d3fa3950d22266679b65d4a6877008a74
Author: Rein Henrichs <rein at puppetlabs.com>
Date: Mon Jun 7 15:45:45 2010 -0700
[#3921] Add facts_terminus setting to Puppet settings
* defaults to "facter"
* no longer set the facts terminus class in for puppetmaster, use
setting instead
Implements an abstract CouchDB terminus and a concrete CouchDB terminus
used to store node facts. Node facts are stored in a "node" document as
the "facts" attribute. This node document may also be used by other
couchdb termini that store node-related information. It is recommended
to use a separate document (or documents) to store large data structures
like catalogs, linking them to their related node document using
embedded ids.
This implementation depends on the "couchrest" gem.
diff --git a/lib/puppet/application/puppetd.rb b/lib/puppet/application/puppetd.rb
index 8b07c90..ca5a0d4 100644
--- a/lib/puppet/application/puppetd.rb
+++ b/lib/puppet/application/puppetd.rb
@@ -215,9 +215,11 @@ Puppet::Application.new(:puppetd) do
# You can still override this on the command-line with, e.g., :compiler.
Puppet[:catalog_terminus] = :rest
+ # Override the default.
+ Puppet[:facts_terminus] = :facter
+
Puppet::Resource::Catalog.cache_class = :yaml
- Puppet::Node::Facts.terminus_class = :facter
# We need tomake the client either way, we just don't start it
# if --no-client is set.
diff --git a/lib/puppet/application/puppetmasterd.rb b/lib/puppet/application/puppetmasterd.rb
index 9b0bf30..6e69445 100644
--- a/lib/puppet/application/puppetmasterd.rb
+++ b/lib/puppet/application/puppetmasterd.rb
@@ -150,9 +150,6 @@ Puppet::Application.new(:puppetmasterd) do
Puppet.settings.use :main, :puppetmasterd, :ssl
- # A temporary solution, to at least make the master work for now.
- Puppet::Node::Facts.terminus_class = :yaml
-
# Cache our nodes in yaml. Currently not configurable.
Puppet::Node.cache_class = :yaml
diff --git a/lib/puppet/defaults.rb b/lib/puppet/defaults.rb
index c815133..0ae0553 100644
--- a/lib/puppet/defaults.rb
+++ b/lib/puppet/defaults.rb
@@ -151,6 +151,7 @@ module Puppet
:node_terminus => ["plain", "Where to find information about nodes."],
:catalog_terminus => ["compiler", "Where to get node catalogs. This is useful to change if, for instance,
you'd like to pre-compile catalogs and store them in memcached or some other easily-accessed store."],
+ :facts_terminus => ["facter", "Where to get node facts."],
:httplog => { :default => "$logdir/http.log",
:owner => "root",
:mode => 0640,
@@ -694,6 +695,10 @@ module Puppet
and other environments normally use ``debug``."]
)
+ setdefaults(:couchdb,
+ :couchdb_url => ["http://127.0.0.1:5984/puppet", "The url where the puppet couchdb database will be created"]
+ )
+
setdefaults(:transaction,
:tags => ["", "Tags to use to find resources. If this is set, then
only resources tagged with the specified tags will be applied.
diff --git a/lib/puppet/feature/base.rb b/lib/puppet/feature/base.rb
index aac04f2..a6111d8 100644
--- a/lib/puppet/feature/base.rb
+++ b/lib/puppet/feature/base.rb
@@ -31,3 +31,6 @@ Puppet.features.add(:rrd, :libs => ["RRDtool"])
# We have OpenSSL
Puppet.features.add(:openssl, :libs => ["openssl"])
+
+# We have CouchDB
+Puppet.features.add(:couchdb, :libs => ["couchrest"])
diff --git a/lib/puppet/indirector/couch.rb b/lib/puppet/indirector/couch.rb
new file mode 100644
index 0000000..6818ee8
--- /dev/null
+++ b/lib/puppet/indirector/couch.rb
@@ -0,0 +1,76 @@
+raise "Couch terminus not supported without couchrest gem" unless Puppet.features.couchdb?
+
+require 'couchrest'
+class Puppet::Indirector::Couch < Puppet::Indirector::Terminus
+
+ # The CouchRest database instance. One database instance per Puppet runtime
+ # should be sufficient.
+ #
+ def self.db; @db ||= CouchRest.database! Puppet[:couchdb_url] end
+ def db; self.class.db end
+
+ def find(request)
+ attributes_of get(request)
+ end
+
+ # Create or update the couchdb document with the request's data hash.
+ #
+ def save(request)
+ raise ArgumentError, "PUT does not accept options" unless request.options.empty?
+ update(request) || create(request)
+ end
+
+ private
+
+ # RKH:TODO: Do not depend on error handling, check if the document exists
+ # first. (Does couchrest support this?)
+ #
+ def get(request)
+ db.get(id_for(request))
+ rescue RestClient::ResourceNotFound
+ Puppet.debug "No couchdb document with id: #{id_for(request)}"
+ return nil
+ end
+
+ def update(request)
+ doc = get request
+ return unless doc
+ doc.merge!(hash_from(request))
+ doc.save
+ return true
+ end
+
+ def create(request)
+ db.save_doc hash_from(request)
+ end
+
+ # The attributes hash that is serialized to CouchDB as JSON. It includes
+ # metadata that is used to help aggregate data in couchdb. Add
+ # model-specific attributes in subclasses.
+ #
+ def hash_from(request)
+ {
+ "_id" => id_for(request),
+ "puppet_type" => document_type_for(request)
+ }
+ end
+
+ # The couchdb response stripped of metadata, used to instantiate the model
+ # instance that is returned by save.
+ #
+ def attributes_of(response)
+ response && response.reject{|k,v| k =~ /^(_rev|puppet_)/ }
+ end
+
+ def document_type_for(request)
+ request.indirection_name
+ end
+
+ # The id used to store the object in couchdb. Implemented in subclasses.
+ #
+ def id_for(request)
+ raise NotImplementedError
+ end
+
+end
+
diff --git a/lib/puppet/indirector/facts/couch.rb b/lib/puppet/indirector/facts/couch.rb
new file mode 100644
index 0000000..522fe33
--- /dev/null
+++ b/lib/puppet/indirector/facts/couch.rb
@@ -0,0 +1,31 @@
+require 'puppet/node/facts'
+require 'puppet/indirector/couch'
+class Puppet::Node::Facts::Couch < Puppet::Indirector::Couch
+
+ # Return the facts object or nil if there is no document
+ def find(request)
+ doc = super
+ doc ? model.new(doc['_id'], doc['facts']) : nil
+ end
+
+ private
+
+ # Facts values are stored to the document's 'facts' attribute. Hostname is
+ # stored to 'name'
+ #
+ def hash_from(request)
+ super.merge('facts' => request.instance.values)
+ end
+
+ # Facts are stored to the 'node' document.
+ def document_type_for(request)
+ 'node'
+ end
+
+ # The id used to store the object in couchdb.
+ def id_for(request)
+ request.key.to_s
+ end
+
+end
+
diff --git a/lib/puppet/node/facts.rb b/lib/puppet/node/facts.rb
index dca435c..a8761f8 100755
--- a/lib/puppet/node/facts.rb
+++ b/lib/puppet/node/facts.rb
@@ -16,8 +16,7 @@ class Puppet::Node::Facts
end
end
- # Use the node source as the indirection terminus.
- indirects :facts, :terminus_class => :facter, :extend => NodeExpirer
+ indirects :facts, :terminus_setting => :facts_terminus, :extend => NodeExpirer
attr_accessor :name, :values
@@ -49,6 +48,11 @@ class Puppet::Node::Facts
end
end
+ def ==(other)
+ return false unless self.name == other.name
+ strip_internal == other.send(:strip_internal)
+ end
+
private
# Add internal data to the facts for storage.
diff --git a/spec/fixtures/yaml/test.local.yaml b/spec/fixtures/yaml/test.local.yaml
new file mode 100644
index 0000000..194d8aa
--- /dev/null
+++ b/spec/fixtures/yaml/test.local.yaml
@@ -0,0 +1,16 @@
+--- !ruby/object:Puppet::Node::Facts
+ expiration: 2010-06-07 19:15:36.519351 -07:00
+ name: test.local
+ values:
+ sp_number_processors: "2"
+ kernelmajversion: "10.3"
+ kernelversion: 10.3.1
+ sp_secure_vm: secure_vm_enabled
+ ps: ps auxwww
+ macosx_productversion_major: "10.6"
+ hostname: test
+ !ruby/sym _timestamp: Mon Jun 07 18:45:36 -0700 2010
+ facterversion: 1.5.7
+ sp_packages: "1"
+ timezone: PDT
+ environment: production
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index e03cc98..e1e7ea6 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -23,6 +23,7 @@ require 'spec/autorun'
# So everyone else doesn't have to include this base constant.
module PuppetSpec
+ FIXTURE_DIR = File.join(dir = File.expand_path(File.dirname(__FILE__)), "fixtures") unless defined?(FIXTURE_DIR)
end
# load any monkey-patches
diff --git a/spec/unit/application/puppetd.rb b/spec/unit/application/puppetd.rb
index 88772b2..338eb8e 100755
--- a/spec/unit/application/puppetd.rb
+++ b/spec/unit/application/puppetd.rb
@@ -173,6 +173,7 @@ describe "puppetd" do
Puppet.stubs(:info)
FileTest.stubs(:exists?).returns(true)
Puppet.stubs(:[])
+ Puppet.stubs(:[]=)
Puppet.stubs(:[]).with(:libdir).returns("/dev/null/lib")
Puppet.settings.stubs(:print_config?)
Puppet.settings.stubs(:print_config)
@@ -312,8 +313,8 @@ describe "puppetd" do
@puppetd.run_setup
end
- it "should tell the facts to use facter" do
- Puppet::Node::Facts.expects(:terminus_class=).with(:facter)
+ it "should change the facts_terminus setting to 'facter'" do
+ Puppet.expects(:[]=).with(:facts_terminus, :facter)
@puppetd.run_setup
end
diff --git a/spec/unit/application/puppetmasterd.rb b/spec/unit/application/puppetmasterd.rb
index f522fcc..f7fe571 100644
--- a/spec/unit/application/puppetmasterd.rb
+++ b/spec/unit/application/puppetmasterd.rb
@@ -182,12 +182,6 @@ describe "PuppetMaster" do
@puppetmasterd.run_setup
end
- it "should set node facst terminus to yaml" do
- Puppet::Node::Facts.expects(:terminus_class=).with(:yaml)
-
- @puppetmasterd.run_setup
- end
-
it "should cache class in yaml" do
Puppet::Node.expects(:cache_class=).with(:yaml)
diff --git a/spec/unit/indirector/facts/couch.rb b/spec/unit/indirector/facts/couch.rb
new file mode 100644
index 0000000..0884012
--- /dev/null
+++ b/spec/unit/indirector/facts/couch.rb
@@ -0,0 +1,98 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+require 'puppet/node/facts'
+
+describe "Puppet::Node::Facts::Couch" do
+ confine "couchrest gem is missing; cannot test couch terminus" => Puppet.features.couchdb?
+ require 'puppet/indirector/facts/couch' if Puppet.features.couchdb?
+
+ before do
+ @mock_db = mock('couch db')
+ mock_document = CouchRest::Document.new(:_id => fake_request.key, :facts => fake_request.values)
+ mock_document.stubs(:database).returns(@mock_db)
+ @mock_db.stubs(:get).with(fake_request.key).returns(mock_document)
+ Puppet::Node::Facts::Couch.stubs(:db).returns(@mock_db)
+ end
+
+ subject { Puppet::Node::Facts::Couch }
+
+ describe "#find" do
+ describe "when the node document exists" do
+ it "should find the request by key" do
+ @mock_db.expects(:get).with(fake_request.key).returns({'_id' => fake_request.key, 'facts' => fake_request.instance.values})
+ subject.new.find(fake_request).should == fake_request.instance
+ end
+ end
+
+ describe "when the node document does not exist" do
+ before do
+ @mock_db.expects(:get).
+ with(fake_request.key).
+ raises(RestClient::ResourceNotFound)
+ end
+
+ it "should return nil" do
+ subject.new.find(fake_request).should be_nil
+ end
+
+ it "should send Puppet a debug message" do
+ Puppet.expects(:debug).with("No couchdb document with id: test.local")
+ subject.new.find(fake_request).should be_nil
+ end
+
+ end
+ end
+
+ describe "#save" do
+ describe "with options" do
+ subject do
+ lambda { Puppet::Node::Facts::Couch.new.save(fake_request([1])) }
+ end
+
+ it { should raise_error(ArgumentError, "PUT does not accept options") }
+ end
+
+ it "should save the json to the CouchDB database" do
+ @mock_db.expects(:save_doc).at_least_once.returns({'ok' => true })
+ subject.new.save(fake_request)
+ end
+
+ describe "when the document exists" do
+ before do
+ @doc = CouchRest::Document.new(:_id => fake_request.key, :facts => fake_request.instance.values)
+ @mock_db.expects(:get).with(fake_request.key).returns(@doc)
+ end
+
+ it "saves the document" do
+ @doc.expects(:save)
+ subject.new.save(fake_request)
+ end
+
+ end
+
+ describe "when the document does not exist" do
+ before do
+ @mock_db.expects(:get).
+ with(fake_request.key).
+ raises(RestClient::ResourceNotFound)
+ end
+
+ it "saves the document" do
+ @mock_db.expects(:save_doc)
+ subject.new.save(fake_request)
+ end
+
+ end
+
+ end
+
+ def fake_request(options={})
+ facts = YAML.load_file(File.join(PuppetSpec::FIXTURE_DIR, 'yaml', 'test.local.yaml'))
+ Struct.new(:instance, :key, :options).new(facts, facts.name, options)
+ end
+ private :fake_request
+
+end
+
--
Puppet packaging for Debian
More information about the Pkg-puppet-devel
mailing list