Class: Puppet::Configurer

Inherits:
Object show all
Includes:
FactHandler, Util
Defined in:
lib/puppet/configurer.rb

Defined Under Namespace

Modules: FactHandler Classes: Downloader, DownloaderFactory, PluginHandler

Constant Summary

Constants included from Util

Util::AbsolutePathPosix, Util::AbsolutePathWindows, Util::DEFAULT_POSIX_MODE, Util::DEFAULT_WINDOWS_MODE

Constants included from Util::POSIX

Util::POSIX::LOCALE_ENV_VARS, Util::POSIX::USER_ENV_VARS

Constants included from Util::SymbolicFileMode

Util::SymbolicFileMode::SetGIDBit, Util::SymbolicFileMode::SetUIDBit, Util::SymbolicFileMode::StickyBit, Util::SymbolicFileMode::SymbolicMode, Util::SymbolicFileMode::SymbolicSpecialToBit

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Util

absolute_path?, benchmark, chuser, clear_environment, default_env, deterministic_rand, deterministic_rand_int, exit_on_fail, get_env, get_environment, logmethods, merge_environment, path_to_uri, pretty_backtrace, replace_file, safe_posix_fork, set_env, symbolizehash, thinmark, uri_encode, uri_query_encode, uri_to_path, which, withenv, withumask

Methods included from Util::POSIX

#get_posix_field, #gid, #idfield, #methodbyid, #methodbyname, #search_posix_field, #uid

Methods included from Util::SymbolicFileMode

#normalize_symbolic_mode, #symbolic_mode_to_int, #valid_symbolic_mode?

Methods included from FactHandler

#facts_for_uploading, #find_facts

Constructor Details

#initialize(factory = Puppet::Configurer::DownloaderFactory.new, transaction_uuid = nil, job_id = nil) ⇒ Configurer

Returns a new instance of Configurer.



59
60
61
62
63
64
65
66
67
68
69
# File 'lib/puppet/configurer.rb', line 59

def initialize(factory = Puppet::Configurer::DownloaderFactory.new, transaction_uuid = nil, job_id = nil)
  @running = false
  @splayed = false
  @cached_catalog_status = 'not_used'
  @environment = Puppet[:environment]
  @transaction_uuid = transaction_uuid || SecureRandom.uuid
  @job_id = job_id
  @static_catalog = true
  @checksum_type = Puppet[:supported_checksum_types]
  @handler = Puppet::Configurer::PluginHandler.new(factory)
end

Instance Attribute Details

#compile_timeObject (readonly)

Returns the value of attribute compile_time.



18
19
20
# File 'lib/puppet/configurer.rb', line 18

def compile_time
  @compile_time
end

#environmentObject (readonly)

Returns the value of attribute environment.



18
19
20
# File 'lib/puppet/configurer.rb', line 18

def environment
  @environment
end

Class Method Details

.should_pluginsync?Boolean

Returns:

  • (Boolean)


25
26
27
28
29
30
31
32
33
34
35
# File 'lib/puppet/configurer.rb', line 25

def self.should_pluginsync?
  if Puppet.settings.set_by_cli?(:pluginsync) || Puppet.settings.set_by_config?(:pluginsync)
    Puppet[:pluginsync]
  else
    if Puppet[:use_cached_catalog]
      false
    else
      true
    end
  end
end

.to_sObject

Provide more helpful strings to the logging that the Agent does



21
22
23
# File 'lib/puppet/configurer.rb', line 21

def self.to_s
  _("Puppet configuration client")
end

Instance Method Details

#apply_catalog(catalog, options) ⇒ Object

Apply supplied catalog and return associated application report



166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/puppet/configurer.rb', line 166

def apply_catalog(catalog, options)
  report = options[:report]
  begin
    report.configuration_version = catalog.version

    benchmark(:notice, _("Applied catalog")) do
      catalog.apply(options)
    end
  ensure
    report.finalize_report
  end
  report
end

#convert_catalog(result, duration) ⇒ Object

Convert a plain resource catalog into our full host catalog.



106
107
108
109
110
111
112
113
# File 'lib/puppet/configurer.rb', line 106

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_commandObject



37
38
39
# File 'lib/puppet/configurer.rb', line 37

def execute_postrun_command
  execute_from_setting(:postrun_command)
end

#execute_prerun_commandObject



41
42
43
# File 'lib/puppet/configurer.rb', line 41

def execute_prerun_command
  execute_from_setting(:prerun_command)
end

#get_facts(options) ⇒ Object



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/puppet/configurer.rb', line 115

def get_facts(options)
  if options[:pluginsync]
    remote_environment_for_plugins = Puppet::Node::Environment.remote(@environment)
    download_plugins(remote_environment_for_plugins)
  end

  facts_hash = {}
  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
    facts_hash = facts_for_uploading
  end
  facts_hash
end

#init_storageObject

Initialize and load storage



46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/puppet/configurer.rb', line 46

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 %{file}: %{detail}") % { file: Puppet[:statefile], detail: detail })
  begin
    Puppet::FileSystem.unlink(Puppet[:statefile])
    retry
  rescue => detail
    raise Puppet::Error.new(_("Cannot remove %{file}: %{detail}") % { file: Puppet[:statefile], detail: detail }, detail)
  end
end

#prepare_and_retrieve_catalog(options, query_options) ⇒ Object



133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/puppet/configurer.rb', line 133

def prepare_and_retrieve_catalog(options, query_options)
  # set report host name now that we have the fact
  options[:report].host = Puppet[:node_name_value]
  query_options[:transaction_uuid] = @transaction_uuid
  query_options[:job_id] = @job_id
  query_options[:static_catalog] = @static_catalog

  # Query params don't enforce ordered evaluation, so munge this list into a
  # dot-separated string.
  query_options[:checksum_type] = @checksum_type.join('.')

  # apply passes in ral catalog
  catalog = options.delete(:catalog)
  return catalog if catalog

  # retrieve_catalog returns json catalog
  catalog = retrieve_catalog(query_options)
  return convert_catalog(catalog, @duration) if catalog

  Puppet.err _("Could not retrieve catalog; skipping run")
  nil
end

#prepare_and_retrieve_catalog_from_cacheObject



156
157
158
159
160
161
162
163
# File 'lib/puppet/configurer.rb', line 156

def prepare_and_retrieve_catalog_from_cache
  result = retrieve_catalog_from_cache({:transaction_uuid => @transaction_uuid, :static_catalog => @static_catalog})
  if result
    Puppet.info _("Using cached catalog from environment '%{catalog_env}'") % { catalog_env: result.environment }
    return convert_catalog(result, @duration)
  end
  nil
end

#retrieve_catalog(query_options) ⇒ Object

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



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/puppet/configurer.rb', line 72

def retrieve_catalog(query_options)
  query_options ||= {}
  if (Puppet[:use_cached_catalog] && result = retrieve_catalog_from_cache(query_options))
    @cached_catalog_status = 'explicitly_requested'

    Puppet.info _("Using cached catalog from environment '%{environment}'") % { environment: result.environment }
  else
    result = retrieve_new_catalog(query_options)

    if !result
      if !Puppet[:usecacheonfailure]
        Puppet.warning _("Not using cache on failed catalog")
        return nil
      end

      result = retrieve_catalog_from_cache(query_options)

      if result
        # don't use use cached catalog if it doesn't match server specified environment
        if @node_environment && result.environment != @environment
          Puppet.err _("Not using cached catalog because its environment '%{catalog_env}' does not match '%{local_env}'") % { catalog_env: result.environment, local_env: @environment }
          return nil
        end

        @cached_catalog_status = 'on_failure'
        Puppet.info _("Using cached catalog from environment '%{catalog_env}'") % { catalog_env: result.environment }
      end
    end
  end

  result
end

#run(options = {}) ⇒ Object

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



183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
# File 'lib/puppet/configurer.rb', line 183

def run(options = {})
  pool = Puppet::Network::HTTP::Pool.new(Puppet[:http_keepalive_timeout])
  # We create the report pre-populated with default settings for
  # environment and transaction_uuid very early, this is to ensure
  # they are sent regardless of any catalog compilation failures or
  # exceptions.
  options[:report] ||= Puppet::Transaction::Report.new(nil, @environment, @transaction_uuid, @job_id)
  report = options[:report]
  init_storage

  Puppet::Util::Log.newdestination(report)

  begin
    Puppet.override(:http_pool => pool) do

      # Skip failover logic if the server_list setting is empty
      if Puppet.settings[:server_list].nil? || Puppet.settings[:server_list].empty?
        do_failover = false;
      else
        do_failover = true
      end
      # When we are passed a catalog, that means we're in apply
      # mode. We shouldn't try to do any failover in that case.
      if options[:catalog].nil? && do_failover
        found = find_functional_server()
        server = found[:server]
        if server.nil?
          Puppet.warning _("Could not select a functional puppet master")
          server = [nil, nil]
        end
        Puppet.override(:server => server[0], :serverport => server[1]) do
          if !server.first.nil?
            Puppet.debug "Selected master: #{server[0]}:#{server[1]}"
            report.master_used = "#{server[0]}:#{server[1]}"
          end

          run_internal(options.merge(:node => found[:node]))
        end
      else
        run_internal(options)
      end
    end
  ensure
    pool.close
  end
end

#save_last_run_summary(report) ⇒ Object



397
398
399
400
401
402
403
404
# File 'lib/puppet/configurer.rb', line 397

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}") % { detail: detail })
end

#send_report(report) ⇒ Object



389
390
391
392
393
394
395
# File 'lib/puppet/configurer.rb', line 389

def send_report(report)
  puts report.summary if Puppet[:summarize]
  save_last_run_summary(report)
  Puppet::Transaction::Report.indirection.save(report, nil, :environment => Puppet::Node::Environment.remote(@environment)) if Puppet[:report]
rescue => detail
  Puppet.log_exception(detail, _("Could not send report: %{detail}") % { detail: detail })
end