diff options
author | Christopher Brown <cb@opscode.com> | 2009-02-25 08:13:20 -0800 |
---|---|---|
committer | Christopher Brown <cb@opscode.com> | 2009-02-25 08:13:20 -0800 |
commit | f79a7385964f6b60220ef1817120d331ae9d8d80 (patch) | |
tree | 62d702e134c1acaa9d0bc3b223705488ebaad29e /chef | |
parent | 6f5042c1947415db20edd4453f3c40252eca6cdc (diff) | |
parent | 409ffd22488aea6afc75ad18b32e64cc8fffcc78 (diff) | |
download | chef-f79a7385964f6b60220ef1817120d331ae9d8d80.tar.gz |
merged master 0.5.5
Diffstat (limited to 'chef')
-rw-r--r-- | chef/Rakefile | 2 | ||||
-rwxr-xr-x | chef/bin/chef-client | 7 | ||||
-rw-r--r-- | chef/chef.gemspec | 2 | ||||
-rw-r--r-- | chef/lib/chef.rb | 2 | ||||
-rw-r--r-- | chef/lib/chef/config.rb | 2 | ||||
-rw-r--r-- | chef/lib/chef/mixin/generate_url.rb | 2 | ||||
-rw-r--r-- | chef/lib/chef/mixin/template.rb | 49 | ||||
-rw-r--r-- | chef/lib/chef/provider/package.rb | 3 | ||||
-rw-r--r-- | chef/lib/chef/provider/package/dpkg.rb | 110 | ||||
-rw-r--r-- | chef/lib/chef/provider/remote_directory.rb | 4 | ||||
-rw-r--r-- | chef/lib/chef/provider/remote_file.rb | 2 | ||||
-rw-r--r-- | chef/lib/chef/resource/remote_directory.rb | 9 | ||||
-rw-r--r-- | chef/lib/chef/rest.rb | 4 | ||||
-rw-r--r-- | chef/spec/unit/mixin/template_spec.rb | 86 | ||||
-rw-r--r-- | chef/spec/unit/provider/package/dpkg_spec.rb | 177 | ||||
-rw-r--r-- | chef/spec/unit/provider/package_spec.rb | 9 | ||||
-rw-r--r-- | chef/spec/unit/rest_spec.rb | 49 |
17 files changed, 481 insertions, 38 deletions
diff --git a/chef/Rakefile b/chef/Rakefile index 9a52dec46a..faa66847a4 100644 --- a/chef/Rakefile +++ b/chef/Rakefile @@ -4,7 +4,7 @@ require 'rake/rdoctask' require './tasks/rspec.rb' GEM = "chef" -CHEF_VERSION = "0.5.3" +CHEF_VERSION = "0.5.5" AUTHOR = "Adam Jacob" EMAIL = "adam@opscode.com" HOMEPAGE = "http://wiki.opscode.com/display/chef" diff --git a/chef/bin/chef-client b/chef/bin/chef-client index e217d11a5b..32a3c45fe0 100755 --- a/chef/bin/chef-client +++ b/chef/bin/chef-client @@ -57,6 +57,13 @@ opts = OptionParser.new do |opts| end opts.parse!(ARGV) +trap("INT") { Chef.fatal!("SIGINT received, stopping", 2) } +trap("HUP") { + Chef::Log.info("SIGHUP received, reloading configuration") + Chef::Config.from_file(config[:config_file]) + Chef::Config.configure { |c| c.merge!(config) } +} + unless File.exists?(config[:config_file]) and File.readable?(config[:config_file]) Chef.fatal!("I cannot find or read the config file: #{config[:config_file]}", 1) end diff --git a/chef/chef.gemspec b/chef/chef.gemspec index 430123a498..5273922e20 100644 --- a/chef/chef.gemspec +++ b/chef/chef.gemspec @@ -1,6 +1,6 @@ Gem::Specification.new do |s| s.name = %q{chef} - s.version = "0.5.3" + s.version = "0.5.5" s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.authors = ["Adam Jacob"] diff --git a/chef/lib/chef.rb b/chef/lib/chef.rb index 934fdc87aa..1123a0ea4a 100644 --- a/chef/lib/chef.rb +++ b/chef/lib/chef.rb @@ -27,7 +27,7 @@ require 'chef/config' Dir[File.join(File.dirname(__FILE__), 'chef/mixin/**/*.rb')].sort.each { |lib| require lib } class Chef - VERSION = '0.5.3' + VERSION = '0.5.5' class << self def fatal!(msg, err = -1) diff --git a/chef/lib/chef/config.rb b/chef/lib/chef/config.rb index b416012044..325156b421 100644 --- a/chef/lib/chef/config.rb +++ b/chef/lib/chef/config.rb @@ -53,6 +53,8 @@ class Chef :log_location => STDOUT, :openid_providers => nil, :ssl_verify_mode => :verify_none, + :ssl_client_cert => "", + :ssl_client_key => "", :rest_timeout => 60, :couchdb_url => "http://localhost:5984", :registration_url => "http://localhost:4000", diff --git a/chef/lib/chef/mixin/generate_url.rb b/chef/lib/chef/mixin/generate_url.rb index abb28d6df0..9ebe22b832 100644 --- a/chef/lib/chef/mixin/generate_url.rb +++ b/chef/lib/chef/mixin/generate_url.rb @@ -24,7 +24,7 @@ class Chef def generate_cookbook_url(url, cookbook, type, node, args=nil) new_url = nil - if url =~ /^http/ + if url =~ /^(http|https):\/\// new_url = url else new_url = "cookbooks/#{cookbook}/#{type}?" diff --git a/chef/lib/chef/mixin/template.rb b/chef/lib/chef/mixin/template.rb index 11329dbaa7..73a6ffbd95 100644 --- a/chef/lib/chef/mixin/template.rb +++ b/chef/lib/chef/mixin/template.rb @@ -26,14 +26,59 @@ class Chef # Render a template with Erubis. Takes a template as a string, and a # context hash. def render_template(template, context) - eruby = Erubis::Eruby.new(template) - output = eruby.evaluate(context) + begin + eruby = Erubis::Eruby.new(template) + output = eruby.evaluate(context) + rescue Object => e + raise TemplateError.new(e, template, context) + end final_tempfile = Tempfile.new("chef-rendered-template") final_tempfile.print(output) final_tempfile.close final_tempfile end + class TemplateError < RuntimeError + attr_reader :original_exception, :context + SOURCE_CONTEXT_WINDOW = 2 unless defined? SOURCE_CONTEXT_WINDOW + + def initialize(original_exception, template, context) + @original_exception, @template, @context = original_exception, template, context + end + + def message + @original_exception.message + end + + def line_number + @line_number ||= $1.to_i if original_exception.backtrace.find {|line| line =~ /\(erubis\):(\d+)/ } + end + + def source_location + "on line ##{line_number}" + end + + def source_listing + @source_listing ||= begin + line_index = line_number - 1 + beginning_line = line_index <= SOURCE_CONTEXT_WINDOW ? 0 : line_index - SOURCE_CONTEXT_WINDOW + source_size = SOURCE_CONTEXT_WINDOW * 2 + 1 + lines = @template.split(/\n/) + contextual_lines = lines[beginning_line, source_size] + output = [] + contextual_lines.each_with_index do |line, index| + line_number = (index+beginning_line+1).to_s.rjust(3) + output << "#{line_number}: #{line}" + end + output.join("\n") + end + end + + def to_s + "\n\n#{self.class} (#{message}) #{source_location}:\n\n" + + "#{source_listing}\n\n #{original_exception.backtrace.join("\n ")}\n\n" + end + end end end end diff --git a/chef/lib/chef/provider/package.rb b/chef/lib/chef/provider/package.rb index 5b323f2bdd..badc7aaacd 100644 --- a/chef/lib/chef/provider/package.rb +++ b/chef/lib/chef/provider/package.rb @@ -71,7 +71,8 @@ class Chef def action_upgrade if @current_resource.version != @candidate_version - Chef::Log.info("Upgrading #{@new_resource} version from #{@current_resource.version} to #{@candidate_version}") + orig_version = @current_resource.version || "uninstalled" + Chef::Log.info("Upgrading #{@new_resource} version from #{orig_version} to #{@candidate_version}") status = upgrade_package(@new_resource.package_name, @candidate_version) if status @new_resource.updated = true diff --git a/chef/lib/chef/provider/package/dpkg.rb b/chef/lib/chef/provider/package/dpkg.rb new file mode 100644 index 0000000000..0cad2d00e8 --- /dev/null +++ b/chef/lib/chef/provider/package/dpkg.rb @@ -0,0 +1,110 @@ +# +# Author:: Bryan McLellan (btm@loftninjas.org) +# Copyright:: Copyright (c) 2009 Bryan McLellan +# 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 'chef/provider/package' +require 'chef/mixin/command' +require 'chef/resource/package' + +class Chef + class Provider + class Package + class Dpkg < Chef::Provider::Package::Apt + + def load_current_resource + @current_resource = Chef::Resource::Package.new(@new_resource.name) + @current_resource.package_name(@new_resource.package_name) + @new_resource.version(nil) + + # We only -need- source for action install + if @new_resource.source + unless ::File.exists?(@new_resource.source) + raise Chef::Exception::Package, "Package #{@new_resource.name} not found: #{@new_resource.source}" + end + + # Get information from the package if supplied + Chef::Log.debug("Checking dpkg status for #{@new_resource.package_name}") + status = popen4("dpkg-deb -W #{@new_resource.source}") do |pid, stdin, stdout, stderr| + stdout.each do |line| + case line + when /([\w\d]+)\t([\w\d.-]+)/ + @current_resource.package_name($1) + @new_resource.version($2) + end + end + end + else + # if the source was not set, and we're installing, fail + if @new_resource.action.include?(:install) + raise Chef::Exception::Package, "Source for package #{@new_resource.name} required for action install" + end + end + + # Check to see if it is installed + package_installed = nil + Chef::Log.debug("Checking install state for #{@current_resource.package_name}") + status = popen4("dpkg -s #{@current_resource.package_name}") do |pid, stdin, stdout, stderr| + stdout.each do |line| + case line + when /^Status: install ok installed/ + package_installed = true + when /^Version: (.+)$/ + if package_installed + Chef::Log.debug("Current version is #{$1}") + @current_resource.version($1) + end + end + end + end + + unless status.exitstatus == 0 || status.exitstatus == 1 + raise Chef::Exception::Package, "dpkg failed - #{status.inspect}!" + end + + @current_resource + end + + def install_package(name, version) + run_command( + :command => "dpkg -i #{@new_resource.source}", + :environment => { + "DEBIAN_FRONTEND" => "noninteractive" + } + ) + end + + def remove_package(name, version) + run_command( + :command => "dpkg -r #{@new_resource.package_name}", + :environment => { + "DEBIAN_FRONTEND" => "noninteractive" + } + ) + end + + def purge_package(name, version) + run_command( + :command => "dpkg -P #{@new_resource.package_name}", + :environment => { + "DEBIAN_FRONTEND" => "noninteractive" + } + ) + end + end + end + end +end diff --git a/chef/lib/chef/provider/remote_directory.rb b/chef/lib/chef/provider/remote_directory.rb index fb490bbb1d..010e0b29cd 100644 --- a/chef/lib/chef/provider/remote_directory.rb +++ b/chef/lib/chef/provider/remote_directory.rb @@ -53,7 +53,7 @@ class Chef full_dir = ::File.dirname(full_path) unless ::File.directory?(full_dir) new_dir = Chef::Resource::Directory.new(full_dir, nil, @node) - new_dir.cookbook_name = @new_resource.cookbook_name + new_dir.cookbook_name = @new_resource.cookbook || @new_resource.cookbook_name new_dir.mode(@new_resource.mode) new_dir.group(@new_resource.group) new_dir.owner(@new_resource.owner) @@ -67,7 +67,7 @@ class Chef end remote_file = Chef::Resource::RemoteFile.new(full_path, nil, @node) - remote_file.cookbook_name = @new_resource.cookbook_name + remote_file.cookbook_name = @new_resource.cookbook || @new_resource.cookbook_name remote_file.source(::File.join(@new_resource.source, remote_file_source)) remote_file.mode(@new_resource.files_mode) if @new_resource.files_mode remote_file.group(@new_resource.files_group) if @new_resource.files_group diff --git a/chef/lib/chef/provider/remote_file.rb b/chef/lib/chef/provider/remote_file.rb index 8ceed5f74d..8fd5eb0104 100644 --- a/chef/lib/chef/provider/remote_file.rb +++ b/chef/lib/chef/provider/remote_file.rb @@ -91,6 +91,7 @@ class Chef uri = URI.parse(source) if uri.absolute r = Chef::REST.new(source) + Chef::Log.debug("Downloading from absolute URI: #{source}") r.get_rest(source, true).open end rescue URI::InvalidURIError @@ -101,6 +102,7 @@ class Chef unless Chef::Config[:solo] r = Chef::REST.new(Chef::Config[:remotefile_url]) url = generate_url(source, "files", :checksum => current_checksum) + Chef::Log.debug("Downloading from server: #{url}") r.get_rest(url, true).open end end diff --git a/chef/lib/chef/resource/remote_directory.rb b/chef/lib/chef/resource/remote_directory.rb index 478cdc6528..1628af3a33 100644 --- a/chef/lib/chef/resource/remote_directory.rb +++ b/chef/lib/chef/resource/remote_directory.rb @@ -34,6 +34,7 @@ class Chef @files_group = nil @files_mode = 0644 @allowed_actions.push(:create, :delete) + @cookbook = nil end def source(args=nil) @@ -76,6 +77,14 @@ class Chef ) end + def cookbook(args=nil) + set_or_return( + :cookbook, + args, + :kind_of => String + ) + end + end end end
\ No newline at end of file diff --git a/chef/lib/chef/rest.rb b/chef/lib/chef/rest.rb index 3224262589..bac6788e52 100644 --- a/chef/lib/chef/rest.rb +++ b/chef/lib/chef/rest.rb @@ -123,6 +123,10 @@ class Chef if Chef::Config[:ssl_verify_mode] == :verify_none http.verify_mode = OpenSSL::SSL::VERIFY_NONE end + if File.exists?(Chef::Config[:ssl_client_cert]) + http.cert = OpenSSL::X509::Certificate.new(File.read(Chef::Config[:ssl_client_cert])) + http.key = OpenSSL::PKey::RSA.new(File.read(Chef::Config[:ssl_client_key])) + end end http.read_timeout = Chef::Config[:rest_timeout] headers = Hash.new diff --git a/chef/spec/unit/mixin/template_spec.rb b/chef/spec/unit/mixin/template_spec.rb index 443ca28e1d..86e0b59232 100644 --- a/chef/spec/unit/mixin/template_spec.rb +++ b/chef/spec/unit/mixin/template_spec.rb @@ -19,42 +19,72 @@ require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "spec_helper")) class TinyTemplateClass; include Chef::Mixin::Template; end - +require 'cgi' describe Chef::Mixin::Template, "render_template" do - before(:each) do - @template = "abcnews" - @context = { :fine => "dear" } - @eruby = mock(:erubis, { :evaluate => "elvis costello" }) - Erubis::Eruby.stub!(:new).and_return(@eruby) - @tempfile = mock(:tempfile, { :print => true, :close => true }) - Tempfile.stub!(:new).and_return(@tempfile) - @tiny_template = TinyTemplateClass.new - end - - it "should create a new Erubis object from the template" do - Erubis::Eruby.should_receive(:new).with("abcnews").and_return(@eruby) - @tiny_template.render_template(@template, @context) + before :each do + @template = TinyTemplateClass.new end - - it "should evaluate the template with the provided context" do - @eruby.should_receive(:evaluate).with(@context).and_return(true) - @tiny_template.render_template(@template, @context) + + it "should render the template evaluated in the given context" do + @template.render_template("<%= @foo %>", { :foo => "bar" }).open.read.should == "bar" end - it "should create a tempfile for the resulting file" do - Tempfile.should_receive(:new).and_return(@tempfile) - @tiny_template.render_template(@template, @context) + it "should return a file" do + @template.render_template("abcdef", {}).should be_kind_of(File) end - it "should print the contents of the resulting template to the tempfile" do - @tempfile.should_receive(:print).with("elvis costello").and_return(true) - @tiny_template.render_template(@template, @context) - end + describe "when an exception is raised in the template" do + def do_raise + @context = {:chef => "cool"} + @template.render_template("foo\nbar\nbaz\n<%= this_is_not_defined %>\nquin\nqunx\ndunno", @context) + end - it "should close the tempfile" do - @tempfile.should_receive(:close).and_return(true) - @tiny_template.render_template(@template, @context) + it "should catch and re-raise the exception as a TemplateError" do + lambda { do_raise }.should raise_error(Chef::Mixin::Template::TemplateError) + end + + describe "the raised TemplateError" do + before :each do + begin + do_raise + rescue Chef::Mixin::Template::TemplateError => e + @exception = e + end + end + + it "should have the original exception" do + @exception.original_exception.should be + @exception.original_exception.message.should =~ /undefined local variable or method `this_is_not_defined'/ + end + + it "should determine the line number of the exception" do + @exception.line_number.should == 4 + end + + it "should provide a source listing of the template around the exception" do + @exception.source_listing.should == " 2: bar\n 3: baz\n 4: <%= this_is_not_defined %>\n 5: quin\n 6: qunx" + end + + it "should provide the evaluation context of the template" do + @exception.context.should == @context + end + + it "should defer the message to the original exception" do + @exception.message.should =~ /undefined local variable or method `this_is_not_defined'/ + end + + it "should provide a nice source location" do + @exception.source_location.should == "on line #4" + end + + it "should create a pretty output for the terminal" do + @exception.to_s.should =~ /Chef::Mixin::Template::TemplateError/ + @exception.to_s.should =~ /undefined local variable or method `this_is_not_defined'/ + @exception.to_s.should include(" 2: bar\n 3: baz\n 4: <%= this_is_not_defined %>\n 5: quin\n 6: qunx") + @exception.to_s.should include(@exception.original_exception.backtrace.first) + end + end end end diff --git a/chef/spec/unit/provider/package/dpkg_spec.rb b/chef/spec/unit/provider/package/dpkg_spec.rb new file mode 100644 index 0000000000..390609aca9 --- /dev/null +++ b/chef/spec/unit/provider/package/dpkg_spec.rb @@ -0,0 +1,177 @@ +# +# Author:: Bryan McLellan (btm@loftninjas.org) +# Copyright:: Copyright (c) 2009 Bryan McLellan +# 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::Provider::Package::Dpkg, "load_current_resource" do + before(:each) do + @node = mock("Chef::Node", :null_object => true) + @new_resource = mock("Chef::Resource::Package", + :null_object => true, + :name => "wget", + :version => nil, + :package_name => "wget", + :updated => nil, + :source => "/tmp/wget_1.11.4-1ubuntu1_amd64.deb" + ) + @current_resource = mock("Chef::Resource::Package", + :null_object => true, + :name => "wget", + :version => nil, + :package_name => nil, + :updated => nil + ) + + @provider = Chef::Provider::Package::Dpkg.new(@node, @new_resource) + Chef::Resource::Package.stub!(:new).and_return(@current_resource) + + @stdin = mock("STDIN", :null_object => true) + @stdout = mock("STDOUT", :null_object => true) + @status = mock("Status", :exitstatus => 0) + @stderr = mock("STDERR", :null_object => true) + @pid = mock("PID", :null_object => true) + @provider.stub!(:popen4).and_return(@status) + + ::File.stub!(:exists?).and_return(true) + end + + it "should create a current resource with the name of the new_resource" do + Chef::Resource::Package.should_receive(:new).and_return(@current_resource) + @provider.load_current_resource + end + + it "should set the current resources package name to the new resources package name" do + @current_resource.should_receive(:package_name).with(@new_resource.package_name) + @provider.load_current_resource + end + + it "should raise an exception if a source is supplied but not found" do + ::File.stub!(:exists?).and_return(false) + lambda { @provider.load_current_resource }.should raise_error(Chef::Exception::Package) + end + + it "should get the source package version from dpkg-deb if provided" do + @stdout.stub!(:each).and_yield("wget\t1.11.4-1ubuntu1") + @provider.stub!(:popen4).with("dpkg-deb -W #{@new_resource.source}").and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status) + @current_resource.should_receive(:package_name).with("wget") + @new_resource.should_receive(:version).with("1.11.4-1ubuntu1") + @provider.load_current_resource + end + + it "should raise an exception if the source is not set but we are installing" do + @new_resource = mock("Chef::Resource::Package", + :null_object => true, + :name => "wget", + :version => nil, + :package_name => "wget", + :updated => nil, + :source => nil + ) + @provider = Chef::Provider::Package::Dpkg.new(@node, @new_resource) + lambda { @provider.load_current_resource }.should raise_error(Chef::Exception::Package) + + end + + it "should return the current version installed if found by dpkg" do + @stdout.stub!(:each).and_yield("Package: wget"). + and_yield("Status: install ok installed"). + and_yield("Priority: important"). + and_yield("Section: web"). + and_yield("Installed-Size: 1944"). + and_yield("Maintainer: Ubuntu Core developers <ubuntu-devel-discuss@lists.ubuntu.com>"). + and_yield("Architecture: amd64"). + and_yield("Version: 1.11.4-1ubuntu1"). + and_yield("Config-Version: 1.11.4-1ubuntu1"). + and_yield("Depends: libc6 (>= 2.8~20080505), libssl0.9.8 (>= 0.9.8f-5)"). + and_yield("Conflicts: wget-ssl") + @provider.stub!(:popen4).with("dpkg -s #{@current_resource.package_name}").and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status) + @current_resource.should_receive(:version).with("1.11.4-1ubuntu1") + @provider.load_current_resource + end + + it "should raise an exception if dpkg fails to run" do + @status = mock("Status", :exitstatus => -1) + @provider.stub!(:popen4).and_return(@status) + lambda { @provider.load_current_resource }.should raise_error(Chef::Exception::Package) + end +end + +describe Chef::Provider::Package::Dpkg, "install and upgrade" do + before(:each) do + @node = mock("Chef::Node", :null_object => true) + @new_resource = mock("Chef::Resource::Package", + :null_object => true, + :name => "wget", + :version => nil, + :package_name => "wget", + :updated => nil, + :source => "/tmp/wget_1.11.4-1ubuntu1_amd64.deb" + ) + @provider = Chef::Provider::Package::Dpkg.new(@node, @new_resource) + end + + it "should run dpkg -i with the package source" do + @provider.should_receive(:run_command).with({ + :command => "dpkg -i /tmp/wget_1.11.4-1ubuntu1_amd64.deb", + :environment => { + "DEBIAN_FRONTEND" => "noninteractive" + } + }) + @provider.install_package("wget", "1.11.4-1ubuntu1") + end + + it "should upgrade by running install_package" do + @provider.should_receive(:install_package).with("wget", "1.11.4-1ubuntu1") + @provider.upgrade_package("wget", "1.11.4-1ubuntu1") + end +end + +describe Chef::Provider::Package::Dpkg, "remove and purge" do + before(:each) do + @node = mock("Chef::Node", :null_object => true) + @new_resource = mock("Chef::Resource::Package", + :null_object => true, + :name => "wget", + :version => nil, + :package_name => "wget", + :updated => nil + ) + @provider = Chef::Provider::Package::Dpkg.new(@node, @new_resource) + end + + it "should run dpkg -r to remove the package" do + @provider.should_receive(:run_command).with({ + :command => "dpkg -r wget", + :environment => { + "DEBIAN_FRONTEND" => "noninteractive" + } + }) + @provider.remove_package("wget", "1.11.4-1ubuntu1") + end + + it "should run dpkg -P to purge the package" do + @provider.should_receive(:run_command).with({ + :command => "dpkg -P wget", + :environment => { + "DEBIAN_FRONTEND" => "noninteractive" + } + }) + @provider.purge_package("wget", "1.11.4-1ubuntu1") + end +end + diff --git a/chef/spec/unit/provider/package_spec.rb b/chef/spec/unit/provider/package_spec.rb index fbfc8b5bf2..925360e1dd 100644 --- a/chef/spec/unit/provider/package_spec.rb +++ b/chef/spec/unit/provider/package_spec.rb @@ -126,7 +126,8 @@ describe Chef::Provider::Package, "action_upgrade" do :null_object => true, :name => "emacs", :version => nil, - :package_name => "emacs" + :package_name => "emacs", + :to_s => 'package[emacs]' ) @current_resource = mock("Chef::Resource::Package", :null_object => true, @@ -158,6 +159,12 @@ describe Chef::Provider::Package, "action_upgrade" do @provider.should_not_receive(:upgrade_package) @provider.action_upgrade end + + it "should print the word 'uninstalled' if there was no original version" do + @current_resource.stub!(:version).and_return(nil) + Chef::Log.should_receive(:info).with("Upgrading #{@new_resource} version from uninstalled to 1.0") + @provider.action_upgrade + end end # Oh ruby, you are so nice. diff --git a/chef/spec/unit/rest_spec.rb b/chef/spec/unit/rest_spec.rb index ba892944fc..525d17e148 100644 --- a/chef/spec/unit/rest_spec.rb +++ b/chef/spec/unit/rest_spec.rb @@ -140,6 +140,55 @@ describe Chef::REST, "run_request method" do do_run_request end + describe "with a client SSL cert" do + before(:each) do + Chef::Config[:ssl_client_cert] = "/etc/chef/client-cert.pem" + Chef::Config[:ssl_client_key] = "/etc/chef/client-cert.key" + File.stub!(:exists?).with("/etc/chef/client-cert.pem").and_return(true) + File.stub!(:exists?).with("/etc/chef/client-cert.key").and_return(true) + File.stub!(:read).with("/etc/chef/client-cert.pem").and_return("monkey magic client") + File.stub!(:read).with("/etc/chef/client-cert.key").and_return("monkey magic key") + OpenSSL::X509::Certificate.stub!(:new).and_return("monkey magic client data") + OpenSSL::PKey::RSA.stub!(:new).and_return("monkey magic key data") + end + + it "should check that the client cert file exists" do + File.should_receive(:exists?).with("/etc/chef/client-cert.pem").and_return(true) + do_run_request + end + + it "should read the cert file" do + File.should_receive(:read).with("/etc/chef/client-cert.pem").and_return("monkey magic client") + do_run_request + end + + it "should read the cert into OpenSSL" do + OpenSSL::X509::Certificate.should_receive(:new).and_return("monkey magic client data") + do_run_request + end + + it "should set the cert" do + @http_mock.should_receive(:cert=).and_return(true) + do_run_request + end + + it "should read the key file" do + File.should_receive(:read).with("/etc/chef/client-cert.key").and_return("monkey magic key") + do_run_request + end + + it "should read the key into OpenSSL" do + OpenSSL::PKey::RSA.should_receive(:new).and_return("monkey magic key data") + do_run_request + end + + it "should set the key" do + @http_mock.should_receive(:key=).and_return(true) + do_run_request + end + + end + it "should set a read timeout based on the rest_timeout config option" do Chef::Config[:rest_timeout] = 10 @http_mock.should_receive(:read_timeout=).with(10).and_return(true) |