diff options
author | Phil Dibowitz <phil@ipom.com> | 2021-01-13 20:14:10 -0800 |
---|---|---|
committer | Phil Dibowitz <phil@ipom.com> | 2021-01-14 09:15:51 -0800 |
commit | b545711d46c304195195ce371f240a3600339933 (patch) | |
tree | 759e832ef87d8b2efff759d252693a298260f3e9 | |
parent | df81bcb2268574f4fee613d9ead64994ccccb561 (diff) | |
download | chef-b545711d46c304195195ce371f240a3600339933.tar.gz |
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 <phil@ipom.com>
-rw-r--r-- | lib/chef/shell.rb | 33 |
1 files changed, 32 insertions, 1 deletions
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] |