Skip to content

Commit

Permalink
(hack) Unset GEM_PATH and GEM_HOME when running local tasks
Browse files Browse the repository at this point in the history
In PE we use the Ruby interpreter shipped with the Puppet Agent to run the
ace server. The ace server is responsible for executing remote tasks.
Remote tasks will often use the puppet library, and run in ACE using the
local transport. Now that puppet has moved to using require_relative
there is a bug whereby a new combination of code is loaded between the
Puppet gem and the Puppet code shipped with the agent (because we set
GEM_HOME and GEM_PATH when we start the service).

As a workaround, this commit uses the `BOLT_ORIG` environment variable
mechanism in Bolt to configure the Ruby environment that the task itself
will run in (and not the ruby code that's *running* the task). ACE can
unset the GEM_PATH and GEM_HOME environment variable so that
`Gem.specifications` in the Puppet autoloader is empty, and loads from
the `$LOAD_PATH` first (which can be added to using the `RUBYLIB` environment
variable). Then, ACE uses `BOLT_ORIG_RUBYLIB` to append the Gem load
paths to the LOAD_PATH so that the dependencies are still available.

This is *very* much a hack, but this problem is also somewhat limited in
scope.
  • Loading branch information
lucywyman committed Oct 22, 2021
1 parent b44ea1e commit 9a941ee
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 3 deletions.
2 changes: 1 addition & 1 deletion agentless-catalog-executor.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Gem::Specification.new do |spec|
spec.add_dependency "hocon", ">= 1.2.5"
spec.add_dependency "json-schema", ">= 2.8.0"
spec.add_dependency "puma", ">= 3.12.0"
spec.add_dependency "puppet", ">= 6.23", "< 8.0.0"
spec.add_dependency "puppet", ">= 6.17.0"
spec.add_dependency "rack", ">= 2.0.5"
spec.add_dependency "rails-auth", ">= 2.1.4"
spec.add_dependency "sinatra", ">= 2.0.4"
Expand Down
11 changes: 9 additions & 2 deletions lib/ace/transport_app.rb
Original file line number Diff line number Diff line change
Expand Up @@ -221,14 +221,17 @@ def self.trusted_facts(certname)
validate_schema(@schemas["run_task"], body)

inventory = Bolt::Inventory.empty
local_data = { 'name' => 'localhost',
'config' => { 'transport' => 'local', 'local' => { 'bundled-ruby' => false } } }
local_target = Bolt::Target.from_hash(local_data, inventory)
target_data = {
'name' => body['target']['host'] || body['target']['name'] || 'remote',
'config' => {
'transport' => 'remote',
'remote' => body['target']
}
}
target = [Bolt::Target.from_hash(target_data, inventory)]
target = [Bolt::Target.from_hash(target_data, local_target.inventory)]
rescue ACE::Error => e
return [400, error_result(e).to_json]
rescue JSON::ParserError => e
Expand All @@ -251,8 +254,12 @@ def self.trusted_facts(certname)

parameters = body['parameters'] || {}

# Since this will only be on one node we can just return the first result
# Unset gem specifications so that LOAD_PATH is loaded first, then
# append gem paths to the LOAD_PATH so they are still loaded. This is
# limited to the task run environment itself.
ENV['BOLT_ORIG_RUBYLIB'] = $LOAD_PATH.clone.concat(Gem.path).join(":")
results = @executor.run_task(target, task, parameters)
# Since this will only be on one node we can just return the first result
result = results.first
# Unwrap _sensitive output (orchestrator will handle obfuscating it from the result)
if result.value.is_a?(Hash) && result.value.key?('_sensitive')
Expand Down

0 comments on commit 9a941ee

Please sign in to comment.