Class: Puppet::Node::Environment
- Defined in:
- lib/puppet/node/environment.rb
Overview
Puppet::Node::Environment acts as a container for all configuration that is expected to vary between environments.
## The root environment
In addition to normal environments that are defined by the user,there is a special ‘root’ environment. It is defined as an instance variable on the Puppet::Node::Environment metaclass. The environment name is ‘root` and can be accessed by looking up the `:root_environment` using Puppet.lookup.
The primary purpose of the root environment is to contain parser functions that are not bound to a specific environment. The main case for this is for logging functions. Logging functions are attached to the ‘root’ environment when Parser::Functions.reset is called.
Defined Under Namespace
Constant Summary collapse
- NO_MANIFEST =
:no_manifest
Instance Attribute Summary collapse
-
#config_version ⇒ Object
readonly
Returns the value of attribute config_version.
-
#configured_path ⇒ Object
For use with versioned dirs our environment path may contain symlinks, while we want to resolve the path while reading the manifests we may want to report the resources as coming from the configured path.
-
#loaders ⇒ Object
private
Cached loaders - management of value handled by Puppet::Pops::Loaders.
-
#lock ⇒ Object
readonly
private
Lock for compilation that needs exclusive access to the environment.
-
#manifest ⇒ Object
readonly
Returns the value of attribute manifest.
-
#name ⇒ Object
readonly
Returns the value of attribute name.
-
#resolved_path ⇒ Object
See :configured_path above.
Class Method Summary collapse
-
.create(name, modulepath, manifest = NO_MANIFEST, config_version = nil) ⇒ Puppet::Node::Environment
Create a new environment with the given name.
-
.expand_dirs(dirs) ⇒ Object
not private so it can be called in initialize.
-
.extralibs ⇒ Object
not private so it can be called in tests.
-
.remote(name) ⇒ Object
A “reference” to a remote environment.
- .split_path(path_string) ⇒ Object
-
.valid_name?(name) ⇒ Boolean
True if name is valid.
Instance Method Summary collapse
- #==(other) ⇒ Object (also: #eql?)
-
#[](param) ⇒ Object
Return an environment-specific Puppet setting.
-
#check_for_reparse ⇒ Object
Checks if a reparse is required (cache of files is stale).
-
#configuration ⇒ Puppet::Settings::EnvironmentConf
private
Return the environment configuration.
-
#conflicting_manifest_settings? ⇒ Boolean
private
Checks to make sure that this environment did not have a manifest set in its original environment.conf if Puppet is configured with
disable_per_environment_manifest
set true. -
#each_plugin_directory {|String| ... } ⇒ Object
Yields each modules’ plugin directory if the plugin directory (modulename/lib) is present on the filesystem.
-
#externalize_path(filepath) ⇒ Object
Ensure the path given is of the format we want in the catalog/report.
-
#full_modulepath ⇒ Array<String>
All directories in the modulepath (even if they are not present on disk).
- #hash ⇒ Object
-
#initialize(name, modulepath, manifest, config_version) ⇒ Environment
constructor
Instantiate a new environment.
- #inspect ⇒ Object
-
#known_resource_types ⇒ Puppet::Resource::TypeCollection
The current global TypeCollection.
-
#module(name) ⇒ Puppet::Module?
Locate a module instance by the module name alone.
-
#module_by_forge_name(forge_name) ⇒ Puppet::Module?
Locate a module instance by the full forge name (EG authorname/module).
-
#module_requirements ⇒ Hash<String, Array<Hash<String, String>>>
All module requirements for all modules in the environment modulepath.
-
#modulepath ⇒ Array<String>
All directories present on disk in the modulepath.
-
#modules ⇒ Array<Puppet::Module>
Return all modules for this environment in the order they appear in the modulepath.
-
#modules_by_path ⇒ Hash<String, Array<Puppet::Module>>
Modules broken out by directory in the modulepath.
-
#override_from_commandline(settings) ⇒ Puppet::Node::Environment
Creates a new Puppet::Node::Environment instance, overriding :manifest, :modulepath, or :config_version from the passed settings if they were originally set from the commandline, or returns self if there is nothing to override.
-
#override_with(env_params) ⇒ Puppet::Node::Environment
Creates a new Puppet::Node::Environment instance, overriding any of the passed parameters.
-
#rich_data? ⇒ Boolean
private
Checks if this environment permits use of rich data types in the catalog Checks the environment conf for an override on first query, then going forward either uses that, or if unset, uses the current value of the ‘rich_data` setting.
- #rich_data_from_env_conf ⇒ Object
- #static_catalogs? ⇒ Boolean private
-
#to_s ⇒ String
The stringified value of the ‘name` instance variable.
-
#to_sym ⇒ Symbol
The ‘name` value, cast to a string, then cast to a symbol.
-
#to_yaml ⇒ String
Return the name of the environment as a string interpretation of the object.
-
#validation_errors ⇒ Array<String>
Checks the environment and settings for any conflicts.
-
#warn_about_mistaken_path(path, name) ⇒ Object
private
Generate a warning if the given directory in a module path entry is named ‘lib`.
-
#with_text_domain ⇒ Object
Loads module translations for the current environment once for the lifetime of the environment.
Constructor Details
#initialize(name, modulepath, manifest, config_version) ⇒ Environment
new is private for historical reasons, as previously it had been overridden to return memoized objects and was replaced with create, so this will not be invoked with the normal Ruby initialization semantics.
Instantiate a new environment
73 74 75 76 77 78 79 80 |
# File 'lib/puppet/node/environment.rb', line 73 def initialize(name, modulepath, manifest, config_version) @lock = Puppet::Concurrent::Lock.new @name = name.intern @modulepath = self.class.(self.class.extralibs() + modulepath) @manifest = manifest == NO_MANIFEST ? manifest : Puppet::FileSystem.(manifest) @config_version = config_version end |
Instance Attribute Details
#config_version ⇒ Object (readonly)
Returns the value of attribute config_version.
159 160 161 |
# File 'lib/puppet/node/environment.rb', line 159 def config_version @config_version end |
#configured_path ⇒ Object
For use with versioned dirs our environment path may contain symlinks, while we want to resolve the path while reading the manifests we may want to report the resources as coming from the configured path.
173 174 175 |
# File 'lib/puppet/node/environment.rb', line 173 def configured_path @configured_path end |
#loaders ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Cached loaders - management of value handled by Puppet::Pops::Loaders
163 164 165 |
# File 'lib/puppet/node/environment.rb', line 163 def loaders @loaders end |
#lock ⇒ Object (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Lock for compilation that needs exclusive access to the environment
167 168 169 |
# File 'lib/puppet/node/environment.rb', line 167 def lock @lock end |
#manifest ⇒ Object (readonly)
Returns the value of attribute manifest.
153 154 155 |
# File 'lib/puppet/node/environment.rb', line 153 def manifest @manifest end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
134 135 136 |
# File 'lib/puppet/node/environment.rb', line 134 def name @name end |
#resolved_path ⇒ Object
See :configured_path above
176 177 178 |
# File 'lib/puppet/node/environment.rb', line 176 def resolved_path @resolved_path end |
Class Method Details
.create(name, modulepath, manifest = NO_MANIFEST, config_version = nil) ⇒ Puppet::Node::Environment
Create a new environment with the given name
42 43 44 |
# File 'lib/puppet/node/environment.rb', line 42 def self.create(name, modulepath, manifest = NO_MANIFEST, config_version = nil) new(name, modulepath, manifest, config_version) end |
.expand_dirs(dirs) ⇒ Object
not private so it can be called in initialize
560 561 562 563 564 |
# File 'lib/puppet/node/environment.rb', line 560 def self.(dirs) dirs.collect do |dir| Puppet::FileSystem.(dir) end end |
.extralibs ⇒ Object
not private so it can be called in tests
551 552 553 554 555 556 557 |
# File 'lib/puppet/node/environment.rb', line 551 def self.extralibs() if Puppet::Util.get_env('PUPPETLIB') split_path(Puppet::Util.get_env('PUPPETLIB')) else [] end end |
.remote(name) ⇒ Object
This does not provide access to the information of the remote
A “reference” to a remote environment. The created environment instance isn’t expected to exist on the local system, but is instead a reference to environment information on a remote system. For instance when a catalog is being applied, this will be used on the agent.
environment’s modules, manifest, or anything else. It is simply a value object to pass around and use as an environment.
61 62 63 |
# File 'lib/puppet/node/environment.rb', line 61 def self.remote(name) Remote.create(name, [], NO_MANIFEST) end |
.split_path(path_string) ⇒ Object
533 534 535 |
# File 'lib/puppet/node/environment.rb', line 533 def self.split_path(path_string) path_string.split(File::PATH_SEPARATOR) end |
.valid_name?(name) ⇒ Boolean
Returns true if name is valid.
126 127 128 |
# File 'lib/puppet/node/environment.rb', line 126 def self.valid_name?(name) !!name.match(/\A\w+\Z/) end |
Instance Method Details
#==(other) ⇒ Object Also known as: eql?
537 538 539 540 541 542 |
# File 'lib/puppet/node/environment.rb', line 537 def ==(other) return true if other.kind_of?(Puppet::Node::Environment) && self.name == other.name && self.full_modulepath == other.full_modulepath && self.manifest == other.manifest end |
#[](param) ⇒ Object
Return an environment-specific Puppet setting.
279 280 281 |
# File 'lib/puppet/node/environment.rb', line 279 def [](param) Puppet.settings.value(param, self.name) end |
#check_for_reparse ⇒ Object
Checks if a reparse is required (cache of files is stale).
496 497 498 499 500 501 502 503 |
# File 'lib/puppet/node/environment.rb', line 496 def check_for_reparse @lock.synchronize do if (Puppet[:code] != @parsed_code || @known_resource_types.parse_failed?) @parsed_code = nil @known_resource_types = nil end end end |
#configuration ⇒ Puppet::Settings::EnvironmentConf
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Return the environment configuration
240 241 242 |
# File 'lib/puppet/node/environment.rb', line 240 def configuration Puppet.lookup(:environments).get_conf(name) end |
#conflicting_manifest_settings? ⇒ Boolean
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Checks to make sure that this environment did not have a manifest set in its original environment.conf if Puppet is configured with disable_per_environment_manifest
set true. If it did, the environment’s modules may not function as intended by the original authors, and we may seek to halt a puppet compilation for a node in this environment.
The only exception to this would be if the environment.conf manifest is an exact, uninterpolated match for the current default_manifest
setting.
221 222 223 224 225 |
# File 'lib/puppet/node/environment.rb', line 221 def conflicting_manifest_settings? return false if !Puppet[:disable_per_environment_manifest] original_manifest = configuration.raw_setting(:manifest) !original_manifest.nil? && !original_manifest.empty? && original_manifest != Puppet[:default_manifest] end |
#each_plugin_directory {|String| ... } ⇒ Object
Yields each modules’ plugin directory if the plugin directory (modulename/lib) is present on the filesystem.
300 301 302 303 304 305 |
# File 'lib/puppet/node/environment.rb', line 300 def each_plugin_directory(&block) modules.map(&:plugin_directory).each do |lib| lib = Puppet::Util::Autoload.cleanpath(lib) yield lib if File.directory?(lib) end end |
#externalize_path(filepath) ⇒ Object
Ensure the path given is of the format we want in the catalog/report.
Intended for use with versioned symlinked environments. If this environment is configured with “/etc/puppetlabs/code/environments/production” but the resolved path is
“/opt/puppetlabs/server/puppetserver/filesync/client/puppet-code/production_abcdef1234”
this changes the filepath
“/opt/puppetlabs/server/puppetserver/filesync/client/puppet-code/production_abcdef1234/modules/foo/manifests/init.pp”
to
“/etc/puppetlabs/code/environments/production/modules/foo/manifests/init.pp”
193 194 195 196 197 198 199 200 201 202 203 204 205 |
# File 'lib/puppet/node/environment.rb', line 193 def externalize_path(filepath) paths_set = configured_path && resolved_path munging_possible = paths_set && configured_path != resolved_path munging_desired = munging_possible && Puppet[:report_configured_environmentpath] && filepath.to_s.start_with?(resolved_path) if munging_desired File.join(configured_path, filepath.delete_prefix(resolved_path)) else filepath end end |
#full_modulepath ⇒ Array<String>
Returns All directories in the modulepath (even if they are not present on disk).
146 147 148 |
# File 'lib/puppet/node/environment.rb', line 146 def full_modulepath @modulepath end |
#hash ⇒ Object
546 547 548 |
# File 'lib/puppet/node/environment.rb', line 546 def hash [self.class, name, full_modulepath, manifest].hash end |
#inspect ⇒ Object
518 519 520 |
# File 'lib/puppet/node/environment.rb', line 518 def inspect %Q{<#{self.class}:#{self.object_id} @name="#{name}" @manifest="#{manifest}" @modulepath="#{full_modulepath.join(":")}" >} end |
#known_resource_types ⇒ Puppet::Resource::TypeCollection
Returns The current global TypeCollection.
285 286 287 288 289 290 291 292 293 |
# File 'lib/puppet/node/environment.rb', line 285 def known_resource_types @lock.synchronize do if @known_resource_types.nil? @known_resource_types = Puppet::Resource::TypeCollection.new(self) @known_resource_types.import_ast(perform_initial_import(), '') end @known_resource_types end end |
#module(name) ⇒ Puppet::Module?
Locate a module instance by the module name alone.
313 314 315 |
# File 'lib/puppet/node/environment.rb', line 313 def module(name) modules_by_name[name] end |
#module_by_forge_name(forge_name) ⇒ Puppet::Module?
Locate a module instance by the full forge name (EG authorname/module)
323 324 325 326 327 328 329 |
# File 'lib/puppet/node/environment.rb', line 323 def module_by_forge_name(forge_name) _, modname = forge_name.split('/') found_mod = self.module(modname) found_mod and found_mod.forge_name == forge_name ? found_mod : nil end |
#module_requirements ⇒ Hash<String, Array<Hash<String, String>>>
All module requirements for all modules in the environment modulepath
450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 |
# File 'lib/puppet/node/environment.rb', line 450 def module_requirements deps = {} modules.each do |mod| next unless mod.forge_name deps[mod.forge_name] ||= [] mod.dependencies and mod.dependencies.each do |mod_dep| dep_name = mod_dep['name'].tr('-', '/') (deps[dep_name] ||= []) << { 'name' => mod.forge_name, 'version' => mod.version, 'version_requirement' => mod_dep['version_requirement'] } end end deps.each do |mod, mod_deps| deps[mod] = mod_deps.sort_by { |d| d['name'] } end deps end |
#modulepath ⇒ Array<String>
Returns All directories present on disk in the modulepath.
138 139 140 141 142 |
# File 'lib/puppet/node/environment.rb', line 138 def modulepath @modulepath.find_all do |p| Puppet::FileSystem.directory?(p) end end |
#modules ⇒ Array<Puppet::Module>
If multiple modules with the same name are present they will both be added, but methods like #module and #module_by_forge_name will return the first matching entry in this list.
This value is cached so that the filesystem doesn’t have to be re-enumerated every time this method is invoked, since that enumeration could be a costly operation and this method is called frequently. The cache expiry is determined by ‘Puppet`.
Return all modules for this environment in the order they appear in the modulepath.
342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 |
# File 'lib/puppet/node/environment.rb', line 342 def modules if @modules.nil? module_references = [] project = Puppet.lookup(:bolt_project) { nil } seen_modules = if project && project.load_as_module? module_references << project.to_h { project.name => true } else {} end modulepath.each do |path| Puppet::FileSystem.children(path).map do |p| Puppet::FileSystem.basename_string(p) end.each do |name| next unless Puppet::Module.is_module_directory?(name, path) warn_about_mistaken_path(path, name) if not seen_modules[name] module_references << {:name => name, :path => File.join(path, name)} seen_modules[name] = true end end end @modules = module_references.collect do |reference| begin Puppet::Module.new(reference[:name], reference[:path], self) rescue Puppet::Module::Error => e Puppet.log_exception(e) nil end end.compact end @modules end |
#modules_by_path ⇒ Hash<String, Array<Puppet::Module>>
Modules broken out by directory in the modulepath
404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 |
# File 'lib/puppet/node/environment.rb', line 404 def modules_by_path modules_by_path = {} modulepath.each do |path| if Puppet::FileSystem.exist?(path) module_names = Puppet::FileSystem.children(path).map do |p| Puppet::FileSystem.basename_string(p) end.select do |name| Puppet::Module.is_module_directory?(name, path) end modules_by_path[path] = module_names.sort.map do |name| Puppet::Module.new(name, File.join(path, name), self) end else modules_by_path[path] = [] end end modules_by_path end |
#override_from_commandline(settings) ⇒ Puppet::Node::Environment
Creates a new Puppet::Node::Environment instance, overriding :manifest, :modulepath, or :config_version from the passed settings if they were originally set from the commandline, or returns self if there is nothing to override.
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/puppet/node/environment.rb', line 103 def override_from_commandline(settings) overrides = {} if settings.set_by_cli?(:modulepath) overrides[:modulepath] = self.class.split_path(settings.value(:modulepath)) end if settings.set_by_cli?(:config_version) overrides[:config_version] = settings.value(:config_version) end if settings.set_by_cli?(:manifest) overrides[:manifest] = settings.value(:manifest) end overrides.empty? ? self : self.override_with(overrides) end |
#override_with(env_params) ⇒ Puppet::Node::Environment
Creates a new Puppet::Node::Environment instance, overriding any of the passed parameters.
88 89 90 91 92 93 |
# File 'lib/puppet/node/environment.rb', line 88 def override_with(env_params) return self.class.create(name, env_params[:modulepath] || modulepath, env_params[:manifest] || manifest, env_params[:config_version] || config_version) end |
#rich_data? ⇒ Boolean
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Checks if this environment permits use of rich data types in the catalog Checks the environment conf for an override on first query, then going forward either uses that, or if unset, uses the current value of the ‘rich_data` setting.
269 270 271 |
# File 'lib/puppet/node/environment.rb', line 269 def rich_data? @rich_data = rich_data_from_env_conf.nil? ? Puppet[:rich_data] : rich_data_from_env_conf end |
#rich_data_from_env_conf ⇒ Object
255 256 257 258 259 260 261 262 |
# File 'lib/puppet/node/environment.rb', line 255 def rich_data_from_env_conf unless @checked_conf_for_rich_data environment_conf = Puppet.lookup(:environments).get_conf(name) @rich_data_from_conf = environment_conf&.rich_data @checked_conf_for_rich_data = true end @rich_data_from_conf end |
#static_catalogs? ⇒ Boolean
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
228 229 230 231 232 233 234 |
# File 'lib/puppet/node/environment.rb', line 228 def static_catalogs? if @static_catalogs.nil? environment_conf = Puppet.lookup(:environments).get_conf(name) @static_catalogs = (environment_conf.nil? ? Puppet[:static_catalogs] : environment_conf.static_catalogs) end @static_catalogs end |
#to_s ⇒ String
Returns The stringified value of the ‘name` instance variable.
513 514 515 |
# File 'lib/puppet/node/environment.rb', line 513 def to_s name.to_s end |
#to_sym ⇒ Symbol
the ‘name` instance variable is a Symbol, but this casts the value to a String and then converts it back into a Symbol which will needlessly create an object that needs to be garbage collected
Returns The ‘name` value, cast to a string, then cast to a symbol.
529 530 531 |
# File 'lib/puppet/node/environment.rb', line 529 def to_sym to_s.to_sym end |
#to_yaml ⇒ String
Return the name of the environment as a string interpretation of the object
507 508 509 |
# File 'lib/puppet/node/environment.rb', line 507 def to_yaml to_s.to_yaml end |
#validation_errors ⇒ Array<String>
Checks the environment and settings for any conflicts
247 248 249 250 251 252 253 |
# File 'lib/puppet/node/environment.rb', line 247 def validation_errors errors = [] if conflicting_manifest_settings? errors << _("The 'disable_per_environment_manifest' setting is true, and the '%{env_name}' environment has an environment.conf manifest that conflicts with the 'default_manifest' setting.") % { env_name: name } end errors end |
#warn_about_mistaken_path(path, name) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Generate a warning if the given directory in a module path entry is named ‘lib`.
389 390 391 392 393 394 395 396 |
# File 'lib/puppet/node/environment.rb', line 389 def warn_about_mistaken_path(path, name) if name == "lib" Puppet.debug { "Warning: Found directory named 'lib' in module path ('#{path}/lib'); unless you \ are expecting to load a module named 'lib', your module path may be set incorrectly." } end end |
#with_text_domain ⇒ Object
Loads module translations for the current environment once for the lifetime of the environment. Execute a block in the context of that translation domain.
477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 |
# File 'lib/puppet/node/environment.rb', line 477 def with_text_domain return yield if Puppet[:disable_i18n] if @text_domain.nil? @text_domain = @name Puppet::GettextConfig.reset_text_domain(@text_domain) Puppet::ModuleTranslations.load_from_modulepath(modules) else Puppet::GettextConfig.use_text_domain(@text_domain) end yield ensure # Is a noop if disable_i18n is true Puppet::GettextConfig.clear_text_domain end |