diff options
author | Jesse Wolfe <jes5199@gmail.com> | 2010-07-28 14:54:23 -0700 |
---|---|---|
committer | markus <markus@AVA-351181.(none)> | 2010-08-03 15:19:34 -0700 |
commit | 449315a2c705df2396852462a1d1e14774b9f117 (patch) | |
tree | c81d69a277c81fe87f46678475c7a1395d9d970a /lib | |
parent | daa801b9ff8c81e6812a08a3f6ef82f593248e9d (diff) | |
download | puppet-449315a2c705df2396852462a1d1e14774b9f117.tar.gz puppet-449315a2c705df2396852462a1d1e14774b9f117.tar.xz puppet-449315a2c705df2396852462a1d1e14774b9f117.zip |
[#4397]+[#4344] Move type-name resolution out of Puppet::Resource into the AST resources.
Move type-name resolution out of Puppet::Resource into the AST resources.
Move find_resource_type out of Puppet::Resource into Scope
Thus, never pass unqualified type names to Puppet::Resource objects.
Thus, Puppet::Resource objects don't need the namespace property,
and Puppet::Resource objects never consult the harddrive to look for
.pp files that might contain their type definitions,
Thus, performance is improved.
Also removes the temporary fix for #4257 that caused #4397
(The code was too eager to look for a class in the topscope)
Paired-With: Paul Berry <paul@puppetlabs.com>
Signed-off-by: Jesse Wolfe <jes5199@gmail.com>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/puppet/parser/ast/resource.rb | 6 | ||||
-rw-r--r-- | lib/puppet/parser/ast/resource_reference.rb | 25 | ||||
-rw-r--r-- | lib/puppet/parser/resource.rb | 6 | ||||
-rw-r--r-- | lib/puppet/parser/scope.rb | 14 | ||||
-rw-r--r-- | lib/puppet/resource.rb | 128 | ||||
-rw-r--r-- | lib/puppet/resource/type_collection.rb | 8 |
6 files changed, 57 insertions, 130 deletions
diff --git a/lib/puppet/parser/ast/resource.rb b/lib/puppet/parser/ast/resource.rb index 1b063c984..9149b06c3 100644 --- a/lib/puppet/parser/ast/resource.rb +++ b/lib/puppet/parser/ast/resource.rb @@ -33,11 +33,11 @@ class Resource < AST::ResourceReference # This is where our implicit iteration takes place; if someone # passed an array as the name, then we act just like the called us # many times. + resource_type = scope.find_resource_type(type) resource_titles.flatten.collect { |resource_title| exceptwrap :type => Puppet::ParseError do - - resource = Puppet::Parser::Resource.new( - type, resource_title, + resource = Puppet::Parser::Resource.new( + resource_type.name, resource_title, :parameters => paramobjects, :file => self.file, :line => self.line, diff --git a/lib/puppet/parser/ast/resource_reference.rb b/lib/puppet/parser/ast/resource_reference.rb index 5d8334335..5b1b0aa3a 100644 --- a/lib/puppet/parser/ast/resource_reference.rb +++ b/lib/puppet/parser/ast/resource_reference.rb @@ -7,8 +7,29 @@ class Puppet::Parser::AST::ResourceReference < Puppet::Parser::AST::Branch # Evaluate our object, but just return a simple array of the type # and name. def evaluate(scope) - titles = Array(title.safeevaluate(scope)).collect { |t| Puppet::Resource.new(type, t, :namespaces => scope.namespaces) } - return(titles.length == 1 ? titles.pop : titles) + a_type = type + titles = Array(title.safeevaluate(scope)) + + case type.downcase + when "class" + # resolve the titles + titles = titles.collect do |a_title| + hostclass = scope.find_hostclass(a_title) + hostclass ? hostclass.name : a_title + end + when "node" + # no-op + else + # resolve the type + resource_type = scope.find_resource_type(type) + a_type = resource_type.name if resource_type + end + + resources = titles.collect{ |a_title| + Puppet::Resource.new(a_type, a_title) + } + + return(resources.length == 1 ? resources.pop : resources) end def to_s diff --git a/lib/puppet/parser/resource.rb b/lib/puppet/parser/resource.rb index 3c451929e..8a5ae886c 100644 --- a/lib/puppet/parser/resource.rb +++ b/lib/puppet/parser/resource.rb @@ -102,9 +102,9 @@ class Puppet::Parser::Resource < Puppet::Resource end def initialize(*args) + raise ArgumentError, "Resources require a scope" unless args.last[:scope] super - raise ArgumentError, "Resources require a scope" unless scope @source ||= scope.source end @@ -140,10 +140,6 @@ class Puppet::Parser::Resource < Puppet::Resource self[:name] || self.title end - def namespaces - scope.namespaces - end - # A temporary occasion, until I get paths in the scopes figured out. def path to_s diff --git a/lib/puppet/parser/scope.rb b/lib/puppet/parser/scope.rb index ae0f9ea4a..2ca28d824 100644 --- a/lib/puppet/parser/scope.rb +++ b/lib/puppet/parser/scope.rb @@ -474,6 +474,20 @@ class Puppet::Parser::Scope end end + def find_resource_type(type) + # It still works fine without the type == 'class' short-cut, but it is a lot slower. + return nil if ["class", "node"].include? type.to_s.downcase + find_builtin_resource_type(type) || find_defined_resource_type(type) + end + + def find_builtin_resource_type(type) + Puppet::Type.type(type.to_s.downcase.to_sym) + end + + def find_defined_resource_type(type) + environment.known_resource_types.find_definition(namespaces, type.to_s.downcase) + end + private def extend_with_functions_module diff --git a/lib/puppet/resource.rb b/lib/puppet/resource.rb index 96d22e414..c4e52af18 100644 --- a/lib/puppet/resource.rb +++ b/lib/puppet/resource.rb @@ -13,7 +13,7 @@ class Puppet::Resource extend Puppet::Util::Pson include Enumerable attr_accessor :file, :line, :catalog, :exported, :virtual, :validate_parameters, :strict - attr_reader :namespaces + attr_reader :type, :title require 'puppet/indirector' extend Puppet::Indirector @@ -157,27 +157,26 @@ class Puppet::Resource # Create our resource. def initialize(type, title = nil, attributes = {}) @parameters = {} - @namespaces = [""] - # Set things like namespaces and strictness first. + # Set things like strictness first. attributes.each do |attr, value| next if attr == :parameters send(attr.to_s + "=", value) end - # We do namespaces first, and use tmp variables, so our title - # canonicalization works (i.e., namespaces are set and resource - # types can be looked up) - tmp_type, tmp_title = extract_type_and_title(type, title) - self.type = tmp_type - self.title = tmp_title + @type, @title = extract_type_and_title(type, title) + + @type = munge_type_name(@type) + + if @type == "Class" + @title = :main if @title == "" + @title = munge_type_name(@title) + end if params = attributes[:parameters] extract_parameters(params) end - resolve_type_and_title - tag(self.type) tag(self.title) if valid_tag?(self.title) @@ -193,17 +192,12 @@ class Puppet::Resource return(catalog ? catalog.resource(to_s) : nil) end - def title=(value) - @unresolved_title = value - @title = nil - end - def resource_type @resource_type ||= case type - when "Class"; find_hostclass(title) - when "Node"; find_node(title) + when "Class"; known_resource_types.hostclass(title == :main ? "" : title) + when "Node"; known_resource_types.node(title) else - find_resource_type(type) + Puppet::Type.type(type.to_s.downcase.to_sym) || known_resource_types.definition(type) end end @@ -314,28 +308,6 @@ class Puppet::Resource self end - # We have to lazy-evaluate this. - def title=(value) - @title = nil - @unresolved_title = value - end - - # We have to lazy-evaluate this. - def type=(value) - @type = nil - @unresolved_type = value || "Class" - end - - def title - resolve_type_and_title unless @title - @title - end - - def type - resolve_type_and_title unless @type - @type - end - def valid_parameter?(name) resource_type.valid_parameter?(name) end @@ -346,29 +318,6 @@ class Puppet::Resource private - def find_node(name) - known_resource_types.node(name) - end - - def find_hostclass(title) - name = title == :main ? "" : title - known_resource_types.find_hostclass(namespaces, name) - end - - def find_resource_type(type) - # It still works fine without the type == 'class' short-cut, but it is a lot slower. - return nil if ["class", "node"].include? type.to_s.downcase - find_builtin_resource_type(type) || find_defined_resource_type(type) - end - - def find_builtin_resource_type(type) - Puppet::Type.type(type.to_s.downcase.to_sym) - end - - def find_defined_resource_type(type) - known_resource_types.find_definition(namespaces, type.to_s.downcase) - end - # Produce a canonical method name. def parameter_name(param) param = param.to_s.downcase.to_sym @@ -378,10 +327,6 @@ class Puppet::Resource param end - def namespaces=(ns) - @namespaces = Array(ns) - end - # The namevar for our resource type. If the type doesn't exist, # always use :name. def namevar @@ -428,54 +373,9 @@ class Puppet::Resource value.to_s.split("::").collect { |s| s.capitalize }.join("::") end - # This is an annoyingly complicated method for resolving qualified - # types as necessary, and putting them in type or title attributes. - def resolve_type_and_title - if @unresolved_type - @type = resolve_type - @unresolved_type = nil - end - if @unresolved_title - @title = resolve_title - @unresolved_title = nil - end - end - - def resolve_type - case type = munge_type_name(@unresolved_type) - when "Class", "Node"; - type - else - # Otherwise, some kind of builtin or defined resource type - munge_type_name( (r = find_resource_type(type)) ? r.name : type) - end - end - - # This method only works if resolve_type was called first - def resolve_title - case @type - when "Node"; return @unresolved_title - when "Class"; - resolve_title_for_class(@unresolved_title) - else - @unresolved_title - end - end - - def resolve_title_for_class(title) - if title == "" or title == :main - return :main - end - - if klass = find_hostclass(title) - result = klass.name - end - munge_type_name(result || title) - end - def parse_title h = {} - type = find_resource_type(@type) + type = resource_type if type.respond_to? :title_patterns type.title_patterns.each { |regexp, symbols_and_lambdas| if captures = regexp.match(title.to_s) diff --git a/lib/puppet/resource/type_collection.rb b/lib/puppet/resource/type_collection.rb index 90b6df9c1..63d110395 100644 --- a/lib/puppet/resource/type_collection.rb +++ b/lib/puppet/resource/type_collection.rb @@ -96,8 +96,8 @@ class Puppet::Resource::TypeCollection #Array("") == [] for some reason namespaces = [namespaces] unless namespaces.is_a?(Array) - if r = find_fully_qualified(name, type) - return r + if name =~ /^::/ + return send(type, name.sub(/^::/, '')) end namespaces.each do |namespace| @@ -198,10 +198,6 @@ class Puppet::Resource::TypeCollection private - def find_fully_qualified(name, type) - send(type, name.sub(/^::/, '')) - end - def find_partially_qualified(namespace, name, type) send(type, [namespace, name].join("::")) end |