summaryrefslogtreecommitdiff
path: root/lib/chef
diff options
context:
space:
mode:
authordanielsdeleo <dan@opscode.com>2013-10-14 15:20:46 -0700
committerdanielsdeleo <dan@opscode.com>2013-10-16 13:53:37 -0700
commitdd998f23aa904011fa3aeef40e2fae31273ad4e5 (patch)
tree0f42bd77f794f7ab91733a2d89ccccfbcfa96114 /lib/chef
parent3b877d8956531eb18ca5b398e2b2c8b4e33b71ce (diff)
downloadchef-dd998f23aa904011fa3aeef40e2fae31273ad4e5.tar.gz
Load client/solo config via ConfigFetcher
* Uses Chef::HTTP::Simple rather than Chef::REST to fetch files * Re-use error handling logic in ConfigFetcher
Diffstat (limited to 'lib/chef')
-rw-r--r--lib/chef/application.rb72
-rw-r--r--lib/chef/config_fetcher.rb33
-rw-r--r--lib/chef/knife.rb36
3 files changed, 64 insertions, 77 deletions
diff --git a/lib/chef/application.rb b/lib/chef/application.rb
index caa6358aa2..7b57556ce2 100644
--- a/lib/chef/application.rb
+++ b/lib/chef/application.rb
@@ -76,66 +76,18 @@ class Chef::Application
# Parse the config file
def load_config_file
- if !config[:config_file]
+ config_fetcher = Chef::ConfigFetcher.new(config[:config_file], Chef::Config.config_file_jail)
+ if config[:config_file].nil?
Chef::Log.warn("No config file found or specified on command line, using command line options.")
- Chef::Config.merge!(config)
- return
- end
-
- if !Chef::Application.config_file_exists?(config[:config_file])
+ elsif config_fetcher.config_missing?
Chef::Log.warn("*****************************************")
- if !File.exists?(config[:config_file])
- Chef::Log.warn("Did not find config file: #{config[:config_file]}, using command line options.")
- else
- Chef::Log.warn("Config file #{config[:config_file]} not inside the jail #{Chef::Config.config_file_jail}, using command line options.", 2)
- end
+ Chef::Log.warn("Did not find config file: #{config[:config_file]}, using command line options.")
Chef::Log.warn("*****************************************")
-
- Chef::Config.merge!(config)
- return
- end
-
- begin
- case config[:config_file]
- when /^(http|https):\/\//
- Chef::REST.new("", nil, nil).fetch(config[:config_file]) { |f| apply_config(f.path) }
- else
- ::File::open(config[:config_file]) { |f| apply_config(f.path) }
- end
- rescue SocketError => error
- Chef::Application.fatal!("Error getting config file #{config[:config_file]}", 2)
- rescue Chef::Exceptions::ConfigurationError => error
- Chef::Application.fatal!("Error processing config file #{config[:config_file]} with error #{error.message}", 2)
- rescue Exception => error
- Chef::Application.fatal!("Unknown error processing config file #{config[:config_file]} with error #{error.message}", 2)
- end
- end
-
- # Determines whether a config file exists, taking into account file existence
- # as well as Chef::Config.config_file_jail (if they are not under the jail,
- # this method will return false). Takes symlinks and relative paths into
- # account.
- def self.config_file_exists?(config_file)
- if config_file =~ /^(http|https):\/\//
- return true
- end
-
- begin
- real_config_file = Pathname.new(config_file).realpath.to_s
- rescue Errno::ENOENT
- return false
- end
-
- return true if !Chef::Config.config_file_jail
-
- begin
- jail = Pathname.new(Chef::Config.config_file_jail).realpath.to_s
- rescue Errno::ENOENT
- Chef::Log.warn("Config file jail #{Chef::Config.config_file_jail} does not exist: will not load any config file.")
- return false
+ else
+ config_content = config_fetcher.read_config
+ apply_config(config_content, config[:config_file])
end
-
- Chef::ChefFS::PathUtils.descendant_of?(real_config_file, jail)
+ Chef::Config.merge!(config)
end
# Initialize and configure the logger.
@@ -263,9 +215,13 @@ class Chef::Application
private
- def apply_config(config_file_path)
- Chef::Config.from_file(config_file_path)
+ def apply_config(config_content, config_file_path)
+ Chef::Config.from_string(config_content, config_file_path)
Chef::Config.merge!(config)
+ rescue Chef::Exceptions::ConfigurationError => error
+ Chef::Application.fatal!("Error processing config file #{config[:config_file]} with error #{error.message}", 2)
+ rescue Exception => error
+ Chef::Application.fatal!("Unknown error processing config file #{config[:config_file]} with error #{error.message}", 2)
end
class << self
diff --git a/lib/chef/config_fetcher.rb b/lib/chef/config_fetcher.rb
index 129d8bed62..2400dc6897 100644
--- a/lib/chef/config_fetcher.rb
+++ b/lib/chef/config_fetcher.rb
@@ -1,11 +1,17 @@
+require 'chef/application'
+require 'chef/chef_fs/path_utils'
require 'chef/http/simple'
+require 'chef/json_compat'
+
class Chef
class ConfigFetcher
attr_reader :config_location
+ attr_reader :config_file_jail
- def initialize(config_location)
+ def initialize(config_location, config_file_jail)
@config_location = config_location
+ @config_file_jail = config_file_jail
end
def fetch_json
@@ -27,7 +33,7 @@ class Chef
def fetch_remote_config
http.get("")
- rescue SocketError, SystemCallError => error
+ rescue SocketError, SystemCallError, Net::HTTPServerException => error
Chef::Application.fatal!("Cannot fetch config '#{config_location}': '#{error.class}: #{error.message}", 2)
end
@@ -39,6 +45,29 @@ class Chef
Chef::Application.fatal!("Permissions are incorrect on #{config_location}. Please chmod a+r #{config_location}", 2)
end
+ def config_missing?
+ return true if remote_config?
+
+ # Check if the config file exists, and check if it is underneath the config file jail
+ begin
+ real_config_file = Pathname.new(config_file).realpath.to_s
+ rescue Errno::ENOENT
+ return false
+ end
+
+ # If realpath succeeded, the file exists
+ return true if !config_file_jail
+
+ begin
+ real_jail = Pathname.new(config_file_jail).realpath.to_s
+ rescue Errno::ENOENT
+ Chef::Log.warn("Config file jail #{config_file_jail} does not exist: will not load any config file.")
+ return false
+ end
+
+ Chef::ChefFS::PathUtils.descendant_of?(real_config_file, real_jail)
+ end
+
def http
Chef::HTTP::Simple.new(config_location)
end
diff --git a/lib/chef/knife.rb b/lib/chef/knife.rb
index dbb719c30a..5d455f9b24 100644
--- a/lib/chef/knife.rb
+++ b/lib/chef/knife.rb
@@ -20,6 +20,7 @@
require 'forwardable'
require 'chef/version'
require 'mixlib/cli'
+require 'chef/config_fetcher'
require 'chef/mixin/convert_to_class_name'
require 'chef/mixin/path_sanity'
require 'chef/knife/core/subcommand_loader'
@@ -335,7 +336,8 @@ class Chef
end
candidate_configs.each do | candidate_config |
- if Chef::Application.config_file_exists?(candidate_config)
+ fetcher = Chef::ConfigFetcher.new(candidate_config, Chef::Config::config_file_jail)
+ if !fetcher.config_missing?
return candidate_config
end
end
@@ -402,20 +404,20 @@ class Chef
end
def configure_chef
- if config[:config_file]
- if !Chef::Application.config_file_exists?(config[:config_file])
- ui.error("Specified config file #{config[:config_file]} does not exist#{Chef::Config.config_file_jail ? " or is not under config file jail #{Chef::Config.config_file_jail}" : ""}!")
- exit 1
- end
- else
+ if !config[:config_file]
located_config_file = self.class.locate_config_file
config[:config_file] = located_config_file if located_config_file
end
# Don't try to load a knife.rb if it wasn't specified.
if config[:config_file]
+ fetcher = Chef::ConfigFetcher.new(config[:config_file], Chef::Config.config_file_jail)
+ if fetcher.config_missing?(config[:config_file])
+ ui.error("Specified config file #{config[:config_file]} does not exist#{Chef::Config.config_file_jail ? " or is not under config file jail #{Chef::Config.config_file_jail}" : ""}!")
+ exit 1
+ end
Chef::Log.debug("Using configuration from #{config[:config_file]}")
- read_config_file(config[:config_file])
+ read_config(fetcher.read_config, config[:config_file])
else
# ...but do log a message if no config was found.
Chef::Config[:color] = config[:color]
@@ -426,24 +428,24 @@ class Chef
apply_computed_config
end
- def read_config_file(file)
- Chef::Config.from_file(file)
+ def read_config(config_content, config_file_path)
+ Chef::Config.from_string(config_content, config_file_path)
rescue SyntaxError => e
- ui.error "You have invalid ruby syntax in your config file #{file}"
+ ui.error "You have invalid ruby syntax in your config file #{config_file_path}"
ui.info(ui.color(e.message, :red))
- if file_line = e.message[/#{Regexp.escape(file)}:[\d]+/]
+ if file_line = e.message[/#{Regexp.escape(config_file_path)}:[\d]+/]
line = file_line[/:([\d]+)$/, 1].to_i
- highlight_config_error(file, line)
+ highlight_config_error(config_file_path, line)
end
exit 1
rescue Exception => e
- ui.error "You have an error in your config file #{file}"
+ ui.error "You have an error in your config file #{config_file_path}"
ui.info "#{e.class.name}: #{e.message}"
- filtered_trace = e.backtrace.grep(/#{Regexp.escape(file)}/)
+ filtered_trace = e.backtrace.grep(/#{Regexp.escape(config_file_path)}/)
filtered_trace.each {|line| ui.msg(" " + ui.color(line, :red))}
if !filtered_trace.empty?
- line_nr = filtered_trace.first[/#{Regexp.escape(file)}:([\d]+)/, 1]
- highlight_config_error(file, line_nr.to_i)
+ line_nr = filtered_trace.first[/#{Regexp.escape(config_file_path)}:([\d]+)/, 1]
+ highlight_config_error(config_file_path, line_nr.to_i)
end
exit 1