summaryrefslogtreecommitdiffstats
path: root/lib/puppet
diff options
context:
space:
mode:
Diffstat (limited to 'lib/puppet')
-rw-r--r--lib/puppet/defaults.rb8
-rw-r--r--lib/puppet/provider/confine.rb88
-rw-r--r--lib/puppet/provider/confine/exists.rb22
-rw-r--r--lib/puppet/provider/confine/facter.rb37
-rw-r--r--lib/puppet/provider/confine/false.rb19
-rw-r--r--lib/puppet/provider/confine/feature.rb17
-rw-r--r--lib/puppet/provider/confine/true.rb20
-rw-r--r--lib/puppet/provider/confine_collection.rb37
-rw-r--r--lib/puppet/provider/confiner.rb2
-rw-r--r--lib/puppet/reference/providers.rb2
-rw-r--r--lib/puppet/util/storage.rb4
-rw-r--r--lib/puppet/util/variables.rb38
12 files changed, 183 insertions, 111 deletions
diff --git a/lib/puppet/defaults.rb b/lib/puppet/defaults.rb
index df2fb9425..57299b7e7 100644
--- a/lib/puppet/defaults.rb
+++ b/lib/puppet/defaults.rb
@@ -505,9 +505,11 @@ module Puppet
# Central fact information.
self.setdefaults(:main,
- :factpath => ["$vardir/facts",
- "Where Puppet should look for facts. Multiple directories should
- be colon-separated, like normal PATH variables."],
+ :factpath => {:default => "$vardir/facts",
+ :desc => "Where Puppet should look for facts. Multiple directories should
+ be colon-separated, like normal PATH variables.",
+ :call_on_define => true, # Call our hook with the default value, so we always get the value added to facter.
+ :hook => proc { |value| Facter.search(value) if Facter.respond_to?(:search) }},
:factdest => ["$vardir/facts",
"Where Puppet should store facts that it pulls down from the central
server."],
diff --git a/lib/puppet/provider/confine.rb b/lib/puppet/provider/confine.rb
index 227c923e6..35b80fdcf 100644
--- a/lib/puppet/provider/confine.rb
+++ b/lib/puppet/provider/confine.rb
@@ -5,85 +5,73 @@ require 'puppet/util'
class Puppet::Provider::Confine
include Puppet::Util
- attr_reader :test, :values, :fact
+ @tests = {}
- # Mark that this confine is used for testing binary existence.
- attr_accessor :for_binary
- def for_binary?
- for_binary
+ class << self
+ attr_accessor :name
end
- def exists?(value)
- if for_binary?
- return false unless value = binary(value)
- end
- value and FileTest.exist?(value)
- end
+ def self.inherited(klass)
+ name = klass.to_s.split("::").pop.downcase.to_sym
+ raise "Test %s is already defined" % name if @tests.include?(name)
+
+ klass.name = name
- # Are we a facter comparison?
- def facter?
- defined?(@facter)
+ @tests[name] = klass
end
- # Retrieve the value from facter
- def facter_value
- unless defined?(@facter_value) and @facter_value
- @facter_value = Facter.value(@fact).to_s.downcase
+ def self.test(name)
+ unless @tests[name]
+ begin
+ require "puppet/provider/confine/%s" % name
+ rescue LoadError => detail
+ unless detail.to_s.include?("no such file")
+ warn "Could not load confine test '%s': %s" % [name, detail]
+ end
+ # Could not find file
+ end
end
- @facter_value
+ return @tests[name]
end
- def false?(value)
- ! value
+ attr_reader :values
+
+ # Mark that this confine is used for testing binary existence.
+ attr_accessor :for_binary
+ def for_binary?
+ for_binary
end
- def initialize(test, values)
+ def initialize(values)
values = [values] unless values.is_a?(Array)
@values = values
-
- if %w{exists false true}.include?(test.to_s)
- @test = test
- @method = @test.to_s + "?"
- else
- @fact = test
- @test = :facter
- @method = "match?"
- end
end
- def match?(value)
- facter_value == value.to_s.downcase
+ # Provide a hook for the message when there's a failure.
+ def message(value)
+ ""
end
# Collect the results of all of them.
def result
- values.collect { |value| send(@method, value) }
- end
-
- def true?(value)
- # Double negate, so we only get true or false.
- ! ! value
+ values.collect { |value| pass?(value) }
end
# Test whether our confine matches.
def valid?
values.each do |value|
- unless send(@method, value)
- msg = case test
- when :false: "false value when expecting true"
- when :true: "true value when expecting false"
- when :exists: "file %s does not exist" % value
- when :facter: "facter value '%s' for '%s' not in required list '%s'" % [value, @fact, values.join(",")]
- end
- Puppet.debug msg
+ unless pass?(value)
+ Puppet.debug message(value)
return false
end
end
return true
ensure
- # Reset the cache. We want to cache it during a given
- # run, but across runs.
- @facter_value = nil
+ reset
+ end
+
+ # Provide a hook for subclasses.
+ def reset
end
end
diff --git a/lib/puppet/provider/confine/exists.rb b/lib/puppet/provider/confine/exists.rb
new file mode 100644
index 000000000..1d1ed8c84
--- /dev/null
+++ b/lib/puppet/provider/confine/exists.rb
@@ -0,0 +1,22 @@
+require 'puppet/provider/confine'
+
+class Puppet::Provider::Confine::Exists < Puppet::Provider::Confine
+ def self.summarize(confines)
+ confines.inject([]) { |total, confine| total + confine.summary }
+ end
+
+ def pass?(value)
+ if for_binary?
+ return false unless value = binary(value)
+ end
+ value and FileTest.exist?(value)
+ end
+
+ def message(value)
+ "file %s does not exist" % value
+ end
+
+ def summary
+ result.zip(values).inject([]) { |array, args| val, f = args; array << f unless val; array }
+ end
+end
diff --git a/lib/puppet/provider/confine/facter.rb b/lib/puppet/provider/confine/facter.rb
new file mode 100644
index 000000000..9bb66c058
--- /dev/null
+++ b/lib/puppet/provider/confine/facter.rb
@@ -0,0 +1,37 @@
+require 'puppet/provider/confine'
+
+class Puppet::Provider::Confine::Facter < Puppet::Provider::Confine
+ def self.summarize(confines)
+ result = Hash.new { |hash, key| hash[key] = [] }
+ confines.inject(result) { |total, confine| total[confine.fact] += confine.values unless confine.valid?; total }
+ end
+
+ attr_accessor :fact
+
+ # Are we a facter comparison?
+ def facter?
+ defined?(@facter)
+ end
+
+ # Retrieve the value from facter
+ def facter_value
+ unless defined?(@facter_value) and @facter_value
+ @facter_value = ::Facter.value(@fact).to_s.downcase
+ end
+ @facter_value
+ end
+
+ def message(value)
+ "facter value '%s' for '%s' not in required list '%s'" % [value, self.fact, values.join(",")]
+ end
+
+ def pass?(value)
+ facter_value == value.to_s.downcase
+ end
+
+ def reset
+ # Reset the cache. We want to cache it during a given
+ # run, but across runs.
+ @facter_value = nil
+ end
+end
diff --git a/lib/puppet/provider/confine/false.rb b/lib/puppet/provider/confine/false.rb
new file mode 100644
index 000000000..b5b2b51c8
--- /dev/null
+++ b/lib/puppet/provider/confine/false.rb
@@ -0,0 +1,19 @@
+require 'puppet/provider/confine'
+
+class Puppet::Provider::Confine::False < Puppet::Provider::Confine
+ def self.summarize(confines)
+ confines.inject(0) { |count, confine| count + confine.summary }
+ end
+
+ def pass?(value)
+ ! value
+ end
+
+ def message(value)
+ "true value when expecting false"
+ end
+
+ def summary
+ result.find_all { |v| v == false }.length
+ end
+end
diff --git a/lib/puppet/provider/confine/feature.rb b/lib/puppet/provider/confine/feature.rb
new file mode 100644
index 000000000..1d92b001a
--- /dev/null
+++ b/lib/puppet/provider/confine/feature.rb
@@ -0,0 +1,17 @@
+require 'puppet/provider/confine'
+
+class Puppet::Provider::Confine::Feature < Puppet::Provider::Confine
+ def self.summarize(confines)
+ confines.collect { |c| c.values }.flatten.uniq.find_all { |value| ! confines[0].pass?(value) }
+ end
+
+ # Is the named feature available?
+ def pass?(value)
+ Puppet.features.send(value.to_s + "?")
+ end
+
+ def message(value)
+ "feature %s is missing" % value
+ end
+end
+
diff --git a/lib/puppet/provider/confine/true.rb b/lib/puppet/provider/confine/true.rb
new file mode 100644
index 000000000..86b3b144f
--- /dev/null
+++ b/lib/puppet/provider/confine/true.rb
@@ -0,0 +1,20 @@
+require 'puppet/provider/confine'
+
+class Puppet::Provider::Confine::True < Puppet::Provider::Confine
+ def self.summarize(confines)
+ confines.inject(0) { |count, confine| count + confine.summary }
+ end
+
+ def pass?(value)
+ # Double negate, so we only get true or false.
+ ! ! value
+ end
+
+ def message(value)
+ "false value when expecting true"
+ end
+
+ def summary
+ result.find_all { |v| v == true }.length
+ end
+end
diff --git a/lib/puppet/provider/confine_collection.rb b/lib/puppet/provider/confine_collection.rb
index f38035521..0c80086c9 100644
--- a/lib/puppet/provider/confine_collection.rb
+++ b/lib/puppet/provider/confine_collection.rb
@@ -11,8 +11,14 @@ class Puppet::Provider::ConfineCollection
for_binary = false
end
hash.each do |test, values|
- @confines << Puppet::Provider::Confine.new(test, values)
- @confines[-1].for_binary = true if for_binary
+ if klass = Puppet::Provider::Confine.test(test)
+ @confines << klass.new(values)
+ @confines[-1].for_binary = true if for_binary
+ else
+ confine = Puppet::Provider::Confine.test(:facter).new(values)
+ confine.fact = test
+ @confines << confine
+ end
end
end
@@ -22,24 +28,17 @@ class Puppet::Provider::ConfineCollection
# Return a hash of the whole confine set, used for the Provider
# reference.
- def result
- defaults = {
- :false => 0,
- :true => 0,
- :exists => [],
- :facter => {}
- }
- missing = Hash.new { |hash, key| hash[key] = defaults[key] }
- @confines.each do |confine|
- case confine.test
- when :false: missing[confine.test] += confine.result.find_all { |v| v == false }.length
- when :true: missing[confine.test] += confine.result.find_all { |v| v == true }.length
- when :exists: confine.result.zip(confine.values).each { |val, f| missing[:exists] << f unless val }
- when :facter: missing[:facter][confine.fact] = confine.values if confine.result.include?(false)
- end
- end
+ def summary
+ confines = Hash.new { |hash, key| hash[key] = [] }
+ @confines.each { |confine| confines[confine.class] << confine }
+ result = {}
+ confines.each do |klass, list|
+ value = klass.summarize(list)
+ next if (value.respond_to?(:length) and value.length == 0) or (value == 0)
+ result[klass.name] = value
- missing
+ end
+ result
end
def valid?
diff --git a/lib/puppet/provider/confiner.rb b/lib/puppet/provider/confiner.rb
index 3e406873b..4605523e8 100644
--- a/lib/puppet/provider/confiner.rb
+++ b/lib/puppet/provider/confiner.rb
@@ -15,6 +15,6 @@ module Puppet::Provider::Confiner
# Check whether this implementation is suitable for our platform.
def suitable?(short = true)
return confine_collection.valid? if short
- return confine_collection.result
+ return confine_collection.summary
end
end
diff --git a/lib/puppet/reference/providers.rb b/lib/puppet/reference/providers.rb
index da815ddf1..610c7550d 100644
--- a/lib/puppet/reference/providers.rb
+++ b/lib/puppet/reference/providers.rb
@@ -71,6 +71,8 @@ providers = Puppet::Util::Reference.newreference :providers, :title => "Provider
details += " - Got %s true tests that should have been false\n" % values
when :false:
details += " - Got %s false tests that should have been true\n" % values
+ when :feature:
+ details += " - Missing features %s\n" % values.collect { |f| f.to_s }.join(",")
end
end
notes << details
diff --git a/lib/puppet/util/storage.rb b/lib/puppet/util/storage.rb
index 9358a28e9..dc4e9cd71 100644
--- a/lib/puppet/util/storage.rb
+++ b/lib/puppet/util/storage.rb
@@ -6,6 +6,10 @@ class Puppet::Util::Storage
include Singleton
include Puppet::Util
+ def self.state
+ return @@state
+ end
+
def initialize
self.class.load
end
diff --git a/lib/puppet/util/variables.rb b/lib/puppet/util/variables.rb
deleted file mode 100644
index 1a78ef5c1..000000000
--- a/lib/puppet/util/variables.rb
+++ /dev/null
@@ -1,38 +0,0 @@
-module Puppet::Util::Variables
- def inithooks
- @instance_init_hooks.dup
- end
-
- def initvars
- return unless defined? @class_init_hooks
- self.inithooks.each do |var, value|
- if value.is_a?(Class)
- instance_variable_set("@" + var.to_s, value.new)
- else
- instance_variable_set("@" + var.to_s, value)
- end
- end
- end
-
- def instancevar(hash)
- @instance_init_hooks ||= {}
-
- unless method_defined?(:initvars)
- define_method(:initvars) do
- self.class.inithooks.each do |var, value|
- if value.is_a?(Class)
- instance_variable_set("@" + var.to_s, value.new)
- else
- instance_variable_set("@" + var.to_s, value)
- end
- end
- end
- end
- hash.each do |var, value|
- raise("Already initializing %s" % var) if @instance_init_hooks[var]
-
- @instance_init_hooks[var] = value
- end
- end
-end
-