From cb0c4eebb0a7b2fadc5e0487e1c692007cb8b2e5 Mon Sep 17 00:00:00 2001 From: Luke Kanies Date: Tue, 11 Dec 2007 15:35:36 -0600 Subject: Renaming 'configuration' to 'catalog', fixing #954. --- lib/puppet/dsl.rb | 4 +- lib/puppet/indirector/catalog/compiler.rb | 173 +++++++++ lib/puppet/indirector/catalog/yaml.rb | 24 ++ lib/puppet/indirector/configuration/compiler.rb | 173 --------- lib/puppet/indirector/configuration/yaml.rb | 24 -- lib/puppet/metatype/evaluation.rb | 2 +- lib/puppet/metatype/instances.rb | 6 +- lib/puppet/metatype/metaparams.rb | 10 +- lib/puppet/network/client/master.rb | 76 ++-- lib/puppet/network/handler/resource.rb | 8 +- lib/puppet/node/catalog.rb | 480 ++++++++++++++++++++++++ lib/puppet/node/configuration.rb | 480 ------------------------ lib/puppet/parser/ast/hostclass.rb | 2 +- lib/puppet/parser/compile.rb | 40 +- lib/puppet/parser/functions.rb | 2 +- lib/puppet/parser/interpreter.rb | 2 +- lib/puppet/resource_reference.rb | 6 +- lib/puppet/transaction.rb | 26 +- lib/puppet/transportable.rb | 14 +- lib/puppet/type.rb | 16 +- lib/puppet/type/component.rb | 2 +- lib/puppet/type/pfile.rb | 10 +- lib/puppet/util/settings.rb | 6 +- 23 files changed, 793 insertions(+), 793 deletions(-) create mode 100644 lib/puppet/indirector/catalog/compiler.rb create mode 100644 lib/puppet/indirector/catalog/yaml.rb delete mode 100644 lib/puppet/indirector/configuration/compiler.rb delete mode 100644 lib/puppet/indirector/configuration/yaml.rb create mode 100644 lib/puppet/node/catalog.rb delete mode 100644 lib/puppet/node/configuration.rb (limited to 'lib/puppet') diff --git a/lib/puppet/dsl.rb b/lib/puppet/dsl.rb index c1b86e06d..4fbce556c 100644 --- a/lib/puppet/dsl.rb +++ b/lib/puppet/dsl.rb @@ -67,8 +67,8 @@ module Puppet def apply bucket = export() - configuration = bucket.to_configuration - configuration.apply + catalog = bucket.to_catalog + catalog.apply end def export diff --git a/lib/puppet/indirector/catalog/compiler.rb b/lib/puppet/indirector/catalog/compiler.rb new file mode 100644 index 000000000..6d769b97d --- /dev/null +++ b/lib/puppet/indirector/catalog/compiler.rb @@ -0,0 +1,173 @@ +require 'puppet/node' +require 'puppet/node/catalog' +require 'puppet/indirector/code' +require 'puppet/parser/interpreter' +require 'yaml' + +class Puppet::Node::Catalog::Compiler < Puppet::Indirector::Code + desc "Puppet's catalog compilation interface, and its back-end is + Puppet's compiler" + + include Puppet::Util + + attr_accessor :code + + # Compile a node's catalog. + def find(key, client = nil, clientip = nil) + if key.is_a?(Puppet::Node) + node = key + else + node = find_node(key) + end + + if catalog = compile(node) + return catalog.to_transportable + else + # This shouldn't actually happen; we should either return + # a config or raise an exception. + return nil + end + end + + def initialize + set_server_facts + end + + # Create/return our interpreter. + def interpreter + unless defined?(@interpreter) and @interpreter + @interpreter = create_interpreter + end + @interpreter + end + + # Is our compiler part of a network, or are we just local? + def networked? + $0 =~ /puppetmasterd/ + end + + # Return the catalog version. Here we're returning the + # latest of the node, fact, or parse date. These are the + # three things that go into compiling a client catalog, + # so changes in any of them result in changes. + # LAK:FIXME Note that this only works when all three sources + # use timestamps; once one of them moves to using real versions, + # the comparison stops working. + def version(key) + if node = Puppet::Node.find_by_any_name(key) + return [Puppet::Node.version(key).to_f, Puppet::Node::Facts.version(key).to_f, interpreter.catalog_version(node).to_f].sort[-1] + else + # This is the standard for "got nothing for ya". + 0 + end + end + + private + + # Add any extra data necessary to the node. + def add_node_data(node) + # Merge in our server-side facts, so they can be used during compilation. + node.merge(@server_facts) + end + + # Compile the actual catalog. + def compile(node) + # Ask the interpreter to compile the catalog. + str = "Compiled catalog for %s" % node.name + if node.environment + str += " in environment %s" % node.environment + end + config = nil + + loglevel = networked? ? :notice : :none + + benchmark(loglevel, "Compiled catalog for %s" % node.name) do + begin + config = interpreter.compile(node) + rescue Puppet::Error => detail + Puppet.err(detail.to_s) if networked? + raise + end + end + + return config + end + + # Create our interpreter object. + def create_interpreter + return Puppet::Parser::Interpreter.new + end + + # Turn our host name into a node object. + def find_node(key) + # If we want to use the cert name as our key + # LAK:FIXME This needs to be figured out somehow, but it requires the routing. + #if Puppet[:node_name] == 'cert' and client + # key = client + #end + + # Note that this is reasonable, because either their node source should actually + # know about the node, or they should be using the ``null`` node source, which + # will always return data. + unless node = Puppet::Node.find_by_any_name(key) + raise Puppet::Error, "Could not find node '%s'" % key + end + + # Add any external data to the node. + add_node_data(node) + + node + end + + # Initialize our server fact hash; we add these to each client, and they + # won't change while we're running, so it's safe to cache the values. + def set_server_facts + @server_facts = {} + + # Add our server version to the fact list + @server_facts["serverversion"] = Puppet.version.to_s + + # And then add the server name and IP + {"servername" => "fqdn", + "serverip" => "ipaddress" + }.each do |var, fact| + if value = Facter.value(fact) + @server_facts[var] = value + else + Puppet.warning "Could not retrieve fact %s" % fact + end + end + + if @server_facts["servername"].nil? + host = Facter.value(:hostname) + if domain = Facter.value(:domain) + @server_facts["servername"] = [host, domain].join(".") + else + @server_facts["servername"] = host + end + end + end + + # Translate our catalog appropriately for sending back to a client. + # LAK:FIXME This method should probably be part of the protocol, but it + # shouldn't be here. + def translate(config) + unless networked? + config + else + CGI.escape(config.to_yaml(:UseBlock => true)) + end + end + + # Mark that the node has checked in. LAK:FIXME this needs to be moved into + # the Node class, or somewhere that's got abstract backends. + def update_node_check(node) + if Puppet.features.rails? and Puppet[:storeconfigs] + Puppet::Rails.connect + + host = Puppet::Rails::Host.find_or_create_by_name(node.name) + host.last_freshcheck = Time.now + host.save + end + end +end diff --git a/lib/puppet/indirector/catalog/yaml.rb b/lib/puppet/indirector/catalog/yaml.rb new file mode 100644 index 000000000..00241d852 --- /dev/null +++ b/lib/puppet/indirector/catalog/yaml.rb @@ -0,0 +1,24 @@ +require 'puppet/node/catalog' +require 'puppet/indirector/yaml' + +class Puppet::Node::Catalog::Yaml < Puppet::Indirector::Yaml + desc "Store catalogs as flat files, serialized using YAML." + + private + + # Override these, because yaml doesn't want to convert our self-referential + # objects. This is hackish, but eh. + def from_yaml(text) + if config = YAML.load(text) + # We can't yaml-dump classes. + #config.edgelist_class = Puppet::Relationship + return config + end + end + + def to_yaml(config) + # We can't yaml-dump classes. + #config.edgelist_class = nil + YAML.dump(config) + end +end diff --git a/lib/puppet/indirector/configuration/compiler.rb b/lib/puppet/indirector/configuration/compiler.rb deleted file mode 100644 index a0726a433..000000000 --- a/lib/puppet/indirector/configuration/compiler.rb +++ /dev/null @@ -1,173 +0,0 @@ -require 'puppet/node' -require 'puppet/node/configuration' -require 'puppet/indirector/code' -require 'puppet/parser/interpreter' -require 'yaml' - -class Puppet::Node::Configuration::Compiler < Puppet::Indirector::Code - desc "Puppet's configuration compilation interface, and its back-end is - Puppet's compiler" - - include Puppet::Util - - attr_accessor :code - - # Compile a node's configuration. - def find(key, client = nil, clientip = nil) - if key.is_a?(Puppet::Node) - node = key - else - node = find_node(key) - end - - if configuration = compile(node) - return configuration.to_transportable - else - # This shouldn't actually happen; we should either return - # a config or raise an exception. - return nil - end - end - - def initialize - set_server_facts - end - - # Create/return our interpreter. - def interpreter - unless defined?(@interpreter) and @interpreter - @interpreter = create_interpreter - end - @interpreter - end - - # Is our compiler part of a network, or are we just local? - def networked? - $0 =~ /puppetmasterd/ - end - - # Return the configuration version. Here we're returning the - # latest of the node, fact, or parse date. These are the - # three things that go into compiling a client configuration, - # so changes in any of them result in changes. - # LAK:FIXME Note that this only works when all three sources - # use timestamps; once one of them moves to using real versions, - # the comparison stops working. - def version(key) - if node = Puppet::Node.find_by_any_name(key) - return [Puppet::Node.version(key).to_f, Puppet::Node::Facts.version(key).to_f, interpreter.configuration_version(node).to_f].sort[-1] - else - # This is the standard for "got nothing for ya". - 0 - end - end - - private - - # Add any extra data necessary to the node. - def add_node_data(node) - # Merge in our server-side facts, so they can be used during compilation. - node.merge(@server_facts) - end - - # Compile the actual configuration. - def compile(node) - # Ask the interpreter to compile the configuration. - str = "Compiled configuration for %s" % node.name - if node.environment - str += " in environment %s" % node.environment - end - config = nil - - loglevel = networked? ? :notice : :none - - benchmark(loglevel, "Compiled configuration for %s" % node.name) do - begin - config = interpreter.compile(node) - rescue Puppet::Error => detail - Puppet.err(detail.to_s) if networked? - raise - end - end - - return config - end - - # Create our interpreter object. - def create_interpreter - return Puppet::Parser::Interpreter.new - end - - # Turn our host name into a node object. - def find_node(key) - # If we want to use the cert name as our key - # LAK:FIXME This needs to be figured out somehow, but it requires the routing. - #if Puppet[:node_name] == 'cert' and client - # key = client - #end - - # Note that this is reasonable, because either their node source should actually - # know about the node, or they should be using the ``null`` node source, which - # will always return data. - unless node = Puppet::Node.find_by_any_name(key) - raise Puppet::Error, "Could not find node '%s'" % key - end - - # Add any external data to the node. - add_node_data(node) - - node - end - - # Initialize our server fact hash; we add these to each client, and they - # won't change while we're running, so it's safe to cache the values. - def set_server_facts - @server_facts = {} - - # Add our server version to the fact list - @server_facts["serverversion"] = Puppet.version.to_s - - # And then add the server name and IP - {"servername" => "fqdn", - "serverip" => "ipaddress" - }.each do |var, fact| - if value = Facter.value(fact) - @server_facts[var] = value - else - Puppet.warning "Could not retrieve fact %s" % fact - end - end - - if @server_facts["servername"].nil? - host = Facter.value(:hostname) - if domain = Facter.value(:domain) - @server_facts["servername"] = [host, domain].join(".") - else - @server_facts["servername"] = host - end - end - end - - # Translate our configuration appropriately for sending back to a client. - # LAK:FIXME This method should probably be part of the protocol, but it - # shouldn't be here. - def translate(config) - unless networked? - config - else - CGI.escape(config.to_yaml(:UseBlock => true)) - end - end - - # Mark that the node has checked in. LAK:FIXME this needs to be moved into - # the Node class, or somewhere that's got abstract backends. - def update_node_check(node) - if Puppet.features.rails? and Puppet[:storeconfigs] - Puppet::Rails.connect - - host = Puppet::Rails::Host.find_or_create_by_name(node.name) - host.last_freshcheck = Time.now - host.save - end - end -end diff --git a/lib/puppet/indirector/configuration/yaml.rb b/lib/puppet/indirector/configuration/yaml.rb deleted file mode 100644 index 1330aaffa..000000000 --- a/lib/puppet/indirector/configuration/yaml.rb +++ /dev/null @@ -1,24 +0,0 @@ -require 'puppet/node/configuration' -require 'puppet/indirector/yaml' - -class Puppet::Node::Configuration::Yaml < Puppet::Indirector::Yaml - desc "Store configurations as flat files, serialized using YAML." - - private - - # Override these, because yaml doesn't want to convert our self-referential - # objects. This is hackish, but eh. - def from_yaml(text) - if config = YAML.load(text) - # We can't yaml-dump classes. - #config.edgelist_class = Puppet::Relationship - return config - end - end - - def to_yaml(config) - # We can't yaml-dump classes. - #config.edgelist_class = nil - YAML.dump(config) - end -end diff --git a/lib/puppet/metatype/evaluation.rb b/lib/puppet/metatype/evaluation.rb index 0451d50a7..b3b6570b2 100644 --- a/lib/puppet/metatype/evaluation.rb +++ b/lib/puppet/metatype/evaluation.rb @@ -32,7 +32,7 @@ class Puppet::Type # If we're in noop mode, we don't want to store the checked time, # because it will result in the resource not getting scheduled if - # someone were to run the configuration in non-noop mode. + # someone were to apply the catalog in non-noop mode. # We're going to go ahead and record that we checked if there were # no changes, since it's unlikely it will affect the scheduling. noop = noop? diff --git a/lib/puppet/metatype/instances.rb b/lib/puppet/metatype/instances.rb index f6773f0b3..3f44413f8 100644 --- a/lib/puppet/metatype/instances.rb +++ b/lib/puppet/metatype/instances.rb @@ -221,8 +221,8 @@ class Puppet::Type hash.delete :name end - if configuration = hash[:configuration] - hash.delete(:configuration) + if catalog = hash[:catalog] + hash.delete(:catalog) end raise(Puppet::Error, "You must specify a title for objects of type %s" % self.to_s) unless title @@ -236,7 +236,7 @@ class Puppet::Type # okay, now make a transobject out of hash begin trans = Puppet::TransObject.new(title, self.name.to_s) - trans.configuration = configuration if configuration + trans.catalog = catalog if catalog hash.each { |param, value| trans[param] = value } diff --git a/lib/puppet/metatype/metaparams.rb b/lib/puppet/metatype/metaparams.rb index 349a2c1bb..b35adae66 100644 --- a/lib/puppet/metatype/metaparams.rb +++ b/lib/puppet/metatype/metaparams.rb @@ -195,12 +195,12 @@ class Puppet::Type aliases = [aliases] end - raise(ArgumentError, "Cannot add aliases without a configuration") unless @resource.configuration + raise(ArgumentError, "Cannot add aliases without a catalog") unless @resource.catalog @resource.info "Adding aliases %s" % aliases.collect { |a| a.inspect }.join(", ") aliases.each do |other| - if obj = @resource.configuration.resource(@resource.class.name, other) + if obj = @resource.catalog.resource(@resource.class.name, other) unless obj.object_id == @resource.object_id self.fail("%s can not create alias %s: object already exists" % [@resource.title, other]) end @@ -210,8 +210,8 @@ class Puppet::Type # LAK:FIXME Old-school, add the alias to the class. @resource.class.alias(other, @resource) - # Newschool, add it to the configuration. - @resource.configuration.alias(@resource, other) + # Newschool, add it to the catalog. + @resource.catalog.alias(@resource, other) end end end @@ -256,7 +256,7 @@ class Puppet::Type def validate_relationship @value.each do |value| - unless @resource.configuration.resource(*value) + unless @resource.catalog.resource(*value) description = self.class.direction == :in ? "dependency" : "dependent" raise Puppet::Error, "Could not find #{description} %s[%s]" % [value[0].to_s.capitalize, value[1]] end diff --git a/lib/puppet/network/client/master.rb b/lib/puppet/network/client/master.rb index 740f01378..54b1dcaa4 100644 --- a/lib/puppet/network/client/master.rb +++ b/lib/puppet/network/client/master.rb @@ -7,7 +7,7 @@ class Puppet::Network::Client::Master < Puppet::Network::Client @@sync = Sync.new end - attr_accessor :configuration + attr_accessor :catalog attr_reader :compile_time class << self @@ -51,7 +51,7 @@ class Puppet::Network::Client::Master < Puppet::Network::Client # Cache the config def cache(text) - Puppet.info "Caching configuration at %s" % self.cachefile + Puppet.info "Caching catalog at %s" % self.cachefile confdir = ::File.dirname(Puppet[:localconfig]) ::File.open(self.cachefile + ".tmp", "w", 0660) { |f| f.print text @@ -67,10 +67,10 @@ class Puppet::Network::Client::Master < Puppet::Network::Client end def clear - @configuration.clear(true) if @configuration + @catalog.clear(true) if @catalog Puppet::Type.allclear mkdefault_objects - @configuration = nil + @catalog = nil end # Initialize and load storage @@ -93,7 +93,7 @@ class Puppet::Network::Client::Master < Puppet::Network::Client end end - # Check whether our configuration is up to date + # Check whether our catalog is up to date def fresh?(facts) if Puppet[:ignorecache] Puppet.notice "Ignoring cache" @@ -124,7 +124,7 @@ class Puppet::Network::Client::Master < Puppet::Network::Client lockfile.unlock(:anonymous => true) end - # Stop the daemon from making any configuration runs. + # Stop the daemon from making any catalog runs. def disable lockfile.lock(:anonymous => true) end @@ -144,15 +144,15 @@ class Puppet::Network::Client::Master < Puppet::Network::Client # Retrieve the plugins. getplugins() if Puppet[:pluginsync] - if (self.configuration or FileTest.exist?(self.cachefile)) and self.fresh?(facts) + if (self.catalog or FileTest.exist?(self.cachefile)) and self.fresh?(facts) Puppet.info "Configuration is up to date" return if use_cached_config end - Puppet.debug("Retrieving configuration") + Puppet.debug("Retrieving catalog") - # If we can't retrieve the configuration, just return, which will either - # fail, or use the in-memory configuration. + # If we can't retrieve the catalog, just return, which will either + # fail, or use the in-memory catalog. unless yaml_objects = get_actual_config(facts) use_cached_config(true) return @@ -162,7 +162,7 @@ class Puppet::Network::Client::Master < Puppet::Network::Client objects = YAML.load(yaml_objects) rescue => detail msg = "Configuration could not be translated from yaml" - msg += "; using cached configuration" if use_cached_config(true) + msg += "; using cached catalog" if use_cached_config(true) Puppet.warning msg return end @@ -170,26 +170,26 @@ class Puppet::Network::Client::Master < Puppet::Network::Client self.setclasses(objects.classes) # Clear all existing objects, so we can recreate our stack. - clear() if self.configuration + clear() if self.catalog - # Now convert the objects to a puppet configuration graph. + # Now convert the objects to a puppet catalog graph. begin - @configuration = objects.to_configuration + @catalog = objects.to_catalog rescue => detail clear() puts detail.backtrace if Puppet[:trace] msg = "Configuration could not be instantiated: %s" % detail - msg += "; using cached configuration" if use_cached_config(true) + msg += "; using cached catalog" if use_cached_config(true) Puppet.warning msg return end - if ! @configuration.from_cache + if ! @catalog.from_cache self.cache(yaml_objects) end # Keep the state database up to date. - @configuration.host_config = true + @catalog.host_config = true end # A simple proxy method, so it's easy to test. @@ -243,15 +243,15 @@ class Puppet::Network::Client::Master < Puppet::Network::Client end end - # The code that actually runs the configuration. - # This just passes any options on to the configuration, + # The code that actually runs the catalog. + # This just passes any options on to the catalog, # which accepts :tags and :ignoreschedules. def run(options = {}) got_lock = false splay Puppet::Util.sync(:puppetrun).synchronize(Sync::EX) do if !lockfile.lock - Puppet.notice "Lock file %s exists; skipping configuration run" % + Puppet.notice "Lock file %s exists; skipping catalog run" % lockfile.lockfile else got_lock = true @@ -261,14 +261,14 @@ class Puppet::Network::Client::Master < Puppet::Network::Client end rescue => detail puts detail.backtrace if Puppet[:trace] - Puppet.err "Could not retrieve configuration: %s" % detail + Puppet.err "Could not retrieve catalog: %s" % detail end - if self.configuration - @configuration.retrieval_duration = duration - Puppet.notice "Starting configuration run" unless @local - benchmark(:notice, "Finished configuration run") do - @configuration.apply(options) + if self.catalog + @catalog.retrieval_duration = duration + Puppet.notice "Starting catalog run" unless @local + benchmark(:notice, "Finished catalog run") do + @catalog.apply(options) end end end @@ -330,7 +330,7 @@ class Puppet::Network::Client::Master < Puppet::Network::Client if args[:ignore] hash[:ignore] = args[:ignore].split(/\s+/) end - downconfig = Puppet::Node::Configuration.new("downloading") + downconfig = Puppet::Node::Catalog.new("downloading") downconfig.add_resource Puppet::Type.type(:file).create(hash) Puppet.info "Retrieving #{args[:name]}s" @@ -489,7 +489,7 @@ class Puppet::Network::Client::Master < Puppet::Network::Client end end - # Actually retrieve the configuration, either from the server or from a + # Actually retrieve the catalog, either from the server or from a # local master. def get_actual_config(facts) begin @@ -508,18 +508,18 @@ class Puppet::Network::Client::Master < Puppet::Network::Client textfacts = CGI.escape(YAML.dump(facts)) - benchmark(:debug, "Retrieved configuration") do + benchmark(:debug, "Retrieved catalog") do # error handling for this is done in the network client begin textobjects = @driver.getconfig(textfacts, "yaml") begin textobjects = CGI.unescape(textobjects) rescue => detail - raise Puppet::Error, "Could not CGI.unescape configuration" + raise Puppet::Error, "Could not CGI.unescape catalog" end rescue => detail - Puppet.err "Could not retrieve configuration: %s" % detail + Puppet.err "Could not retrieve catalog: %s" % detail return nil end end @@ -562,23 +562,23 @@ class Puppet::Network::Client::Master < Puppet::Network::Client # Use our cached config, optionally specifying whether this is # necessary because of a failure. def use_cached_config(because_of_failure = false) - return true if self.configuration + return true if self.catalog if because_of_failure and ! Puppet[:usecacheonfailure] - @configuration = nil - Puppet.warning "Not using cache on failed configuration" + @catalog = nil + Puppet.warning "Not using cache on failed catalog" return false end return false unless oldtext = self.retrievecache begin - @configuration = YAML.load(oldtext).to_configuration - @configuration.from_cache = true - @configuration.host_config = true + @catalog = YAML.load(oldtext).to_catalog + @catalog.from_cache = true + @catalog.host_config = true rescue => detail puts detail.backtrace if Puppet[:trace] - Puppet.warning "Could not load cached configuration: %s" % detail + Puppet.warning "Could not load cached catalog: %s" % detail clear return false end diff --git a/lib/puppet/network/handler/resource.rb b/lib/puppet/network/handler/resource.rb index 0fcd694fb..f2a339751 100755 --- a/lib/puppet/network/handler/resource.rb +++ b/lib/puppet/network/handler/resource.rb @@ -39,14 +39,14 @@ class Puppet::Network::Handler end end - config = bucket.to_configuration + catalog = bucket.to_catalog - # And then apply the configuration. This way we're reusing all + # And then apply the catalog. This way we're reusing all # the code in there. It should probably just be separated out, though. - transaction = config.apply + transaction = catalog.apply # And then clean up - config.clear(true) + catalog.clear(true) # It'd be nice to return some kind of report, but... at this point # we have no such facility. diff --git a/lib/puppet/node/catalog.rb b/lib/puppet/node/catalog.rb new file mode 100644 index 000000000..a02d59ae9 --- /dev/null +++ b/lib/puppet/node/catalog.rb @@ -0,0 +1,480 @@ +require 'puppet/indirector' +require 'puppet/external/gratr/digraph' + +# This class models a node catalog. It is the thing +# meant to be passed from server to client, and it contains all +# of the information in the catalog, including the resources +# and the relationships between them. +class Puppet::Node::Catalog < Puppet::PGraph + extend Puppet::Indirector + indirects :catalog, :terminus_class => :compiler + + # The host name this is a catalog for. + attr_accessor :name + + # The catalog version. Used for testing whether a catalog + # is up to date. + attr_accessor :version + + # How long this catalog took to retrieve. Used for reporting stats. + attr_accessor :retrieval_duration + + # How we should extract the catalog for sending to the client. + attr_reader :extraction_format + + # We need the ability to set this externally, so we can yaml-dump the + # catalog. + attr_accessor :edgelist_class + + # Whether this is a host catalog, which behaves very differently. + # In particular, reports are sent, graphs are made, and state is + # stored in the state database. If this is set incorrectly, then you often + # end up in infinite loops, because catalogs are used to make things + # that the host catalog needs. + attr_accessor :host_config + + # Whether this graph is another catalog's relationship graph. + # We don't want to accidentally create a relationship graph for another + # relationship graph. + attr_accessor :is_relationship_graph + + # Whether this catalog was retrieved from the cache, which affects + # whether it is written back out again. + attr_accessor :from_cache + + # Add classes to our class list. + def add_class(*classes) + classes.each do |klass| + @classes << klass + end + + # Add the class names as tags, too. + tag(*classes) + end + + # Add one or more resources to our graph and to our resource table. + def add_resource(*resources) + resources.each do |resource| + unless resource.respond_to?(:ref) + raise ArgumentError, "Can only add objects that respond to :ref" + end + + ref = resource.ref + if @resource_table.include?(ref) + raise ArgumentError, "Resource %s is already defined" % ref + else + @resource_table[ref] = resource + end + resource.catalog = self unless is_relationship_graph + add_vertex!(resource) + end + end + + # Create an alias for a resource. + def alias(resource, name) + resource.ref =~ /^(.+)\[/ + + newref = "%s[%s]" % [$1 || resource.class.name, name] + raise(ArgumentError, "Cannot alias %s to %s; resource %s already exists" % [resource.ref, name, newref]) if @resource_table[newref] + @resource_table[newref] = resource + @aliases[resource.ref] << newref + end + + # Apply our catalog to the local host. Valid options + # are: + # :tags - set the tags that restrict what resources run + # during the transaction + # :ignoreschedules - tell the transaction to ignore schedules + # when determining the resources to run + def apply(options = {}) + @applying = true + + Puppet::Util::Storage.load if host_config? + transaction = Puppet::Transaction.new(self) + + transaction.tags = options[:tags] if options[:tags] + transaction.ignoreschedules = true if options[:ignoreschedules] + + transaction.addtimes :config_retrieval => @retrieval_duration + + + begin + transaction.evaluate + rescue Puppet::Error => detail + Puppet.err "Could not apply complete catalog: %s" % detail + rescue => detail + puts detail.backtrace if Puppet[:trace] + Puppet.err "Got an uncaught exception of type %s: %s" % [detail.class, detail] + ensure + # Don't try to store state unless we're a host config + # too recursive. + Puppet::Util::Storage.store if host_config? + end + + yield transaction if block_given? + + transaction.send_report if host_config and (Puppet[:report] or Puppet[:summarize]) + + return transaction + ensure + @applying = false + cleanup() + transaction.cleanup if defined? transaction and transaction + end + + # Are we in the middle of applying the catalog? + def applying? + @applying + end + + def clear(remove_resources = true) + super() + # We have to do this so that the resources clean themselves up. + @resource_table.values.each { |resource| resource.remove } if remove_resources + @resource_table.clear + + if defined?(@relationship_graph) and @relationship_graph + @relationship_graph.clear(false) + @relationship_graph = nil + end + end + + def classes + @classes.dup + end + + # Create an implicit resource, meaning that it will lose out + # to any explicitly defined resources. This method often returns + # nil. + # The quirk of this method is that it's not possible to create + # an implicit resource before an explicit resource of the same name, + # because all explicit resources are created before any generate() + # methods are called on the individual resources. Thus, this + # method can safely just check if an explicit resource already exists + # and toss this implicit resource if so. + def create_implicit_resource(type, options) + unless options.include?(:implicit) + options[:implicit] = true + end + + # This will return nil if an equivalent explicit resource already exists. + # When resource classes no longer retain references to resource instances, + # this will need to be modified to catch that conflict and discard + # implicit resources. + if resource = create_resource(type, options) + resource.implicit = true + + return resource + else + return nil + end + end + + # Create a new resource and register it in the catalog. + def create_resource(type, options) + unless klass = Puppet::Type.type(type) + raise ArgumentError, "Unknown resource type %s" % type + end + return unless resource = klass.create(options) + + @transient_resources << resource if applying? + add_resource(resource) + if @relationship_graph + @relationship_graph.add_resource(resource) unless @relationship_graph.resource(resource.ref) + end + resource + end + + # Make sure we support the requested extraction format. + def extraction_format=(value) + unless respond_to?("extract_to_%s" % value) + raise ArgumentError, "Invalid extraction format %s" % value + end + @extraction_format = value + end + + # Turn our catalog graph into whatever the client is expecting. + def extract + send("extract_to_%s" % extraction_format) + end + + # Create the traditional TransBuckets and TransObjects from our catalog + # graph. This will hopefully be deprecated soon. + def extract_to_transportable + top = nil + current = nil + buckets = {} + + unless main = vertices.find { |res| res.type == "Class" and res.title == :main } + raise Puppet::DevError, "Could not find 'main' class; cannot generate catalog" + end + + # Create a proc for examining edges, which we'll use to build our tree + # of TransBuckets and TransObjects. + bucket = nil + edges = proc do |edge| + # The sources are always non-builtins. + source, target = edge.source, edge.target + unless tmp = buckets[source.to_s] + if tmp = buckets[source.to_s] = source.to_trans + bucket = tmp + else + # This is because virtual resources return nil. If a virtual + # container resource contains realized resources, we still need to get + # to them. So, we keep a reference to the last valid bucket + # we returned and use that if the container resource is virtual. + end + end + bucket = tmp || bucket + if child = target.to_trans + unless bucket + raise "No bucket created for %s" % source + end + bucket.push child + + # It's important that we keep a reference to any TransBuckets we've created, so + # we don't create multiple buckets for children. + unless target.builtin? + buckets[target.to_s] = child + end + end + end + dfs(:start => main, :examine_edge => edges) + + unless main + raise Puppet::DevError, "Could not find 'main' class; cannot generate catalog" + end + + # Retrieve the bucket for the top-level scope and set the appropriate metadata. + unless result = buckets[main.to_s] + # This only happens when the catalog is entirely empty. + result = buckets[main.to_s] = main.to_trans + end + + result.classes = classes + + # Clear the cache to encourage the GC + buckets.clear + return result + end + + # Make sure all of our resources are "finished". + def finalize + @resource_table.values.each { |resource| resource.finish } + + write_graph(:resources) + end + + def host_config? + host_config || false + end + + def initialize(name = nil) + super() + @name = name if name + @extraction_format ||= :transportable + @tags = [] + @classes = [] + @resource_table = {} + @transient_resources = [] + @applying = false + @relationship_graph = nil + + @aliases = Hash.new { |hash, key| hash[key] = [] } + + if block_given? + yield(self) + finalize() + end + end + + # Create a graph of all of the relationships in our catalog. + def relationship_graph + raise(Puppet::DevError, "Tried get a relationship graph for a relationship graph") if self.is_relationship_graph + + unless defined? @relationship_graph and @relationship_graph + # It's important that we assign the graph immediately, because + # the debug messages below use the relationships in the + # relationship graph to determine the path to the resources + # spitting out the messages. If this is not set, + # then we get into an infinite loop. + @relationship_graph = Puppet::Node::Catalog.new + @relationship_graph.host_config = host_config? + @relationship_graph.is_relationship_graph = true + + # First create the dependency graph + self.vertices.each do |vertex| + @relationship_graph.add_vertex! vertex + vertex.builddepends.each do |edge| + @relationship_graph.add_edge!(edge) + end + end + + # Lastly, add in any autorequires + @relationship_graph.vertices.each do |vertex| + vertex.autorequire.each do |edge| + unless @relationship_graph.edge?(edge.source, edge.target) # don't let automatic relationships conflict with manual ones. + unless @relationship_graph.edge?(edge.target, edge.source) + vertex.debug "Autorequiring %s" % [edge.source] + @relationship_graph.add_edge!(edge) + else + vertex.debug "Skipping automatic relationship with %s" % (edge.source == vertex ? edge.target : edge.source) + end + end + end + end + + @relationship_graph.write_graph(:relationships) + + # Then splice in the container information + @relationship_graph.splice!(self, Puppet::Type::Component) + + @relationship_graph.write_graph(:expanded_relationships) + end + @relationship_graph + end + + # Remove the resource from our catalog. Notice that we also call + # 'remove' on the resource, at least until resource classes no longer maintain + # references to the resource instances. + def remove_resource(*resources) + resources.each do |resource| + @resource_table.delete(resource.ref) + @aliases[resource.ref].each { |res_alias| @resource_table.delete(res_alias) } + @aliases[resource.ref].clear + remove_vertex!(resource) if vertex?(resource) + @relationship_graph.remove_vertex!(resource) if @relationship_graph and @relationship_graph.vertex?(resource) + resource.remove + end + end + + # Look a resource up by its reference (e.g., File[/etc/passwd]). + def resource(type, title = nil) + # Always create a resource reference, so that it always canonizes how we + # are referring to them. + if title + ref = Puppet::ResourceReference.new(type, title).to_s + else + # If they didn't provide a title, then we expect the first + # argument to be of the form 'Class[name]', which our + # Reference class canonizes for us. + ref = Puppet::ResourceReference.new(nil, type).to_s + end + if resource = @resource_table[ref] + return resource + elsif defined?(@relationship_graph) and @relationship_graph + @relationship_graph.resource(ref) + end + end + + # Add a tag. + def tag(*names) + names.each do |name| + name = name.to_s + @tags << name unless @tags.include?(name) + if name.include?("::") + name.split("::").each do |sub| + @tags << sub unless @tags.include?(sub) + end + end + end + nil + end + + # Return the list of tags. + def tags + @tags.dup + end + + # Convert our catalog into a RAL catalog. + def to_ral + to_catalog :to_type + end + + # Turn our parser catalog into a transportable catalog. + def to_transportable + to_catalog :to_transobject + end + + # Produce the graph files if requested. + def write_graph(name) + # We only want to graph the main host catalog. + return unless host_config? + + return unless Puppet[:graph] + + Puppet.settings.use(:graphing) + + file = File.join(Puppet[:graphdir], "%s.dot" % name.to_s) + File.open(file, "w") { |f| + f.puts to_dot("name" => name.to_s.capitalize) + } + end + + # LAK:NOTE We cannot yaml-dump the class in the edgelist_class, because classes cannot be + # dumped by default, nor does yaml-dumping # the edge-labels work at this point (I don't + # know why). + # Neither of these matters right now, but I suppose it could at some point. + # We also have to have the vertex_dict dumped after the resource table, because yaml can't + # seem to handle the output of yaml-dumping the vertex_dict. + def to_yaml_properties + props = instance_variables.reject { |v| %w{@edgelist_class @edge_labels @vertex_dict}.include?(v) } + props << "@vertex_dict" + props + end + + private + + def cleanup + unless @transient_resources.empty? + remove_resource(*@transient_resources) + @transient_resources.clear + @relationship_graph = nil + end + end + + # An abstracted method for converting one catalog into another type of catalog. + # This pretty much just converts all of the resources from one class to another, using + # a conversion method. + def to_catalog(convert) + result = self.class.new(self.name) + + map = {} + vertices.each do |resource| + next if resource.respond_to?(:virtual?) and resource.virtual? + + newres = resource.send(convert) + + # We can't guarantee that resources don't munge their names + # (like files do with trailing slashes), so we have to keep track + # of what a resource got converted to. + map[resource.ref] = newres + + result.add_resource newres + end + + message = convert.to_s.gsub "_", " " + edges.each do |edge| + # Skip edges between virtual resources. + next if edge.source.respond_to?(:virtual?) and edge.source.virtual? + next if edge.target.respond_to?(:virtual?) and edge.target.virtual? + + unless source = map[edge.source.ref] + raise Puppet::DevError, "Could not find resource %s when converting %s resources" % [edge.source.ref, message] + end + + unless target = map[edge.target.ref] + raise Puppet::DevError, "Could not find resource %s when converting %s resources" % [edge.target.ref, message] + end + + result.add_edge!(source, target, edge.label) + end + + map.clear + + result.add_class *self.classes + result.tag(*self.tags) + + return result + end +end diff --git a/lib/puppet/node/configuration.rb b/lib/puppet/node/configuration.rb deleted file mode 100644 index 5da539e5c..000000000 --- a/lib/puppet/node/configuration.rb +++ /dev/null @@ -1,480 +0,0 @@ -require 'puppet/indirector' -require 'puppet/external/gratr/digraph' - -# This class models a node configuration. It is the thing -# meant to be passed from server to client, and it contains all -# of the information in the configuration, including the resources -# and the relationships between them. -class Puppet::Node::Configuration < Puppet::PGraph - extend Puppet::Indirector - indirects :configuration, :terminus_class => :compiler - - # The host name this is a configuration for. - attr_accessor :name - - # The configuration version. Used for testing whether a configuration - # is up to date. - attr_accessor :version - - # How long this configuration took to retrieve. Used for reporting stats. - attr_accessor :retrieval_duration - - # How we should extract the configuration for sending to the client. - attr_reader :extraction_format - - # We need the ability to set this externally, so we can yaml-dump the - # configuration. - attr_accessor :edgelist_class - - # Whether this is a host configuration, which behaves very differently. - # In particular, reports are sent, graphs are made, and state is - # stored in the state database. If this is set incorrectly, then you often - # end up in infinite loops, because configurations are used to make things - # that the host configuration needs. - attr_accessor :host_config - - # Whether this graph is another configuration's relationship graph. - # We don't want to accidentally create a relationship graph for another - # relationship graph. - attr_accessor :is_relationship_graph - - # Whether this configuration was retrieved from the cache, which affects - # whether it is written back out again. - attr_accessor :from_cache - - # Add classes to our class list. - def add_class(*classes) - classes.each do |klass| - @classes << klass - end - - # Add the class names as tags, too. - tag(*classes) - end - - # Add one or more resources to our graph and to our resource table. - def add_resource(*resources) - resources.each do |resource| - unless resource.respond_to?(:ref) - raise ArgumentError, "Can only add objects that respond to :ref" - end - - ref = resource.ref - if @resource_table.include?(ref) - raise ArgumentError, "Resource %s is already defined" % ref - else - @resource_table[ref] = resource - end - resource.configuration = self unless is_relationship_graph - add_vertex!(resource) - end - end - - # Create an alias for a resource. - def alias(resource, name) - resource.ref =~ /^(.+)\[/ - - newref = "%s[%s]" % [$1 || resource.class.name, name] - raise(ArgumentError, "Cannot alias %s to %s; resource %s already exists" % [resource.ref, name, newref]) if @resource_table[newref] - @resource_table[newref] = resource - @aliases[resource.ref] << newref - end - - # Apply our configuration to the local host. Valid options - # are: - # :tags - set the tags that restrict what resources run - # during the transaction - # :ignoreschedules - tell the transaction to ignore schedules - # when determining the resources to run - def apply(options = {}) - @applying = true - - Puppet::Util::Storage.load if host_config? - transaction = Puppet::Transaction.new(self) - - transaction.tags = options[:tags] if options[:tags] - transaction.ignoreschedules = true if options[:ignoreschedules] - - transaction.addtimes :config_retrieval => @retrieval_duration - - - begin - transaction.evaluate - rescue Puppet::Error => detail - Puppet.err "Could not apply complete configuration: %s" % detail - rescue => detail - puts detail.backtrace if Puppet[:trace] - Puppet.err "Got an uncaught exception of type %s: %s" % [detail.class, detail] - ensure - # Don't try to store state unless we're a host config - # too recursive. - Puppet::Util::Storage.store if host_config? - end - - yield transaction if block_given? - - transaction.send_report if host_config and (Puppet[:report] or Puppet[:summarize]) - - return transaction - ensure - @applying = false - cleanup() - transaction.cleanup if defined? transaction and transaction - end - - # Are we in the middle of applying the configuration? - def applying? - @applying - end - - def clear(remove_resources = true) - super() - # We have to do this so that the resources clean themselves up. - @resource_table.values.each { |resource| resource.remove } if remove_resources - @resource_table.clear - - if defined?(@relationship_graph) and @relationship_graph - @relationship_graph.clear(false) - @relationship_graph = nil - end - end - - def classes - @classes.dup - end - - # Create an implicit resource, meaning that it will lose out - # to any explicitly defined resources. This method often returns - # nil. - # The quirk of this method is that it's not possible to create - # an implicit resource before an explicit resource of the same name, - # because all explicit resources are created before any generate() - # methods are called on the individual resources. Thus, this - # method can safely just check if an explicit resource already exists - # and toss this implicit resource if so. - def create_implicit_resource(type, options) - unless options.include?(:implicit) - options[:implicit] = true - end - - # This will return nil if an equivalent explicit resource already exists. - # When resource classes no longer retain references to resource instances, - # this will need to be modified to catch that conflict and discard - # implicit resources. - if resource = create_resource(type, options) - resource.implicit = true - - return resource - else - return nil - end - end - - # Create a new resource and register it in the configuration. - def create_resource(type, options) - unless klass = Puppet::Type.type(type) - raise ArgumentError, "Unknown resource type %s" % type - end - return unless resource = klass.create(options) - - @transient_resources << resource if applying? - add_resource(resource) - if @relationship_graph - @relationship_graph.add_resource(resource) unless @relationship_graph.resource(resource.ref) - end - resource - end - - # Make sure we support the requested extraction format. - def extraction_format=(value) - unless respond_to?("extract_to_%s" % value) - raise ArgumentError, "Invalid extraction format %s" % value - end - @extraction_format = value - end - - # Turn our configuration graph into whatever the client is expecting. - def extract - send("extract_to_%s" % extraction_format) - end - - # Create the traditional TransBuckets and TransObjects from our configuration - # graph. This will hopefully be deprecated soon. - def extract_to_transportable - top = nil - current = nil - buckets = {} - - unless main = vertices.find { |res| res.type == "Class" and res.title == :main } - raise Puppet::DevError, "Could not find 'main' class; cannot generate configuration" - end - - # Create a proc for examining edges, which we'll use to build our tree - # of TransBuckets and TransObjects. - bucket = nil - edges = proc do |edge| - # The sources are always non-builtins. - source, target = edge.source, edge.target - unless tmp = buckets[source.to_s] - if tmp = buckets[source.to_s] = source.to_trans - bucket = tmp - else - # This is because virtual resources return nil. If a virtual - # container resource contains realized resources, we still need to get - # to them. So, we keep a reference to the last valid bucket - # we returned and use that if the container resource is virtual. - end - end - bucket = tmp || bucket - if child = target.to_trans - unless bucket - raise "No bucket created for %s" % source - end - bucket.push child - - # It's important that we keep a reference to any TransBuckets we've created, so - # we don't create multiple buckets for children. - unless target.builtin? - buckets[target.to_s] = child - end - end - end - dfs(:start => main, :examine_edge => edges) - - unless main - raise Puppet::DevError, "Could not find 'main' class; cannot generate configuration" - end - - # Retrieve the bucket for the top-level scope and set the appropriate metadata. - unless result = buckets[main.to_s] - # This only happens when the configuration is entirely empty. - result = buckets[main.to_s] = main.to_trans - end - - result.classes = classes - - # Clear the cache to encourage the GC - buckets.clear - return result - end - - # Make sure all of our resources are "finished". - def finalize - @resource_table.values.each { |resource| resource.finish } - - write_graph(:resources) - end - - def host_config? - host_config || false - end - - def initialize(name = nil) - super() - @name = name if name - @extraction_format ||= :transportable - @tags = [] - @classes = [] - @resource_table = {} - @transient_resources = [] - @applying = false - @relationship_graph = nil - - @aliases = Hash.new { |hash, key| hash[key] = [] } - - if block_given? - yield(self) - finalize() - end - end - - # Create a graph of all of the relationships in our configuration. - def relationship_graph - raise(Puppet::DevError, "Tried get a relationship graph for a relationship graph") if self.is_relationship_graph - - unless defined? @relationship_graph and @relationship_graph - # It's important that we assign the graph immediately, because - # the debug messages below use the relationships in the - # relationship graph to determine the path to the resources - # spitting out the messages. If this is not set, - # then we get into an infinite loop. - @relationship_graph = Puppet::Node::Configuration.new - @relationship_graph.host_config = host_config? - @relationship_graph.is_relationship_graph = true - - # First create the dependency graph - self.vertices.each do |vertex| - @relationship_graph.add_vertex! vertex - vertex.builddepends.each do |edge| - @relationship_graph.add_edge!(edge) - end - end - - # Lastly, add in any autorequires - @relationship_graph.vertices.each do |vertex| - vertex.autorequire.each do |edge| - unless @relationship_graph.edge?(edge.source, edge.target) # don't let automatic relationships conflict with manual ones. - unless @relationship_graph.edge?(edge.target, edge.source) - vertex.debug "Autorequiring %s" % [edge.source] - @relationship_graph.add_edge!(edge) - else - vertex.debug "Skipping automatic relationship with %s" % (edge.source == vertex ? edge.target : edge.source) - end - end - end - end - - @relationship_graph.write_graph(:relationships) - - # Then splice in the container information - @relationship_graph.splice!(self, Puppet::Type::Component) - - @relationship_graph.write_graph(:expanded_relationships) - end - @relationship_graph - end - - # Remove the resource from our configuration. Notice that we also call - # 'remove' on the resource, at least until resource classes no longer maintain - # references to the resource instances. - def remove_resource(*resources) - resources.each do |resource| - @resource_table.delete(resource.ref) - @aliases[resource.ref].each { |res_alias| @resource_table.delete(res_alias) } - @aliases[resource.ref].clear - remove_vertex!(resource) if vertex?(resource) - @relationship_graph.remove_vertex!(resource) if @relationship_graph and @relationship_graph.vertex?(resource) - resource.remove - end - end - - # Look a resource up by its reference (e.g., File[/etc/passwd]). - def resource(type, title = nil) - # Always create a resource reference, so that it always canonizes how we - # are referring to them. - if title - ref = Puppet::ResourceReference.new(type, title).to_s - else - # If they didn't provide a title, then we expect the first - # argument to be of the form 'Class[name]', which our - # Reference class canonizes for us. - ref = Puppet::ResourceReference.new(nil, type).to_s - end - if resource = @resource_table[ref] - return resource - elsif defined?(@relationship_graph) and @relationship_graph - @relationship_graph.resource(ref) - end - end - - # Add a tag. - def tag(*names) - names.each do |name| - name = name.to_s - @tags << name unless @tags.include?(name) - if name.include?("::") - name.split("::").each do |sub| - @tags << sub unless @tags.include?(sub) - end - end - end - nil - end - - # Return the list of tags. - def tags - @tags.dup - end - - # Convert our configuration into a RAL configuration. - def to_ral - to_configuration :to_type - end - - # Turn our parser configuration into a transportable configuration. - def to_transportable - to_configuration :to_transobject - end - - # Produce the graph files if requested. - def write_graph(name) - # We only want to graph the main host configuration. - return unless host_config? - - return unless Puppet[:graph] - - Puppet.settings.use(:graphing) - - file = File.join(Puppet[:graphdir], "%s.dot" % name.to_s) - File.open(file, "w") { |f| - f.puts to_dot("name" => name.to_s.capitalize) - } - end - - # LAK:NOTE We cannot yaml-dump the class in the edgelist_class, because classes cannot be - # dumped by default, nor does yaml-dumping # the edge-labels work at this point (I don't - # know why). - # Neither of these matters right now, but I suppose it could at some point. - # We also have to have the vertex_dict dumped after the resource table, because yaml can't - # seem to handle the output of yaml-dumping the vertex_dict. - def to_yaml_properties - props = instance_variables.reject { |v| %w{@edgelist_class @edge_labels @vertex_dict}.include?(v) } - props << "@vertex_dict" - props - end - - private - - def cleanup - unless @transient_resources.empty? - remove_resource(*@transient_resources) - @transient_resources.clear - @relationship_graph = nil - end - end - - # An abstracted method for converting one configuration into another type of configuration. - # This pretty much just converts all of the resources from one class to another, using - # a conversion method. - def to_configuration(convert) - result = self.class.new(self.name) - - map = {} - vertices.each do |resource| - next if resource.respond_to?(:virtual?) and resource.virtual? - - newres = resource.send(convert) - - # We can't guarantee that resources don't munge their names - # (like files do with trailing slashes), so we have to keep track - # of what a resource got converted to. - map[resource.ref] = newres - - result.add_resource newres - end - - message = convert.to_s.gsub "_", " " - edges.each do |edge| - # Skip edges between virtual resources. - next if edge.source.respond_to?(:virtual?) and edge.source.virtual? - next if edge.target.respond_to?(:virtual?) and edge.target.virtual? - - unless source = map[edge.source.ref] - raise Puppet::DevError, "Could not find resource %s when converting %s resources" % [edge.source.ref, message] - end - - unless target = map[edge.target.ref] - raise Puppet::DevError, "Could not find resource %s when converting %s resources" % [edge.target.ref, message] - end - - result.add_edge!(source, target, edge.label) - end - - map.clear - - result.add_class *self.classes - result.tag(*self.tags) - - return result - end -end diff --git a/lib/puppet/parser/ast/hostclass.rb b/lib/puppet/parser/ast/hostclass.rb index d4904bebf..63900d0e3 100644 --- a/lib/puppet/parser/ast/hostclass.rb +++ b/lib/puppet/parser/ast/hostclass.rb @@ -30,7 +30,7 @@ class Puppet::Parser::AST return nil end - scope.compile.configuration.tag(self.classname) + scope.compile.catalog.tag(self.classname) pnames = nil if pklass = self.parentobj diff --git a/lib/puppet/parser/compile.rb b/lib/puppet/parser/compile.rb index 93ba180a7..fdd0cbcf2 100644 --- a/lib/puppet/parser/compile.rb +++ b/lib/puppet/parser/compile.rb @@ -6,15 +6,15 @@ require 'puppet/external/gratr/import' require 'puppet/external/gratr/dot' require 'puppet/node' -require 'puppet/node/configuration' +require 'puppet/node/catalog' require 'puppet/util/errors' # Maintain a graph of scopes, along with a bunch of data -# about the individual configuration we're compiling. +# about the individual catalog we're compiling. class Puppet::Parser::Compile include Puppet::Util include Puppet::Util::Errors - attr_reader :parser, :node, :facts, :collections, :configuration, :node_scope + attr_reader :parser, :node, :facts, :collections, :catalog, :node_scope # Add a collection to the global list. def add_collection(coll) @@ -37,7 +37,7 @@ class Puppet::Parser::Compile end end @class_scopes[name] = scope - @configuration.add_class(name) unless name == "" + @catalog.add_class(name) unless name == "" end # Return the scope associated with a class. This is just here so @@ -55,11 +55,11 @@ class Puppet::Parser::Compile # Return a list of all of the defined classes. def classlist - return @configuration.classes + return @catalog.classes end - # Compile our configuration. This mostly revolves around finding and evaluating classes. - # This is the main entry into our configuration. + # Compile our catalog. This mostly revolves around finding and evaluating classes. + # This is the main entry into our catalog. def compile # Set the client's parameters into the top scope. set_node_parameters() @@ -80,7 +80,7 @@ class Puppet::Parser::Compile store() end - return @configuration + return @catalog end # LAK:FIXME There are no tests for this. @@ -111,7 +111,7 @@ class Puppet::Parser::Compile end # Evaluate each specified class in turn. If there are any classes we can't - # find, just tag the configuration and move on. This method really just + # find, just tag the catalog and move on. This method really just # creates resource objects that point back to the classes, and then the # resources are themselves evaluated later in the process. def evaluate_classes(classes, scope, lazy_evaluate = true) @@ -130,11 +130,11 @@ class Puppet::Parser::Compile # If they've disabled lazy evaluation (which the :include function does), # then evaluate our resource immediately. resource.evaluate unless lazy_evaluate - @configuration.tag(klass.classname) + @catalog.tag(klass.classname) found << name else Puppet.info "Could not find class %s for %s" % [name, node.name] - @configuration.tag(name) + @catalog.tag(name) end end found @@ -224,7 +224,7 @@ class Puppet::Parser::Compile # And in the resource graph. At some point, this might supercede # the global resource table, but the table is a lot faster # so it makes sense to maintain for now. - @configuration.add_edge!(scope.resource, resource) + @catalog.add_edge!(scope.resource, resource) end # The top scope is usually the top-level scope, but if we're using AST nodes, @@ -253,7 +253,7 @@ class Puppet::Parser::Compile # of resources. resource = Puppet::Parser::Resource.new(:type => "node", :title => astnode.classname, :scope => topscope, :source => topscope.source) store_resource(topscope, resource) - @configuration.tag(astnode.classname) + @catalog.tag(astnode.classname) resource.evaluate @@ -311,7 +311,7 @@ class Puppet::Parser::Compile done = false if evaluate_definitions break if done if count > 1000 - raise Puppet::ParseError, "Somehow looped more than 1000 times while evaluating host configuration" + raise Puppet::ParseError, "Somehow looped more than 1000 times while evaluating host catalog" end end end @@ -323,14 +323,14 @@ class Puppet::Parser::Compile @main_resource = Puppet::Parser::Resource.new(:type => "class", :title => :main, :scope => @topscope, :source => @main) @topscope.resource = @main_resource - @configuration.add_vertex!(@main_resource) + @catalog.add_vertex!(@main_resource) @resource_table["Class[main]"] = @main_resource @main_resource.evaluate end - # Make sure the entire configuration is evaluated. + # Make sure the entire catalog is evaluated. def fail_on_unevaluated fail_on_unevaluated_overrides fail_on_unevaluated_resource_collections @@ -420,8 +420,8 @@ class Puppet::Parser::Compile @scope_graph = GRATR::Digraph.new # For maintaining the relationship between scopes and their resources. - @configuration = Puppet::Node::Configuration.new(@node.name) - @configuration.version = @parser.version + @catalog = Puppet::Node::Catalog.new(@node.name) + @catalog.version = @parser.version end # Set the node's parameters into the top-scope as variables. @@ -431,7 +431,7 @@ class Puppet::Parser::Compile end end - # Store the configuration into the database. + # Store the catalog into the database. def store unless Puppet.features.rails? raise Puppet::Error, @@ -451,7 +451,7 @@ class Puppet::Parser::Compile def store_to_active_record(node, resources) begin # We store all of the objects, even the collectable ones - benchmark(:info, "Stored configuration for #{node.name}") do + benchmark(:info, "Stored catalog for #{node.name}") do Puppet::Rails::Host.transaction do Puppet::Rails::Host.store(node, resources) end diff --git a/lib/puppet/parser/functions.rb b/lib/puppet/parser/functions.rb index a0e8da86f..34b38b809 100644 --- a/lib/puppet/parser/functions.rb +++ b/lib/puppet/parser/functions.rb @@ -146,7 +146,7 @@ module Functions tells you whether the current container is tagged with the specified tags. The tags are ANDed, so that all of the specified tags must be included for the function to return true.") do |vals| - configtags = compile.configuration.tags + configtags = compile.catalog.tags resourcetags = resource.tags retval = true diff --git a/lib/puppet/parser/interpreter.rb b/lib/puppet/parser/interpreter.rb index 87513cb18..e29e19944 100644 --- a/lib/puppet/parser/interpreter.rb +++ b/lib/puppet/parser/interpreter.rb @@ -9,7 +9,7 @@ require 'puppet/parser/scope' # The interpreter is a very simple entry-point class that # manages the existence of the parser (e.g., replacing it # when files are reparsed). You can feed it a node and -# get the node's configuration back. +# get the node's catalog back. class Puppet::Parser::Interpreter include Puppet::Util diff --git a/lib/puppet/resource_reference.rb b/lib/puppet/resource_reference.rb index 479de6127..3e92662b2 100644 --- a/lib/puppet/resource_reference.rb +++ b/lib/puppet/resource_reference.rb @@ -8,7 +8,7 @@ require 'puppet' # resources. class Puppet::ResourceReference attr_reader :type - attr_accessor :title, :configuration + attr_accessor :title, :catalog def initialize(type, title) # This will set @type if it looks like a resource reference. @@ -22,8 +22,8 @@ class Puppet::ResourceReference # Find our resource. def resolve - if configuration - return configuration.resource(to_s) + if catalog + return catalog.resource(to_s) end # If it's builtin, then just ask for it directly from the type. if t = builtin_type diff --git a/lib/puppet/transaction.rb b/lib/puppet/transaction.rb index ef53889cf..6a4981298 100644 --- a/lib/puppet/transaction.rb +++ b/lib/puppet/transaction.rb @@ -6,7 +6,7 @@ require 'puppet/propertychange' module Puppet class Transaction - attr_accessor :component, :configuration, :ignoreschedules + attr_accessor :component, :catalog, :ignoreschedules attr_accessor :sorted_resources, :configurator # The report, once generated. @@ -311,7 +311,7 @@ class Transaction ret = eval_resource(resource) end - if Puppet[:evaltrace] and @configuration.host_config? + if Puppet[:evaltrace] and @catalog.host_config? resource.info "Evaluated in %0.2f seconds" % seconds end ret @@ -358,7 +358,7 @@ class Transaction # Collect any dynamically generated resources. def generate - list = @configuration.vertices + list = @catalog.vertices # Store a list of all generated resources, so that we can clean them up # after the transaction closes. @@ -380,8 +380,8 @@ class Transaction end made.uniq! made.each do |res| - @configuration.add_resource(res) - res.configuration = configuration + @catalog.add_resource(res) + res.catalog = catalog newlist << res @generated << res res.finish @@ -424,22 +424,22 @@ class Transaction # Should we ignore tags? def ignore_tags? - ! @configuration.host_config? + ! @catalog.host_config? end # this should only be called by a Puppet::Type::Component resource now # and it should only receive an array def initialize(resources) - if resources.is_a?(Puppet::Node::Configuration) - @configuration = resources + if resources.is_a?(Puppet::Node::Catalog) + @catalog = resources elsif resources.is_a?(Puppet::PGraph) - raise "Transactions should get configurations now, not PGraph" + raise "Transactions should get catalogs now, not PGraph" else - raise "Transactions require configurations" + raise "Transactions require catalogs" end @resourcemetrics = { - :total => @configuration.vertices.length, + :total => @catalog.vertices.length, :out_of_sync => 0, # The number of resources that had changes :applied => 0, # The number of resources fixed :skipped => 0, # The number of resources skipped @@ -478,7 +478,7 @@ class Transaction # types, just providers. def prefetch prefetchers = {} - @configuration.vertices.each do |resource| + @catalog.vertices.each do |resource| if provider = resource.provider and provider.class.respond_to?(:prefetch) prefetchers[provider.class] ||= {} prefetchers[provider.class][resource.title] = resource @@ -511,7 +511,7 @@ class Transaction end def relationship_graph - configuration.relationship_graph + catalog.relationship_graph end # Send off the transaction report. diff --git a/lib/puppet/transportable.rb b/lib/puppet/transportable.rb index 6f5b2761c..c1d68a881 100644 --- a/lib/puppet/transportable.rb +++ b/lib/puppet/transportable.rb @@ -9,7 +9,7 @@ module Puppet # YAML. class TransObject include Enumerable - attr_accessor :type, :name, :file, :line, :configuration + attr_accessor :type, :name, :file, :line, :catalog attr_writer :tags @@ -99,7 +99,7 @@ module Puppet class TransBucket include Enumerable - attr_accessor :name, :type, :file, :line, :classes, :keyword, :top, :configuration + attr_accessor :name, :type, :file, :line, :classes, :keyword, :top, :catalog %w{delete shift include? length empty? << []}.each { |method| define_method(method) do |*args| @@ -179,16 +179,16 @@ module Puppet end # Create a resource graph from our structure. - def to_configuration - configuration = Puppet::Node::Configuration.new(Facter.value("hostname")) do |config| + def to_catalog + catalog = Puppet::Node::Catalog.new(Facter.value("hostname")) do |config| delver = proc do |obj| - obj.configuration = config + obj.catalog = config unless container = config.resource(obj.to_ref) container = obj.to_type config.add_resource container end obj.each do |child| - child.configuration = config + child.catalog = config unless resource = config.resource(child.to_ref) next unless resource = child.to_type config.add_resource resource @@ -203,7 +203,7 @@ module Puppet delver.call(self) end - return configuration + return catalog end def to_ref diff --git a/lib/puppet/type.rb b/lib/puppet/type.rb index 31ffe3bfb..def9e44e4 100644 --- a/lib/puppet/type.rb +++ b/lib/puppet/type.rb @@ -118,8 +118,8 @@ class Type #@validate = block end - # The configuration that this resource is stored in. - attr_accessor :configuration + # The catalog that this resource is stored in. + attr_accessor :catalog # create a log at specified level def log(msg) @@ -186,7 +186,7 @@ class Type self.title = hash.name #self[:name] = hash[:name] - [:file, :line, :tags, :configuration].each { |getter| + [:file, :line, :tags, :catalog].each { |getter| if hash.respond_to?(getter) setter = getter.to_s + "=" if val = hash.send(getter) @@ -289,7 +289,7 @@ class Type self.schedule # Make sure all of our relationships are valid. Again, must be done - # when the entire configuration is instantiated. + # when the entire catalog is instantiated. self.class.relationship_params.collect do |klass| if param = @parameters[klass.name] param.validate_relationship @@ -323,16 +323,16 @@ class Type return self[:name] end - # Look up our parent in the configuration, if we have one. + # Look up our parent in the catalog, if we have one. def parent - return nil unless configuration + return nil unless catalog unless defined?(@parent) # This is kinda weird. if implicit? - parents = configuration.relationship_graph.adjacent(self, :direction => :in) + parents = catalog.relationship_graph.adjacent(self, :direction => :in) else - parents = configuration.adjacent(self, :direction => :in) + parents = catalog.adjacent(self, :direction => :in) end if parents # We should never have more than one parent, so let's just ignore diff --git a/lib/puppet/type/component.rb b/lib/puppet/type/component.rb index 6dc90596d..356205089 100644 --- a/lib/puppet/type/component.rb +++ b/lib/puppet/type/component.rb @@ -140,7 +140,7 @@ Puppet::Type.newtype(:component) do end def refresh - configuration.adjacent(self).each do |child| + catalog.adjacent(self).each do |child| if child.respond_to?(:refresh) child.refresh child.log "triggering %s" % :refresh diff --git a/lib/puppet/type/pfile.rb b/lib/puppet/type/pfile.rb index 73c60bd14..bccdaa265 100644 --- a/lib/puppet/type/pfile.rb +++ b/lib/puppet/type/pfile.rb @@ -574,7 +574,7 @@ module Puppet # Create a new file or directory object as a child to the current # object. def newchild(path, local, hash = {}) - raise(Puppet::DevError, "File recursion cannot happen without a configuration") unless configuration + raise(Puppet::DevError, "File recursion cannot happen without a catalog") unless catalog # make local copy of arguments args = symbolize_options(@arghash) @@ -615,7 +615,7 @@ module Puppet # before 'sourcerecurse'. I could push the override stuff into # a separate method or something, but the work is the same other # than this last bit, so it doesn't really make sense. - if child = configuration.resource(:file, path) + if child = catalog.resource(:file, path) unless child.parent.object_id == self.object_id self.debug "Not managing more explicit file %s" % path @@ -643,7 +643,7 @@ module Puppet begin # This method is used by subclasses of :file, so use the class name rather than hard-coding # :file. - return nil unless child = configuration.create_implicit_resource(self.class.name, args) + return nil unless child = catalog.create_implicit_resource(self.class.name, args) rescue => detail puts detail.backtrace self.notice "Cannot manage: %s" % [detail] @@ -653,7 +653,7 @@ module Puppet # LAK:FIXME This shouldn't be necessary, but as long as we're # modeling the relationship graph specifically, it is. - configuration.relationship_graph.add_edge! self, child + catalog.relationship_graph.add_edge! self, child return child end @@ -663,7 +663,7 @@ module Puppet # time. def pathbuilder # We specifically need to call the method here, so it looks - # up our parent in the configuration graph. + # up our parent in the catalog graph. if parent = parent() # We only need to behave specially when our parent is also # a file diff --git a/lib/puppet/util/settings.rb b/lib/puppet/util/settings.rb index 7b446e736..b672d9564 100644 --- a/lib/puppet/util/settings.rb +++ b/lib/puppet/util/settings.rb @@ -75,7 +75,7 @@ class Puppet::Util::Settings def apply trans = self.to_transportable begin - config = trans.to_configuration + config = trans.to_catalog config.store_state = false config.apply config.clear @@ -590,7 +590,7 @@ class Puppet::Util::Settings # Convert our list of objects into a component that can be applied. def to_configuration transport = self.to_transportable - return transport.to_configuration + return transport.to_catalog end # Convert our list of config elements into a configuration file. @@ -676,7 +676,7 @@ Generated on #{Time.now}. bucket = to_transportable(*sections) - config = bucket.to_configuration + config = bucket.to_catalog config.host_config = false config.apply do |transaction| if failures = transaction.any_failed? -- cgit