Skip to content

Commit

Permalink
(maint) Compare Environment#name in compiler
Browse files Browse the repository at this point in the history
During catalog compilation, after loading the requested environment we
load the node and server specified environment. Previously, We would
then compare the Environment objects to determine if the requested
environment matched the server specified environment. However, if the
environment cache is flushed between those two environments being loaded
they could be different object instances representing the same desired
environment. Environment objects define a `==` method but require the
name and modulepath to be the same. If we are running with versioned
environment dirs those modulepaths may be different (ie different
versions of the same environment).

To resolve this race condition we now check the environment names
(Environment#name canoncalizes to symbols to avoid symbol/string
mismatch). The catalog already uses the server specified environment
which, if we are running with versioned environment dirs and have
different versions of the same environment, will be the most up to date
version of the environment.
  • Loading branch information
justinstoller committed Oct 31, 2023
1 parent 4d7ebae commit 27f118b
Showing 1 changed file with 12 additions and 4 deletions.
16 changes: 12 additions & 4 deletions lib/puppet/indirector/catalog/compiler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,20 @@ def find(request)
node.trusted_data = Puppet.lookup(:trusted_information) { Puppet::Context::TrustedInformation.local(node) }.to_h

if node.environment
# If the requested environment doesn't match the server specified environment,
# as determined by the node terminus, and the request wants us to check for an
# If the requested environment name doesn't match the server specified environment
# name, as determined by the node terminus, and the request wants us to check for an
# environment mismatch, then return an empty catalog with the server-specified
# enviroment.
if request.remote? && request.options[:check_environment] && node.environment != request.environment
return Puppet::Resource::Catalog.new(node.name, node.environment)
if request.remote? && request.options[:check_environment]
# The "environment" may be same while environment objects differ. This
# is most likely because the environment cache was flushed between the request
# processing and node lookup. Environment overrides `==` but requires the
# name and modulepath to be the same. When using versioned environment dirs the
# same "environment" can have different modulepaths so simply compare names here.
if node.environment.name != request.environment.name
Puppet.warning _("Requested environment '%{request_env}' did not match server specified environment '%{server_env}'") % {request_env: request.environment.name, server_env: node.environment.name}
return Puppet::Resource::Catalog.new(node.name, node.environment)
end
end

node.environment.with_text_domain do
Expand Down

0 comments on commit 27f118b

Please sign in to comment.