diff options
author | AJ Christensen <aj@junglist.gen.nz> | 2009-06-06 10:19:23 +1200 |
---|---|---|
committer | AJ Christensen <aj@junglist.gen.nz> | 2009-06-08 11:39:48 +1200 |
commit | c362c603e01d8393c14779f83cdc18a75b923c06 (patch) | |
tree | 737318e9ebf78d6fb3994cd520a44627d93e6b1f | |
parent | 8e1316cd96086f6a94ce2c0f65344250184a4fdc (diff) | |
download | chef-c362c603e01d8393c14779f83cdc18a75b923c06.tar.gz |
CHEF-330: Add verbose(r) error messages, specs; for JSON fetching
-rw-r--r-- | chef/lib/chef/application/client.rb | 23 | ||||
-rw-r--r-- | chef/lib/chef/application/solo.rb | 24 | ||||
-rw-r--r-- | chef/spec/unit/application/client_spec.rb | 2 | ||||
-rw-r--r-- | chef/spec/unit/application/solo_spec.rb | 103 |
4 files changed, 137 insertions, 15 deletions
diff --git a/chef/lib/chef/application/client.rb b/chef/lib/chef/application/client.rb index 1496a45f92..0e0e146fd3 100644 --- a/chef/lib/chef/application/client.rb +++ b/chef/lib/chef/application/client.rb @@ -20,6 +20,8 @@ require 'chef/client' require 'chef/config' require 'chef/daemon' require 'chef/log' +require 'net/http' +require 'open-uri' class Chef::Application::Client < Chef::Application @@ -120,15 +122,22 @@ class Chef::Application::Client < Chef::Application end if Chef::Config[:json_attribs] - require 'net/http' - require 'open-uri' + begin + json_io = open(Chef::Config[:json_attribs]) + rescue SocketError => error + Chef::Application.fatal!("I cannot connect to #{Chef::Config[:json_attribs]}", 2) + rescue Errno::ENOENT => error + Chef::Application.fatal!("I cannot find #{Chef::Config[:json_attribs]}", 2) + rescue Errno::EACCES => error + Chef::Application.fatal!("Permissions are incorrect on #{Chef::Config[:json_attribs]}. Please chmod a+r #{Chef::Config[:json_attribs]}", 2) + rescue Exception => error + Chef::Application.fatal!("Got an unexpected error reading #{Chef::Config[:json_attribs]}: #{error.message}", 2) + end begin - open(Chef::Config[:json_attribs]) do |json_io| - @chef_client_json = JSON.parse(json_io.read) - end - rescue Exception - Chef::Application.fatal!("Error parsing json attributes", 2) + @chef_client_json = JSON.parse(json_io.read) + rescue JSON::ParserError => error + Chef::Application.fatal!("Could not parse the provided JSON file (#{Chef::Config[:json_attribs]})!: " + error.message, 2) end end end diff --git a/chef/lib/chef/application/solo.rb b/chef/lib/chef/application/solo.rb index 86eaba3d16..87a815fe88 100644 --- a/chef/lib/chef/application/solo.rb +++ b/chef/lib/chef/application/solo.rb @@ -20,6 +20,9 @@ require 'chef/client' require 'chef/config' require 'chef/daemon' require 'chef/log' +require 'net/http' +require 'open-uri' +require 'fileutils' class Chef::Application::Solo < Chef::Application @@ -72,8 +75,17 @@ class Chef::Application::Solo < Chef::Application super if Chef::Config[:json_attribs] - require 'net/http' - require 'open-uri' + begin + json_io = open(Chef::Config[:json_attribs]) + rescue SocketError => error + Chef::Application.fatal!("I cannot connect to #{Chef::Config[:json_attribs]}", 2) + rescue Errno::ENOENT => error + Chef::Application.fatal!("I cannot find #{Chef::Config[:json_attribs]}", 2) + rescue Errno::EACCES => error + Chef::Application.fatal!("Permissions are incorrect on #{Chef::Config[:json_attribs]}. Please chmod a+r #{Chef::Config[:json_attribs]}", 2) + rescue Exception => error + Chef::Application.fatal!("Got an unexpected error reading #{Chef::Config[:json_attribs]}: #{error.message}", 2) + end json_io = nil begin @@ -89,20 +101,18 @@ class Chef::Application::Solo < Chef::Application end begin - @chef_solo_json = JSON.parse(json_io.read) + @chef_client_json = JSON.parse(json_io.read) rescue JSON::ParserError => error Chef::Application.fatal!("Could not parse the provided JSON file (#{Chef::Config[:json_attribs]})!: " + error.message, 2) - exit 2 end end if Chef::Config[:recipe_url] cookbooks_path = Chef::Config[:cookbook_path].detect{|e| e =~ /\/cookbooks\/*$/ } recipes_path = File.expand_path(File.join(cookbooks_path, '..')) - require 'net/http' - require 'open-uri' - require 'fileutils' + target_file = File.join(recipes_path, 'recipes.tgz') + Chef::Log.debug "Creating path #{recipes_path} to extract recipes into" FileUtils.mkdir_p recipes_path path = File.join(recipes_path, 'recipes.tgz') File.open(path, 'wb') do |f| diff --git a/chef/spec/unit/application/client_spec.rb b/chef/spec/unit/application/client_spec.rb index 0f937a2bf4..ad20d0976d 100644 --- a/chef/spec/unit/application/client_spec.rb +++ b/chef/spec/unit/application/client_spec.rb @@ -76,7 +76,7 @@ describe Chef::Application::Client, "reconfigure" do before do Chef::Config.stub!(:[]).with(:json_attribs).and_return("/etc/chef/dna.json") @json = mock("Tempfile", :read => {:a=>"b"}.to_json, :null_object => true) - @app.stub!(:open).and_yield(@json) + @app.stub!(:open).with("/etc/chef/dna.json").and_return(@json) end it "should parse the json out of the file" do diff --git a/chef/spec/unit/application/solo_spec.rb b/chef/spec/unit/application/solo_spec.rb index e69de29bb2..19202a2533 100644 --- a/chef/spec/unit/application/solo_spec.rb +++ b/chef/spec/unit/application/solo_spec.rb @@ -0,0 +1,103 @@ +# +# Author:: AJ Christensen (<aj@junglist.gen.nz>) +# Copyright:: Copyright (c) 2008 Opscode, 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 File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "spec_helper")) + +describe Chef::Application::Solo, "initialize" do + before do + @app = Chef::Application::Solo.new + end + + it "should create an instance of Chef::Application::Solo" do + @app.should be_kind_of(Chef::Application::Solo) + end +end + +describe Chef::Application::Solo, "reconfigure" do + before do + @app = Chef::Application::Solo.new + @app.stub!(:configure_opt_parser).and_return(true) + @app.stub!(:configure_chef).and_return(true) + @app.stub!(:configure_logging).and_return(true) + Chef::Config.stub!(:[]).with(:recipe_url).and_return(false) + Chef::Config.stub!(:[]).with(:json_attribs).and_return(false) + end + + it "should set solo mode to true" do + Chef::Config.should_receive(:[]=).with(:solo, true).and_return(true) + @app.reconfigure + end + + describe "when the json_attribs configuration option is specified" do + before do + Chef::Config.stub!(:[]).with(:json_attribs).and_return("/etc/chef/dna.json") + @json = mock("Tempfile", :read => {:a=>"b"}.to_json, :null_object => true) + @app.stub!(:open).with("/etc/chef/dna.json").and_return(@json) + end + + it "should parse the json out of the file" do + JSON.should_receive(:parse).with(@json.read) + @app.reconfigure + end + end + + describe "when the recipe_url configuration option is specified" do + before do + Chef::Config.stub!(:[]).with(:cookbook_path).and_return("/tmp/chef-solo/cookbooks") + Chef::Config.stub!(:[]).with(:recipe_url).and_return("http://junglist.gen.nz/recipes.tgz") + FileUtils.stub!(:mkdir_p).and_return(true) + @tarfile = mock("Tempfile", :null_object => true, :read => "blah") + @app.stub!(:open).with("http://junglist.gen.nz/recipes.tgz").and_yield(@tarfile) + @target_file = mock("Tempfile", :null_object => true) + File.stub!(:open).with("/tmp/chef-solo/recipes.tgz", "wb").and_yield(@target_file) + Chef::Mixin::Command.stub!(:run_command).with({:command => "tar xzvfC /tmp/chef-solo/recipes.tgz /tmp/chef-solo"}).and_return(true) + end + + it "should create the recipes path based on the parent of the cookbook path" do + FileUtils.should_receive(:mkdir_p).with("/tmp/chef-solo").and_return(true) + @app.reconfigure + end + + it "should download the recipes" do + @app.should_receive(:open).with("http://junglist.gen.nz/recipes.tgz").and_yield(@tarfile) + @app.reconfigure + end + + it "should write the recipes to the target path" do + @target_file.should_receive(:write).with("blah").and_return(true) + @app.reconfigure + end + + it "should untar the target file to the parent of the cookbook path" do + Chef::Mixin::Command.should_receive(:run_command).with({:command => "tar xzvfC /tmp/chef-solo/recipes.tgz /tmp/chef-solo"}).and_return(true) + @app.reconfigure + end + end +end + +describe Chef::Application::Solo, "setup_application" do + before do + @chef_client = mock("Chef::Client", :null_object => true) + Chef::Client.stub!(:new).and_return(@chef_client) + @app = Chef::Application::Solo.new + end + + it "should instantiate a chef::client object" do + Chef::Client.should_receive(:new).and_return(@chef_client) + @app.setup_application + end +end
\ No newline at end of file |