Class: Puppet::Property
- Defined in:
- lib/puppet/property.rb,
lib/puppet/type/zpool.rb,
lib/puppet/property/list.rb,
lib/puppet/property/keyvalue.rb,
lib/puppet/property/ordered_list.rb
Direct Known Subclasses
Defined Under Namespace
Classes: Ensure, KeyValue, List, MultiVDev, OrderedList, VDev
Class Attribute Summary collapse
-
.name ⇒ Object
readonly
Returns the value of attribute name.
-
.unmanaged ⇒ Object
Returns the value of attribute unmanaged.
Instance Attribute Summary collapse
-
#noop ⇒ Object
for testing whether we should actually do anything.
-
#shadow ⇒ Object
readonly
Returns the value of attribute shadow.
-
#shouldorig ⇒ Object
readonly
Because ‘should’ uses an array, we have a special method for handling it.
Attributes inherited from Parameter
Attributes included from Util::Docs
Attributes included from Util::Cacher::Expirer
Class Method Summary collapse
-
.array_matching ⇒ Object
Return array matching info, defaulting to just matching the first value.
-
.array_matching=(value) ⇒ Object
Set whether properties should match all values or just the first one.
- .method_added(sym) ⇒ Object
-
.newvalue(name, options = {}, &block) ⇒ Object
Define a new valid value for a property.
-
.value_name(name) ⇒ Object
Look up a value’s name, so we can find options and such.
-
.value_option(name, option) ⇒ Object
Retrieve an option set when a value was defined.
Instance Method Summary collapse
-
#call_provider(value) ⇒ Object
Call the provider method.
-
#call_valuemethod(name, value) ⇒ Object
Call the dynamically-created method associated with our value, if there is one.
-
#change_to_s(current_value, newvalue) ⇒ Object
How should a property change be printed as a string?.
-
#event ⇒ Object
Return a modified form of the resource event.
-
#event_name ⇒ Object
Figure out which event to return.
-
#initialize(hash = {}) ⇒ Property
constructor
initialize our property.
-
#insync?(is) ⇒ Boolean
This method should be overridden by derived classes if necessary to provide extra logic to determine whether the property is in sync.
-
#is_to_s(currentvalue) ⇒ Object
because the @should and @is vars might be in weird formats, we need to set up a mechanism for pretty printing of the values default to just the values, but this way individual properties can override these methods.
-
#log(msg) ⇒ Object
Send a log message.
-
#match_all? ⇒ Boolean
Should we match all values, or just the first?.
-
#munge(value) ⇒ Object
Execute our shadow’s munge code, too, if we have one.
-
#name ⇒ Object
each property class must define the name method, and property instances do not change that name this implicitly means that a given object can only have one property instance of a given property class.
-
#retrieve ⇒ Object
By default, call the method associated with the property name on our provider.
-
#safe_insync?(is) ⇒ Boolean
Determine whether the property is in-sync or not.
-
#set(value) ⇒ Object
Set our value, using the provider, an associated block, or both.
-
#setup_shadow(klass) ⇒ Object
If there’s a shadowing metaparam, instantiate it now.
-
#should ⇒ Object
Only return the first value.
-
#should=(values) ⇒ Object
Set the should value.
- #should_to_s(newvalue) ⇒ Object
- #sync ⇒ Object
-
#unsafe_validate(value) ⇒ Object
Verify that the passed value is valid.
-
#validate_features_per_value(value) ⇒ Object
Make sure that we’ve got all of the required features for a given value.
-
#value ⇒ Object
Just return any should value we might have.
-
#value=(value) ⇒ Object
Match the Parameter interface, but we really just use ‘should’ internally.
Methods inherited from Parameter
aliasvalue, defaultto, desc, #devfail, doc, #expirer, #fail, initvars, isnamevar, isnamevar?, isrequired, #metaparam?, munge, newvalues, nodefault, #pathbuilder, #provider, proxymethods, #remove, required?, #tags, #to_s, unmunge, #unmunge, #unsafe_munge, #validate, validate
Methods included from Util::Docs
#desc, #dochook, #doctable, #nodoc?, #pad, scrub
Methods included from Util
activerecord_version, benchmark, chuser, classproxy, #execfail, #execpipe, execute, logmethods, memory, proxy, recmkdir, secure_open, symbolize, symbolizehash, symbolizehash!, synchronize_on, thinmark, #threadlock, which, withumask
Methods included from Util::POSIX
#get_posix_field, #gid, #idfield, #methodbyid, #methodbyname, #search_posix_field, #uid
Methods included from Util::Cacher
Methods included from Util::Cacher::Expirer
#dependent_data_expired?, #expire
Methods included from Util::MethodHelper
#requiredopts, #set_options, #symbolize_options
Methods included from Util::Logging
Methods included from Util::LogPaths
Methods included from Util::Errors
#adderrorcontext, #devfail, #error_context, #exceptwrap, #fail
Constructor Details
Class Attribute Details
.name ⇒ Object (readonly)
Returns the value of attribute name.
19 20 21 |
# File 'lib/puppet/property.rb', line 19 def name @name end |
.unmanaged ⇒ Object
Returns the value of attribute unmanaged.
18 19 20 |
# File 'lib/puppet/property.rb', line 18 def unmanaged @unmanaged end |
Instance Attribute Details
#noop ⇒ Object
for testing whether we should actually do anything
228 229 230 231 232 233 234 235 236 237 238 239 |
# File 'lib/puppet/property.rb', line 228 def noop # This is only here to make testing easier. if @resource.respond_to?(:noop?) @resource.noop? else if defined?(@noop) @noop else Puppet[:noop] end end end |
#shadow ⇒ Object (readonly)
Returns the value of attribute shadow.
138 139 140 |
# File 'lib/puppet/property.rb', line 138 def shadow @shadow end |
#shouldorig ⇒ Object (readonly)
Because ‘should’ uses an array, we have a special method for handling it. We also want to keep copies of the original values, so that they can be retrieved and compared later when merging.
13 14 15 |
# File 'lib/puppet/property.rb', line 13 def shouldorig @shouldorig end |
Class Method Details
.array_matching ⇒ Object
Return array matching info, defaulting to just matching the first value.
23 24 25 |
# File 'lib/puppet/property.rb', line 23 def array_matching @array_matching ||= :first end |
.array_matching=(value) ⇒ Object
Set whether properties should match all values or just the first one.
28 29 30 31 32 |
# File 'lib/puppet/property.rb', line 28 def array_matching=(value) value = value.intern if value.is_a?(String) raise ArgumentError, "Supported values for Property#array_matching are 'first' and 'all'" unless [:first, :all].include?(value) @array_matching = value end |
.method_added(sym) ⇒ Object
165 166 167 |
# File 'lib/puppet/property.rb', line 165 def self.method_added(sym) raise "Puppet::Property#safe_insync? shouldn't be overridden; please override insync? instead" if sym == :safe_insync? end |
.newvalue(name, options = {}, &block) ⇒ Object
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.
The first argument to the method is either the value itself or a regex. The second argument is an option hash; valid options are:
-
:method: The name of the method to define. Defaults to ‘set_<value>’. -
:required_features: A list of features this value requires. -
:event: The event that should be returned when this value is set. -
:call: When to call any associated block. The default value is ‘instead`, which means to call the value instead of calling the provider. You can also specify `before` or `after`, which will call both the block and the provider, according to the order you specify (the `first` refers to when the block is called, not the provider).
62 63 64 65 66 67 |
# File 'lib/puppet/property.rb', line 62 def self.newvalue(name, = {}, &block) value = value_collection.newvalue(name, , &block) define_method(value.method, &value.block) if value.method and value.block value end |
.value_name(name) ⇒ Object
Look up a value’s name, so we can find options and such.
36 37 38 39 40 |
# File 'lib/puppet/property.rb', line 36 def self.value_name(name) if value = value_collection.match?(name) value.name end end |
.value_option(name, option) ⇒ Object
Retrieve an option set when a value was defined.
43 44 45 46 47 |
# File 'lib/puppet/property.rb', line 43 def self.value_option(name, option) if value = value_collection.value(name) value.send(option) end end |
Instance Method Details
#call_provider(value) ⇒ Object
Call the provider method.
70 71 72 73 74 |
# File 'lib/puppet/property.rb', line 70 def call_provider(value) provider.send(self.class.name.to_s + "=", value) rescue NoMethodError self.fail "The #{provider.class.name} provider can not handle attribute #{self.class.name}" end |
#call_valuemethod(name, value) ⇒ Object
Call the dynamically-created method associated with our value, if there is one.
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/puppet/property.rb', line 78 def call_valuemethod(name, value) if method = self.class.value_option(name, :method) and self.respond_to?(method) begin event = self.send(method) rescue Puppet::Error raise rescue => detail puts detail.backtrace if Puppet[:trace] error = Puppet::Error.new("Could not set '#{value} on #{self.class.name}: #{detail}", @resource.line, @resource.file) error.set_backtrace detail.backtrace raise error end elsif block = self.class.value_option(name, :block) # FIXME It'd be better here to define a method, so that # the blocks could return values. self.instance_eval(&block) else devfail "Could not find method for value '#{name}'" end end |
#change_to_s(current_value, newvalue) ⇒ Object
How should a property change be printed as a string?
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/puppet/property.rb', line 100 def change_to_s(current_value, newvalue) begin if current_value == :absent return "defined '#{name}' as '#{should_to_s(newvalue)}'" elsif newvalue == :absent or newvalue == [:absent] return "undefined '#{name}' from '#{is_to_s(current_value)}'" else return "#{name} changed '#{is_to_s(current_value)}' to '#{should_to_s(newvalue)}'" end rescue Puppet::Error, Puppet::DevError raise rescue => detail puts detail.backtrace if Puppet[:trace] raise Puppet::DevError, "Could not convert change '#{name}' to string: #{detail}" end end |
#event ⇒ Object
Return a modified form of the resource event.
134 135 136 |
# File 'lib/puppet/property.rb', line 134 def event resource.event :name => event_name, :desired_value => should, :property => self, :source_description => path end |
#event_name ⇒ Object
Figure out which event to return.
118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/puppet/property.rb', line 118 def event_name value = self.should event_name = self.class.value_option(value, :event) and return event_name name == :ensure or return (name.to_s + "_changed").to_sym return (resource.type.to_s + case value when :present; "_created" when :absent; "_removed" else "_changed" end).to_sym end |
#insync?(is) ⇒ Boolean
This method should be overridden by derived classes if necessary to provide extra logic to determine whether the property is in sync.
172 173 174 175 176 177 178 179 180 181 182 183 184 185 |
# File 'lib/puppet/property.rb', line 172 def insync?(is) self.devfail "#{self.class.name}'s should is not array" unless @should.is_a?(Array) # an empty array is analogous to no should values return true if @should.empty? # Look for a matching value return (is == @should or is == @should.collect { |v| v.to_s }) if match_all? @should.each { |val| return true if is == val or is == val.to_s } # otherwise, return false false end |
#is_to_s(currentvalue) ⇒ Object
because the @should and @is vars might be in weird formats, we need to set up a mechanism for pretty printing of the values default to just the values, but this way individual properties can override these methods
191 192 193 |
# File 'lib/puppet/property.rb', line 191 def is_to_s(currentvalue) currentvalue end |
#log(msg) ⇒ Object
Send a log message.
196 197 198 199 200 201 202 203 204 205 |
# File 'lib/puppet/property.rb', line 196 def log(msg) Puppet::Util::Log.create( :level => resource[:loglevel], :message => msg, :source => self ) end |
#match_all? ⇒ Boolean
Should we match all values, or just the first?
208 209 210 |
# File 'lib/puppet/property.rb', line 208 def match_all? self.class.array_matching == :all end |
#munge(value) ⇒ Object
Execute our shadow’s munge code, too, if we have one.
213 214 215 216 217 |
# File 'lib/puppet/property.rb', line 213 def munge(value) self.shadow.munge(value) if self.shadow super end |
#name ⇒ Object
each property class must define the name method, and property instances do not change that name this implicitly means that a given object can only have one property instance of a given property class
223 224 225 |
# File 'lib/puppet/property.rb', line 223 def name self.class.name end |
#retrieve ⇒ Object
By default, call the method associated with the property name on our provider. In other words, if the property name is ‘gid’, we’ll call ‘provider.gid’ to retrieve the current value.
244 245 246 |
# File 'lib/puppet/property.rb', line 244 def retrieve provider.send(self.class.name) end |
#safe_insync?(is) ⇒ Boolean
Determine whether the property is in-sync or not. If @should is not defined or is set to a non-true value, then we do not have a valid value for it and thus consider the property to be in-sync since we cannot fix it. Otherwise, we expect our should value to be an array, and if @is matches any of those values, then we consider it to be in-sync.
Don’t override this method.
157 158 159 160 161 162 163 |
# File 'lib/puppet/property.rb', line 157 def safe_insync?(is) # If there is no @should value, consider the property to be in sync. return true unless @should # Otherwise delegate to the (possibly derived) insync? method. insync?(is) end |
#set(value) ⇒ Object
Set our value, using the provider, an associated block, or both.
249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 |
# File 'lib/puppet/property.rb', line 249 def set(value) # Set a name for looking up associated options like the event. name = self.class.value_name(value) call = self.class.value_option(name, :call) || :none if call == :instead call_valuemethod(name, value) elsif call == :none # They haven't provided a block, and our parent does not have # a provider, so we have no idea how to handle this. self.fail "#{self.class.name} cannot handle values of type #{value.inspect}" unless @resource.provider call_provider(value) else # LAK:NOTE 20081031 This is a change in behaviour -- you could # previously specify :call => [;before|:after], which would call # the setter *in addition to* the block. I'm convinced this # was never used, and it makes things unecessarily complicated. # If you want to specify a block and still call the setter, then # do so in the block. devfail "Cannot use obsolete :call value '#{call}' for property '#{self.class.name}'" end end |
#setup_shadow(klass) ⇒ Object
If there’s a shadowing metaparam, instantiate it now. This allows us to create a property or parameter with the same name as a metaparameter, and the metaparam will only be stored as a shadow.
277 278 279 |
# File 'lib/puppet/property.rb', line 277 def setup_shadow(klass) @shadow = klass.new(:resource => self.resource) end |
#should ⇒ Object
Only return the first value
282 283 284 285 286 287 288 289 290 291 292 |
# File 'lib/puppet/property.rb', line 282 def should return nil unless defined?(@should) self.devfail "should for #{self.class.name} on #{resource.name} is not an array" unless @should.is_a?(Array) if match_all? return @should.collect { |val| self.unmunge(val) } else return self.unmunge(@should[0]) end end |
#should=(values) ⇒ Object
Set the should value.
295 296 297 298 299 300 301 302 |
# File 'lib/puppet/property.rb', line 295 def should=(values) values = [values] unless values.is_a?(Array) @shouldorig = values values.each { |val| validate(val) } @should = values.collect { |val| self.munge(val) } end |
#should_to_s(newvalue) ⇒ Object
304 305 306 |
# File 'lib/puppet/property.rb', line 304 def should_to_s(newvalue) [newvalue].flatten.join(" ") end |
#sync ⇒ Object
308 309 310 311 |
# File 'lib/puppet/property.rb', line 308 def sync devfail "Got a nil value for should" unless should set(should) end |
#unsafe_validate(value) ⇒ Object
Verify that the passed value is valid. If the developer uses a ‘validate’ hook, this method will get overridden.
315 316 317 318 |
# File 'lib/puppet/property.rb', line 315 def unsafe_validate(value) super validate_features_per_value(value) end |
#validate_features_per_value(value) ⇒ Object
Make sure that we’ve got all of the required features for a given value.
321 322 323 324 325 326 327 |
# File 'lib/puppet/property.rb', line 321 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 |
#value ⇒ Object
Just return any should value we might have.
330 331 332 |
# File 'lib/puppet/property.rb', line 330 def value self.should end |
#value=(value) ⇒ Object
Match the Parameter interface, but we really just use ‘should’ internally. Note that the should= method does all of the validation and such.
336 337 338 |
# File 'lib/puppet/property.rb', line 336 def value=(value) self.should = value end |