class Puppet::Settings

The class for handling configuration files.

Constants

ALLOWED_SECTION_NAMES

The acceptable sections of the puppet.conf configuration file.

DEPRECATION_REFS
NONE
PuppetOptionParser

local reference for convenience

REQUIRED_APP_SETTINGS

These are the settings that every app is required to specify; there are reasonable defaults defined in application.rb.

SETTING_TYPES

Attributes

files[RW]
timer[R]

Public Class Methods

app_defaults_for_run_mode(run_mode) click to toggle source

This method is intended for puppet internal use only; it is a convenience method that returns reasonable application default settings values for a given run_mode.

   # File lib/puppet/settings.rb
57 def self.app_defaults_for_run_mode(run_mode)
58   {
59       :name      => run_mode.to_s,
60       :run_mode  => run_mode.name,
61       :confdir   => run_mode.conf_dir,
62       :codedir   => run_mode.code_dir,
63       :vardir    => run_mode.var_dir,
64       :publicdir => run_mode.public_dir,
65       :rundir    => run_mode.run_dir,
66       :logdir    => run_mode.log_dir,
67   }
68 end
clean_opt(opt, val) click to toggle source

A utility method (public, is used by application.rb and perhaps elsewhere) that munges a command-line option string into the format that Puppet.settings expects. (This mostly has to deal with handling the “no-” prefix on flag/boolean options).

@param [String] opt the command line option that we are munging @param [String, TrueClass, FalseClass] val the value for the setting (as determined by the OptionParser)

    # File lib/puppet/settings.rb
361 def self.clean_opt(opt, val)
362   # rewrite --[no-]option to --no-option if that's what was given
363   if opt =~ /\[no-\]/ and !val
364     opt = opt.gsub(/\[no-\]/,'no-')
365   end
366   # otherwise remove the [no-] prefix to not confuse everybody
367   opt = opt.gsub(/\[no-\]/, '')
368   [opt, val]
369 end
default_certname() click to toggle source
   # File lib/puppet/settings.rb
70 def self.default_certname()
71   hostname = hostname_fact
72   domain = domain_fact
73   if domain and domain != ""
74     fqdn = [hostname, domain].join(".")
75   else
76     fqdn = hostname
77   end
78   fqdn.to_s.gsub(/\.$/, '')
79 end
default_config_file_name() click to toggle source
   # File lib/puppet/settings.rb
89 def self.default_config_file_name
90   "puppet.conf"
91 end
domain_fact() click to toggle source
   # File lib/puppet/settings.rb
85 def self.domain_fact()
86   Facter.value :domain
87 end
hostname_fact() click to toggle source
   # File lib/puppet/settings.rb
81 def self.hostname_fact()
82   Facter.value :hostname
83 end
new() click to toggle source

Create a new collection of config settings.

    # File lib/puppet/settings.rb
134 def initialize
135   @config = {}
136   @shortnames = {}
137 
138   @created = []
139 
140   # Keep track of set values.
141   @value_sets = {
142     :cli => Values.new(:cli, @config),
143     :memory => Values.new(:memory, @config),
144     :application_defaults => Values.new(:application_defaults, @config),
145     :overridden_defaults => Values.new(:overridden_defaults, @config),
146   }
147   @configuration_file = nil
148 
149   # And keep a per-environment cache
150   @cache = Concurrent::Hash.new { |hash, key| hash[key] = Concurrent::Hash.new }
151   @values = Concurrent::Hash.new { |hash, key| hash[key] = Concurrent::Hash.new }
152 
153   # The list of sections we've used.
154   @used = []
155 
156   @hooks_to_call_on_application_initialization = []
157   @deprecated_setting_names = []
158   @deprecated_settings_that_have_been_configured = []
159 
160   @translate = Puppet::Settings::ValueTranslator.new
161   @config_file_parser = Puppet::Settings::ConfigFile.new(@translate)
162 end

Public Instance Methods

[](param) click to toggle source

Retrieve a config value @param param [Symbol] the name of the setting @return [Object] the value of the setting @api private

    # File lib/puppet/settings.rb
168 def [](param)
169   if @deprecated_setting_names.include?(param)
170     issue_deprecation_warning(setting(param), "Accessing '#{param}' as a setting is deprecated.")
171   end
172   value(param)
173 end
[]=(param, value) click to toggle source

Set a config value. This doesn't set the defaults, it sets the value itself. @param param [Symbol] the name of the setting @param value [Object] the new value of the setting @api private

    # File lib/puppet/settings.rb
179 def []=(param, value)
180   if @deprecated_setting_names.include?(param)
181     issue_deprecation_warning(setting(param), "Modifying '#{param}' as a setting is deprecated.")
182   end
183   @value_sets[:memory].set(param, value)
184   unsafe_flush_cache
185 end
addargs(options) click to toggle source

Generate the list of valid arguments, in a format that GetoptLong can understand, and add them to the passed option list.

    # File lib/puppet/settings.rb
203 def addargs(options)
204   # Add all of the settings as valid options.
205   self.each { |name, setting|
206     setting.getopt_args.each { |args| options << args }
207   }
208 
209   options
210 end
app_defaults_initialized?() click to toggle source
    # File lib/puppet/settings.rb
372 def app_defaults_initialized?
373   @app_defaults_initialized
374 end
apply_metadata_from_section(section) click to toggle source
    # File lib/puppet/settings.rb
711 def apply_metadata_from_section(section)
712   section.settings.each do |setting|
713     type = @config[setting.name] if setting.has_metadata?
714     if type
715       type.set_meta(setting.meta)
716     end
717   end
718 end
boolean?(param) click to toggle source

Is our setting a boolean setting?

    # File lib/puppet/settings.rb
224 def boolean?(param)
225   param = param.to_sym
226   @config.include?(param) and @config[param].kind_of?(BooleanSetting)
227 end
clear() click to toggle source

Remove all set values, potentially skipping cli values.

    # File lib/puppet/settings.rb
230 def clear
231   unsafe_clear
232 end
clear_environment_settings(environment) click to toggle source

Clears all cached settings for a particular environment to ensure that changes to environment.conf are reflected in the settings if the environment timeout has expired.

param [String, Symbol] environment the name of environment to clear settings for

@api private

    # File lib/puppet/settings.rb
266 def clear_environment_settings(environment)
267 
268   if environment.nil?
269     return
270   end
271 
272   @cache[environment.to_sym].clear
273   @values[environment.to_sym] = {}
274 end
clearused() click to toggle source
    # File lib/puppet/settings.rb
295 def clearused
296   @cache.clear
297   @used = []
298 end
configsearchpath(environment = nil, run_mode = preferred_run_mode) click to toggle source

The order in which to search for values, without defaults.

@param environment [String,Symbol] symbolic reference to an environment name @param run_mode [Symbol] symbolic reference to a Puppet run mode @return [Array<SearchPathElement>] @api private

    # File lib/puppet/settings.rb
834 def configsearchpath(environment = nil, run_mode = preferred_run_mode)
835   searchpath = [
836     SearchPathElement.new(:memory, :values),
837     SearchPathElement.new(:cli, :values),
838   ]
839   searchpath << SearchPathElement.new(environment.intern, :environment) if environment
840 
841   if run_mode
842     if [:master, :server].include?(run_mode)
843       searchpath << SearchPathElement.new(:server, :section)
844       searchpath << SearchPathElement.new(:master, :section)
845     else
846       searchpath << SearchPathElement.new(run_mode, :section)
847     end
848   end
849 
850   searchpath << SearchPathElement.new(:main, :section)
851 end
define_settings(section, defs) click to toggle source

Define a group of settings.

@param [Symbol] section a symbol to use for grouping multiple settings together into a conceptual unit. This value

(and the conceptual separation) is not used very often; the main place where it will have a potential impact
is when code calls Settings#use method.  See docs on that method for further details, but basically that method
just attempts to do any preparation that may be necessary before code attempts to leverage the value of a particular
setting.  This has the most impact for file/directory settings, where #use will attempt to "ensure" those
files / directories.

@param [Hash] defs the settings to be defined. This argument is a hash of hashes; each key should be a symbol,

which is basically the name of the setting that you are defining.  The value should be another hash that specifies
the parameters for the particular setting.  Legal values include:
 [:default] => not required; this is the value for the setting if no other value is specified (via cli, config file, etc.)
    For string settings this may include "variables", demarcated with $ or ${} which will be interpolated with values of other settings.
    The default value may also be a Proc that will be called only once to evaluate the default when the setting's value is retrieved.
 [:desc] => required; a description of the setting, used in documentation / help generation
 [:type] => not required, but highly encouraged!  This specifies the data type that the setting represents.  If
    you do not specify it, it will default to "string".  Legal values include:
    :string - A generic string setting
    :boolean - A boolean setting; values are expected to be "true" or "false"
    :file - A (single) file path; puppet may attempt to create this file depending on how the settings are used.  This type
        also supports additional options such as "mode", "owner", "group"
    :directory - A (single) directory path; puppet may attempt to create this file depending on how the settings are used.  This type
        also supports additional options such as "mode", "owner", "group"
    :path - This is intended to be used for settings whose value can contain multiple directory paths, represented
        as strings separated by the system path separator (e.g. system path, module path, etc.).
  [:mode] => an (optional) octal value to be used as the permissions/mode for :file and :directory settings
  [:owner] => optional owner username/uid for :file and :directory settings
  [:group] => optional group name/gid for :file and :directory settings
     # File lib/puppet/settings.rb
1003 def define_settings(section, defs)
1004   section = section.to_sym
1005   call = []
1006   defs.each do |name, hash|
1007     raise ArgumentError, _("setting definition for '%{name}' is not a hash!") % { name: name } unless hash.is_a? Hash
1008 
1009     name = name.to_sym
1010     hash[:name] = name
1011     hash[:section] = section
1012     raise ArgumentError, _("Setting %{name} is already defined") % { name: name } if @config.include?(name)
1013     tryconfig = newsetting(hash)
1014     short = tryconfig.short
1015     if short
1016       other = @shortnames[short]
1017       if other
1018         raise ArgumentError, _("Setting %{name} is already using short name '%{short}'") % { name: other.name, short: short }
1019       end
1020       @shortnames[short] = tryconfig
1021     end
1022     @config[name] = tryconfig
1023 
1024     # Collect the settings that need to have their hooks called immediately.
1025     # We have to collect them so that we can be sure we're fully initialized before
1026     # the hook is called.
1027     if tryconfig.has_hook?
1028       if tryconfig.call_hook_on_define?
1029         call << tryconfig
1030       elsif tryconfig.call_hook_on_initialize?
1031         @hooks_to_call_on_application_initialization |= [ tryconfig ]
1032       end
1033     end
1034 
1035     @deprecated_setting_names << name if tryconfig.deprecated?
1036   end
1037 
1038   call.each do |setting|
1039     setting.handle(self.value(setting.name))
1040   end
1041 end
description(name) click to toggle source

Return a value's description.

    # File lib/puppet/settings.rb
428 def description(name)
429   obj = @config[name.to_sym]
430   if obj
431     obj.desc
432   else
433     nil
434   end
435 end
eachsection() { |section| ... } click to toggle source

Iterate over each section name.

    # File lib/puppet/settings.rb
440 def eachsection
441   yielded = []
442   @config.each_value do |object|
443     section = object.section
444     unless yielded.include? section
445       yield section
446       yielded << section
447     end
448   end
449 end
flush_cache() click to toggle source

Clear @cache, @used and the Environment.

Whenever an object is returned by Settings, a copy is stored in @cache. As long as Setting attributes that determine the content of returned objects remain unchanged, Settings can keep returning objects from @cache without re-fetching or re-generating them.

Whenever a Settings attribute changes, such as @values or @preferred_run_mode, this method must be called to clear out the caches so that updated objects will be returned.

    # File lib/puppet/settings.rb
286 def flush_cache
287   unsafe_flush_cache
288 end
generate_config() click to toggle source
    # File lib/puppet/settings.rb
539 def generate_config
540   puts to_config
541   true
542 end
generate_manifest() click to toggle source
    # File lib/puppet/settings.rb
544 def generate_manifest
545   puts to_manifest
546   true
547 end
global_defaults_initialized?() click to toggle source
    # File lib/puppet/settings.rb
300 def global_defaults_initialized?()
301   @global_defaults_initialized
302 end
handlearg(opt, value = nil) click to toggle source

Handle a command-line argument.

    # File lib/puppet/settings.rb
460 def handlearg(opt, value = nil)
461   @cache.clear
462 
463   if value.is_a?(FalseClass)
464     value = "false"
465   elsif value.is_a?(TrueClass)
466     value = "true"
467   end
468 
469   value &&= @translate[value]
470   str = opt.sub(/^--/,'')
471 
472   bool = true
473   newstr = str.sub(/^no-/, '')
474   if newstr != str
475     str = newstr
476     bool = false
477   end
478   str = str.intern
479 
480   if @config[str].is_a?(Puppet::Settings::BooleanSetting)
481     if value == "" or value.nil?
482       value = bool
483     end
484   end
485 
486   s = @config[str]
487   if s
488     @deprecated_settings_that_have_been_configured << s if s.completely_deprecated?
489   end
490 
491   @value_sets[:cli].set(str, value)
492   unsafe_flush_cache
493 end
include?(name) click to toggle source
    # File lib/puppet/settings.rb
495 def include?(name)
496   name = name.intern if name.is_a? String
497   @config.include?(name)
498 end
initialize_app_defaults(app_defaults) click to toggle source
    # File lib/puppet/settings.rb
376 def initialize_app_defaults(app_defaults)
377   REQUIRED_APP_SETTINGS.each do |key|
378     raise SettingsError, "missing required app default setting '#{key}'" unless app_defaults.has_key?(key)
379   end
380 
381   app_defaults.each do |key, value|
382     if key == :run_mode
383       self.preferred_run_mode = value
384     else
385       @value_sets[:application_defaults].set(key, value)
386       unsafe_flush_cache
387     end
388   end
389   apply_metadata
390   call_hooks_deferred_to_application_initialization
391   issue_deprecations
392 
393   REQUIRED_APP_SETTINGS.each do |key|
394     create_ancestors(Puppet[key])
395   end
396 
397   @app_defaults_initialized = true
398 end
initialize_global_settings(args = [], require_config = true) click to toggle source
    # File lib/puppet/settings.rb
304 def initialize_global_settings(args = [], require_config = true)
305   raise Puppet::DevError, _("Attempting to initialize global default settings more than once!") if global_defaults_initialized?
306 
307   # The first two phases of the lifecycle of a puppet application are:
308   # 1) Parse the command line options and handle any of them that are
309   #    registered, defined "global" puppet settings (mostly from defaults.rb).
310   # 2) Parse the puppet config file(s).
311 
312   parse_global_options(args)
313   parse_config_files(require_config)
314 
315   @global_defaults_initialized = true
316 end
optparse_addargs(options) click to toggle source

Generate the list of valid arguments, in a format that OptionParser can understand, and add them to the passed option list.

    # File lib/puppet/settings.rb
214 def optparse_addargs(options)
215   # Add all of the settings as valid options.
216   self.each { |name, setting|
217     options << setting.optparse_args
218   }
219 
220   options
221 end
override_default(param, value) click to toggle source

Create a new default value for the given setting. The default overrides are higher precedence than the defaults given in defaults.rb, but lower precedence than any other values for the setting. This allows one setting `a` to change the default of setting `b`, but still allow a user to provide a value for setting `b`.

@param param [Symbol] the name of the setting @param value [Object] the new default value for the setting @api private

    # File lib/puppet/settings.rb
196 def override_default(param, value)
197   @value_sets[:overridden_defaults].set(param, value)
198   unsafe_flush_cache
199 end
parse_config(text, file = "text") click to toggle source
    # File lib/puppet/settings.rb
580 def parse_config(text, file = "text")
581   begin
582     data = @config_file_parser.parse_file(file, text, ALLOWED_SECTION_NAMES)
583   rescue => detail
584     Puppet.log_exception(detail, "Could not parse #{file}: #{detail}")
585     return
586   end
587 
588   # If we get here and don't have any data, we just return and don't muck with the current state of the world.
589   return if data.nil?
590 
591   # If we get here then we have some data, so we need to clear out any
592   # previous settings that may have come from config files.
593   unsafe_clear(false, false)
594 
595   # Screen settings which have been deprecated and removed from puppet.conf
596   # but are still valid on the command line and/or in environment.conf
597   screen_non_puppet_conf_settings(data)
598 
599   # Make note of deprecated settings we will warn about later in initialization
600   record_deprecations_from_puppet_conf(data)
601 
602   # And now we can repopulate with the values from our last parsing of the config files.
603   @configuration_file = data
604 
605   # Determine our environment, if we have one.
606   if @config[:environment]
607     env = self.value(:environment).to_sym
608   else
609     env = NONE
610   end
611 
612   # Call any hooks we should be calling.
613   value_sets = value_sets_for(env, preferred_run_mode)
614   @config.values.select(&:has_hook?).each do |setting|
615     value_sets.each do |source|
616       if source.include?(setting.name)
617         # We still have to use value to retrieve the value, since
618         # we want the fully interpolated value, not $vardir/lib or whatever.
619         # This results in extra work, but so few of the settings
620         # will have associated hooks that it ends up being less work this
621         # way overall.
622         if setting.call_hook_on_initialize?
623           @hooks_to_call_on_application_initialization |= [ setting ]
624         else
625           setting.handle(ChainedValues.new(
626             preferred_run_mode,
627             env,
628             value_sets,
629             @config).interpolate(setting.name))
630         end
631         break
632       end
633     end
634   end
635 
636   call_hooks_deferred_to_application_initialization :ignore_interpolation_dependency_errors => true
637   apply_metadata
638 end
parse_file(file, allowed_sections = []) click to toggle source

This method just turns a file into a new ConfigFile::Conf instance @param file [String] absolute path to the configuration file @return [Puppet::Settings::ConfigFile::Conf] @api private

     # File lib/puppet/settings.rb
1239 def parse_file(file, allowed_sections = [])
1240   @config_file_parser.parse_file(file, read_file(file), allowed_sections)
1241 end
patch_value(param, value, type) click to toggle source

Patches the value for a param in a section. This method is required to support the use case of unifying –dns-alt-names and –dns_alt_names in the certificate face. Ideally this should be cleaned up. See PUP-3684 for more information. For regular use of setting a value, the method `[]=` should be used. @api private

    # File lib/puppet/settings.rb
967 def patch_value(param, value, type)
968   if @value_sets[type]
969     @value_sets[type].set(param, value)
970     unsafe_flush_cache
971   end
972 end
persection(section) { |obj| ... } click to toggle source

Iterate across all of the objects in a given section.

    # File lib/puppet/settings.rb
775 def persection(section)
776   section = section.to_sym
777   self.each { |name, obj|
778     if obj.section == section
779       yield obj
780     end
781   }
782 end
preferred_run_mode() click to toggle source

The currently configured run mode that is preferred for constructing the application configuration.

    # File lib/puppet/settings.rb
560 def preferred_run_mode
561   @preferred_run_mode_name || :user
562 end
preferred_run_mode=(mode) click to toggle source

PRIVATE! This only exists because we need a hook to validate the run mode when it's being set, and

it should never, ever, ever, ever be called from outside of this file.

This method is also called when –run_mode MODE is used on the command line to set the default

@param mode [String|Symbol] the name of the mode to have in effect @api private

    # File lib/puppet/settings.rb
570 def preferred_run_mode=(mode)
571   mode = mode.to_s.downcase.intern
572   raise ValidationError, "Invalid run mode '#{mode}'" unless [:server, :master, :agent, :user].include?(mode)
573   @preferred_run_mode_name = mode
574   # Changing the run mode has far-reaching consequences. Flush any cached
575   # settings so they will be re-generated.
576   flush_cache
577   mode
578 end
print_config_options() click to toggle source

Prints the contents of a config file with the available config settings, or it prints a single value of a config setting.

print_configs() click to toggle source
print_configs?() click to toggle source
reparse_config_files() click to toggle source

Reparse our config file, if necessary.

    # File lib/puppet/settings.rb
785 def reparse_config_files
786   if files
787     filename = any_files_changed?
788     if filename
789       Puppet.notice "Config file #{filename} changed; triggering re-parse of all config files."
790       parse_config_files
791       reuse
792     end
793   end
794 end
reuse() click to toggle source
    # File lib/puppet/settings.rb
819 def reuse
820   return unless defined?(@used)
821   new = @used
822   @used = []
823   self.use(*new)
824 end
searchpath(environment = nil, run_mode = preferred_run_mode) click to toggle source

The order in which to search for values.

@param environment [String,Symbol] symbolic reference to an environment name @param run_mode [Symbol] symbolic reference to a Puppet run mode @return [Array<SearchPathElement>] @api private

    # File lib/puppet/settings.rb
859 def searchpath(environment = nil, run_mode = preferred_run_mode)
860   searchpath = configsearchpath(environment, run_mode)
861   searchpath << SearchPathElement.new(:application_defaults, :values)
862   searchpath << SearchPathElement.new(:overridden_defaults, :values)
863 end
searchpath_values(source) click to toggle source

Get values from a search path entry. @api private

    # File lib/puppet/settings.rb
914 def searchpath_values(source)
915   case source.type
916   when :values
917     @value_sets[source.name]
918   when :section
919     section = @configuration_file.sections[source.name] if @configuration_file
920     if section
921       ValuesFromSection.new(source.name, section)
922     end
923   when :environment
924     ValuesFromEnvironmentConf.new(source.name)
925   else
926     raise Puppet::DevError, _("Unknown searchpath case: %{source_type} for the %{source} settings path element.") % { source_type: source.type, source: source}
927   end
928 end
service_group_available?() click to toggle source
    # File lib/puppet/settings.rb
881 def service_group_available?
882   return @service_group_available if defined?(@service_group_available)
883 
884   if self[:group]
885     group = Puppet::Type.type(:group).new :name => self[:group], :audit => :ensure
886 
887     if group.suitable?
888       @service_group_available = group.exists?
889     else
890       raise Puppet::Error, (_("Cannot manage group permissions, because the provider for '%{name}' is not functional") % { name: group })
891     end
892   else
893     @service_group_available = false
894   end
895 end
service_user_available?() click to toggle source
    # File lib/puppet/settings.rb
865 def service_user_available?
866   return @service_user_available if defined?(@service_user_available)
867 
868   if self[:user]
869     user = Puppet::Type.type(:user).new :name => self[:user], :audit => :ensure
870 
871     if user.suitable?
872       @service_user_available = user.exists?
873     else
874       raise Puppet::Error, (_("Cannot manage owner permissions, because the provider for '%{name}' is not functional") % { name: user })
875     end
876   else
877     @service_user_available = false
878   end
879 end
set_by_cli(param) click to toggle source

Allow later inspection to determine if the setting was set on the command line, or through some other code path. Used for the `dns_alt_names` option during cert generate. –daniel 2011-10-18

@param param [String, Symbol] the setting to look up @return [Object, nil] the value of the setting or nil if unset

    # File lib/puppet/settings.rb
903 def set_by_cli(param)
904   param = param.to_sym
905   @value_sets[:cli].lookup(param)
906 end
set_by_cli?(param) click to toggle source
    # File lib/puppet/settings.rb
908 def set_by_cli?(param)
909   !!set_by_cli(param)
910 end
set_by_config?(param, environment = nil, run_mode = preferred_run_mode) click to toggle source

Allow later inspection to determine if the setting was set by user config, rather than a default setting.

    # File lib/puppet/settings.rb
932 def set_by_config?(param, environment = nil, run_mode = preferred_run_mode)
933   param = param.to_sym
934   configsearchpath(environment, run_mode).any? do |source|
935     vals = searchpath_values(source)
936     if vals
937       vals.lookup(param)
938     end
939   end
940 end
set_in_section(param, section) click to toggle source

Allow later inspection to determine if the setting was set in a specific section

@param param [String, Symbol] the setting to look up @param section [Symbol] the section in which to look up the setting @return [Object, nil] the value of the setting or nil if unset

    # File lib/puppet/settings.rb
948 def set_in_section(param, section)
949   param = param.to_sym
950   vals = searchpath_values(SearchPathElement.new(section, :section))
951   if vals
952     vals.lookup(param)
953   end
954 end
set_in_section?(param, section) click to toggle source
    # File lib/puppet/settings.rb
956 def set_in_section?(param, section)
957   !!set_in_section(param, section)
958 end
setting(param) click to toggle source

Returns a given setting by name @param name [Symbol] The name of the setting to fetch @return [Puppet::Settings::BaseSetting] The setting object

    # File lib/puppet/settings.rb
454 def setting(param)
455   param = param.to_sym
456   @config[param]
457 end
stringify_settings(section, settings = :all) click to toggle source
    # File lib/puppet/settings.rb
 93 def stringify_settings(section, settings = :all)
 94   values_from_the_selected_section =
 95     values(nil, section.to_sym)
 96 
 97   loader_settings = {
 98     :environmentpath => values_from_the_selected_section.interpolate(:environmentpath),
 99     :basemodulepath => values_from_the_selected_section.interpolate(:basemodulepath),
100   }
101 
102   Puppet.override(Puppet.base_context(loader_settings),
103                   _("New environment loaders generated from the requested section.")) do
104     # And now we can lookup values that include those from environments configured from
105     # the requested section
106     values = values(Puppet[:environment].to_sym, section.to_sym)
107 
108     to_be_rendered = {}
109     settings = Puppet.settings.to_a.collect(&:first) if settings == :all
110     settings.sort.each do |setting_name|
111       to_be_rendered[setting_name] = values.print(setting_name.to_sym)
112     end
113 
114     stringifyhash(to_be_rendered)
115   end
116 end
stringifyhash(hash) click to toggle source
    # File lib/puppet/settings.rb
118 def stringifyhash(hash)
119   newhash = {}
120   hash.each do |key, val|
121     key = key.to_s
122     if val.is_a? Hash
123       newhash[key] = stringifyhash(val)
124     elsif val.is_a? Symbol
125       newhash[key] = val.to_s
126     else
127       newhash[key] = val
128     end
129   end
130   newhash
131 end
to_catalog(*sections) click to toggle source

Convert the settings we manage into a catalog full of resources that model those settings.

     # File lib/puppet/settings.rb
1044 def to_catalog(*sections)
1045   sections = nil if sections.empty?
1046 
1047   catalog = Puppet::Resource::Catalog.new("Settings", Puppet::Node::Environment::NONE)
1048   @config.keys.find_all { |key| @config[key].is_a?(FileSetting) }.each do |key|
1049     file = @config[key]
1050     next if file.value.nil?
1051     next unless (sections.nil? or sections.include?(file.section))
1052     resource = file.to_resource
1053     next unless resource
1054     next if catalog.resource(resource.ref)
1055 
1056     Puppet.debug {"Using settings: adding file resource '#{key}': '#{resource.inspect}'"}
1057 
1058     catalog.add_resource(resource)
1059   end
1060 
1061   add_user_resources(catalog, sections)
1062   add_environment_resources(catalog, sections)
1063 
1064   catalog
1065 end
to_config() click to toggle source

Convert our list of config settings into a configuration file.

     # File lib/puppet/settings.rb
1068   def to_config
1069     str = %{The configuration file for #{Puppet.run_mode.name}.  Note that this file
1070 is likely to have unused settings in it; any setting that's
1071 valid anywhere in Puppet can be in any config file, even if it's not used.
1072 
1073 Every section can specify three special parameters: owner, group, and mode.
1074 These parameters affect the required permissions of any files specified after
1075 their specification.  Puppet will sometimes use these parameters to check its
1076 own configured state, so they can be used to make Puppet a bit more self-managing.
1077 
1078 The file format supports octothorpe-commented lines, but not partial-line comments.
1079 
1080 Generated on #{Time.now}.
1081 
1082 }.gsub(/^/, "# ")
1083 
1084 #         Add a section heading that matches our name.
1085     str += "[#{preferred_run_mode}]\n"
1086     eachsection do |section|
1087       persection(section) do |obj|
1088         str += obj.to_config + "\n" unless obj.name == :genconfig
1089       end
1090     end
1091 
1092     return str
1093   end
to_manifest() click to toggle source

Convert to a parseable manifest

     # File lib/puppet/settings.rb
1096 def to_manifest
1097   catalog = to_catalog
1098   catalog.resource_refs.collect do |ref|
1099     catalog.resource(ref).to_manifest
1100   end.join("\n\n")
1101 end
use(*sections) click to toggle source

Create the necessary objects to use a section. This is idempotent; you can 'use' a section as many times as you want.

     # File lib/puppet/settings.rb
1105 def use(*sections)
1106   if Puppet[:settings_catalog]
1107     sections = sections.collect { |s| s.to_sym }
1108     sections = sections.reject { |s| @used.include?(s) }
1109 
1110     Puppet.warning(":master section deprecated in favor of :server section") if sections.include?(:master)
1111 
1112     # add :server if sections include :master or :master if sections include :server
1113     sections |= [:master, :server] if (sections & [:master, :server]).any?
1114 
1115     sections = sections.collect { |s| s.to_sym }
1116     sections = sections.reject { |s| @used.include?(s) }
1117 
1118     return if sections.empty?
1119 
1120     Puppet.debug { "Applying settings catalog for sections #{sections.join(', ')}" }
1121 
1122     begin
1123       catalog = to_catalog(*sections).to_ral
1124     rescue => detail
1125       Puppet.log_and_raise(detail, "Could not create resources for managing Puppet's files and directories in sections #{sections.inspect}: #{detail}")
1126     end
1127 
1128     catalog.host_config = false
1129     catalog.apply do |transaction|
1130       if transaction.any_failed?
1131         report = transaction.report
1132         status_failures = report.resource_statuses.values.select { |r| r.failed? }
1133         status_fail_msg = status_failures.
1134           collect(&:events).
1135           flatten.
1136           select { |event| event.status == 'failure' }.
1137           collect { |event| "#{event.resource}: #{event.message}" }.join("; ")
1138 
1139         raise "Got #{status_failures.length} failure(s) while initializing: #{status_fail_msg}"
1140       end
1141     end
1142 
1143     sections.each { |s| @used << s }
1144     @used.uniq!
1145   else
1146     Puppet.debug("Skipping settings catalog for sections #{sections.join(', ')}")
1147   end
1148 end
valid?(param) click to toggle source
     # File lib/puppet/settings.rb
1150 def valid?(param)
1151   param = param.to_sym
1152   @config.has_key?(param)
1153 end
value(param, environment = nil, bypass_interpolation = false) click to toggle source

Find the correct value using our search path.

@param param [String, Symbol] The value to look up @param environment [String, Symbol] The environment to check for the value @param bypass_interpolation [true, false] Whether to skip interpolation

@return [Object] The looked up value

@raise [InterpolationError]

     # File lib/puppet/settings.rb
1179 def value(param, environment = nil, bypass_interpolation = false)
1180   environment &&= environment.to_sym
1181   value_sym(param.to_sym, environment, bypass_interpolation)
1182 end
value_sym(param, environment = nil, bypass_interpolation = false) click to toggle source

Find the correct value using symbols and our search path.

@param param [Symbol] The value to look up @param environment [Symbol] The environment to check for the value @param bypass_interpolation [true, false] Whether to skip interpolation

@return [Object] The looked up value

@raise [InterpolationError]

     # File lib/puppet/settings.rb
1193 def value_sym(param, environment = nil, bypass_interpolation = false)
1194   # Check the cache first.  It needs to be a per-environment
1195   # cache so that we don't spread values from one env
1196   # to another.
1197   cached_env = @cache[environment || NONE]
1198 
1199   # Avoid two lookups in cache_env unless val is nil. When it is, it's important
1200   # to check if the key is included so that further processing (that will result
1201   # in nil again) is avoided.
1202   val = cached_env[param]
1203   return val if !val.nil? || cached_env.include?(param)
1204 
1205   # Short circuit to nil for undefined settings.
1206   return nil unless @config.include?(param)
1207 
1208   vals = values(environment, preferred_run_mode)
1209   val = bypass_interpolation ? vals.lookup(param) : vals.interpolate(param)
1210   cached_env[param] = val
1211   val
1212 end
values(environment, section) click to toggle source

Retrieve an object that can be used for looking up values of configuration settings.

@param environment [Symbol] The name of the environment in which to lookup @param section [Symbol] The name of the configuration section in which to lookup @return [Puppet::Settings::ChainedValues] An object to perform lookups @api public

     # File lib/puppet/settings.rb
1162 def values(environment, section)
1163   @values[environment][section] ||= ChainedValues.new(
1164     section,
1165     environment,
1166     value_sets_for(environment, section),
1167     @config)
1168 end
which_configuration_file() click to toggle source

(#15337) All of the logic to determine the configuration file to use

should be centralized into this method.  The simplified approach is:
  1. If there is an explicit configuration file, use that. (–confdir or –config)

  2. If we're running as a root process, use the system puppet.conf (usually /etc/puppetlabs/puppet/puppet.conf)

  3. Otherwise, use the user puppet.conf (usually ~/.puppetlabs/etc/puppet/puppet.conf)

@api private @todo this code duplicates {Puppet::Util::RunMode#which_dir} as described

in {https://projects.puppetlabs.com/issues/16637 #16637}
     # File lib/puppet/settings.rb
1227 def which_configuration_file
1228   if explicit_config_file? or Puppet.features.root? then
1229     return main_config_file
1230   else
1231     return user_config_file
1232   end
1233 end

Private Instance Methods

add_environment_resources(catalog, sections) click to toggle source
     # File lib/puppet/settings.rb
1300 def add_environment_resources(catalog, sections)
1301   configured_environment = self[:environment]
1302 
1303   if configured_environment == "production" && !production_environment_exists?
1304     environment_path = self[:environmentpath]
1305     first_environment_path = environment_path.split(File::PATH_SEPARATOR).first
1306 
1307     if Puppet::FileSystem.exist?(first_environment_path)
1308       production_environment_path = File.join(first_environment_path, configured_environment)
1309       parameters = { :ensure => 'directory' }
1310       parameters[:mode] = '0750'
1311       if Puppet.features.root?
1312         parameters[:owner] = Puppet[:user] if service_user_available?
1313         parameters[:group] = Puppet[:group] if service_group_available?
1314       end
1315       catalog.add_resource(Puppet::Resource.new(:file, production_environment_path, :parameters => parameters))
1316     end
1317   end
1318 end
add_user_resources(catalog, sections) click to toggle source
     # File lib/puppet/settings.rb
1332 def add_user_resources(catalog, sections)
1333   return unless Puppet.features.root?
1334   return if Puppet::Util::Platform.windows?
1335   return unless self[:mkusers]
1336 
1337   @config.each do |name, setting|
1338     next unless setting.respond_to?(:owner)
1339     next unless sections.nil? or sections.include?(setting.section)
1340 
1341     user = setting.owner
1342     if user && user != "root" && catalog.resource(:user, user).nil?
1343       resource = Puppet::Resource.new(:user, user, :parameters => {:ensure => :present})
1344       resource[:gid] = self[:group] if self[:group]
1345       catalog.add_resource resource
1346     end
1347     group = setting.group
1348     if group && ! %w{root wheel}.include?(group) && catalog.resource(:group, group).nil?
1349       catalog.add_resource Puppet::Resource.new(:group, group, :parameters => {:ensure => :present})
1350     end
1351   end
1352 end
any_files_changed?() click to toggle source

Checks to see if any of the config files have been modified @return the filename of the first file that is found to have changed, or

nil if no files have changed
    # File lib/puppet/settings.rb
811 def any_files_changed?
812   files.each do |file|
813     return file.to_str if file.changed?
814   end
815   nil
816 end
apply_metadata() click to toggle source
    # File lib/puppet/settings.rb
696 def apply_metadata
697   # We have to do it in the reverse of the search path,
698   # because multiple sections could set the same value
699   # and I'm too lazy to only set the metadata once.
700   if @configuration_file
701     searchpath(nil, preferred_run_mode).reverse_each do |source|
702       section = @configuration_file.sections[source.name] if source.type == :section
703       if section
704         apply_metadata_from_section(section)
705       end
706     end
707   end
708 end
call_hooks_deferred_to_application_initialization(options = {}) click to toggle source
    # File lib/puppet/settings.rb
414 def call_hooks_deferred_to_application_initialization(options = {})
415   @hooks_to_call_on_application_initialization.each do |setting|
416     begin
417       setting.handle(self.value(setting.name))
418     rescue InterpolationError => err
419       raise InterpolationError, err.message, err.backtrace unless options[:ignore_interpolation_dependency_errors]
420       #swallow. We're not concerned if we can't call hooks because dependencies don't exist yet
421       #we'll get another chance after application defaults are initialized
422     end
423   end
424 end
clear_everything_for_tests() click to toggle source

Private method for internal test use only; allows to do a comprehensive clear of all settings between tests.

@return nil

     # File lib/puppet/settings.rb
1368 def clear_everything_for_tests()
1369   unsafe_clear(true, true)
1370   @configuration_file = nil
1371   @global_defaults_initialized = false
1372   @app_defaults_initialized = false
1373 end
config_file_name() click to toggle source

This method is here to get around some life-cycle issues. We need to be able to determine the config file name before the settings / defaults are fully loaded. However, we also need to respect any overrides of this value that the user may have specified on the command line.

The easiest way to do this is to attempt to read the setting, and if we catch an error (meaning that it hasn't been set yet), we'll fall back to the default value.

    # File lib/puppet/settings.rb
685 def config_file_name
686   begin
687     return self[:config_file_name] if self[:config_file_name]
688   rescue SettingsError
689     # This just means that the setting wasn't explicitly set on the command line, so we will ignore it and
690     #  fall through to the default name.
691   end
692   return self.class.default_config_file_name
693 end
create_ancestors(dir) click to toggle source

Create ancestor directories.

@param dir [String] absolute path for a required application default directory @api private

    # File lib/puppet/settings.rb
405 def create_ancestors(dir)
406   parent_dir = File.dirname(dir)
407 
408   if !File.exist?(parent_dir)
409     FileUtils.mkdir_p(parent_dir)
410   end
411 end
explicit_config_file?() click to toggle source
     # File lib/puppet/settings.rb
1376 def explicit_config_file?
1377   # Figure out if the user has provided an explicit configuration file.  If
1378   # so, return the path to the file, if not return nil.
1379   #
1380   # The easiest way to determine whether an explicit one has been specified
1381   #  is to simply attempt to evaluate the value of ":config".  This will
1382   #  obviously be successful if they've passed an explicit value for :config,
1383   #  but it will also result in successful interpolation if they've only
1384   #  passed an explicit value for :confdir.
1385   #
1386   # If they've specified neither, then the interpolation will fail and we'll
1387   #  get an exception.
1388   #
1389   begin
1390     return true if self[:config]
1391   rescue InterpolationError
1392     # This means we failed to interpolate, which means that they didn't
1393     #  explicitly specify either :config or :confdir... so we'll fall out to
1394     #  the default value.
1395     return false
1396   end
1397 end
issue_deprecation_warning(setting, msg = nil) click to toggle source
     # File lib/puppet/settings.rb
1280 def issue_deprecation_warning(setting, msg = nil)
1281   name = setting.name
1282   ref = DEPRECATION_REFS.find { |params,reference| params.include?(name) }
1283   ref = ref[1] if ref
1284   case
1285   when msg
1286     msg << " #{ref}" if ref
1287     Puppet.deprecation_warning(msg)
1288   when setting.completely_deprecated?
1289     message = _("Setting %{name} is deprecated.") % { name: name }
1290     message += " #{ref}"
1291     Puppet.deprecation_warning(message, "setting-#{name}")
1292   when setting.allowed_on_commandline?
1293     #TRANSLATORS 'puppet.conf' is a file name and should not be translated
1294     message = _("Setting %{name} is deprecated in puppet.conf.") % { name: name }
1295     message += " #{ref}"
1296     Puppet.deprecation_warning(message, "puppet-conf-setting-#{name}")
1297   end
1298 end
issue_deprecations() click to toggle source
     # File lib/puppet/settings.rb
1274 def issue_deprecations
1275   @deprecated_settings_that_have_been_configured.each do |setting|
1276     issue_deprecation_warning(setting)
1277   end
1278 end
main_config_file() click to toggle source
    # File lib/puppet/settings.rb
663 def main_config_file
664   if explicit_config_file?
665     return self[:config]
666   else
667     return File.join(Puppet::Util::RunMode[:server].conf_dir, config_file_name)
668   end
669 end
newsetting(hash) click to toggle source

Create a new setting. The value is passed in because it's used to determine what kind of setting we're creating, but the value itself might be either a default or a value, so we can't actually assign it.

See define_settings for documentation on the legal values for the “:type” option.

    # File lib/puppet/settings.rb
748 def newsetting(hash)
749   klass = nil
750   hash[:section] = hash[:section].to_sym if hash[:section]
751 
752   type = hash[:type]
753   if type
754     klass = SETTING_TYPES[type]
755     unless klass
756       raise ArgumentError, _("Invalid setting type '%{type}'") % { type: type }
757     end
758     hash.delete(:type)
759   else
760     # The only implicit typing we still do for settings is to fall back to "String" type if they didn't explicitly
761     # specify a type.  Personally I'd like to get rid of this too, and make the "type" option mandatory... but
762     # there was a little resistance to taking things quite that far for now.  --cprice 2012-03-19
763     klass = StringSetting
764   end
765   hash[:settings] = self
766   setting = klass.new(hash)
767 
768   setting
769 end
parse_config_files(require_config = true) click to toggle source

Parse the configuration file. Just provides thread safety.

    # File lib/puppet/settings.rb
641 def parse_config_files(require_config = true)
642   file = which_configuration_file
643   if Puppet::FileSystem.exist?(file)
644     begin
645       text = read_file(file)
646     rescue => detail
647       message = _("Could not load %{file}: %{detail}") % { file: file, detail: detail}
648       if require_config
649         Puppet.log_and_raise(detail, message)
650       else
651         Puppet.log_exception(detail, message)
652         return
653       end
654     end
655   else
656     return
657   end
658 
659   parse_config(text, file)
660 end
parse_global_options(args) click to toggle source

This method is called during application bootstrapping. It is responsible for parsing all of the command line options and initializing the settings accordingly.

It will ignore options that are not defined in the global puppet settings list, because they may be valid options for the specific application that we are about to launch… however, at this point in the bootstrapping lifecycle, we don't yet know what that application is.

    # File lib/puppet/settings.rb
324 def parse_global_options(args)
325   # Create an option parser
326   option_parser = PuppetOptionParser.new
327   option_parser.ignore_invalid_options = true
328 
329   # Add all global options to it.
330   self.optparse_addargs([]).each do |option|
331     option_parser.on(*option) do |arg|
332       opt, val = Puppet::Settings.clean_opt(option[0], arg)
333       handlearg(opt, val)
334     end
335   end
336 
337   option_parser.on('--run_mode',
338                    "The effective 'run mode' of the application: server, agent, or user.",
339                    :REQUIRED) do |arg|
340     Puppet.settings.preferred_run_mode = arg
341   end
342 
343   option_parser.parse(args)
344 
345   # remove run_mode options from the arguments so that later parses don't think
346   # it is an unknown option.
347   while option_index = args.index('--run_mode') do #rubocop:disable Lint/AssignmentInCondition
348     args.delete_at option_index
349     args.delete_at option_index
350   end
351   args.reject! { |arg| arg.start_with? '--run_mode=' }
352 end
production_environment_exists?() click to toggle source
     # File lib/puppet/settings.rb
1320 def production_environment_exists?
1321   environment_path = self[:environmentpath]
1322   paths = environment_path.split(File::PATH_SEPARATOR)
1323 
1324   paths.any? do |path|
1325     # If expected_path is a symlink, assume the source path is being managed
1326     # elsewhere, so accept it also as a valid production environment path
1327     expected_path = File.join(path, 'production')
1328     Puppet::FileSystem.directory?(expected_path) || Puppet::FileSystem.symlink?(expected_path)
1329   end
1330 end
read_file(file) click to toggle source

Read the file in. @api private

     # File lib/puppet/settings.rb
1361 def read_file(file)
1362   return Puppet::FileSystem.read(file, :encoding => 'utf-8')
1363 end
record_deprecations_from_puppet_conf(puppet_conf) click to toggle source

Record that we want to issue a deprecation warning later in the application initialization cycle when we have settings bootstrapped to the point where we can read the Puppet setting.

We are only recording warnings applicable to settings set in puppet.conf itself.

     # File lib/puppet/settings.rb
1263 def record_deprecations_from_puppet_conf(puppet_conf)
1264   puppet_conf.sections.values.each do |section|
1265     section.settings.each do |conf_setting|
1266       setting = self.setting(conf_setting.name)
1267       if setting
1268         @deprecated_settings_that_have_been_configured << setting if setting.deprecated?
1269       end
1270     end
1271   end
1272 end
screen_non_puppet_conf_settings(puppet_conf) click to toggle source
     # File lib/puppet/settings.rb
1250 def screen_non_puppet_conf_settings(puppet_conf)
1251   puppet_conf.sections.values.each do |section|
1252     forbidden = section.settings.select { |setting| Puppet::Settings::EnvironmentConf::ENVIRONMENT_CONF_ONLY_SETTINGS.include?(setting.name) }
1253     raise(SettingsError, "Cannot set #{forbidden.map { |s| s.name }.join(", ")} settings in puppet.conf") if !forbidden.empty?
1254   end
1255 end
unsafe_clear(clear_cli = true, clear_application_defaults = false) click to toggle source

Remove all set values, potentially skipping cli values.

    # File lib/puppet/settings.rb
235 def unsafe_clear(clear_cli = true, clear_application_defaults = false)
236   if clear_application_defaults
237     @value_sets[:application_defaults] = Values.new(:application_defaults, @config)
238     @app_defaults_initialized = false
239   end
240 
241   if clear_cli
242     @value_sets[:cli] = Values.new(:cli, @config)
243 
244     # Only clear the 'used' values if we were explicitly asked to clear out
245     #  :cli values; otherwise, it may be just a config file reparse,
246     #  and we want to retain this cli values.
247     @used = []
248   end
249 
250   @value_sets[:memory] = Values.new(:memory, @config)
251   @value_sets[:overridden_defaults] = Values.new(:overridden_defaults, @config)
252 
253   @deprecated_settings_that_have_been_configured.clear
254   @values.clear
255   @cache.clear
256 end
unsafe_flush_cache() click to toggle source
    # File lib/puppet/settings.rb
290 def unsafe_flush_cache
291   clearused
292 end
user_config_file() click to toggle source
    # File lib/puppet/settings.rb
672 def user_config_file
673   return File.join(Puppet::Util::RunMode[:user].conf_dir, config_file_name)
674 end
value_sets_for(environment, mode) click to toggle source

Yield each search source in turn.

     # File lib/puppet/settings.rb
1355 def value_sets_for(environment, mode)
1356   searchpath(environment, mode).collect { |source| searchpath_values(source) }.compact
1357 end