Skip to content

Commit

Permalink
(hack) Require bolt gem before 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 where `require 'puppet'` in the task will load Puppet
from the Ruby vendor path instead of the Puppet gem. The vendor Puppet
will then try to autoload gems from the Gem path including Puppet,
causing a `UniqueFile` error when the same file is loaded from different
locations.

This updates ACE to run `-r bolt` before executing tasks on localhost,
which will add Bolt and it's dependencies to the `$LOAD_PATH` including
Puppet, so that the Gem puppet is prefered over the vendor Puppet.
  • Loading branch information
lucywyman committed Oct 22, 2021
1 parent b44ea1e commit 8ab52f1
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 4 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.23.0", "< 8.0.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: 8 additions & 3 deletions lib/ace/transport_app.rb
Original file line number Diff line number Diff line change
Expand Up @@ -221,14 +221,20 @@ def self.trusted_facts(certname)
validate_schema(@schemas["run_task"], body)

inventory = Bolt::Inventory.empty
local_data = { 'name' => 'localhost',
'config' => { 'transport' => 'local',
'local' => { 'interpreters' => {
'rb' => ['/opt/puppetlabs/puppet/bin/ruby', '-r', 'bolt']
} } } }
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 @@ -250,9 +256,8 @@ def self.trusted_facts(certname)
task = Bolt::Task::PuppetServer.new(task_data['name'], task_data['metadata'], task_data['files'], @file_cache)

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

# Since this will only be on one node we can just return the first result
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 8ab52f1

Please sign in to comment.