summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaire McQuin <mcquin@users.noreply.github.com>2015-07-24 10:05:16 -0700
committerClaire McQuin <mcquin@users.noreply.github.com>2015-07-24 10:05:16 -0700
commit114db57c8ae1558f24e8b69c5ae19a59a1ca4b19 (patch)
treef3baca79fbd8314bc6b3b25e22b3b66906870073
parent008d187f572e35a025e68476d3bb449eb7dd3db2 (diff)
parent68630cdda403271384f6af38bf3af91e2a53a862 (diff)
downloadohai-114db57c8ae1558f24e8b69c5ae19a59a1ca4b19.tar.gz
Merge pull request #588 from chef/mcquin/ohai-config/load-config
Ohai::Application loads configuration file
-rw-r--r--CHANGELOG.md2
-rw-r--r--DOC_CHANGES.md10
-rw-r--r--lib/ohai/application.rb33
-rw-r--r--lib/ohai/system.rb23
-rw-r--r--spec/functional/application_spec.rb147
-rw-r--r--spec/unit/application_spec.rb81
-rw-r--r--spec/unit/system_spec.rb69
7 files changed, 309 insertions, 56 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2bf6d901..91f13bda 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -14,6 +14,8 @@
Fix Darwin filesystem plugin on newer MacOSX
* [**Claire McQuin**](https://github.com/mcquin):
Deprecate Ohai::Config in favor of Ohai::Config.ohai.
+* [**Claire McQuin**](https://github.com/mcquin):
+ Load a configuration file while running as an application.
## Release 8.5.0
diff --git a/DOC_CHANGES.md b/DOC_CHANGES.md
index 7b832d75..56470c1d 100644
--- a/DOC_CHANGES.md
+++ b/DOC_CHANGES.md
@@ -20,3 +20,13 @@ subsection of the `client.rb` documentation should be updated to use
If there is any mention of the ability to access configuration options via
`Ohai::Config`, it should be updated to `Ohai::Config.ohai`. Additionally, it
should be mentioned that `Ohai.config` is an alias for `Ohai::Config.ohai`.
+
+## Load a configuration file while running ohai as an application
+You can specify a configuration file for ohai to load while running as an
+application. For example, if your configuration file is located at
+`~/.chef/config.rb` you can run ohai with that configuration file with
+`ohai -c ~/.chef/config.rb`.
+
+When running ohai as an application and no configuration file is specified
+as a command line parameter, ohai will load a configuration file from your
+workstation (`config.rb` or `knife.rb`) if one is found.
diff --git a/lib/ohai/application.rb b/lib/ohai/application.rb
index 4388fdf7..a4b34699 100644
--- a/lib/ohai/application.rb
+++ b/lib/ohai/application.rb
@@ -15,6 +15,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+require 'chef-config/workstation_config_loader'
require 'ohai'
require 'ohai/log'
require 'mixlib/cli'
@@ -22,6 +23,12 @@ require 'mixlib/cli'
class Ohai::Application
include Mixlib::CLI
+ option :config_file,
+ :short => "-c CONFIG",
+ :long => "--config CONFIG",
+ :description => "A configuration file to use",
+ :proc => lambda { |path| File.expand_path(path, Dir.pwd) }
+
option :directory,
:short => "-d DIRECTORY",
:long => "--directory DIRECTORY",
@@ -66,7 +73,6 @@ class Ohai::Application
def run
configure_ohai
- configure_logging
run_application
end
@@ -74,20 +80,11 @@ class Ohai::Application
@attributes = parse_options
@attributes = nil if @attributes.empty?
- Ohai::Config.merge_deprecated_config
- Ohai.config.merge!(config)
- if Ohai.config[:directory]
- Ohai.config[:plugin_path] << Ohai.config[:directory]
- end
- end
-
- def configure_logging
- Ohai::Log.init(Ohai.config[:log_location])
- Ohai::Log.level = Ohai.config[:log_level]
+ load_workstation_config
end
def run_application
- ohai = Ohai::System.new
+ ohai = Ohai::System.new(config)
ohai.all_plugins(@attributes)
if @attributes
@@ -112,4 +109,16 @@ class Ohai::Application
Process.exit err
end
end
+
+ private
+ def load_workstation_config
+ config_loader = ChefConfig::WorkstationConfigLoader.new(
+ config[:config_file], Ohai::Log
+ )
+ begin
+ config_loader.load
+ rescue ChefConfig::ConfigurationError => config_error
+ Ohai::Application.fatal!(config_error.message)
+ end
+ end
end
diff --git a/lib/ohai/system.rb b/lib/ohai/system.rb
index c98ac1af..d733191f 100644
--- a/lib/ohai/system.rb
+++ b/lib/ohai/system.rb
@@ -34,23 +34,22 @@ module Ohai
include Ohai::Mixin::ConstantHelper
attr_accessor :data
+ attr_reader :config
attr_reader :provides_map
attr_reader :v6_dependency_solver
- def initialize
+ def initialize(config = {})
@plugin_path = ""
+ @config = config
reset_system
end
def reset_system
@data = Mash.new
@provides_map = ProvidesMap.new
-
@v6_dependency_solver = Hash.new
- # configure logging
- Ohai::Log.init(Ohai.config[:log_location])
- Ohai::Log.level = Ohai.config[:log_level]
+ configure_ohai
@loader = Ohai::Loader.new(self)
@runner = Ohai::Runner.new(self, true)
@@ -204,5 +203,19 @@ module Ohai
raise ArgumentError, "I can only generate JSON for Hashes, Mashes, Arrays and Strings. You fed me a #{data.class}!"
end
end
+
+ private
+ def configure_ohai
+ Ohai::Config.merge_deprecated_config
+ Ohai.config.merge!(@config)
+
+ if Ohai.config[:directory] &&
+ !Ohai.config[:plugin_path].include?(Ohai::Config[:directory])
+ Ohai.config[:plugin_path] << Ohai.config[:directory]
+ end
+
+ Ohai::Log.init(Ohai.config[:log_location])
+ Ohai::Log.level = Ohai.config[:log_level]
+ end
end
end
diff --git a/spec/functional/application_spec.rb b/spec/functional/application_spec.rb
new file mode 100644
index 00000000..33992f5d
--- /dev/null
+++ b/spec/functional/application_spec.rb
@@ -0,0 +1,147 @@
+#
+# Author:: Claire McQuin <claire@chef.io>
+# Copyright:: Copyright (c) 2015 Chef Software, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require_relative '../spec_helper'
+
+require 'ohai/application'
+
+RSpec.describe 'Ohai::Application' do
+
+ let(:app) { Ohai::Application.new }
+ let(:argv) { [] }
+ let(:stderr) { StringIO.new }
+
+ before(:each) do
+ @original_argv = ARGV.dup
+ ARGV.replace(argv)
+ end
+
+ after(:each) do
+ ARGV.replace(@original_argv)
+ end
+
+ describe '#configure_ohai' do
+
+ let(:config_content) { '' }
+ let(:config_dir) { Dir.mktmpdir('.chef') }
+ let(:config_location) { File.join(config_dir, 'config.rb') }
+
+ before(:each) do
+ File.open(config_location, 'w+') do |f|
+ f.write(config_content)
+ end
+ end
+
+ after(:each) do
+ FileUtils.rm_rf(config_dir)
+ end
+
+ context 'when a configuration file is provided as a command line option' do
+
+ let(:argv) { [ '-c', config_location + '.oops' ] }
+
+ context 'and the configuration file does not exist' do
+
+ it 'logs an error and terminates the application' do
+ expect(STDERR).to receive(:puts).with(/FATAL:/)
+ expect(Ohai::Log).to receive(:fatal).
+ with(/Specified config file #{argv[1]} does not exist/)
+ expect { app.configure_ohai }.to raise_error(SystemExit)
+ end
+ end
+ end
+
+ context 'when a workstation configuration file exists' do
+
+ let(:config_content) { 'ohai.disabled_plugins = [ :Foo, :Baz ]' }
+
+ # env['KNIFE_HOME']/config.rb is the first config file the workstation
+ # config loader looks for:
+ # https://github.com/chef/chef/blob/master/chef-config/lib/chef-config/workstation_config_loader.rb#L102
+ let(:env) { { 'KNIFE_HOME' => config_dir } }
+
+ before(:each) do
+ allow_any_instance_of(ChefConfig::WorkstationConfigLoader).
+ to receive(:env).and_return(env)
+ end
+
+ it 'loads the workstation configuration file' do
+ app.configure_ohai
+ expect(Ohai.config[:disabled_plugins]).to eq([ :Foo, :Baz ])
+ end
+ end
+
+ context 'when the configuration file contains deprecated config options' do
+ # For the purpose of these tests it doesn't matter if the configuration
+ # file was specified via command line or discovered on the local
+ # workstation. It's easier if we pass the configuration file as a cli
+ # argument (there's less to stub).
+
+ let(:argv) { [ '-c', config_location ] }
+
+ let(:config_content) do
+ <<-CONFIG
+log_location "#{log_location}"
+log_level :#{log_level}
+Ohai::Config[:disabled_plugins] = #{disabled_plugins}
+Ohai::Config[:plugin_path] << "#{plugin_path}"
+CONFIG
+ end
+
+ # config settings
+ let(:disabled_plugins) { [ :Foo, :Baz ] }
+
+ let(:log_level) { :debug }
+
+ let(:log_location) { 'path/to/log' }
+
+ let(:plugin_path) { '/path/to/plugins' }
+
+ it 'logs warnings for deprecated top-level options' do
+ # deprecation warnings for options need to be stubbed in the order
+ # they are received, in this case it's the order they appear in the
+ # configuration file.
+ options = [ :log_location, :log_level, :disabled_plugins ]
+ options.each do |option|
+ expect(Ohai::Log).to receive(:warn).
+ with(/Ohai::Config\[:#{option}\] is deprecated/)
+ end
+ app.configure_ohai
+ end
+ end
+
+ context 'when the configuration file has a syntax error' do
+ # For the purpose of these tests it doesn't matter if the configuration
+ # file was specified via command line or discovered on the local
+ # workstation. It's easier if we pass the configuration file as a cli
+ # argument (there's less to stub).
+
+ let(:argv) { [ '-c', config_location ] }
+
+ let(:config_content) { 'config_location "blaaaaa' }
+
+ it 'logs an error and terminates the application' do
+ expect(STDERR).to receive(:puts).with(/FATAL:/)
+ expect(Ohai::Log).to receive(:fatal).
+ with(/You have invalid ruby syntax in your config file/)
+ expect { app.configure_ohai }.to raise_error(SystemExit)
+ end
+ end
+
+ end
+end
diff --git a/spec/unit/application_spec.rb b/spec/unit/application_spec.rb
index 32b6f8e1..3fbb5a2e 100644
--- a/spec/unit/application_spec.rb
+++ b/spec/unit/application_spec.rb
@@ -35,54 +35,63 @@ RSpec.describe 'Ohai::Application' do
end
describe '#configure_ohai' do
- it 'merges deprecated config settings into the ohai config context' do
- expect(Ohai::Config).to receive(:merge_deprecated_config)
- app.configure_ohai
- end
-
- context 'when CLI options are provided' do
- let(:argv) { [ '-d', directory ] }
- let(:directory) { '/some/fantastic/plugins' }
-
- it 'does not generate deprecated config warnings for cli options' do
- expect(Ohai::Log).to_not receive(:warn).
- with(/Ohai::Config\[:directory\] is deprecated/)
- app.configure_ohai
- end
-
- it 'merges CLI options into the ohai config context' do
- app.configure_ohai
- expect(Ohai.config[:directory]).to eq(directory)
- end
- end
-
- context 'when directory is configured' do
- let(:directory) { '/some/fantastic/plugins' }
+ describe 'loading configuration from a file' do
+ let(:config_file) { '/local/workstation/config' }
+ let(:config_loader) { instance_double('ChefConfig::WorkstationConfigLoader') }
+
+ context 'when specified on the command line' do
+ let(:argv) { [ '-c', config_file ] }
+
+ before(:each) do
+ if windows?
+ expect(ChefConfig::WorkstationConfigLoader).to receive(:new).
+ with("C:#{config_file}", Ohai::Log).
+ and_return(config_loader)
+ else
+ expect(ChefConfig::WorkstationConfigLoader).to receive(:new).
+ with(config_file, Ohai::Log).
+ and_return(config_loader)
+ end
+ end
- shared_examples_for 'directory' do
- it 'adds directory to plugin_path' do
+ it 'loads the configuration file' do
+ expect(config_loader).to receive(:load)
app.configure_ohai
- expect(Ohai.config[:plugin_path]).to include(directory)
+ end
+
+ context 'when the configuration file does not exist' do
+ it 'terminates the application' do
+ expect(config_loader).to receive(:load).and_raise(ChefConfig::ConfigurationError)
+ expect(Ohai::Application).to receive(:fatal!)
+ app.configure_ohai
+ end
end
end
- context 'in a configuration file' do
- before do
- allow(Ohai::Log).to receive(:warn).
- with(/Ohai::Config\[:directory\] is deprecated/)
- Ohai::Config[:directory] = directory
+ context 'when a local workstation config exists' do
+ before(:each) do
+ expect(ChefConfig::WorkstationConfigLoader).to receive(:new).
+ with(nil, Ohai::Log).
+ and_return(config_loader)
end
- include_examples 'directory'
+ it 'loads the configuration file' do
+ expect(config_loader).to receive(:load)
+ app.configure_ohai
+ end
end
+ end
- context 'as a command line option' do
- let(:argv) { ['-d', directory] }
+ context 'when CLI options are provided' do
+ let(:argv) { [ '-d', directory ] }
+ let(:directory) { '/some/fantastic/plugins' }
- include_examples 'directory'
+ it 'does not generate deprecated config warnings for cli options' do
+ expect(Ohai::Log).to_not receive(:warn).
+ with(/Ohai::Config\[:directory\] is deprecated/)
+ app.configure_ohai
end
end
end
-
end
diff --git a/spec/unit/system_spec.rb b/spec/unit/system_spec.rb
index 0eb7f439..1d6d65f5 100644
--- a/spec/unit/system_spec.rb
+++ b/spec/unit/system_spec.rb
@@ -26,17 +26,80 @@ describe "Ohai::System" do
let(:ohai) { Ohai::System.new }
describe "#initialize" do
- it "should return an Ohai::System object" do
+ it "returns an Ohai::System object" do
expect(ohai).to be_a_kind_of(Ohai::System)
end
- it "should set @attributes to a ProvidesMap" do
+ it "sets @attributes to a ProvidesMap" do
expect(ohai.provides_map).to be_a_kind_of(Ohai::ProvidesMap)
end
- it "should set @v6_dependency_solver to a Hash" do
+ it "sets @v6_dependency_solver to a Hash" do
expect(ohai.v6_dependency_solver).to be_a_kind_of(Hash)
end
+
+ it 'merges deprecated config settings into the ohai config context' do
+ expect(Ohai::Log).to receive(:warn).
+ with(/Ohai::Config\[:disabled_plugins\] is deprecated/)
+ Ohai::Config[:disabled_plugins] = [ :Foo, :Baz ]
+ expect(Ohai::Config).to receive(:merge_deprecated_config).
+ and_call_original
+ Ohai::System.new
+ expect(Ohai.config[:disabled_plugins]).to eq([ :Foo, :Baz ])
+ end
+
+ it 'merges provided configuration options into the ohai config context' do
+ config = {
+ disabled_plugins: [ :Foo, :Baz ],
+ directory: '/some/extra/plugins'
+ }
+ allow(Ohai::Config).to receive(:merge_deprecated_config)
+ expect(Ohai.config).to receive(:merge!).with(config).and_call_original
+ Ohai::System.new(config)
+ config.each do |option, value|
+ expect(Ohai.config[option]).to eq(value)
+ end
+ end
+
+ context 'when directory is configured' do
+ let(:directory) { '/some/fantastic/plugins' }
+
+ it 'adds directory to plugin_path' do
+ Ohai.config[:directory] = directory
+ Ohai::System.new
+ expect(Ohai.config[:plugin_path]).to include(directory)
+ end
+ end
+
+ shared_examples_for 'appendable deprecated configuration option' do
+ it 'logs a warning and configures the option on the ohai config context' do
+ Ohai::Config[option] << value
+ expect(Ohai::Log).to receive(:warn).
+ with(/Ohai::Config\[:#{option}\] is deprecated/)
+ Ohai::System.new
+ expect(Ohai.config[option]).to include(value)
+ end
+ end
+
+ context 'when a top-level hints_path is configured' do
+ include_examples 'appendable deprecated configuration option' do
+ let(:option) { :hints_path }
+ let(:value) { '/path/to/hints' }
+ end
+ end
+
+ context 'when a top-level plugin_path is configured' do
+ include_examples 'appendable deprecated configuration option' do
+ let(:option) { :plugin_path }
+ let(:value) { '/path/to/plugins' }
+ end
+ end
+
+ it 'configures logging' do
+ expect(Ohai::Log).to receive(:init).with(Ohai.config[:log_location])
+ expect(Ohai::Log).to receive(:level=).with(Ohai.config[:log_level])
+ Ohai::System.new
+ end
end
when_plugins_directory "contains v6 and v7 plugins" do