class Puppet::Configurer

Attributes

instance[RW]

Puppet agent should only have one instance running, and we need a way to retrieve it.

compile_time[R]
environment[R]

Public Class Methods

new() click to toggle source

Just so we can specify that we are “the” instance.

# File lib/puppet/configurer.rb, line 54
def initialize
  Puppet.settings.use(:main, :ssl, :agent)

  self.class.instance = self
  @running = false
  @splayed = false
  @environment = Puppet[:environment]
end
to_s() click to toggle source

Provide more helpful strings to the logging that the Agent does

# File lib/puppet/configurer.rb, line 20
def self.to_s
  "Puppet configuration client"
end

Public Instance Methods

apply_catalog(catalog, options) click to toggle source

Retrieve (optionally) and apply a catalog. If a catalog is passed in the options, then apply that one, otherwise retrieve it.

# File lib/puppet/configurer.rb, line 116
def apply_catalog(catalog, options)
  report = options[:report]
  report.configuration_version = catalog.version
  report.environment = @environment

  benchmark(:notice, "Finished catalog run") do
    catalog.apply(options)
  end

  report.finalize_report
  report
end
convert_catalog(result, duration) click to toggle source

Convert a plain resource catalog into our full host catalog.

# File lib/puppet/configurer.rb, line 81
def convert_catalog(result, duration)
  catalog = result.to_ral
  catalog.finalize
  catalog.retrieval_duration = duration
  catalog.write_class_file
  catalog.write_resource_file
  catalog
end
execute_postrun_command() click to toggle source
# File lib/puppet/configurer.rb, line 31
def execute_postrun_command
  execute_from_setting(:postrun_command)
end
execute_prerun_command() click to toggle source
# File lib/puppet/configurer.rb, line 35
def execute_prerun_command
  execute_from_setting(:prerun_command)
end
get_facts(options) click to toggle source
# File lib/puppet/configurer.rb, line 90
def get_facts(options)
  download_plugins if options[:pluginsync]

  if Puppet::Resource::Catalog.indirection.terminus_class == :rest
    # This is a bit complicated.  We need the serialized and escaped facts,
    # and we need to know which format they're encoded in.  Thus, we
    # get a hash with both of these pieces of information.
    #
    # facts_for_uploading may set Puppet[:node_name_value] as a side effect
    return facts_for_uploading
  end
end
init_storage() click to toggle source

Initialize and load storage

# File lib/puppet/configurer.rb, line 40
def init_storage
    Puppet::Util::Storage.load
    @compile_time ||= Puppet::Util::Storage.cache(:configuration)[:compile_time]
rescue => detail
  Puppet.log_exception(detail, "Removing corrupt state file #{Puppet[:statefile]}: #{detail}")
  begin
    ::File.unlink(Puppet[:statefile])
    retry
  rescue => detail
    raise Puppet::Error.new("Cannot remove #{Puppet[:statefile]}: #{detail}")
  end
end
prepare_and_retrieve_catalog(options, fact_options) click to toggle source
# File lib/puppet/configurer.rb, line 103
def prepare_and_retrieve_catalog(options, fact_options)
  # set report host name now that we have the fact
  options[:report].host = Puppet[:node_name_value]

  unless catalog = (options.delete(:catalog) || retrieve_catalog(fact_options))
    Puppet.err "Could not retrieve catalog; skipping run"
    return
  end
  catalog
end
retrieve_catalog(fact_options) click to toggle source

Get the remote catalog, yo. Returns nil if no catalog can be found.

# File lib/puppet/configurer.rb, line 64
def retrieve_catalog(fact_options)
  fact_options ||= {}
  # First try it with no cache, then with the cache.
  unless (Puppet[:use_cached_catalog] and result = retrieve_catalog_from_cache(fact_options)) or result = retrieve_new_catalog(fact_options)
    if ! Puppet[:usecacheonfailure]
      Puppet.warning "Not using cache on failed catalog"
      return nil
    end
    result = retrieve_catalog_from_cache(fact_options)
  end

  return nil unless result

  convert_catalog(result, @duration)
end
run(options = {}) click to toggle source

The code that actually runs the catalog. This just passes any options on to the catalog, which accepts :tags and :ignoreschedules.

# File lib/puppet/configurer.rb, line 132
def run(options = {})
  options[:report] ||= Puppet::Transaction::Report.new("apply")
  report = options[:report]
  init_storage

  Puppet::Util::Log.newdestination(report)
  begin
    unless Puppet[:node_name_fact].empty?
      fact_options = get_facts(options)
    end

    begin
      if node = Puppet::Node.indirection.find(Puppet[:node_name_value],
          :environment => @environment, :ignore_cache => true)
        if node.environment.to_s != @environment
          Puppet.warning "Local environment: \"#{@environment}\" doesn't match server specified node environment \"#{node.environment}\", switching agent to \"#{node.environment}\"."
          @environment = node.environment.to_s
          fact_options = nil
        end
      end
    rescue Puppet::Error, Net::HTTPError => detail
      Puppet.warning("Unable to fetch my node definition, but the agent run will continue:")
      Puppet.warning(detail)
    end

    fact_options = get_facts(options) unless fact_options

    unless catalog = prepare_and_retrieve_catalog(options, fact_options)
      return nil
    end

    # Here we set the local environment based on what we get from the
    # catalog. Since a change in environment means a change in facts, and
    # facts may be used to determine which catalog we get, we need to
    # rerun the process if the environment is changed.
    tries = 0
    while catalog.environment and not catalog.environment.empty? and catalog.environment != @environment
      if tries > 3
        raise Puppet::Error, "Catalog environment didn't stabilize after #{tries} fetches, aborting run"
      end
      Puppet.warning "Local environment: \"#{@environment}\" doesn't match server specified environment \"#{catalog.environment}\", restarting agent run with environment \"#{catalog.environment}\""
      @environment = catalog.environment
      return nil unless catalog = prepare_and_retrieve_catalog(options, fact_options)
      tries += 1
    end

    execute_prerun_command or return nil
    apply_catalog(catalog, options)
    report.exit_status
  rescue => detail
    Puppet.log_exception(detail, "Failed to apply catalog: #{detail}")
    return nil
  ensure
    execute_postrun_command or return nil
  end
ensure
  # Between Puppet runs we need to forget the cached values.  This lets us
  # pick up on new functions installed by gems or new modules being added
  # without the daemon being restarted.
  Thread.current[:env_module_directories] = nil

  Puppet::Util::Log.close(report)
  send_report(report)
end
save_last_run_summary(report) click to toggle source
# File lib/puppet/configurer.rb, line 205
def save_last_run_summary(report)
  mode = Puppet.settings.setting(:lastrunfile).mode
  Puppet::Util.replace_file(Puppet[:lastrunfile], mode) do |fh|
    fh.print YAML.dump(report.raw_summary)
  end
rescue => detail
  Puppet.log_exception(detail, "Could not save last run local report: #{detail}")
end
send_report(report) click to toggle source
# File lib/puppet/configurer.rb, line 197
def send_report(report)
  puts report.summary if Puppet[:summarize]
  save_last_run_summary(report)
  Puppet::Transaction::Report.indirection.save(report, nil, :environment => @environment) if Puppet[:report]
rescue => detail
  Puppet.log_exception(detail, "Could not send report: #{detail}")
end