Hello all,

I've been trying my hand at fixing #5036 (and getting a bit acquainted with puppet internals while at it). My current diff can be found at the end of this mail. Unfortunately, I can't get the validation to work and judging by the absense of my debug output, my code doesn't even get run. AFAICT, it should be reached via Puppet::Property.value= -> .should= -> Puppet::Parameter.validate -> .unsafe_validate -> .validate_features_per_value

I'm having a bit of trouble finding the actual control path. Any hints?

TIA,
Aggelos

diff --git a/lib/puppet/parameter.rb b/lib/puppet/parameter.rb
index ff7cab2..817548f 100644
--- a/lib/puppet/parameter.rb
+++ b/lib/puppet/parameter.rb
@@ -243,10 +243,36 @@ class Puppet::Parameter
     ret
   end

+ # Make sure that we've got all of the required features for a given value.
+  def validate_features_per_value(value)
+    Puppet.debug "validate_features_per_value #{self.class.name} #{value}"
+ if features = self.class.value_option(self.class.value_name(value), :required_features)
+      features = Array(features)
+      needed_features = features.collect { |f| f.to_s }.join(", ")
+      Puppet.debug "validate_features_per_value #{needed_features}"
+ raise ArgumentError, "Provider must have features '#{needed_features}' to set '#{self.class.name}' to '#{value}'" unless provider.satisfies?(features)
+    end
+  end
+
+  # Look up a value's name, so we can find options and such.
+  def self.value_name(name)
+    if value = value_collection.match?(name)
+      value.name
+    end
+  end
+
+  # Retrieve an option set when a value was defined.
+  def self.value_option(name, option)
+    if value = value_collection.value(name)
+      value.send(option)
+    end
+  end
+
   # Verify that the passed value is valid.
# If the developer uses a 'validate' hook, this method will get overridden.
   def unsafe_validate(value)
     self.class.value_collection.validate(value)
+    validate_features_per_value(value)
   end

   # A protected validation method that only ever raises useful exceptions.
diff --git a/lib/puppet/property.rb b/lib/puppet/property.rb
index 84e1a03..cc3aeee 100644
--- a/lib/puppet/property.rb
+++ b/lib/puppet/property.rb
@@ -32,20 +32,6 @@ class Puppet::Property < Puppet::Parameter
     end
   end

-  # Look up a value's name, so we can find options and such.
-  def self.value_name(name)
-    if value = value_collection.match?(name)
-      value.name
-    end
-  end
-
-  # Retrieve an option set when a value was defined.
-  def self.value_option(name, option)
-    if value = value_collection.value(name)
-      value.send(option)
-    end
-  end
-
# Define a new valid value for a property. You must provide the value itself,
   # usually as a symbol, or a regex to match the value.
   #
@@ -299,16 +285,6 @@ class Puppet::Property < Puppet::Parameter
# If the developer uses a 'validate' hook, this method will get overridden.
   def unsafe_validate(value)
     super
-    validate_features_per_value(value)
-  end
-
- # Make sure that we've got all of the required features for a given value.
-  def validate_features_per_value(value)
- if features = self.class.value_option(self.class.value_name(value), :required_features)
-      features = Array(features)
-      needed_features = features.collect { |f| f.to_s }.join(", ")
- raise ArgumentError, "Provider must have features '#{needed_features}' to set '#{self.class.name}' to '#{value}'" unless provider.satisfies?(features)
-    end
   end

   # Just return any should value we might have.
diff --git a/lib/puppet/provider/package/apt.rb b/lib/puppet/provider/package/apt.rb
index 2fc7874..5c485b2 100755
--- a/lib/puppet/provider/package/apt.rb
+++ b/lib/puppet/provider/package/apt.rb
@@ -42,6 +42,7 @@ Puppet::Type.type(:package).provide :apt, :parent => :dpkg, :source => :dpkg do
   # Install a package using 'apt-get'.  This function needs to support
   # installing a specific version.
   def install
+    force = false
     self.run_preseed if @resource[:responsefile]
     should = @resource[:ensure]

@@ -57,6 +58,7 @@ Puppet::Type.type(:package).provide :apt, :parent => :dpkg, :source => :dpkg do
       end
     end

+    force |= @resource[:force]
     str = @resource[:name]
     case should
     when true, false, Symbol
@@ -64,9 +66,9 @@ Puppet::Type.type(:package).provide :apt, :parent => :dpkg, :source => :dpkg do
     else
       # Add the package version and --force-yes option
       str += "=#{should}"
-      cmd << "--force-yes"
+      force = true
     end
-
+    cmd << "--force-yes" if force
     cmd << :install << str

     aptget(*cmd)
diff --git a/lib/puppet/type/package.rb b/lib/puppet/type/package.rb
index 51a8663..55ccbef 100644
--- a/lib/puppet/type/package.rb
+++ b/lib/puppet/type/package.rb
@@ -40,6 +40,7 @@ module Puppet
         a user or another package. Held is considered a superset of
         installed.",
       :methods => [:hold]
+    feature :forceable, "The provider can force package installation."

     ensurable do
       desc "What state the package should be in.
@@ -214,6 +215,10 @@ module Puppet
       isnamevar
     end

+    newparam(:force, :required_features => [:forceable]) do
+      desc "Whether to force the install"
+      newvalues(:true, :false)
+    end
     newparam(:source) do
       desc "Where to find the actual package.  This must be a local file
         (or on a network file system) or a URL that your specific

--
You received this message because you are subscribed to the Google Groups "Puppet 
Developers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/puppet-dev?hl=en.

Reply via email to