From b545711d46c304195195ce371f240a3600339933 Mon Sep 17 00:00:00 2001 From: Phil Dibowitz Date: Wed, 13 Jan 2021 20:14:10 -0800 Subject: Add support for client.d files in chef-shell This brings chef-shell a bit closer to behaving properly. This code is tons of copy-pasta and needs some love. Because it's not using *any* of `Chef::Application` (not `Application` or `Application::Base` or even it's own fork of `Application` like half the other stuff in the repo), it doesn't have access to _any_ of the many versions of `load_config_file` (note to self: collapse those into one). Pulling in Application will be a significant chunk of work, so in the mean time I did the minimal amount of work to make the `parse_opts` in shell.rb create the right bits so that Chef::Config and Mixin::DotD can work... so while this doesn't fix the problem that we're invoking our own config parsing, it at least uses as much of the common code as I can without reworking the entirety of chef-shell. Here's an example of it working: ``` root@ldt-hardwired:~# cinc-shell -s -c /etc/chef/client.rb loading configuration: /etc/chef/client.rb true Session type: solo ``` From there it loads not only `/et/chef/client.rb` but also `/etc/chef/client.d/ohai.rb`. Neat. None of this portion of the code is tested in the specs and frankly, I'm not entirely certainly how to go about writing a test, but I'll poke around. fixes #10748 Signed-off-by: Phil Dibowitz --- lib/chef/shell.rb | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) (limited to 'lib/chef/shell.rb') diff --git a/lib/chef/shell.rb b/lib/chef/shell.rb index a425129fa8..5bff9c0292 100644 --- a/lib/chef/shell.rb +++ b/lib/chef/shell.rb @@ -25,6 +25,7 @@ require "pp" unless defined?(PP) require "etc" unless defined?(Etc) require "mixlib/cli" unless defined?(Mixlib::CLI) require "chef-utils/dist" unless defined?(ChefUtils::Dist) +require "chef-config/mixin/dot_d" require_relative "../chef" require_relative "version" @@ -211,6 +212,7 @@ module Shell class Options include Mixlib::CLI + include ChefConfig::Mixin::DotD def self.footer(text = nil) @footer = text if text @@ -341,15 +343,44 @@ module Shell # We have to nuke ARGV to make sure irb's option parser never sees it. # otherwise, IRB complains about command line switches it doesn't recognize. ARGV.clear + + # This code should not exist. + # We should be using Application::Client and then calling load_config_file + # which does all this properly. However this will do for now. config[:config_file] = config_file_for_shell_mode(environment) config_msg = config[:config_file] || "none (standalone session)" puts "loading configuration: #{config_msg}" - Chef::Config.from_file(config[:config_file]) if !config[:config_file].nil? && File.exist?(config[:config_file]) && File.readable?(config[:config_file]) + + # load the config (if we have one) + if !config[:config_file].nil? + if File.exist?(config[:config_file]) && File.readable?(config[:config_file]) + Chef::Config.from_file(config[:config_file]) + end + + # even if we couldn't load that, we need to tell Chef::Config what + # the file was so it sets confdir and d_dir and such properly + Chef::Config[:config_file] = config[:config_file] + + # now attempt to load any relevant dot-dirs + load_dot_d(Chef::Config[:client_d_dir]) if Chef::Config[:client_d_dir] + end + + # finally merge command-line options in Chef::Config.merge!(config) end private + # shamelessly lifted from application.rb + def apply_config(config_content, config_file_path) + Chef::Config.from_string(config_content, config_file_path) + rescue Exception => error + logger.fatal("Configuration error #{error.class}: #{error.message}") + filtered_trace = error.backtrace.grep(/#{Regexp.escape(config_file_path)}/) + filtered_trace.each { |line| logger.fatal(" " + line ) } + raise Chef::Exceptions::ConfigurationError.new("Aborting due to error in '#{config_file_path}': #{error}") + end + def config_file_for_shell_mode(environment) dot_chef_dir = Chef::Util::PathHelper.home(".chef") if config[:config_file] -- cgit v1.2.1