diff options
author | Bryan McLellan <btm@opscode.com> | 2012-10-16 09:29:30 -0700 |
---|---|---|
committer | Bryan McLellan <btm@opscode.com> | 2012-10-16 09:29:30 -0700 |
commit | 81bef0f1a7f1ff476159eda5d69185e2c14efc69 (patch) | |
tree | 3ae2ab66876fb6f2aa98094c398aed53aa076c77 /chef/lib | |
parent | 5f5da8f9fa7ed3ab8ab664d8d26919c8c258a2cc (diff) | |
parent | 2f6eae7d03d181fd9cbd0b6e27d39a1cc28804e9 (diff) | |
download | chef-81bef0f1a7f1ff476159eda5d69185e2c14efc69.tar.gz |
Merge branch '10-stable'
Conflicts:
chef-server-webui/lib/chef-server-webui/version.rb
chef-solr/lib/chef/solr/version.rb
chef/lib/chef/chef_fs/file_system/nonexistent_fs_object.rb
chef/lib/chef/knife/ssh.rb
chef/lib/chef/resource/ruby_block.rb
chef/spec/unit/client_spec.rb
chef/spec/unit/cookbook_loader_spec.rb
chef/spec/unit/resource/ruby_block_spec.rb
Diffstat (limited to 'chef/lib')
62 files changed, 461 insertions, 117 deletions
diff --git a/chef/lib/chef/application/client.rb b/chef/lib/chef/application/client.rb index c24b9de03a..3a68a41c14 100644 --- a/chef/lib/chef/application/client.rb +++ b/chef/lib/chef/application/client.rb @@ -176,10 +176,10 @@ class Chef::Application::Client < Chef::Application :description => "Fork client", :boolean => true - option :disable_reporting, + option :enable_reporting, :short => "-R", - :long => "--disable-reporting", - :description => "Disable reporting data collection for chef runs", + :long => "--enable-reporting", + :description => "Enable reporting data collection for chef runs", :boolean => true attr_reader :chef_client_json diff --git a/chef/lib/chef/client.rb b/chef/lib/chef/client.rb index 54788724fd..ea74f5f50a 100644 --- a/chef/lib/chef/client.rb +++ b/chef/lib/chef/client.rb @@ -453,7 +453,10 @@ class Chef # Ensures runlist override contains RunListItem instances def runlist_override_sanity_check! - @override_runlist = @override_runlist.split(',') if @override_runlist.is_a?(String) + # Convert to array and remove whitespace + if @override_runlist.is_a?(String) + @override_runlist = @override_runlist.split(',').map { |e| e.strip } + end @override_runlist = [@override_runlist].flatten.compact @override_runlist.map! do |item| if(item.is_a?(Chef::RunList::RunListItem)) diff --git a/chef/lib/chef/config.rb b/chef/lib/chef/config.rb index 7697357ec9..924a20ab3b 100644 --- a/chef/lib/chef/config.rb +++ b/chef/lib/chef/config.rb @@ -67,6 +67,7 @@ class Chef # url<String>:: String to be set for all of the chef-server-api URL's # config_attr_writer :chef_server_url do |url| + url.strip! configure do |c| [ :registration_url, :template_url, @@ -209,7 +210,8 @@ class Chef why_run false color false client_fork false - disable_reporting true + enable_reporting true + enable_reporting_url_fatals false # Set these to enable SSL authentication / mutual-authentication # with the server diff --git a/chef/lib/chef/formatters/error_inspectors/compile_error_inspector.rb b/chef/lib/chef/formatters/error_inspectors/compile_error_inspector.rb index 24aa2bb699..1fa8a70b52 100644 --- a/chef/lib/chef/formatters/error_inspectors/compile_error_inspector.rb +++ b/chef/lib/chef/formatters/error_inspectors/compile_error_inspector.rb @@ -73,20 +73,29 @@ class Chef end def culprit_backtrace_entry - @culprit_backtrace_entry ||= filtered_bt.first + @culprit_backtrace_entry ||= begin + bt_entry = filtered_bt.first + Chef::Log.debug("backtrace entry for compile error: '#{bt_entry}'") + bt_entry + end end def culprit_line - @culprit_line ||= culprit_backtrace_entry[/^(?:[A-Z]\:)[^:]+:([\d]+)/,1].to_i + @culprit_line ||= begin + line_number = culprit_backtrace_entry[/^(?:.\:)?[^:]+:([\d]+)/,1].to_i + Chef::Log.debug("Line number of compile error: '#{line_number}'") + line_number + end end def culprit_file - @culprit_file ||= culprit_backtrace_entry[/^((?:[A-Z]\:)?[^:]+):([\d]+)/,1] + @culprit_file ||= culprit_backtrace_entry[/^((?:.\:)?[^:]+):([\d]+)/,1] end def filtered_bt filters = Array(Chef::Config.cookbook_path).map {|p| /^#{Regexp.escape(p)}/ } r = exception.backtrace.select {|line| filters.any? {|filter| line =~ filter }} + Chef::Log.debug("filtered backtrace of compile error: #{r.join(",")}") return r.count > 0 ? r : exception.backtrace end diff --git a/chef/lib/chef/formatters/error_inspectors/cookbook_resolve_error_inspector.rb b/chef/lib/chef/formatters/error_inspectors/cookbook_resolve_error_inspector.rb index 6fc09f7c12..5642070336 100644 --- a/chef/lib/chef/formatters/error_inspectors/cookbook_resolve_error_inspector.rb +++ b/chef/lib/chef/formatters/error_inspectors/cookbook_resolve_error_inspector.rb @@ -63,7 +63,6 @@ all of the cookbooks in its expanded run list. E error_description.section("Expanded Run List:", expanded_run_list_ul) error_description.section("Server Response:", format_rest_error) -E when Net::HTTPPreconditionFailed describe_412_error(error_description) when Net::HTTPBadRequest diff --git a/chef/lib/chef/formatters/error_inspectors/registration_error_inspector.rb b/chef/lib/chef/formatters/error_inspectors/registration_error_inspector.rb index cd50556d34..5389f9f7d0 100644 --- a/chef/lib/chef/formatters/error_inspectors/registration_error_inspector.rb +++ b/chef/lib/chef/formatters/error_inspectors/registration_error_inspector.rb @@ -42,7 +42,7 @@ E validation_key "#{api_key}" E else - "#{e.class.name}: #{e.message}" + "#{exception.class.name}: #{exception.message}" end end diff --git a/chef/lib/chef/formatters/error_inspectors/resource_failure_inspector.rb b/chef/lib/chef/formatters/error_inspectors/resource_failure_inspector.rb index 9de3fc50ef..cfcd9b2f07 100644 --- a/chef/lib/chef/formatters/error_inspectors/resource_failure_inspector.rb +++ b/chef/lib/chef/formatters/error_inspectors/resource_failure_inspector.rb @@ -55,13 +55,11 @@ class Chef relevant_lines = ["# In #{file}\n\n"] - current_line = line - 2 + current_line = line - 1 + current_line = 0 if current_line < 0 nesting = 0 - relevant_lines << format_line(current_line, lines[current_line]) - loop do - current_line += 1 # low rent parser. try to gracefully handle nested blocks in resources nesting += 1 if lines[current_line] =~ /[\s]+do[\s]*/ @@ -69,9 +67,11 @@ class Chef relevant_lines << format_line(current_line, lines[current_line]) - break if lines[current_line].nil? + break if lines[current_line + 1].nil? break if current_line >= (line + 50) break if nesting <= 0 + + current_line += 1 end relevant_lines << format_line(current_line + 1, lines[current_line + 1]) if lines[current_line + 1] relevant_lines.join("") diff --git a/chef/lib/chef/knife/bootstrap/archlinux-gems.erb b/chef/lib/chef/knife/bootstrap/archlinux-gems.erb index 6dd57cc64d..85d6236197 100644 --- a/chef/lib/chef/knife/bootstrap/archlinux-gems.erb +++ b/chef/lib/chef/knife/bootstrap/archlinux-gems.erb @@ -17,6 +17,7 @@ EOP ) > /tmp/validation.pem awk NF /tmp/validation.pem > /etc/chef/validation.pem rm /tmp/validation.pem +chmod 0600 /etc/chef/validation.pem <% if @chef_config[:encrypted_data_bag_secret] -%> ( @@ -26,6 +27,7 @@ EOP ) > /tmp/encrypted_data_bag_secret awk NF /tmp/encrypted_data_bag_secret > /etc/chef/encrypted_data_bag_secret rm /tmp/encrypted_data_bag_secret +chmod 0600 /etc/chef/encrypted_data_bag_secret <% end -%> <%# Generate Ohai Hints -%> diff --git a/chef/lib/chef/knife/bootstrap/centos5-gems.erb b/chef/lib/chef/knife/bootstrap/centos5-gems.erb index 2b1b1816fe..f9626c3c2b 100644 --- a/chef/lib/chef/knife/bootstrap/centos5-gems.erb +++ b/chef/lib/chef/knife/bootstrap/centos5-gems.erb @@ -30,6 +30,7 @@ EOP ) > /tmp/validation.pem awk NF /tmp/validation.pem > /etc/chef/validation.pem rm /tmp/validation.pem +chmod 0600 /etc/chef/validation.pem <% if @chef_config[:encrypted_data_bag_secret] -%> ( @@ -39,6 +40,7 @@ EOP ) > /tmp/encrypted_data_bag_secret awk NF /tmp/encrypted_data_bag_secret > /etc/chef/encrypted_data_bag_secret rm /tmp/encrypted_data_bag_secret +chmod 0600 /etc/chef/encrypted_data_bag_secret <% end -%> <%# Generate Ohai Hints -%> diff --git a/chef/lib/chef/knife/bootstrap/chef-full.erb b/chef/lib/chef/knife/bootstrap/chef-full.erb index c02245690d..771ef85884 100644 --- a/chef/lib/chef/knife/bootstrap/chef-full.erb +++ b/chef/lib/chef/knife/bootstrap/chef-full.erb @@ -32,7 +32,7 @@ EOP ) > /tmp/validation.pem awk NF /tmp/validation.pem > /etc/chef/validation.pem rm /tmp/validation.pem - +chmod 0600 /etc/chef/validation.pem <% if @chef_config[:encrypted_data_bag_secret] -%> ( @@ -42,6 +42,7 @@ EOP ) > /tmp/encrypted_data_bag_secret awk NF /tmp/encrypted_data_bag_secret > /etc/chef/encrypted_data_bag_secret rm /tmp/encrypted_data_bag_secret +chmod 0600 /etc/chef/encrypted_data_bag_secret <% end -%> <%# Generate Ohai Hints -%> diff --git a/chef/lib/chef/knife/bootstrap/fedora13-gems.erb b/chef/lib/chef/knife/bootstrap/fedora13-gems.erb index a216b4e313..a8448342df 100644 --- a/chef/lib/chef/knife/bootstrap/fedora13-gems.erb +++ b/chef/lib/chef/knife/bootstrap/fedora13-gems.erb @@ -17,6 +17,7 @@ EOP ) > /tmp/validation.pem awk NF /tmp/validation.pem > /etc/chef/validation.pem rm /tmp/validation.pem +chmod 0600 /etc/chef/validation.pem <% if @chef_config[:encrypted_data_bag_secret] -%> ( @@ -26,6 +27,7 @@ EOP ) > /tmp/encrypted_data_bag_secret awk NF /tmp/encrypted_data_bag_secret > /etc/chef/encrypted_data_bag_secret rm /tmp/encrypted_data_bag_secret +chmod 0600 /etc/chef/encrypted_data_bag_secret <% end -%> <%# Generate Ohai Hints -%> diff --git a/chef/lib/chef/knife/bootstrap/ubuntu10.04-apt.erb b/chef/lib/chef/knife/bootstrap/ubuntu10.04-apt.erb index 14a924e032..0e44361d82 100644 --- a/chef/lib/chef/knife/bootstrap/ubuntu10.04-apt.erb +++ b/chef/lib/chef/knife/bootstrap/ubuntu10.04-apt.erb @@ -17,6 +17,7 @@ EOP ) > /tmp/validation.pem awk NF /tmp/validation.pem > /etc/chef/validation.pem rm /tmp/validation.pem +chmod 0600 /etc/chef/validation.pem <% if @chef_config[:encrypted_data_bag_secret] -%> ( @@ -26,6 +27,7 @@ EOP ) > /tmp/encrypted_data_bag_secret awk NF /tmp/encrypted_data_bag_secret > /etc/chef/encrypted_data_bag_secret rm /tmp/encrypted_data_bag_secret +chmod 0600 /etc/chef/encrypted_data_bag_secret <% end -%> <%# Generate Ohai Hints -%> diff --git a/chef/lib/chef/knife/bootstrap/ubuntu10.04-gems.erb b/chef/lib/chef/knife/bootstrap/ubuntu10.04-gems.erb index 88dcc48286..63448fc4d3 100644 --- a/chef/lib/chef/knife/bootstrap/ubuntu10.04-gems.erb +++ b/chef/lib/chef/knife/bootstrap/ubuntu10.04-gems.erb @@ -24,6 +24,7 @@ EOP ) > /tmp/validation.pem awk NF /tmp/validation.pem > /etc/chef/validation.pem rm /tmp/validation.pem +chmod 0600 /etc/chef/validation.pem <% if @chef_config[:encrypted_data_bag_secret] -%> ( @@ -33,6 +34,7 @@ EOP ) > /tmp/encrypted_data_bag_secret awk NF /tmp/encrypted_data_bag_secret > /etc/chef/encrypted_data_bag_secret rm /tmp/encrypted_data_bag_secret +chmod 0600 /etc/chef/encrypted_data_bag_secret <% end -%> <%# Generate Ohai Hints -%> diff --git a/chef/lib/chef/knife/bootstrap/ubuntu12.04-gems.erb b/chef/lib/chef/knife/bootstrap/ubuntu12.04-gems.erb index df128300db..e7da7db39b 100644 --- a/chef/lib/chef/knife/bootstrap/ubuntu12.04-gems.erb +++ b/chef/lib/chef/knife/bootstrap/ubuntu12.04-gems.erb @@ -19,6 +19,7 @@ EOP ) > /tmp/validation.pem awk NF /tmp/validation.pem > /etc/chef/validation.pem rm /tmp/validation.pem +chmod 0600 /etc/chef/validation.pem <% if @chef_config[:encrypted_data_bag_secret] -%> ( @@ -28,6 +29,7 @@ EOP ) > /tmp/encrypted_data_bag_secret awk NF /tmp/encrypted_data_bag_secret > /etc/chef/encrypted_data_bag_secret rm /tmp/encrypted_data_bag_secret +chmod 0600 /etc/chef/encrypted_data_bag_secret <% end -%> <%# Generate Ohai Hints -%> diff --git a/chef/lib/chef/knife/configure.rb b/chef/lib/chef/knife/configure.rb index 0526244053..0be7093e29 100644 --- a/chef/lib/chef/knife/configure.rb +++ b/chef/lib/chef/knife/configure.rb @@ -42,6 +42,22 @@ class Chef :boolean => true, :description => "Create an initial API Client" + option :admin_client_name, + :long => "--admin-client-name NAME", + :description => "The existing admin clientname (usually chef-webui)" + + option :admin_client_key, + :long => "--admin-client-key PATH", + :description => "The path to the admin client's private key (usually a file named webui.pem)" + + option :validation_client_name, + :long => "--validation-client-name NAME", + :description => "The validation clientname (usually chef-validator)" + + option :validation_key, + :long => "--validation-key PATH", + :description => "The location of the location of the validation key (usually a file named validation.pem)" + def configure_chef # We are just faking out the system so that you can do this without a key specified Chef::Config[:node_name] = 'woot' @@ -120,14 +136,17 @@ EOH @new_client_name = config[:node_name] || ask_question("Please enter a clientname for the new client: ", :default => Etc.getlogin) @admin_client_name = config[:admin_client_name] || ask_question("Please enter the existing admin clientname: ", :default => 'chef-webui') @admin_client_key = config[:admin_client_key] || ask_question("Please enter the location of the existing admin client's private key: ", :default => '/etc/chef/webui.pem') + @admin_client_key = File.expand_path(@admin_client_key) else @new_client_name = config[:node_name] || ask_question("Please enter an existing username or clientname for the API: ", :default => Etc.getlogin) end @validation_client_name = config[:validation_client_name] || ask_question("Please enter the validation clientname: ", :default => 'chef-validator') @validation_key = config[:validation_key] || ask_question("Please enter the location of the validation key: ", :default => '/etc/chef/validation.pem') + @validation_key = File.expand_path(@validation_key) @chef_repo = config[:repository] || ask_question("Please enter the path to a chef repository (or leave blank): ") @new_client_key = config[:client_key] || File.join(chef_config_path, "#{@new_client_name}.pem") + @new_client_key = File.expand_path(@new_client_key) end def guess_servername diff --git a/chef/lib/chef/knife/data_bag_edit.rb b/chef/lib/chef/knife/data_bag_edit.rb index 9ea9e5d282..234c77177d 100644 --- a/chef/lib/chef/knife/data_bag_edit.rb +++ b/chef/lib/chef/knife/data_bag_edit.rb @@ -84,7 +84,7 @@ class Chef output = edit_item(item) rest.put_rest("data/#{@name_args[0]}/#{@name_args[1]}", output) stdout.puts("Saved data_bag_item[#{@name_args[1]}]") - output(format_for_display(object.raw_data)) if config[:print_after] + ui.output(output) if config[:print_after] end end end diff --git a/chef/lib/chef/knife/data_bag_from_file.rb b/chef/lib/chef/knife/data_bag_from_file.rb index 4d26548c5e..275cbeac52 100644 --- a/chef/lib/chef/knife/data_bag_from_file.rb +++ b/chef/lib/chef/knife/data_bag_from_file.rb @@ -46,7 +46,7 @@ class Chef option :all, :short => "-a", :long => "--all", - :description => "Upload all data bags" + :description => "Upload all data bags or all items for specified data bags" def read_secret if config[:secret] diff --git a/chef/lib/chef/knife/environment_from_file.rb b/chef/lib/chef/knife/environment_from_file.rb index 5a0ce8bef4..af72f84622 100644 --- a/chef/lib/chef/knife/environment_from_file.rb +++ b/chef/lib/chef/knife/environment_from_file.rb @@ -25,26 +25,59 @@ class Chef require 'chef/knife/core/object_loader' end - banner "knife environment from file FILE (options)" + banner "knife environment from file FILE [FILE..] (options)" + + option :all, + :short => "-a", + :long => "--all", + :description => "Upload all environments" def loader @loader ||= Knife::Core::ObjectLoader.new(Chef::Environment, ui) end + def environments_path + @environments_path ||= "environments" + end - def run - if @name_args[0].nil? - show_usage - ui.fatal("You must specify a file to load") - exit 1 - end + def find_all_environments + loader.find_all_objects("./#{environments_path}/") + end + def load_all_environments + environments = find_all_environments + if environments.empty? + ui.fatal("Unable to find any environment files in '#{environments_path}'") + exit(1) + end + environments.each do |env| + load_environment(env) + end + end - updated = loader.load_from("environments", @name_args[0]) + def load_environment(env) + updated = loader.load_from("environments", env) updated.save output(format_for_display(updated)) if config[:print_after] ui.info("Updated Environment #{updated.name}") end + + + def run + if config[:all] == true + load_all_environments + else + if @name_args[0].nil? + show_usage + ui.fatal("You must specify a file to load") + exit 1 + end + + @name_args.each do |arg| + load_environment(arg) + end + end + end end end end diff --git a/chef/lib/chef/knife/ssh.rb b/chef/lib/chef/knife/ssh.rb index d3aafc73f8..a1b37723a6 100644 --- a/chef/lib/chef/knife/ssh.rb +++ b/chef/lib/chef/knife/ssh.rb @@ -124,7 +124,8 @@ class Chef q = Chef::Search::Query.new @action_nodes = q.search(:node, @name_args[0])[0] @action_nodes.each do |item| - + # we should skip the loop to next iteration if the item returned by the search is nil + next if item.nil? # if a command line attribute was not passed, and we have a cloud public_hostname, use that. # see #configure_attribute for the source of config[:attribute] and config[:override_attribute] if !config[:override_attribute] && item[:cloud] and item[:cloud][:public_hostname] @@ -134,11 +135,22 @@ class Chef else i = extract_nested_value(item, config[:attribute]) end - r.push(i) unless i.nil? + # next if we couldn't find the specified attribute in the returned node object + next if i.nil? + r.push(i) end r end - (ui.fatal("No nodes returned from search!"); exit 10) if list.length == 0 + if list.length == 0 + if @action_nodes.length == 0 + ui.fatal("No nodes returned from search!") + else + ui.fatal("#{@action_nodes.length} #{@action_nodes.length > 1 ? "nodes":"node"} found, " + + "but do not have the required attribute to stablish the connection. " + + "Try setting another attribute to open the connection using --attribute.") + end + exit 10 + end session_from_list(list) end diff --git a/chef/lib/chef/platform.rb b/chef/lib/chef/platform.rb index a25cf78155..2cb6690da1 100644 --- a/chef/lib/chef/platform.rb +++ b/chef/lib/chef/platform.rb @@ -369,7 +369,7 @@ class Chef return platform, version end - def provider_for_resource(resource, action) + def provider_for_resource(resource, action=:nothing) node = resource.run_context && resource.run_context.node raise ArgumentError, "Cannot find the provider for a resource with no run context set" unless node provider = find_provider_for_node(node, resource).new(resource, resource.run_context) diff --git a/chef/lib/chef/provider/cookbook_file.rb b/chef/lib/chef/provider/cookbook_file.rb index 88a3ec96c3..431f3f2367 100644 --- a/chef/lib/chef/provider/cookbook_file.rb +++ b/chef/lib/chef/provider/cookbook_file.rb @@ -29,10 +29,7 @@ class Chef def load_current_resource @current_resource = Chef::Resource::CookbookFile.new(@new_resource.name) - @new_resource.path.gsub!(/\\/, "/") # for Windows - @current_resource.path(@new_resource.path) - setup_acl - @current_resource + super end def action_create @@ -47,6 +44,9 @@ class Chef Chef::Log.debug("#{@new_resource} staging #{file_cache_location} to #{tempfile.path}") tempfile.close FileUtils.cp(file_cache_location, tempfile.path) + # Since the @new_resource.path file will not be updated + # at the time of converge, we must use the tempfile + update_new_file_state(tempfile.path) end Chef::Log.info("#{@new_resource} created file #{@new_resource.path}") end diff --git a/chef/lib/chef/provider/deploy.rb b/chef/lib/chef/provider/deploy.rb index 69b3222579..2920917d11 100644 --- a/chef/lib/chef/provider/deploy.rb +++ b/chef/lib/chef/provider/deploy.rb @@ -408,10 +408,10 @@ class Chef end def run_callback_from_file(callback_file) - if ::File.exist?(callback_file) + Chef::Log.info "#{@new_resource} queueing checkdeploy hook #{callback_file}" + recipe_eval do Dir.chdir(release_path) do - Chef::Log.info "#{@new_resource} running deploy hook #{callback_file}" - recipe_eval { from_file(callback_file) } + from_file(callback_file) if ::File.exist?(callback_file) end end end diff --git a/chef/lib/chef/provider/directory.rb b/chef/lib/chef/provider/directory.rb index ea9de5df34..0329aeb1ad 100644 --- a/chef/lib/chef/provider/directory.rb +++ b/chef/lib/chef/provider/directory.rb @@ -33,9 +33,12 @@ class Chef def load_current_resource @current_resource = Chef::Resource::Directory.new(@new_resource.name) @current_resource.path(@new_resource.path) + load_current_resource_attrs setup_acl + @current_resource end + def define_resource_requirements # this must be evaluated before whyrun messages are printed access_controls.requires_changes? diff --git a/chef/lib/chef/provider/file.rb b/chef/lib/chef/provider/file.rb index faaf469984..659afc6517 100644 --- a/chef/lib/chef/provider/file.rb +++ b/chef/lib/chef/provider/file.rb @@ -58,12 +58,14 @@ class Chef def is_binary?(path) ::File.open(path) do |file| + buff = file.read(Chef::Config[:diff_filesize_threshold]) buff = "" if buff.nil? return buff !~ /^[\r[:print:]]*$/ end end + def diff_current(temp_path) suppress_resource_reporting = false @@ -123,13 +125,39 @@ class Chef end def load_current_resource - @current_resource = Chef::Resource::File.new(@new_resource.name) + # Every child should be specifying their own constructor, so this + # should only be run in the file case. + @current_resource ||= Chef::Resource::File.new(@new_resource.name) @new_resource.path.gsub!(/\\/, "/") # for Windows @current_resource.path(@new_resource.path) - if @new_resource.content && ::File.exist?(@new_resource.path) - @current_resource.checksum(checksum(@new_resource.path)) + if !::File.directory?(@new_resource.path) + if ::File.exist?(@new_resource.path) + @current_resource.checksum(checksum(@new_resource.path)) + end end + load_current_resource_attrs setup_acl + + @current_resource + end + + def load_current_resource_attrs + if ::File.exist?(@new_resource.path) + stat = ::File.stat(@new_resource.path) + @current_resource.owner(stat.uid) + @current_resource.mode(stat.mode & 07777) + @current_resource.group(stat.gid) + + if @new_resource.group.nil? + @new_resource.group(@current_resource.group) + end + if @new_resource.owner.nil? + @new_resource.owner(@current_resource.owner) + end + if @new_resource.mode.nil? + @new_resource.mode(@current_resource.mode) + end + end end def setup_acl @@ -183,6 +211,19 @@ class Chef end end + # if you are using a tempfile before creating, you must + # override the default with the tempfile, since the + # file at @new_resource.path will not be updated on converge + def update_new_file_state(path=@new_resource.path) + stat = ::File.stat(path) + @new_resource.owner(stat.uid) + @new_resource.mode(stat.mode & 07777) + @new_resource.group(stat.gid) + if !::File.directory?(path) + @new_resource.checksum(checksum(path)) + end + end + def action_create if !::File.exists?(@new_resource.path) description = [] @@ -190,10 +231,13 @@ class Chef desc << " with content checksum #{short_cksum(new_resource_content_checksum)}" if new_resource.content description << desc description << diff_current_from_content(@new_resource.content) + converge_by(description) do + Chef::Log.info("entered create") ::File.open(@new_resource.path, "w+") {|f| f.write @new_resource.content } access_controls.set_all Chef::Log.info("#{@new_resource} created file #{@new_resource.path}") + update_new_file_state end else set_content unless @new_resource.content.nil? @@ -205,6 +249,8 @@ class Chef if access_controls.requires_changes? converge_by(access_controls.describe_changes) do access_controls.set_all + #Update file state with new access values + update_new_file_state end end end diff --git a/chef/lib/chef/provider/http_request.rb b/chef/lib/chef/provider/http_request.rb index d21cdad19b..0ea5f8289f 100644 --- a/chef/lib/chef/provider/http_request.rb +++ b/chef/lib/chef/provider/http_request.rb @@ -34,18 +34,21 @@ class Chef # Send a HEAD request to @new_resource.url, with ?message=@new_resource.message def action_head - converge_by("#{@new_resource} HEAD to #{@new_resource.url}") do - message = check_message(@new_resource.message) - modified = @rest.run_request( - :HEAD, - @rest.create_url("#{@new_resource.url}?message=#{message}"), - @new_resource.headers, - false, - 10, - false - ) - Chef::Log.info("#{@new_resource} HEAD to #{@new_resource.url} successful") - Chef::Log.debug("#{@new_resource} HEAD request response: #{modified}") + message = check_message(@new_resource.message) + # returns true from Chef::REST if returns 2XX (Net::HTTPSuccess) + modified = @rest.run_request( + :HEAD, + @rest.create_url("#{@new_resource.url}?message=#{message}"), + @new_resource.headers, + false, + 10, + false + ) + Chef::Log.info("#{@new_resource} HEAD to #{@new_resource.url} successful") + Chef::Log.debug("#{@new_resource} HEAD request response: #{modified}") + # :head is usually used to trigger notifications, which converge_by now does + if modified + converge_by("#{@new_resource} HEAD to #{@new_resource.url} returned modified, trigger notifications") {} end end diff --git a/chef/lib/chef/provider/ifconfig.rb b/chef/lib/chef/provider/ifconfig.rb index ba8c16933e..86680b2229 100644 --- a/chef/lib/chef/provider/ifconfig.rb +++ b/chef/lib/chef/provider/ifconfig.rb @@ -199,7 +199,7 @@ class Chef ifcfg_file = "/etc/sysconfig/network-scripts/ifcfg-#{@new_resource.device}" if ::File.exist?(ifcfg_file) converge_by ("delete the #{ifcfg_file}") do - FileUtils.rm_f(ifcfg_file, :verbose => false, :force => true) + FileUtils.rm_f(ifcfg_file, :verbose => false) end end when "debian","ubuntu" diff --git a/chef/lib/chef/provider/package.rb b/chef/lib/chef/provider/package.rb index 424792000e..a28a6f93fb 100644 --- a/chef/lib/chef/provider/package.rb +++ b/chef/lib/chef/provider/package.rb @@ -78,6 +78,7 @@ class Chef end description = install_version ? "version #{install_version} of" : "" converge_by("install #{description} package #{@new_resource.package_name}") do + @new_resource.version(install_version) install_package(@new_resource.package_name, install_version) end end @@ -88,6 +89,7 @@ class Chef elsif @current_resource.version == candidate_version Chef::Log.debug("#{@new_resource} is at the latest version - nothing to do") else + @new_resource.version(candidate_version) orig_version = @current_resource.version || "uninstalled" converge_by("upgrade package #{@new_resource.package_name} from #{orig_version} to #{candidate_version}") do status = upgrade_package(@new_resource.package_name, candidate_version) diff --git a/chef/lib/chef/provider/package/pacman.rb b/chef/lib/chef/provider/package/pacman.rb index 0df909a092..f81486ae84 100644 --- a/chef/lib/chef/provider/package/pacman.rb +++ b/chef/lib/chef/provider/package/pacman.rb @@ -53,10 +53,19 @@ class Chef def candidate_version return @candidate_version if @candidate_version + repos = ["extra","core","community"] + + if(::File.exists?("/etc/pacman.conf")) + pacman = ::File.read("/etc/pacman.conf") + repos = pacman.scan(/\[(.+)\]/).flatten + end + + package_repos = repos.map {|r| Regexp.escape(r) }.join('|') + status = popen4("pacman -Ss #{@new_resource.package_name}") do |pid, stdin, stdout, stderr| stdout.each do |line| case line - when /^(extra|core|community)\/#{Regexp.escape(@new_resource.package_name)} (.+)$/ + when /^(#{package_repos})\/#{Regexp.escape(@new_resource.package_name)} (.+)$/ # $2 contains a string like "4.4.0-1 (kde kdenetwork)" or "3.10-4 (base)" # simply split by space and use first token @candidate_version = $2.split(" ").first diff --git a/chef/lib/chef/provider/remote_file.rb b/chef/lib/chef/provider/remote_file.rb index 67e4e0027e..90e367f558 100644 --- a/chef/lib/chef/provider/remote_file.rb +++ b/chef/lib/chef/provider/remote_file.rb @@ -27,8 +27,8 @@ class Chef class RemoteFile < Chef::Provider::File def load_current_resource + @current_resource = Chef::Resource::RemoteFile.new(@new_resource.name) super - @current_resource.checksum(checksum(@current_resource.path)) if ::File.exist?(@current_resource.path) end def action_create diff --git a/chef/lib/chef/provider/service.rb b/chef/lib/chef/provider/service.rb index 22098a0d6b..decca7fd7c 100644 --- a/chef/lib/chef/provider/service.rb +++ b/chef/lib/chef/provider/service.rb @@ -34,6 +34,17 @@ class Chef true end + def load_new_resource_state + # If the user didn't specify a change in enabled state, + # it will be the same as the old resource + if ( @new_resource.enabled.nil? ) + @new_resource.enabled(@current_resource.enabled) + end + if ( @new_resource.running.nil? ) + @new_resource.running(@current_resource.running) + end + end + def shared_resource_requirements end @@ -56,6 +67,8 @@ class Chef Chef::Log.info("#{@new_resource} enabled") end end + load_new_resource_state + @new_resource.enabled(true) end def action_disable @@ -67,6 +80,8 @@ class Chef else Chef::Log.debug("#{@new_resource} already disabled - nothing to do") end + load_new_resource_state + @new_resource.enabled(false) end def action_start @@ -78,6 +93,8 @@ class Chef else Chef::Log.debug("#{@new_resource} already running - nothing to do") end + load_new_resource_state + @new_resource.running(true) end def action_stop @@ -89,6 +106,8 @@ class Chef else Chef::Log.debug("#{@new_resource} already stopped - nothing to do") end + load_new_resource_state + @new_resource.running(false) end def action_restart @@ -96,6 +115,8 @@ class Chef restart_service Chef::Log.info("#{@new_resource} restarted") end + load_new_resource_state + @new_resource.running(true) end def action_reload @@ -105,6 +126,7 @@ class Chef Chef::Log.info("#{@new_resource} reloaded") end end + load_new_resource_state end def enable_service diff --git a/chef/lib/chef/provider/template.rb b/chef/lib/chef/provider/template.rb index bcf2151088..c937b9d980 100644 --- a/chef/lib/chef/provider/template.rb +++ b/chef/lib/chef/provider/template.rb @@ -31,8 +31,8 @@ class Chef include Chef::Mixin::Template def load_current_resource + @current_resource = Chef::Resource::Template.new(@new_resource.name) super - @current_resource.checksum(checksum(@current_resource.path)) if ::File.exist?(@current_resource.path) end def define_resource_requirements @@ -64,6 +64,14 @@ class Chef FileUtils.mv(rendered_template.path, @new_resource.path) Chef::Log.info("#{@new_resource} updated content") access_controls.set_all! + stat = ::File.stat(@new_resource.path) + + # template depends on the checksum not changing, and updates it + # itself later in the code, so we cannot set it here, as we do with + # all other < File child provider classes + @new_resource.owner(stat.uid) + @new_resource.mode(stat.mode & 07777) + @new_resource.group(stat.gid) end end end diff --git a/chef/lib/chef/resource.rb b/chef/lib/chef/resource.rb index c98f3b451d..536f75ca88 100644 --- a/chef/lib/chef/resource.rb +++ b/chef/lib/chef/resource.rb @@ -586,8 +586,8 @@ F raise customize_exception(e) end ensure - events.resource_completed(self) @elapsed_time = Time.now - start_time + events.resource_completed(self) end end diff --git a/chef/lib/chef/resource/cookbook_file.rb b/chef/lib/chef/resource/cookbook_file.rb index 255257890f..de758aef71 100644 --- a/chef/lib/chef/resource/cookbook_file.rb +++ b/chef/lib/chef/resource/cookbook_file.rb @@ -1,6 +1,7 @@ # # Author:: Adam Jacob (<adam@opscode.com>) # Author:: Seth Chisamore (<schisamo@opscode.com>) +# Author:: Tyler Cloke (<tyler@opscode.com>) # Copyright:: Copyright (c) 2008, 2011 Opscode, Inc. # License:: Apache License, Version 2.0 # diff --git a/chef/lib/chef/resource/cron.rb b/chef/lib/chef/resource/cron.rb index 7dfb86b3ed..5f858cec81 100644 --- a/chef/lib/chef/resource/cron.rb +++ b/chef/lib/chef/resource/cron.rb @@ -1,5 +1,6 @@ # # Author:: Bryan McLellan (btm@loftninjas.org) +# Author:: Tyler Cloke (<tyler@opscode.com>) # Copyright:: Copyright (c) 2009 Bryan McLellan # License:: Apache License, Version 2.0 # @@ -22,6 +23,10 @@ class Chef class Resource class Cron < Chef::Resource + identity_attr :command + + state_attrs :minute, :hour, :day, :month, :weekday, :user + def initialize(name, run_context=nil) super @resource_name = :cron diff --git a/chef/lib/chef/resource/deploy.rb b/chef/lib/chef/resource/deploy.rb index 037c172183..8b614028bf 100644 --- a/chef/lib/chef/resource/deploy.rb +++ b/chef/lib/chef/resource/deploy.rb @@ -1,5 +1,6 @@ # # Author:: Daniel DeLeo (<dan@kallistec.com>) +# Author:: Tyler Cloke (<tyler@opscode.com>) # Copyright:: Copyright (c) 2008 Opscode, Inc. # License:: Apache License, Version 2.0 # @@ -49,9 +50,13 @@ class Chef # release directory. Callback files can contain chef code (resources, etc.) # class Deploy < Chef::Resource - + provider_base Chef::Provider::Deploy + identity_attr :repository + + state_attrs :deploy_to, :revision + def initialize(name, run_context=nil) super @resource_name = :deploy diff --git a/chef/lib/chef/resource/directory.rb b/chef/lib/chef/resource/directory.rb index 729948b099..a5d5ea7366 100644 --- a/chef/lib/chef/resource/directory.rb +++ b/chef/lib/chef/resource/directory.rb @@ -1,6 +1,7 @@ # # Author:: Adam Jacob (<adam@opscode.com>) # Author:: Seth Chisamore (<schisamo@opscode.com>) +# Author:: Tyler Cloke (<tyler@opscode.com>) # Copyright:: Copyright (c) 2008, 2011 Opscode, Inc. # License:: Apache License, Version 2.0 # @@ -24,6 +25,11 @@ require 'chef/mixin/securable' class Chef class Resource class Directory < Chef::Resource + + identity_attr :path + + state_attrs :group, :mode, :owner + include Chef::Mixin::Securable provides :directory, :on_platforms => :all diff --git a/chef/lib/chef/resource/env.rb b/chef/lib/chef/resource/env.rb index ed3442cdfb..4b5fe6cc09 100644 --- a/chef/lib/chef/resource/env.rb +++ b/chef/lib/chef/resource/env.rb @@ -1,5 +1,6 @@ # # Author:: Doug MacEachern (<dougm@vmware.com>) +# Author:: Tyler Cloke (<tyler@opscode.com>) # Copyright:: Copyright (c) 2010 VMware, Inc. # License:: Apache License, Version 2.0 # @@ -20,6 +21,10 @@ class Chef class Resource class Env < Chef::Resource + identity_attr :key_name + + state_attrs :value + def initialize(name, run_context=nil) super @resource_name = :env diff --git a/chef/lib/chef/resource/erl_call.rb b/chef/lib/chef/resource/erl_call.rb index 00d8fd19a1..e0e38926bb 100644 --- a/chef/lib/chef/resource/erl_call.rb +++ b/chef/lib/chef/resource/erl_call.rb @@ -1,5 +1,6 @@ # # Author:: Joe Williams (<joe@joetify.com>) +# Author:: Tyler Cloke (<tyler@opscode.com>) # Copyright:: Copyright (c) 2009 Joe Williams # License:: Apache License, Version 2.0 # @@ -24,6 +25,8 @@ class Chef # erl_call : http://erlang.org/doc/man/erl_call.html + identity_attr :code + def initialize(name, run_context=nil) super @resource_name = :erl_call diff --git a/chef/lib/chef/resource/execute.rb b/chef/lib/chef/resource/execute.rb index cad3bfde4f..6c07bf9352 100644 --- a/chef/lib/chef/resource/execute.rb +++ b/chef/lib/chef/resource/execute.rb @@ -1,5 +1,6 @@ # # Author:: Adam Jacob (<adam@opscode.com>) +# Author:: Tyler Cloke (<tyler@opscode.com>) # Copyright:: Copyright (c) 2008 Opscode, Inc. # License:: Apache License, Version 2.0 # @@ -22,6 +23,8 @@ class Chef class Resource class Execute < Chef::Resource + identity_attr :command + def initialize(name, run_context=nil) super @resource_name = :execute diff --git a/chef/lib/chef/resource/file.rb b/chef/lib/chef/resource/file.rb index 8abc219015..0b92f3332d 100644 --- a/chef/lib/chef/resource/file.rb +++ b/chef/lib/chef/resource/file.rb @@ -29,11 +29,11 @@ class Chef identity_attr :path - state_attrs :checksum, :owner, :group, :mode - - # By default, windows gets `state_attrs :rights, :deny_rights` if Platform.windows? - state_attrs :rights, :deny_rights + # Use Windows rights instead of standard *nix permissions + state_attrs :checksum, :rights, :deny_rights + else + state_attrs :checksum, :owner, :group, :mode end provides :file, :on_platforms => :all @@ -52,7 +52,7 @@ class Chef def content(arg=nil) set_or_return( - :content, + :content, arg, :kind_of => String ) diff --git a/chef/lib/chef/resource/group.rb b/chef/lib/chef/resource/group.rb index d5c2b3f2fb..76f3a779ae 100644 --- a/chef/lib/chef/resource/group.rb +++ b/chef/lib/chef/resource/group.rb @@ -1,5 +1,6 @@ # # Author:: Adam Jacob (<adam@opscode.com>) +# Author:: Tyler Cloke (<tyler@opscode.com>) # Copyright:: Copyright (c) 2008 OpsCode, Inc. # License:: Apache License, Version 2.0 # @@ -20,6 +21,10 @@ class Chef class Resource class Group < Chef::Resource + identity_attr :group_name + + state_attrs :members + def initialize(name, run_context=nil) super @resource_name = :group diff --git a/chef/lib/chef/resource/http_request.rb b/chef/lib/chef/resource/http_request.rb index c850bb72c1..d31ff0b1c9 100644 --- a/chef/lib/chef/resource/http_request.rb +++ b/chef/lib/chef/resource/http_request.rb @@ -1,5 +1,6 @@ # # Author:: Adam Jacob (<adam@opscode.com>) +# Author:: Tyler Cloke (<tyler@opscode.com>) # Copyright:: Copyright (c) 2008 Opscode, Inc. # License:: Apache License, Version 2.0 # @@ -22,6 +23,8 @@ class Chef class Resource class HttpRequest < Chef::Resource + identity_attr :url + def initialize(name, run_context=nil) super @resource_name = :http_request diff --git a/chef/lib/chef/resource/ifconfig.rb b/chef/lib/chef/resource/ifconfig.rb index e738e462bc..daa8a572a0 100644 --- a/chef/lib/chef/resource/ifconfig.rb +++ b/chef/lib/chef/resource/ifconfig.rb @@ -1,5 +1,6 @@ # # Author:: Jason K. Jackson (jasonjackson@gmail.com) +# Author:: Tyler Cloke (<tyler@opscode.com>) # Copyright:: Copyright (c) 2009 Jason K. Jackson # License:: Apache License, Version 2.0 # @@ -22,6 +23,10 @@ class Chef class Resource class Ifconfig < Chef::Resource + identity_attr :device + + state_attrs :inet_addr, :mask + def initialize(name, run_context=nil) super @resource_name = :ifconfig diff --git a/chef/lib/chef/resource/link.rb b/chef/lib/chef/resource/link.rb index a0c5726abc..a0fab0428d 100644 --- a/chef/lib/chef/resource/link.rb +++ b/chef/lib/chef/resource/link.rb @@ -1,5 +1,6 @@ # # Author:: Adam Jacob (<adam@opscode.com>) +# Author:: Tyler Cloke (<tyler@opscode.com>) # Copyright:: Copyright (c) 2008 Opscode, Inc. # License:: Apache License, Version 2.0 # @@ -24,7 +25,11 @@ class Chef class Link < Chef::Resource include Chef::Mixin::Securable - provides :link, :on_platform => :all + provides :link, :on_platform => :all + + identity_attr :target_file + + state_attrs :to, :owner, :group def initialize(name, run_context=nil) super diff --git a/chef/lib/chef/resource/log.rb b/chef/lib/chef/resource/log.rb index 95f995298f..d1b6b5af0b 100644 --- a/chef/lib/chef/resource/log.rb +++ b/chef/lib/chef/resource/log.rb @@ -1,5 +1,6 @@ # # Author:: Cary Penniman (<cary@rightscale.com>) +# Author:: Tyler Cloke (<tyler@opscode.com>) # Copyright:: Copyright (c) 2008 Opscode, Inc. # License:: Apache License, Version 2.0 # @@ -17,22 +18,24 @@ # class Chef class Resource - - # Sends a string from a recipe to a log provider - # - # log "some string to log" do - # level :info # (default) also supports :warn, :debug, and :error - # end - # - # === Example - # log "your string to log" - # - # or - # - # log "a debug string" { level :debug } - # class Log < Chef::Resource - + + identity_attr :name + + # Sends a string from a recipe to a log provider + # + # log "some string to log" do + # level :info # (default) also supports :warn, :debug, and :error + # end + # + # === Example + # log "your string to log" + # + # or + # + # log "a debug string" { level :debug } + # + # Initialize log resource with a name as the string to log # # === Parameters @@ -54,7 +57,7 @@ class Chef :equal_to => [ :debug, :info, :warn, :error, :fatal ] ) end - + end end end diff --git a/chef/lib/chef/resource/mdadm.rb b/chef/lib/chef/resource/mdadm.rb index 14e9c650a2..46a85b2475 100644 --- a/chef/lib/chef/resource/mdadm.rb +++ b/chef/lib/chef/resource/mdadm.rb @@ -1,5 +1,6 @@ # # Author:: Joe Williams (<joe@joetify.com>) +# Author:: Tyler Cloke (<tyler@opscode.com>) # Copyright:: Copyright (c) 2009 Joe Williams # License:: Apache License, Version 2.0 # @@ -22,6 +23,10 @@ class Chef class Resource class Mdadm < Chef::Resource + identity_attr :raid_device + + state_attrs :devices, :level, :chunk + def initialize(name, run_context=nil) super @resource_name = :mdadm diff --git a/chef/lib/chef/resource/mount.rb b/chef/lib/chef/resource/mount.rb index e9b3533943..8c32bdd280 100644 --- a/chef/lib/chef/resource/mount.rb +++ b/chef/lib/chef/resource/mount.rb @@ -1,5 +1,6 @@ # # Author:: Joshua Timberman (<joshua@opscode.com>) +# Author:: Tyler Cloke (<tyler@opscode.com>) # Copyright:: Copyright (c) 2009 Opscode, Inc # License:: Apache License, Version 2.0 # @@ -22,6 +23,10 @@ class Chef class Resource class Mount < Chef::Resource + identity_attr :device + + state_attrs :mount_point, :device_type, :fstype + def initialize(name, run_context=nil) super @resource_name = :mount diff --git a/chef/lib/chef/resource/ohai.rb b/chef/lib/chef/resource/ohai.rb index 91da1a4a5b..48e55e9f01 100644 --- a/chef/lib/chef/resource/ohai.rb +++ b/chef/lib/chef/resource/ohai.rb @@ -1,5 +1,6 @@ # # Author:: Michael Leinartas (<mleinartas@gmail.com>) +# Author:: Tyler Cloke (<tyler@opscode.com>) # Copyright:: Copyright (c) 2010 Michael Leinartas # License:: Apache License, Version 2.0 # @@ -20,9 +21,14 @@ class Chef class Resource class Ohai < Chef::Resource + identity_attr :name + + state_attrs :plugin + def initialize(name, run_context=nil) super @resource_name = :ohai + @name = name @allowed_actions.push(:reload) @action = :reload @plugin = nil @@ -35,6 +41,14 @@ class Chef :kind_of => [ String ] ) end + + def name(arg=nil) + set_or_return( + :name, + arg, + :kind_of => [ String ] + ) + end end end end diff --git a/chef/lib/chef/resource/package.rb b/chef/lib/chef/resource/package.rb index fa863b3810..eaad3e2e58 100644 --- a/chef/lib/chef/resource/package.rb +++ b/chef/lib/chef/resource/package.rb @@ -1,5 +1,6 @@ # # Author:: Adam Jacob (<adam@opscode.com>) +# Author:: Tyler Cloke (<tyler@opscode.com>) # Copyright:: Copyright (c) 2008 Opscode, Inc. # License:: Apache License, Version 2.0 # @@ -24,7 +25,7 @@ class Chef identity_attr :package_name - state_attrs :version + state_attrs :version, :options def initialize(name, run_context=nil) super diff --git a/chef/lib/chef/resource/remote_directory.rb b/chef/lib/chef/resource/remote_directory.rb index 20bbc883e2..490e3c6ba7 100644 --- a/chef/lib/chef/resource/remote_directory.rb +++ b/chef/lib/chef/resource/remote_directory.rb @@ -1,5 +1,6 @@ # # Author:: Adam Jacob (<adam@opscode.com>) +# Author:: Tyler Cloke (<tyler@opscode.com>) # Copyright:: Copyright (c) 2008 Opscode, Inc. # License:: Apache License, Version 2.0 # @@ -27,6 +28,10 @@ class Chef provides :remote_directory, :on_platforms => :all + identity_attr :path + + state_attrs :files_owner, :files_group, :files_mode + def initialize(name, run_context=nil) super @resource_name = :remote_directory diff --git a/chef/lib/chef/resource/route.rb b/chef/lib/chef/resource/route.rb index 1a568dd2d0..cdd61f3a4b 100644 --- a/chef/lib/chef/resource/route.rb +++ b/chef/lib/chef/resource/route.rb @@ -1,5 +1,6 @@ # # Author:: Bryan McLellan (btm@loftninjas.org) +# Author:: Tyler Cloke (<tyler@opscode.com>) # Copyright:: Copyright (c) 2009 Bryan McLellan # License:: Apache License, Version 2.0 # @@ -21,7 +22,11 @@ require 'chef/resource' class Chef class Resource class Route < Chef::Resource - + + identity_attr :target + + state_attrs :netmask, :gateway + def initialize(name, run_context=nil) super @resource_name = :route diff --git a/chef/lib/chef/resource/ruby_block.rb b/chef/lib/chef/resource/ruby_block.rb index 517e5949d7..296345bde3 100644 --- a/chef/lib/chef/resource/ruby_block.rb +++ b/chef/lib/chef/resource/ruby_block.rb @@ -21,11 +21,14 @@ class Chef class Resource class RubyBlock < Chef::Resource + identity_attr :block_name + def initialize(name, run_context=nil) super @resource_name = :ruby_block @action = "run" @allowed_actions << :create << :run + @block_name = name end def block(&block) @@ -35,6 +38,14 @@ class Chef @block end end + + def block_name(arg=nil) + set_or_return( + :block_name, + arg, + :kind_of => String + ) + end end end end diff --git a/chef/lib/chef/resource/scm.rb b/chef/lib/chef/resource/scm.rb index 132dad6ede..781e09a2c9 100644 --- a/chef/lib/chef/resource/scm.rb +++ b/chef/lib/chef/resource/scm.rb @@ -23,6 +23,10 @@ class Chef class Resource class Scm < Chef::Resource + identity_attr :destination + + state_attrs :revision + def initialize(name, run_context=nil) super @destination = name diff --git a/chef/lib/chef/resource/script.rb b/chef/lib/chef/resource/script.rb index e6a8e56c0d..6a7c8e0d5e 100644 --- a/chef/lib/chef/resource/script.rb +++ b/chef/lib/chef/resource/script.rb @@ -1,5 +1,6 @@ # # Author:: Adam Jacob (<adam@opscode.com>) +# Author:: Tyler Cloke (<tyler@opscode.com>) # Copyright:: Copyright (c) 2008 Opscode, Inc. # License:: Apache License, Version 2.0 # @@ -22,6 +23,8 @@ class Chef class Resource class Script < Chef::Resource::Execute + identity_attr :command + def initialize(name, run_context=nil) super @resource_name = :script diff --git a/chef/lib/chef/resource/service.rb b/chef/lib/chef/resource/service.rb index fdbde350da..3ace5cbec3 100644 --- a/chef/lib/chef/resource/service.rb +++ b/chef/lib/chef/resource/service.rb @@ -1,5 +1,6 @@ # # Author:: AJ Christensen (<aj@hjksolutions.com>) +# Author:: Tyler Cloke (<tyler@opscode.com>) # Copyright:: Copyright (c) 2008 Opscode, Inc. # License:: Apache License, Version 2.0 # @@ -22,6 +23,10 @@ class Chef class Resource class Service < Chef::Resource + identity_attr :service_name + + state_attrs :enabled, :running + def initialize(name, run_context=nil) super @resource_name = :service diff --git a/chef/lib/chef/resource/subversion.rb b/chef/lib/chef/resource/subversion.rb index 97f48c3a44..e3226d8b3b 100644 --- a/chef/lib/chef/resource/subversion.rb +++ b/chef/lib/chef/resource/subversion.rb @@ -1,5 +1,6 @@ # # Author:: Daniel DeLeo (<dan@kallistec.com>) +# Author:: Tyler Cloke (<tyler@opscode.com>) # Copyright:: Copyright (c) 2008 Opscode, Inc. # License:: Apache License, Version 2.0 # @@ -21,7 +22,7 @@ require "chef/resource/scm" class Chef class Resource class Subversion < Chef::Resource::Scm - + def initialize(name, run_context=nil) super @svn_arguments = '--no-auth-cache' diff --git a/chef/lib/chef/resource/template.rb b/chef/lib/chef/resource/template.rb index 2ece12e52c..af51b64700 100644 --- a/chef/lib/chef/resource/template.rb +++ b/chef/lib/chef/resource/template.rb @@ -1,6 +1,7 @@ # # Author:: Adam Jacob (<adam@opscode.com>) # Author:: Seth Chisamore (<schisamo@opscode.com>) +# Author:: Tyler Cloke (<tyler@opscode.com>) # Copyright:: Copyright (c) 2008, 2011 Opscode, Inc. # License:: Apache License, Version 2.0 # diff --git a/chef/lib/chef/resource/user.rb b/chef/lib/chef/resource/user.rb index 2a8941e87f..4d8c4ac11b 100644 --- a/chef/lib/chef/resource/user.rb +++ b/chef/lib/chef/resource/user.rb @@ -21,6 +21,10 @@ require 'chef/resource' class Chef class Resource class User < Chef::Resource + + identity_attr :username + + state_attrs :uid, :gid, :home def initialize(name, run_context=nil) super diff --git a/chef/lib/chef/resource_reporter.rb b/chef/lib/chef/resource_reporter.rb index a420cbf0b6..3d10c1e961 100644 --- a/chef/lib/chef/resource_reporter.rb +++ b/chef/lib/chef/resource_reporter.rb @@ -58,6 +58,7 @@ class Chef as_hash["duration"] = (elapsed_time * 1000).to_i.to_s as_hash["delta"] = new_resource.diff if new_resource.respond_to?("diff") as_hash["delta"] = "" if as_hash["delta"].nil? + # TODO: rename as "action" as_hash["result"] = action.to_s if success? @@ -84,12 +85,13 @@ class Chef attr_reader :exception attr_reader :run_id attr_reader :error_descriptions + attr_reader :summary_only def initialize(rest_client) - if Chef::Config[:disable_reporting] - @reporting_enabled = false - else + if Chef::Config[:enable_reporting] && !Chef::Config[:why_run] @reporting_enabled = true + else + @reporting_enabled = false end @updated_resources = [] @total_res_count = 0 @@ -99,22 +101,31 @@ class Chef @run_id = nil @rest_client = rest_client @node = nil - @error_descriptions = nil + @error_descriptions = {} + @summary_only = true end def node_load_completed(node, expanded_run_list_with_versions, config) @node = node - if reporting_enabled? begin - resource_history_url = "reports/nodes/#{@node.name}/runs" + resource_history_url = "reports/nodes/#{node.name}/runs" server_response = @rest_client.post_rest(resource_history_url, {:action => :begin}) run_uri = URI.parse(server_response["uri"]) @run_id = ::File.basename(run_uri.path) Chef::Log.info("Chef server generated run history id: #{@run_id}") - rescue Net::HTTPServerException => e - raise unless e.response.code.to_s == "404" - Chef::Log.debug("Received 404 attempting to generate run history id (URL Path: #{resource_history_url}), assuming feature is not supported.") + @summary_only = server_response["summary_only"] + rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => e + if !e.response || e.response.code.to_s != 404 + if Chef::Config[:enable_reporting_url_fatals] + Chef::Log.error("Received exception attempting to generate run history id (URL Path: #{resource_history_url}), and enable_reporting_url_fatals is set, aborting run.") + raise + else + Chef::Log.info("Received exception attempting to generate run history id (URL Path: #{resource_history_url}), disabling reporting for this run.") + end + else + Chef::Log.debug("Received 404 attempting to generate run history id (URL Path: #{resource_history_url}), assuming feature is not supported.") + end @reporting_enabled = false end end @@ -159,42 +170,69 @@ class Chef end def run_completed(node) - if reporting_enabled? - resource_history_url = "reports/nodes/#{@node.name}/runs/#{run_id}" - run_data = report(node) - run_data["action"] = "end" - Chef::Log.info("Sending resource update report (run-id: #{run_id})") - Chef::Log.debug run_data.inspect - @rest_client.post_rest(resource_history_url, run_data) - else - Chef::Log.debug("Server doesn't support resource history, skipping resource report.") - end + @status = "success" + post_reporting_data end def run_failed(exception) @exception = exception @status = "failure" + post_reporting_data end - def report(node) + def post_reporting_data + if reporting_enabled? + run_data = prepare_run_data + resource_history_url = "reports/nodes/#{@node.name}/runs/#{@run_id}" + Chef::Log.info("Sending resource update report (run-id: #{@run_id})") + Chef::Log.debug run_data.inspect + compressed_data = encode_gzip(run_data.to_json) + #if summary only is enabled send the uncompressed run_data excluding the run_data["resources"] and some additional metrics. + if @summary_only + run_data = report_summary(run_data, compressed_data) + Chef::Log.info("run_data_summary: #{run_data}") + @rest_client.post_rest(resource_history_url, run_data) + else + Chef::Log.debug("Sending Compressed Run Data...") + # Since we're posting compressed data we can not directly call + # post_rest which expects JSON + reporting_url = @rest_client.create_url(resource_history_url) + @rest_client.raw_http_request(:POST, reporting_url, {'Content-Encoding' => 'gzip'}, compressed_data) + end + else + Chef::Log.debug("Server doesn't support resource history, skipping resource report.") + end + end + + def prepare_run_data run_data = {} + run_data["action"] = "end" run_data["resources"] = updated_resources.map do |resource_record| resource_record.for_json end - run_data["status"] = status - run_data["run_list"] = node.run_list.to_json + run_data["status"] = @status + run_data["run_list"] = @node.run_list.to_json run_data["total_res_count"] = @total_res_count.to_s run_data["data"] = {} + if exception - run_data["data"]["exception"] = {} - run_data["data"]["exception"]["class"] = exception.inspect - run_data["data"]["exception"]["message"] = exception.message - run_data["data"]["exception"]["backtrace"] = exception.backtrace - run_data["data"]["exception"]["description"] = @error_descriptions + exception_data = {} + exception_data["class"] = exception.inspect + exception_data["message"] = exception.message + exception_data["backtrace"] = exception.backtrace.to_json + exception_data["description"] = @error_descriptions + run_data["data"]["exception"] = exception_data end run_data end + def report_summary(run_data, compressed_data) + run_data["updated_res_count"] = updated_resources.count.to_s + run_data["post_size"] = compressed_data.bytesize.to_s + run_data["resources"] = [] + run_data + end + def run_list_expand_failed(node, exception) description = Formatters::ErrorMapper.run_list_expand_failed(node, exception) @error_descriptions = description.for_json @@ -224,5 +262,11 @@ class Chef @pending_update && @pending_update.new_resource != new_resource end + def encode_gzip(data) + "".tap do |out| + Zlib::GzipWriter.wrap(StringIO.new(out)){|gz| gz << data } + end + end + end end diff --git a/chef/lib/chef/rest.rb b/chef/lib/chef/rest.rb index fd10b1993b..1e67d762b3 100644 --- a/chef/lib/chef/rest.rb +++ b/chef/lib/chef/rest.rb @@ -236,16 +236,20 @@ class Chef end end - # Runs an HTTP request to a JSON API. File Download not supported. + # Runs an HTTP request to a JSON API with JSON body. File Download not supported. def api_request(method, url, headers={}, data=false) json_body = data ? Chef::JSONCompat.to_json(data) : nil # Force encoding to binary to fix SSL related EOFErrors # cf. http://tickets.opscode.com/browse/CHEF-2363 # http://redmine.ruby-lang.org/issues/5233 json_body.force_encoding(Encoding::BINARY) if json_body.respond_to?(:force_encoding) - headers = build_headers(method, url, headers, json_body) - - retriable_rest_request(method, url, json_body, headers) do |rest_request| + raw_http_request(method, url, headers, json_body) + end + + # Runs an HTTP request to a JSON API with raw body. File Download not supported. + def raw_http_request(method, url, headers, body) + headers = build_headers(method, url, headers, body) + retriable_rest_request(method, url, body, headers) do |rest_request| begin response = rest_request.call {|r| r.read_body} diff --git a/chef/lib/chef/run_list.rb b/chef/lib/chef/run_list.rb index cb77691d5b..1e4bdd255a 100644 --- a/chef/lib/chef/run_list.rb +++ b/chef/lib/chef/run_list.rb @@ -29,7 +29,7 @@ class Chef include Enumerable include Chef::Mixin::ParamsValidate - # @run_list_items is an array of RunListItems that describe the items to + # @run_list_items is an array of RunListItems that describe the items to # execute in order. RunListItems can load from and convert to the string # forms users set on roles and nodes. # For example: @@ -67,6 +67,7 @@ class Chef end alias :push :<< + alias :add :<< def ==(other) if other.kind_of?(Chef::RunList) @@ -162,4 +163,3 @@ class Chef end end - diff --git a/chef/lib/chef/scan_access_control.rb b/chef/lib/chef/scan_access_control.rb index 5b83a59695..5863a8c7c4 100644 --- a/chef/lib/chef/scan_access_control.rb +++ b/chef/lib/chef/scan_access_control.rb @@ -46,7 +46,7 @@ class Chef # Modifies @current_resource, setting the current access control state. def set_all! - if File.exist?(new_resource.path) + if ::File.exist?(new_resource.path) set_owner set_group set_mode |