Class Puppet::Type
In: lib/puppet/type.rb
Parent: Object

Methods

[]   []   []=   []=   add_property_parameter   alias   allattrs   argclean   attr_alias   attr_alias   attrclass   attrtype   autorequire   autorequire   builddepends   cache   cached   clear   copyparam   create   currentpropvalues   defaultprovider   delete   delete   deleting?   depthfirst?   depthfirst?   doc   each   eachattr   eachautorequire   eachmetaparam   eachproperty   ensurable   ensurable?   evaluate   finish   flush   handle_param_options   has_key?   hash2obj   hash2trans   implicit?   initvars   initvars   instances   insync?   isomorphic?   isomorphic?   log   managed?   metaparam?   metaparamclass   metaparamdoc   metaparams   munge_relationship   name   namevar   new   newattr   newmetaparam   newparam   newproperty   newstate   noop   noop?   paramclass   paramdoc   parameter   parameters   parent   parentof?   pathbuilder   property   propertybyname   propertychanges   propertydefined?   provide   provider   provider=   providers   providers_by_source   providify   purging   purging?   ref   relationship_params   remove   requires?   retrieve   schedule   scheduled?   self_refresh?   set_attr_alias   setdefaults   should   states   suitableprovider   tag   tagged?   tags=   title   to_hash   to_s   to_s   to_trans   trigger   unprovide   unsubscribe   validate   validattr?   validparameter?   validproperties   validproperty?   validprovider?   value  

Included Modules

Puppet::Util Puppet::Util::Errors Puppet::Util::LogPaths Puppet::Util::Logging Puppet::Util::ClassGen Puppet::Util::Warnings Enumerable Enumerable Puppet::Util::ClassGen Puppet::MetaType::Manager Puppet::Util Puppet::Util::Logging

Classes and Modules

Class Puppet::Type::RelationshipMetaparam

Attributes

catalog  [RW]  The catalog that this resource is stored in.
defaultprovider  [W] 
file  [RW]  In naming methods, I have tried to consistently name the method so that it is clear whether it operates on all attributes (thus has ‘attr’ in the method name, or whether it operates on a specific type of attributes.
implicit  [W]  Code related to the closure-like behaviour of the resource classes.
line  [RW]  In naming methods, I have tried to consistently name the method so that it is clear whether it operates on all attributes (thus has ‘attr’ in the method name, or whether it operates on a specific type of attributes.
name  [R] 
noop  [W] 
parenttype  [RW] 
properties  [R] 
provider  [R] 
providerloader  [RW] 
self_refresh  [RW] 
tags  [R]  All of the tagging code.
title  [W] 

Public Class methods

retrieve a named instance of the current type

[Source]

     # File lib/puppet/type.rb, line 990
990:     def self.[](name)
991:         @objects[name] || @aliases[name]
992:     end

add an instance by name to the class list of instances

[Source]

      # File lib/puppet/type.rb, line 995
 995:     def self.[]=(name,object)
 996:         newobj = nil
 997:         if object.is_a?(Puppet::Type)
 998:             newobj = object
 999:         else
1000:             raise Puppet::DevError, "must pass a Puppet::Type object"
1001:         end
1002: 
1003:         if exobj = @objects[name] and self.isomorphic?
1004:             msg = "Object '%s[%s]' already exists" %
1005:                 [newobj.class.name, name]
1006: 
1007:             if exobj.file and exobj.line
1008:                 msg += ("in file %s at line %s" %
1009:                     [object.file, object.line])
1010:             end
1011:             if object.file and object.line
1012:                 msg += ("and cannot be redefined in file %s at line %s" %
1013:                     [object.file, object.line])
1014:             end
1015:             error = Puppet::Error.new(msg)
1016:             raise error
1017:         else
1018:             #Puppet.info("adding %s of type %s to class list" %
1019:             #    [name,object.class])
1020:             @objects[name] = newobj
1021:         end
1022:     end

Create an alias. We keep these in a separate hash so that we don‘t encounter the objects multiple times when iterating over them.

[Source]

      # File lib/puppet/type.rb, line 1026
1026:     def self.alias(name, obj)
1027:         if @objects.include?(name)
1028:             unless @objects[name] == obj
1029:                 raise Puppet::Error.new(
1030:                     "Cannot create alias %s: object already exists" %
1031:                     [name]
1032:                 )
1033:             end
1034:         end
1035: 
1036:         if @aliases.include?(name)
1037:             unless @aliases[name] == obj
1038:                 raise Puppet::Error.new(
1039:                     "Object %s already has alias %s" %
1040:                     [@aliases[name].name, name]
1041:                 )
1042:             end
1043:         end
1044: 
1045:         @aliases[name] = obj
1046:     end

All parameters, in the appropriate order. The namevar comes first, then the properties, then the params and metaparams in the order they were specified in the files.

[Source]

    # File lib/puppet/type.rb, line 39
39:     def self.allattrs
40:         # now get all of the arguments, in a specific order
41:         # Cache this, since it gets called so many times
42:         namevar = self.namevar
43: 
44:         order = [namevar]
45:         if self.parameters.include?(:provider)
46:             order << :provider
47:         end
48:         order << [self.properties.collect { |property| property.name },
49:             self.parameters - [:provider],
50:             self.metaparams].flatten.reject { |param|
51:                 # we don't want our namevar in there multiple times
52:                 param == namevar
53:         }
54: 
55:         order.flatten!
56: 
57:         return order
58:     end

Retrieve an attribute alias, if there is one.

[Source]

    # File lib/puppet/type.rb, line 61
61:     def self.attr_alias(param)
62:         @attr_aliases[symbolize(param)]
63:     end

Find the class associated with any given attribute.

[Source]

    # File lib/puppet/type.rb, line 74
74:     def self.attrclass(name)
75:         @attrclasses ||= {}
76: 
77:         # We cache the value, since this method gets called such a huge number
78:         # of times (as in, hundreds of thousands in a given run).
79:         unless @attrclasses.include?(name)
80:             @attrclasses[name] = case self.attrtype(name)
81:             when :property: @validproperties[name]
82:             when :meta: @@metaparamhash[name]
83:             when :param: @paramhash[name]
84:             end
85:         end
86:         @attrclasses[name]
87:     end

What type of parameter are we dealing with? Cache the results, because this method gets called so many times.

[Source]

     # File lib/puppet/type.rb, line 91
 91:     def self.attrtype(attr)
 92:         @attrtypes ||= {}
 93:         unless @attrtypes.include?(attr)
 94:             @attrtypes[attr] = case
 95:                 when @validproperties.include?(attr): :property
 96:                 when @paramhash.include?(attr): :param
 97:                 when @@metaparamhash.include?(attr): :meta
 98:                 else
 99:                     raise Puppet::DevError,
100:                         "Invalid attribute '%s' for class '%s'" %
101:                         [attr, self.name]
102:                 end
103:         end
104: 
105:         @attrtypes[attr]
106:     end

Specify a block for generating a list of objects to autorequire. This makes it so that you don‘t have to manually specify things that you clearly require.

[Source]

      # File lib/puppet/type.rb, line 1952
1952:     def self.autorequire(name, &block)
1953:         @autorequires ||= {}
1954:         @autorequires[name] = block
1955:     end

remove all of the instances of a single type

[Source]

      # File lib/puppet/type.rb, line 1049
1049:     def self.clear
1050:         if defined? @objects
1051:             @objects.each do |name, obj|
1052:                 obj.remove(true)
1053:             end
1054:             @objects.clear
1055:         end
1056:         if defined? @aliases
1057:             @aliases.clear
1058:         end
1059:     end

Copy an existing class parameter. This allows other types to avoid duplicating a parameter definition, and is mostly used by subclasses of the File class.

[Source]

     # File lib/puppet/type.rb, line 111
111:     def self.copyparam(klass, name)
112:         param = klass.attrclass(name)
113: 
114:         unless param
115:             raise Puppet::DevError, "Class %s has no param %s" % [klass, name]
116:         end
117:         @parameters << param
118:         @parameters.each { |p| @paramhash[name] = p }
119: 
120:         if param.isnamevar?
121:             @namevar = param.name
122:         end
123:     end

Force users to call this, so that we can merge objects if necessary.

[Source]

      # File lib/puppet/type.rb, line 1063
1063:     def self.create(args)
1064:         # Don't modify the original hash; instead, create a duplicate and modify it.
1065:         # We have to dup and use the ! so that it stays a TransObject if it is
1066:         # one.
1067:         hash = args.dup
1068:         symbolizehash!(hash)
1069: 
1070:         # If we're the base class, then pass the info on appropriately
1071:         if self == Puppet::Type
1072:             type = nil
1073:             if hash.is_a? Puppet::TransObject
1074:                 type = hash.type
1075:             else
1076:                 # If we're using the type to determine object type, then delete it
1077:                 if type = hash[:type]
1078:                     hash.delete(:type)
1079:                 end
1080:             end
1081: 
1082:             # If they've specified a type and called on the base, then
1083:             # delegate to the subclass.
1084:             if type
1085:                 if typeklass = self.type(type)
1086:                     return typeklass.create(hash)
1087:                 else
1088:                     raise Puppet::Error, "Unknown type %s" % type
1089:                 end
1090:             else
1091:                 raise Puppet::Error, "No type found for %s" % hash.inspect
1092:             end
1093:         end
1094: 
1095:         # Handle this new object being implicit
1096:         implicit = hash[:implicit] || false
1097:         if hash.include?(:implicit)
1098:             hash.delete(:implicit)
1099:         end
1100: 
1101:         name = nil
1102:         unless hash.is_a? Puppet::TransObject
1103:             hash = self.hash2trans(hash)
1104:         end
1105: 
1106:         # XXX This will have to change when transobjects change to using titles
1107:         title = hash.name
1108: 
1109:         # if the object already exists
1110:         if self.isomorphic? and retobj = self[title]
1111:             # if only one of our objects is implicit, then it's easy to see
1112:             # who wins -- the non-implicit one.
1113:             if retobj.implicit? and ! implicit
1114:                 Puppet.notice "Removing implicit %s" % retobj.title
1115:                 # Remove all of the objects, but do not remove their subscriptions.
1116:                 retobj.remove(false)
1117: 
1118:                 # now pass through and create the new object
1119:             elsif implicit
1120:                 Puppet.debug "Ignoring implicit %s[%s]" % [self.name, title]
1121:                 return nil
1122:             else
1123:                 raise Puppet::Error, "%s is already being managed" % retobj.ref
1124:             end
1125:         end
1126: 
1127:         # create it anew
1128:         # if there's a failure, destroy the object if it got that far, but raise
1129:         # the error.
1130:         begin
1131:             obj = new(hash)
1132:         rescue => detail
1133:             Puppet.err "Could not create %s: %s" % [title, detail.to_s]
1134:             if obj
1135:                 obj.remove(true)
1136:             elsif obj = self[title]
1137:                 obj.remove(true)
1138:             end
1139:             raise
1140:         end
1141: 
1142:         if implicit
1143:             obj.implicit = true
1144:         end
1145: 
1146:         # Store the object by title
1147:         self[obj.title] = obj
1148: 
1149:         return obj
1150:     end

Find the default provider.

[Source]

      # File lib/puppet/type.rb, line 1714
1714:     def self.defaultprovider
1715:         unless defined? @defaultprovider and @defaultprovider
1716:             suitable = suitableprovider()
1717: 
1718:             # Find which providers are a default for this system.
1719:             defaults = suitable.find_all { |provider| provider.default? }
1720: 
1721:             # If we don't have any default we use suitable providers
1722:             defaults = suitable if defaults.empty?
1723:             max = defaults.collect { |provider| provider.defaultnum }.max
1724:             defaults = defaults.find_all { |provider| provider.defaultnum == max }
1725: 
1726:             retval = nil
1727:             if defaults.length > 1
1728:                 Puppet.warning(
1729:                     "Found multiple default providers for %s: %s; using %s" %
1730:                     [self.name, defaults.collect { |i| i.name.to_s }.join(", "),
1731:                         defaults[0].name]
1732:                 )
1733:                 retval = defaults.shift
1734:             elsif defaults.length == 1
1735:                 retval = defaults.shift
1736:             else
1737:                 raise Puppet::DevError, "Could not find a default provider for %s" %
1738:                     self.name
1739:             end
1740: 
1741:             @defaultprovider = retval
1742:         end
1743: 
1744:         return @defaultprovider
1745:     end

remove a specified object

[Source]

      # File lib/puppet/type.rb, line 1153
1153:     def self.delete(resource)
1154:         return unless defined? @objects
1155:         if @objects.include?(resource.title)
1156:             @objects.delete(resource.title)
1157:         end
1158:         if @aliases.include?(resource.title)
1159:             @aliases.delete(resource.title)
1160:         end
1161:         if @aliases.has_value?(resource)
1162:             names = []
1163:             @aliases.each do |name, otherres|
1164:                 if otherres == resource
1165:                     names << name
1166:                 end
1167:             end
1168:             names.each { |name| @aliases.delete(name) }
1169:         end
1170:     end

Code related to the container behaviour.

[Source]

     # File lib/puppet/type.rb, line 759
759:     def self.depthfirst?
760:         if defined? @depthfirst
761:             return @depthfirst
762:         else
763:             return false
764:         end
765:     end

We need to add documentation for each provider.

[Source]

      # File lib/puppet/type.rb, line 1871
1871:             def self.doc
1872:                 @doc + "  Available providers are:\n\n" + parenttype().providers.sort { |a,b|
1873:                     a.to_s <=> b.to_s
1874:                 }.collect { |i|
1875:                     "* **%s**: %s" % [i, parenttype().provider(i).doc]
1876:                 }.join("\n")
1877:             end

iterate across each of the type‘s instances

[Source]

      # File lib/puppet/type.rb, line 1173
1173:     def self.each
1174:         return unless defined? @objects
1175:         @objects.each { |name,instance|
1176:             yield instance
1177:         }
1178:     end

A similar function but one that yields the class and type. This is mainly so that setdefaults doesn‘t call quite so many functions.

[Source]

     # File lib/puppet/type.rb, line 127
127:     def self.eachattr(*ary)
128:         if ary.empty?
129:             ary = nil
130:         end
131: 
132:         # We have to do this in a specific order, so that defaults are
133:         # created in that order (e.g., providers should be set up before
134:         # anything else).
135:         allattrs.each do |name|
136:             next unless ary.nil? or ary.include?(name)
137:             if obj = @properties.find { |p| p.name == name }
138:                 yield obj, :property
139:             elsif obj = @parameters.find { |p| p.name == name }
140:                 yield obj, :param
141:             elsif obj = @@metaparams.find { |p| p.name == name }
142:                 yield obj, :meta
143:             else
144:                 raise Puppet::DevError, "Could not find parameter %s" % name
145:             end
146:         end
147:     end

Yield each of those autorequires in turn, yo.

[Source]

      # File lib/puppet/type.rb, line 1958
1958:     def self.eachautorequire
1959:         @autorequires ||= {}
1960:         @autorequires.each { |type, block|
1961:             yield(type, block)
1962:         }
1963:     end

[Source]

     # File lib/puppet/type.rb, line 149
149:     def self.eachmetaparam
150:         @@metaparams.each { |p| yield p.name }
151:     end

Create the ‘ensure’ class. This is a separate method so other types can easily call it and create their own ‘ensure’ values.

[Source]

     # File lib/puppet/type.rb, line 155
155:     def self.ensurable(&block)
156:         if block_given?
157:             self.newproperty(:ensure, :parent => Puppet::Property::Ensure, &block)
158:         else
159:             self.newproperty(:ensure, :parent => Puppet::Property::Ensure) do
160:                 self.defaultvalues
161:             end
162:         end
163:     end

Should we add the ‘ensure’ property to this class?

[Source]

     # File lib/puppet/type.rb, line 166
166:     def self.ensurable?
167:         # If the class has all three of these methods defined, then it's
168:         # ensurable.
169:         ens = [:exists?, :create, :destroy].inject { |set, method|
170:             set &&= self.public_method_defined?(method)
171:         }
172: 
173:         return ens
174:     end

Deal with any options passed into parameters.

[Source]

     # File lib/puppet/type.rb, line 177
177:     def self.handle_param_options(name, options)
178:         # If it's a boolean parameter, create a method to test the value easily
179:         if options[:boolean]
180:             define_method(name.to_s + "?") do
181:                 val = self[name]
182:                 if val == :true or val == true
183:                     return true
184:                 end
185:             end
186:         end
187:         
188:         # If this param handles relationships, store that information
189:     end

does the type have an object with the given name?

[Source]

      # File lib/puppet/type.rb, line 1181
1181:     def self.has_key?(name)
1182:         return @objects.has_key?(name)
1183:     end

Convert a hash, as provided by, um, a provider, into an instance of self.

[Source]

      # File lib/puppet/type.rb, line 1748
1748:     def self.hash2obj(hash)
1749:         obj = nil
1750:         
1751:         namevar = self.namevar
1752:         unless hash.include?(namevar) and hash[namevar]
1753:             raise Puppet::DevError, "Hash was not passed with namevar"
1754:         end
1755: 
1756:         # if the obj already exists with that name...
1757:         if obj = self[hash[namevar]]
1758:             # We're assuming here that objects with the same name
1759:             # are the same object, which *should* be the case, assuming
1760:             # we've set up our naming stuff correctly everywhere.
1761: 
1762:             # Mark found objects as present
1763:             hash.each { |param, value|
1764:                 if property = obj.property(param)
1765:                 elsif val = obj[param]
1766:                     obj[param] = val
1767:                 else
1768:                     # There is a value on disk, but it should go away
1769:                     obj[param] = :absent
1770:                 end
1771:             }
1772:         else
1773:             # create a new obj, since no existing one seems to
1774:             # match
1775:             obj = self.create(namevar => hash[namevar])
1776: 
1777:             # We can't just pass the hash in at object creation time,
1778:             # because it sets the should value, not the is value.
1779:             hash.delete(namevar)
1780:             hash.each { |param, value|
1781:                 obj[param] = value unless obj.add_property_parameter(param)
1782:             }
1783:         end
1784: 
1785:         return obj
1786:     end

Convert a hash to a TransObject.

[Source]

      # File lib/puppet/type.rb, line 1186
1186:     def self.hash2trans(hash)
1187:         title = nil
1188:         if hash.include? :title
1189:             title = hash[:title]
1190:             hash.delete(:title)
1191:         elsif hash.include? self.namevar
1192:             title = hash[self.namevar]
1193:             hash.delete(self.namevar)
1194: 
1195:             if hash.include? :name
1196:                 raise ArgumentError, "Cannot provide both name and %s to %s" %
1197:                     [self.namevar, self.name]
1198:             end
1199:         elsif hash[:name]
1200:             title = hash[:name]
1201:             hash.delete :name
1202:         end
1203: 
1204:         if catalog = hash[:catalog]
1205:             hash.delete(:catalog)
1206:         end
1207: 
1208:         raise(Puppet::Error, "You must specify a title for objects of type %s" % self.to_s) unless title
1209: 
1210:         if hash.include? :type
1211:             unless self.validattr? :type
1212:                 hash.delete :type
1213:             end
1214:         end
1215: 
1216:         # okay, now make a transobject out of hash
1217:         begin
1218:             trans = Puppet::TransObject.new(title, self.name.to_s)
1219:             trans.catalog = catalog if catalog
1220:             hash.each { |param, value|
1221:                 trans[param] = value
1222:             }
1223:         rescue => detail
1224:             raise Puppet::Error, "Could not create %s: %s" %
1225:                 [name, detail]
1226:         end
1227: 
1228:         return trans
1229:     end

all of the variables that must be initialized for each subclass

[Source]

      # File lib/puppet/type.rb, line 2165
2165:     def self.initvars
2166:         # all of the instances of this class
2167:         @objects = Hash.new
2168:         @aliases = Hash.new
2169: 
2170:         @providers = Hash.new
2171:         @defaults = {}
2172: 
2173:         unless defined? @parameters
2174:             @parameters = []
2175:         end
2176: 
2177:         @validproperties = {}
2178:         @properties = []
2179:         @parameters = []
2180:         @paramhash = {}
2181: 
2182:         @attr_aliases = {}
2183: 
2184:         @paramdoc = Hash.new { |hash,key|
2185:           if key.is_a?(String)
2186:             key = key.intern
2187:           end
2188:           if hash.include?(key)
2189:             hash[key]
2190:           else
2191:             "Param Documentation for %s not found" % key
2192:           end
2193:         }
2194: 
2195:         unless defined? @doc
2196:             @doc = ""
2197:         end
2198: 
2199:     end

Retrieve all known instances. Either requires providers or must be overridden.

[Source]

      # File lib/puppet/type.rb, line 1232
1232:     def self.instances
1233:         unless defined?(@providers) and ! @providers.empty?
1234:             raise Puppet::DevError, "%s has no providers and has not overridden 'instances'" % self.name
1235:         end
1236: 
1237:         # Put the default provider first, then the rest of the suitable providers.
1238:         provider_instances = {}
1239:         providers_by_source.collect do |provider|
1240:             provider.instances.collect do |instance|
1241:                 # First try to get the resource if it already exists
1242:                 # Skip instances that map to a managed resource with a different provider
1243:                 next if resource = self[instance.name] and resource.provider.class != instance.class
1244: 
1245:                 # We always want to use the "first" provider instance we find, unless the resource
1246:                 # is already managed and has a different provider set
1247:                 if other = provider_instances[instance.name]
1248:                     Puppet.warning "%s %s found in both %s and %s; skipping the %s version" %
1249:                         [self.name.to_s.capitalize, instance.name, other.class.name, instance.class.name, instance.class.name]
1250:                     next
1251:                 end
1252:                 provider_instances[instance.name] = instance
1253: 
1254:                 if resource
1255:                     resource.provider = instance
1256:                     resource
1257:                 else
1258:                     create(:name => instance.name, :provider => instance, :check => :all)
1259:                 end
1260:             end
1261:         end.flatten.compact
1262:     end

Is this type‘s name isomorphic with the object? That is, if the name conflicts, does it necessarily mean that the objects conflict? Defaults to true.

[Source]

     # File lib/puppet/type.rb, line 714
714:     def self.isomorphic?
715:         if defined? @isomorphic
716:             return @isomorphic
717:         else
718:             return true
719:         end
720:     end

Is the parameter in question a meta-parameter?

[Source]

     # File lib/puppet/type.rb, line 192
192:     def self.metaparam?(param)
193:         @@metaparamhash.include?(symbolize(param))
194:     end

Find the metaparameter class associated with a given metaparameter name.

[Source]

     # File lib/puppet/type.rb, line 197
197:     def self.metaparamclass(name)
198:         @@metaparamhash[symbolize(name)]
199:     end

[Source]

     # File lib/puppet/type.rb, line 205
205:     def self.metaparamdoc(metaparam)
206:         @@metaparamhash[metaparam].doc
207:     end

[Source]

     # File lib/puppet/type.rb, line 201
201:     def self.metaparams
202:         @@metaparams.collect { |param| param.name }
203:     end

Find the namevar

[Source]

     # File lib/puppet/type.rb, line 238
238:     def self.namevar
239:         unless defined? @namevar
240:             params = @parameters.find_all { |param|
241:                 param.isnamevar? or param.name == :name
242:             }
243: 
244:             if params.length > 1
245:                 raise Puppet::DevError, "Found multiple namevars for %s" % self.name
246:             elsif params.length == 1
247:                 @namevar = params[0].name
248:             else
249:                 raise Puppet::DevError, "No namevar for %s" % self.name
250:             end
251:         end
252:         @namevar
253:     end

initialize the type instance

[Source]

      # File lib/puppet/type.rb, line 2267
2267:     def initialize(hash)
2268:         unless defined? @inited
2269:             self.initvars
2270:         end
2271:         namevar = self.class.namevar
2272: 
2273:         orighash = hash
2274: 
2275:         # If we got passed a transportable object, we just pull a bunch of info
2276:         # directly from it.  This is the main object instantiation mechanism.
2277:         if hash.is_a?(Puppet::TransObject)
2278:             # XXX This will need to change when transobjects change to titles.
2279:             self.title = hash.name
2280: 
2281:             #self[:name] = hash[:name]
2282:             [:file, :line, :tags, :catalog].each { |getter|
2283:                 if hash.respond_to?(getter)
2284:                     setter = getter.to_s + "="
2285:                     if val = hash.send(getter)
2286:                         self.send(setter, val)
2287:                     end
2288:                 end
2289:             }
2290: 
2291:             hash = hash.to_hash
2292:         else
2293:             if hash[:title]
2294:                 @title = hash[:title]
2295:                 hash.delete(:title)
2296:             end
2297:         end
2298: 
2299:         # Before anything else, set our parent if it was included
2300:         if hash.include?(:parent)
2301:             @parent = hash[:parent]
2302:             hash.delete(:parent)
2303:         end
2304: 
2305:         # Munge up the namevar stuff so we only have one value.
2306:         hash = self.argclean(hash)
2307: 
2308:         # Let's do the name first, because some things need to happen once
2309:         # we have the name but before anything else
2310: 
2311:         attrs = self.class.allattrs
2312: 
2313:         if hash.include?(namevar)
2314:             #self.send(namevar.to_s + "=", hash[namevar])
2315:             self[namevar] = hash[namevar]
2316:             hash.delete(namevar)
2317:             if attrs.include?(namevar)
2318:                 attrs.delete(namevar)
2319:             else
2320:                 self.devfail "My namevar isn't a valid attribute...?"
2321:             end
2322:         else
2323:             self.devfail "I was not passed a namevar"
2324:         end
2325: 
2326:         # If the name and title differ, set up an alias
2327:         if self.name != self.title
2328:             if obj = self.class[self.name] 
2329:                 if self.class.isomorphic?
2330:                     raise Puppet::Error, "%s already exists with name %s" %
2331:                         [obj.title, self.name]
2332:                 end
2333:             else
2334:                 self.class.alias(self.name, self)
2335:             end
2336:         end
2337: 
2338:         if hash.include?(:provider)
2339:             self[:provider] = hash[:provider]
2340:             hash.delete(:provider)
2341:         else
2342:             setdefaults(:provider)
2343:         end
2344: 
2345:         # This is all of our attributes except the namevar.
2346:         attrs.each { |attr|
2347:             if hash.include?(attr)
2348:                 begin
2349:                     self[attr] = hash[attr]
2350:                 rescue ArgumentError, Puppet::Error, TypeError
2351:                     raise
2352:                 rescue => detail
2353:                     error = Puppet::DevError.new( "Could not set %s on %s: %s" % [attr, self.class.name, detail])
2354:                     error.set_backtrace(detail.backtrace)
2355:                     raise error
2356:                 end
2357:                 hash.delete attr
2358:             end
2359:         }
2360:         
2361:         # Set all default values.
2362:         self.setdefaults
2363: 
2364:         if hash.length > 0
2365:             self.debug hash.inspect
2366:             self.fail("Class %s does not accept argument(s) %s" %
2367:                 [self.class.name, hash.keys.join(" ")])
2368:         end
2369: 
2370:         if self.respond_to?(:validate)
2371:             self.validate
2372:         end
2373:     end

Create a new metaparam. Requires a block and a name, stores it in the @parameters array, and does some basic checking on it.

[Source]

     # File lib/puppet/type.rb, line 211
211:     def self.newmetaparam(name, options = {}, &block)
212:         @@metaparams ||= []
213:         @@metaparamhash ||= {}
214:         name = symbolize(name)
215: 
216:         param = genclass(name,
217:             :parent => options[:parent] || Puppet::Parameter,
218: