diff options
Diffstat (limited to 'lib/chef')
153 files changed, 703 insertions, 301 deletions
diff --git a/lib/chef/api_client/registration.rb b/lib/chef/api_client/registration.rb index b05bdcac31..e8ab0149e8 100644 --- a/lib/chef/api_client/registration.rb +++ b/lib/chef/api_client/registration.rb @@ -69,7 +69,7 @@ class Chef end def assert_destination_writable! - if (File.exists?(destination) && !File.writable?(destination)) or !File.writable?(File.dirname(destination)) + if (File.exists?(destination) && !File.writable?(destination)) || !File.writable?(File.dirname(destination)) abs_path = File.expand_path(destination) raise Chef::Exceptions::CannotWritePrivateKey, "I can't write your private key to #{abs_path} - check permissions?" end diff --git a/lib/chef/application/apply.rb b/lib/chef/application/apply.rb index 38b00f293c..03c86b86f2 100644 --- a/lib/chef/application/apply.rb +++ b/lib/chef/application/apply.rb @@ -204,7 +204,7 @@ class Chef::Application::Apply < Chef::Application parse_options run_chef_recipe Chef::Application.exit! "Exiting", 0 - rescue SystemExit => e + rescue SystemExit raise rescue Exception => e Chef::Application.debug_stacktrace(e) diff --git a/lib/chef/application/client.rb b/lib/chef/application/client.rb index 8f30037ac7..500aa8ac59 100644 --- a/lib/chef/application/client.rb +++ b/lib/chef/application/client.rb @@ -265,7 +265,7 @@ class Chef::Application::Client < Chef::Application option :audit_mode, :long => "--audit-mode MODE", :description => "Enable audit-mode with `enabled`. Disable audit-mode with `disabled`. Skip converge and only perform audits with `audit-only`", - :proc => lambda { |mo| mo.gsub("-", "_").to_sym } + :proc => lambda { |mo| mo.tr("-", "_").to_sym } option :minimal_ohai, :long => "--minimal-ohai", @@ -480,7 +480,7 @@ class Chef::Application::Client < Chef::Application end def client_sleep(sec) - IO.select([ SELF_PIPE[0] ], nil, nil, sec) or return + return unless IO.select([ SELF_PIPE[0] ], nil, nil, sec) @signal = SELF_PIPE[0].getc.chr end diff --git a/lib/chef/application/windows_service.rb b/lib/chef/application/windows_service.rb index 0328a65487..fca1ed3689 100644 --- a/lib/chef/application/windows_service.rb +++ b/lib/chef/application/windows_service.rb @@ -312,13 +312,13 @@ class Chef else ::File.open(config[:config_file]) { |f| apply_config(f.path) } end - rescue Errno::ENOENT => error + rescue Errno::ENOENT Chef::Log.warn("*****************************************") Chef::Log.warn("Did not find config file: #{config[:config_file]}, using command line options.") Chef::Log.warn("*****************************************") Chef::Config.merge!(config) - rescue SocketError => error + rescue SocketError Chef::Application.fatal!("Error getting config file #{Chef::Config[:config_file]}", 2) rescue Chef::Exceptions::ConfigurationError => error Chef::Application.fatal!("Error processing config file #{Chef::Config[:config_file]} with error #{error.message}", 2) diff --git a/lib/chef/chef_fs/config.rb b/lib/chef/chef_fs/config.rb index 1dbbe1a508..6e3cc50ac1 100644 --- a/lib/chef/chef_fs/config.rb +++ b/lib/chef/chef_fs/config.rb @@ -270,7 +270,8 @@ class Chef end object_names.each do |object_name| # cookbooks -> cookbook_path - singular_name = INFLECTIONS[object_name] or raise "Unknown object name #{object_name}" + singular_name = INFLECTIONS[object_name] + raise "Unknown object name #{object_name}" unless singular_name variable_name = "#{singular_name}_path" paths = Array(@chef_config[variable_name]).flatten result[object_name] = paths.map { |path| File.expand_path(path) } diff --git a/lib/chef/chef_fs/data_handler/container_data_handler.rb b/lib/chef/chef_fs/data_handler/container_data_handler.rb index a2e277fc7a..04973b5135 100644 --- a/lib/chef/chef_fs/data_handler/container_data_handler.rb +++ b/lib/chef/chef_fs/data_handler/container_data_handler.rb @@ -15,10 +15,16 @@ class Chef return key == "containername" end - def verify_integrity(object, entry, &on_error) + # Verify that the JSON hash for this type has a key that matches its name. + # + # @param object [Object] JSON hash of the object + # @param entry [Chef::ChefFS::FileSystem::BaseFSObject] filesystem object we are verifying + # @yield [s] callback to handle errors + # @yieldparam [s<string>] error message + def verify_integrity(object, entry) base_name = remove_dot_json(entry.name) if object["containername"] != base_name - on_error.call("Name in #{entry.path_for_printing} must be '#{base_name}' (is '#{object['name']}')") + yield("Name in #{entry.path_for_printing} must be '#{base_name}' (is '#{object['containername']}')") end end diff --git a/lib/chef/chef_fs/data_handler/data_bag_item_data_handler.rb b/lib/chef/chef_fs/data_handler/data_bag_item_data_handler.rb index 8ac9a520a4..c6b6449d52 100644 --- a/lib/chef/chef_fs/data_handler/data_bag_item_data_handler.rb +++ b/lib/chef/chef_fs/data_handler/data_bag_item_data_handler.rb @@ -42,10 +42,16 @@ class Chef Chef::DataBagItem end - def verify_integrity(object, entry, &on_error) + # Verify that the JSON hash for this type has a key that matches its name. + # + # @param object [Object] JSON hash of the object + # @param entry [Chef::ChefFS::FileSystem::BaseFSObject] filesystem object we are verifying + # @yield [s] callback to handle errors + # @yieldparam [s<string>] error message + def verify_integrity(object, entry) base_name = remove_dot_json(entry.name) if object["raw_data"]["id"] != base_name - on_error.call("ID in #{entry.path_for_printing} must be '#{base_name}' (is '#{object['raw_data']['id']}')") + yield("ID in #{entry.path_for_printing} must be '#{base_name}' (is '#{object['raw_data']['id']}')") end end diff --git a/lib/chef/chef_fs/data_handler/data_handler_base.rb b/lib/chef/chef_fs/data_handler/data_handler_base.rb index 83f56ed16d..b30ae9c708 100644 --- a/lib/chef/chef_fs/data_handler/data_handler_base.rb +++ b/lib/chef/chef_fs/data_handler/data_handler_base.rb @@ -185,14 +185,16 @@ class Chef result end - # # Verify that the JSON hash for this type has a key that matches its name. - # Calls the on_error block with the error, if there is one. # - def verify_integrity(object, entry, &on_error) + # @param object [Object] JSON hash of the object + # @param entry [Chef::ChefFS::FileSystem::BaseFSObject] filesystem object we are verifying + # @yield [s] callback to handle errors + # @yieldparam [s<string>] error message + def verify_integrity(object, entry) base_name = remove_dot_json(entry.name) if object["name"] != base_name - on_error.call("Name must be '#{base_name}' (is '#{object['name']}')") + yield("Name must be '#{base_name}' (is '#{object['name']}')") end end diff --git a/lib/chef/chef_fs/data_handler/organization_data_handler.rb b/lib/chef/chef_fs/data_handler/organization_data_handler.rb index 3e5528cc49..0facd5d55d 100644 --- a/lib/chef/chef_fs/data_handler/organization_data_handler.rb +++ b/lib/chef/chef_fs/data_handler/organization_data_handler.rb @@ -19,9 +19,15 @@ class Chef return key == "name" end - def verify_integrity(object, entry, &on_error) + # Verify that the JSON hash for this type has a key that matches its name. + # + # @param object [Object] JSON hash of the object + # @param entry [Chef::ChefFS::FileSystem::BaseFSObject] filesystem object we are verifying + # @yield [s] callback to handle errors + # @yieldparam [s<string>] error message + def verify_integrity(object, entry) if entry.org != object["name"] - on_error.call("Name must be '#{entry.org}' (is '#{object['name']}')") + yield("Name must be '#{entry.org}' (is '#{object['name']}')") end end end diff --git a/lib/chef/chef_fs/data_handler/policy_data_handler.rb b/lib/chef/chef_fs/data_handler/policy_data_handler.rb index 477d2bf637..fa7bbe9101 100644 --- a/lib/chef/chef_fs/data_handler/policy_data_handler.rb +++ b/lib/chef/chef_fs/data_handler/policy_data_handler.rb @@ -26,14 +26,20 @@ class Chef normalize_hash(policy, defaults) end - def verify_integrity(object_data, entry, &on_error) + # Verify that the JSON hash for this type has a key that matches its name. + # + # @param object [Object] JSON hash of the object + # @param entry [Chef::ChefFS::FileSystem::BaseFSObject] filesystem object we are verifying + # @yield [s] callback to handle errors + # @yieldparam [s<string>] error message + def verify_integrity(object_data, entry) name, revision = name_and_revision(entry.name) if object_data["name"] != name - on_error.call("Object name '#{object_data['name']}' doesn't match entry '#{entry.name}'.") + yield("Object name '#{object_data['name']}' doesn't match entry '#{name}'.") end if object_data["revision_id"] != revision - on_error.call("Object revision ID '#{object_data['revision']}' doesn't match entry '#{entry.name}'.") + yield("Object revision ID '#{object_data['revision_id']}' doesn't match entry '#{revision}'.") end end end diff --git a/lib/chef/chef_fs/data_handler/policy_group_data_handler.rb b/lib/chef/chef_fs/data_handler/policy_group_data_handler.rb index e5c430ab64..f7aa92373c 100644 --- a/lib/chef/chef_fs/data_handler/policy_group_data_handler.rb +++ b/lib/chef/chef_fs/data_handler/policy_group_data_handler.rb @@ -15,9 +15,15 @@ class Chef result end - def verify_integrity(object_data, entry, &on_error) + # Verify that the JSON hash for this type has a key that matches its name. + # + # @param object [Object] JSON hash of the object + # @param entry [Chef::ChefFS::FileSystem::BaseFSObject] filesystem object we are verifying + # @yield [s] callback to handle errors + # @yieldparam [s<string>] error message + def verify_integrity(object_data, entry) if object_data["policies"].empty? - on_error.call("Policy group #{object_data["name"]} does not have any policies in it.") + yield("Policy group #{object_data["name"]} does not have any policies in it.") end end diff --git a/lib/chef/chef_fs/file_system.rb b/lib/chef/chef_fs/file_system.rb index 415556300c..e6cf735971 100644 --- a/lib/chef/chef_fs/file_system.rb +++ b/lib/chef/chef_fs/file_system.rb @@ -55,7 +55,7 @@ class Chef def list_from(entry, &block) # Include self in results if it matches if pattern.match?(entry.path) - block.call(entry) + yield(entry) end if pattern.could_match_children?(entry.path) diff --git a/lib/chef/chef_fs/file_system/chef_server/acl_dir.rb b/lib/chef/chef_fs/file_system/chef_server/acl_dir.rb index 9943aaeca7..58a32d3860 100644 --- a/lib/chef/chef_fs/file_system/chef_server/acl_dir.rb +++ b/lib/chef/chef_fs/file_system/chef_server/acl_dir.rb @@ -30,7 +30,7 @@ class Chef end def make_child_entry(name, exists = nil) - result = @children.select { |child| child.name == name }.first if @children + result = @children.find { |child| child.name == name } if @children result || AclEntry.new(name, self, exists) end diff --git a/lib/chef/chef_fs/file_system/chef_server/acls_dir.rb b/lib/chef/chef_fs/file_system/chef_server/acls_dir.rb index d03164023f..b9af486203 100644 --- a/lib/chef/chef_fs/file_system/chef_server/acls_dir.rb +++ b/lib/chef/chef_fs/file_system/chef_server/acls_dir.rb @@ -39,7 +39,7 @@ class Chef end def make_child_entry(name) - children.select { |child| child.name == name }.first + children.find { |child| child.name == name } end def can_have_child?(name, is_dir) diff --git a/lib/chef/chef_fs/file_system/chef_server/chef_server_root_dir.rb b/lib/chef/chef_fs/file_system/chef_server/chef_server_root_dir.rb index 6c99d6de73..5030a0733f 100644 --- a/lib/chef/chef_fs/file_system/chef_server/chef_server_root_dir.rb +++ b/lib/chef/chef_fs/file_system/chef_server/chef_server_root_dir.rb @@ -119,7 +119,7 @@ class Chef end def can_have_child?(name, is_dir) - result = children.select { |child| child.name == name }.first + result = children.find { |child| child.name == name } result && !!result.dir? == !!is_dir end @@ -136,7 +136,7 @@ class Chef end def make_child_entry(name) - children.select { |child| child.name == name }.first + children.find { |child| child.name == name } end def children diff --git a/lib/chef/chef_fs/file_system/chef_server/cookbook_artifacts_dir.rb b/lib/chef/chef_fs/file_system/chef_server/cookbook_artifacts_dir.rb index 020f8510b7..0b82a64a0a 100644 --- a/lib/chef/chef_fs/file_system/chef_server/cookbook_artifacts_dir.rb +++ b/lib/chef/chef_fs/file_system/chef_server/cookbook_artifacts_dir.rb @@ -35,7 +35,7 @@ class Chef class CookbookArtifactsDir < CookbooksDir def make_child_entry(name) - result = @children.select { |child| child.name == name }.first if @children + result = @children.find { |child| child.name == name } if @children result || CookbookArtifactDir.new(name, self) end diff --git a/lib/chef/chef_fs/file_system/chef_server/cookbook_dir.rb b/lib/chef/chef_fs/file_system/chef_server/cookbook_dir.rb index 3a08768baf..f7e5f058be 100644 --- a/lib/chef/chef_fs/file_system/chef_server/cookbook_dir.rb +++ b/lib/chef/chef_fs/file_system/chef_server/cookbook_dir.rb @@ -53,7 +53,7 @@ class Chef :attributes => { :ruby_only => true }, :definitions => { :ruby_only => true }, :recipes => { :ruby_only => true }, - :libraries => { :ruby_only => true }, + :libraries => { :recursive => true }, :templates => { :recursive => true }, :files => { :recursive => true }, :resources => { :ruby_only => true, :recursive => true }, @@ -74,7 +74,7 @@ class Chef # we need to make sure we don't rethrow the exception. (child(name) # is not supposed to fail.) begin - children.select { |child| child.name == name }.first + children.find { |child| child.name == name } rescue Chef::ChefFS::FileSystem::NotFoundError nil end @@ -101,7 +101,7 @@ class Chef container = self parts[0, parts.length - 1].each do |part| old_container = container - container = old_container.children.select { |child| part == child.name }.first + container = old_container.children.find { |child| part == child.name } if !container container = CookbookSubdir.new(part, old_container, segment_info[:ruby_only], segment_info[:recursive]) old_container.add_child(container) diff --git a/lib/chef/chef_fs/file_system/chef_server/cookbook_subdir.rb b/lib/chef/chef_fs/file_system/chef_server/cookbook_subdir.rb index 913cf1a5e2..01297a39ba 100644 --- a/lib/chef/chef_fs/file_system/chef_server/cookbook_subdir.rb +++ b/lib/chef/chef_fs/file_system/chef_server/cookbook_subdir.rb @@ -47,7 +47,7 @@ class Chef end def make_child_entry(name) - result = @children.select { |child| child.name == name }.first if @children + result = @children.find { |child| child.name == name } if @children result || NonexistentFSObject.new(name, self) end diff --git a/lib/chef/chef_fs/file_system/chef_server/cookbooks_dir.rb b/lib/chef/chef_fs/file_system/chef_server/cookbooks_dir.rb index 75d7150f8e..72cefe44eb 100644 --- a/lib/chef/chef_fs/file_system/chef_server/cookbooks_dir.rb +++ b/lib/chef/chef_fs/file_system/chef_server/cookbooks_dir.rb @@ -41,7 +41,7 @@ class Chef include Chef::Mixin::FileClass def make_child_entry(name) - result = @children.select { |child| child.name == name }.first if @children + result = @children.find { |child| child.name == name } if @children result || CookbookDir.new(name, self) end diff --git a/lib/chef/chef_fs/file_system/chef_server/data_bags_dir.rb b/lib/chef/chef_fs/file_system/chef_server/data_bags_dir.rb index 9246d8e2b7..ec382e60ef 100644 --- a/lib/chef/chef_fs/file_system/chef_server/data_bags_dir.rb +++ b/lib/chef/chef_fs/file_system/chef_server/data_bags_dir.rb @@ -25,7 +25,7 @@ class Chef module ChefServer class DataBagsDir < RestListDir def make_child_entry(name, exists = false) - result = @children.select { |child| child.name == name }.first if @children + result = @children.find { |child| child.name == name } if @children result || DataBagDir.new(name, self, exists) end diff --git a/lib/chef/chef_fs/file_system/chef_server/policies_dir.rb b/lib/chef/chef_fs/file_system/chef_server/policies_dir.rb index ebb274a9eb..4a4be19fe4 100644 --- a/lib/chef/chef_fs/file_system/chef_server/policies_dir.rb +++ b/lib/chef/chef_fs/file_system/chef_server/policies_dir.rb @@ -47,7 +47,7 @@ class Chef # } def make_child_entry(name, exists = nil) - @children.select { |child| child.name == name }.first if @children + @children.find { |child| child.name == name } if @children PolicyRevisionEntry.new(name, self, exists) end diff --git a/lib/chef/chef_fs/file_system/chef_server/rest_list_dir.rb b/lib/chef/chef_fs/file_system/chef_server/rest_list_dir.rb index 488e9c0ed0..b5b602a208 100644 --- a/lib/chef/chef_fs/file_system/chef_server/rest_list_dir.rb +++ b/lib/chef/chef_fs/file_system/chef_server/rest_list_dir.rb @@ -168,7 +168,7 @@ class Chef end def make_child_entry(name, exists = nil) - @children.select { |child| child.name == name }.first if @children + @children.find { |child| child.name == name } if @children RestListEntry.new(name, self, exists) end end diff --git a/lib/chef/chef_fs/file_system/chef_server/versioned_cookbooks_dir.rb b/lib/chef/chef_fs/file_system/chef_server/versioned_cookbooks_dir.rb index 9abafed5e7..172405763a 100644 --- a/lib/chef/chef_fs/file_system/chef_server/versioned_cookbooks_dir.rb +++ b/lib/chef/chef_fs/file_system/chef_server/versioned_cookbooks_dir.rb @@ -41,7 +41,7 @@ class Chef class VersionedCookbooksDir < CookbooksDir def make_child_entry(name) - result = @children.select { |child| child.name == name }.first if @children + result = @children.find { |child| child.name == name } if @children result || VersionedCookbookDir.new(name, self) end diff --git a/lib/chef/chef_fs/file_system/memory/memory_dir.rb b/lib/chef/chef_fs/file_system/memory/memory_dir.rb index beb661448d..6049f404b1 100644 --- a/lib/chef/chef_fs/file_system/memory/memory_dir.rb +++ b/lib/chef/chef_fs/file_system/memory/memory_dir.rb @@ -14,7 +14,7 @@ class Chef attr_reader :children def make_child_entry(name) - @children.select { |child| child.name == name }.first + @children.find { |child| child.name == name } end def add_child(child) diff --git a/lib/chef/chef_fs/parallelizer/flatten_enumerable.rb b/lib/chef/chef_fs/parallelizer/flatten_enumerable.rb index 6094fab493..84db2c2053 100644 --- a/lib/chef/chef_fs/parallelizer/flatten_enumerable.rb +++ b/lib/chef/chef_fs/parallelizer/flatten_enumerable.rb @@ -26,7 +26,7 @@ class Chef flatten(child, levels.nil? ? levels : levels - 1, &block) end else - block.call(value) + yield(value) end end end diff --git a/lib/chef/client.rb b/lib/chef/client.rb index 7d2dcf8057..8ca0fd5e89 100644 --- a/lib/chef/client.rb +++ b/lib/chef/client.rb @@ -312,9 +312,7 @@ class Chef events.run_failed(run_error) ensure Chef::RequestID.instance.reset_request_id - request_id = nil @run_status = nil - run_context = nil runlock.release end diff --git a/lib/chef/config_fetcher.rb b/lib/chef/config_fetcher.rb index 13f9fc3825..acd2f07f5e 100644 --- a/lib/chef/config_fetcher.rb +++ b/lib/chef/config_fetcher.rb @@ -45,9 +45,9 @@ class Chef def read_local_config ::File.read(config_location) - rescue Errno::ENOENT => error + rescue Errno::ENOENT Chef::Application.fatal!("Cannot load configuration from #{config_location}", 2) - rescue Errno::EACCES => error + rescue Errno::EACCES Chef::Application.fatal!("Permissions are incorrect on #{config_location}. Please chmod a+r #{config_location}", 2) end diff --git a/lib/chef/cookbook/cookbook_collection.rb b/lib/chef/cookbook/cookbook_collection.rb index 81e7bb92b4..d06b8fd042 100644 --- a/lib/chef/cookbook/cookbook_collection.rb +++ b/lib/chef/cookbook/cookbook_collection.rb @@ -1,7 +1,7 @@ #-- # Author:: Tim Hinderliter (<tim@chef.io>) # Author:: Christopher Walters (<cw@chef.io>) -# Copyright:: Copyright 2010-2016, Chef Software, Inc. +# Copyright:: Copyright 2010-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,6 +18,7 @@ # require "chef/mash" +require "chef/cookbook/gem_installer" class Chef # == Chef::CookbookCollection @@ -54,5 +55,9 @@ class Chef cookbook_version.metadata.validate_ohai_version! end end + + def install_gems(events) + Cookbook::GemInstaller.new(self, events).install + end end end diff --git a/lib/chef/cookbook/cookbook_version_loader.rb b/lib/chef/cookbook/cookbook_version_loader.rb index 48fa6a03a1..d9b027f322 100644 --- a/lib/chef/cookbook/cookbook_version_loader.rb +++ b/lib/chef/cookbook/cookbook_version_loader.rb @@ -86,7 +86,7 @@ class Chef load_as(:attribute_filenames, "attributes", "*.rb") load_as(:definition_filenames, "definitions", "*.rb") load_as(:recipe_filenames, "recipes", "*.rb") - load_recursively_as(:library_filenames, "libraries", "*.rb") + load_recursively_as(:library_filenames, "libraries", "*") load_recursively_as(:template_filenames, "templates", "*") load_recursively_as(:file_filenames, "files", "*") load_recursively_as(:resource_filenames, "resources", "*.rb") diff --git a/lib/chef/cookbook/gem_installer.rb b/lib/chef/cookbook/gem_installer.rb new file mode 100644 index 0000000000..a85868ccfd --- /dev/null +++ b/lib/chef/cookbook/gem_installer.rb @@ -0,0 +1,118 @@ +#-- +# Copyright:: Copyright (c) 2010-2016 Chef Software, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require "bundler" +require "bundler/inline" + +class Chef + class Cookbook + class GemInstaller + + # @return [Chef::EventDispatch::Dispatcher] the client event dispatcher + attr_accessor :events + # @return [Chef::CookbookCollection] the cookbook collection + attr_accessor :cookbook_collection + + def initialize(cookbook_collection, events) + @cookbook_collection = cookbook_collection + @events = events + end + + # Installs the gems into the omnibus gemset. + # + def install + cookbook_gems = [] + + cookbook_collection.each do |cookbook_name, cookbook_version| + cookbook_gems += cookbook_version.metadata.gems + end + + events.cookbook_gem_start(cookbook_gems) + + unless cookbook_gems.empty? + begin + inline_gemfile do + source Chef::Config[:rubygems_url] + cookbook_gems.each do |args| + gem(*args) + end + end + rescue Exception => e + events.cookbook_gem_failed(e) + raise + end + end + + events.cookbook_gem_finished + end + + # Bundler::UI object so that we can intercept and log the output + # of the in-memory bundle install that we are going to do. + # + class ChefBundlerUI < Bundler::UI::Silent + attr_accessor :events + + def initialize(events) + @events = events + super() + end + + def confirm(msg, newline = nil) + # looks like "Installing time_ago_in_words 0.1.1" when installing + if msg =~ /Installing\s+(\S+)\s+(\S+)/ + events.cookbook_gem_installing($1, $2) + end + Chef::Log.info(msg) + end + + def error(msg, newline = nil) + Chef::Log.error(msg) + end + + def debug(msg, newline = nil) + Chef::Log.debug(msg) + end + + def info(msg, newline = nil) + # looks like "Using time_ago_in_words 0.1.1" when using, plus other misc output + if msg =~ /Using\s+(\S+)\s+(\S+)/ + events.cookbook_gem_using($1, $2) + end + Chef::Log.info(msg) + end + + def warn(msg, newline = nil) + Chef::Log.warn(msg) + end + end + + private + + # Helper to handle older bundler versions that do not support injecting the UI + # object. On older bundler versions, we work, but you get no output other than + # on STDOUT. + # + def inline_gemfile(&block) + # requires https://github.com/bundler/bundler/pull/4245 + gemfile(true, ui: ChefBundlerUI.new(events), &block) + rescue ArgumentError # Method#arity doesn't inspect optional arguments, so we rescue + # requires bundler 1.10.0 + gemfile(true, &block) + end + end + end +end diff --git a/lib/chef/cookbook/metadata.rb b/lib/chef/cookbook/metadata.rb index 1cad526b65..603f80748c 100644 --- a/lib/chef/cookbook/metadata.rb +++ b/lib/chef/cookbook/metadata.rb @@ -58,12 +58,14 @@ class Chef PRIVACY = "privacy".freeze CHEF_VERSIONS = "chef_versions".freeze OHAI_VERSIONS = "ohai_versions".freeze + GEMS = "gems".freeze COMPARISON_FIELDS = [ :name, :description, :long_description, :maintainer, :maintainer_email, :license, :platforms, :dependencies, :recommendations, :suggestions, :conflicting, :providing, :replacing, :attributes, :groupings, :recipes, :version, - :source_url, :issues_url, :privacy, :chef_versions, :ohai_versions ] + :source_url, :issues_url, :privacy, :chef_versions, :ohai_versions, + :gems ] VERSION_CONSTRAINTS = { :depends => DEPENDENCIES, :recommends => RECOMMENDATIONS, @@ -93,6 +95,8 @@ class Chef attr_reader :chef_versions # @return [Array<Gem::Dependency>] Array of supported Ohai versions attr_reader :ohai_versions + # @return [Array<Array>] Array of gems to install with *args as an Array + attr_reader :gems # Builds a new Chef::Cookbook::Metadata object. # @@ -130,6 +134,7 @@ class Chef @privacy = false @chef_versions = [] @ohai_versions = [] + @gems = [] @errors = [] end @@ -420,6 +425,17 @@ class Chef @ohai_versions end + # Metadata DSL to set a gem to install from the cookbook metadata. May be declared + # multiple times. All the gems from all the cookbooks are combined into one Gemfile + # and depsolved together. Uses Bundler's DSL for its implementation. + # + # @param args [Array<String>] Gem name and options to pass to Bundler's DSL + # @return [Array<Array>] Array of gem statements as args + def gem(*args) + @gems << args unless args.empty? + @gems + end + # Adds a description for a recipe. # # === Parameters @@ -573,6 +589,7 @@ class Chef PRIVACY => self.privacy, CHEF_VERSIONS => gem_requirements_to_array(*self.chef_versions), OHAI_VERSIONS => gem_requirements_to_array(*self.ohai_versions), + GEMS => self.gems, } end @@ -609,6 +626,7 @@ class Chef @privacy = o[PRIVACY] if o.has_key?(PRIVACY) @chef_versions = gem_requirements_from_array("chef", o[CHEF_VERSIONS]) if o.has_key?(CHEF_VERSIONS) @ohai_versions = gem_requirements_from_array("ohai", o[OHAI_VERSIONS]) if o.has_key?(OHAI_VERSIONS) + @gems = o[GEMS] if o.has_key?(GEMS) self end diff --git a/lib/chef/cookbook/syntax_check.rb b/lib/chef/cookbook/syntax_check.rb index fd7835db96..f8559433dc 100644 --- a/lib/chef/cookbook/syntax_check.rb +++ b/lib/chef/cookbook/syntax_check.rb @@ -114,7 +114,7 @@ class Chef end def ruby_files - path = Chef::Util::PathHelper.escape_glob(cookbook_path) + path = Chef::Util::PathHelper.escape_glob_dir(cookbook_path) files = Dir[File.join(path, "**", "*.rb")] files = remove_ignored_files(files) files = remove_uninteresting_ruby_files(files) @@ -133,7 +133,7 @@ class Chef end def template_files - remove_ignored_files Dir[File.join(Chef::Util::PathHelper.escape_glob(cookbook_path), "**/templates/**", "*.erb")] + remove_ignored_files Dir[File.join(Chef::Util::PathHelper.escape_glob_dir(cookbook_path), "**/templates/**", "*.erb")] end def untested_template_files diff --git a/lib/chef/cookbook_loader.rb b/lib/chef/cookbook_loader.rb index 9367936c32..bff77fa13b 100644 --- a/lib/chef/cookbook_loader.rb +++ b/lib/chef/cookbook_loader.rb @@ -47,7 +47,7 @@ class Chef @cookbooks_paths = Hash.new { |h, k| h[k] = [] } # for deprecation warnings @chefignores = {} @repo_paths = repo_paths.map do |repo_path| - repo_path = File.expand_path(repo_path) + File.expand_path(repo_path) end @preloaded_cookbooks = false @@ -121,7 +121,7 @@ class Chef end def [](cookbook) - if @cookbooks_by_name.has_key?(cookbook.to_sym) or load_cookbook(cookbook.to_sym) + if @cookbooks_by_name.has_key?(cookbook.to_sym) || load_cookbook(cookbook.to_sym) @cookbooks_by_name[cookbook.to_sym] else raise Exceptions::CookbookNotFoundInRepo, "Cannot find a cookbook named #{cookbook}; did you forget to add metadata to a cookbook? (https://docs.chef.io/config_rb_metadata.html)" @@ -179,7 +179,7 @@ class Chef @all_files_in_repo_paths ||= begin @repo_paths.inject([]) do |all_children, repo_path| - all_children += Dir[File.join(Chef::Util::PathHelper.escape_glob(repo_path), "*")] + all_children + Dir[File.join(Chef::Util::PathHelper.escape_glob_dir(repo_path), "*")] end end end diff --git a/lib/chef/cookbook_site_streaming_uploader.rb b/lib/chef/cookbook_site_streaming_uploader.rb index d6a270b033..9fb8d0d4bc 100644 --- a/lib/chef/cookbook_site_streaming_uploader.rb +++ b/lib/chef/cookbook_site_streaming_uploader.rb @@ -77,7 +77,6 @@ class Chef parts = [] content_file = nil - timestamp = Time.now.utc.iso8601 secret_key = OpenSSL::PKey::RSA.new(File.read(secret_key_filename)) unless params.nil? || params.empty? diff --git a/lib/chef/cookbook_version.rb b/lib/chef/cookbook_version.rb index 2857d8098e..1e903608b5 100644 --- a/lib/chef/cookbook_version.rb +++ b/lib/chef/cookbook_version.rb @@ -316,11 +316,17 @@ class Chef error_message << error_locations.join("\n") existing_files = segment_filenames(segment) # Strip the root_dir prefix off all files for readability - existing_files.map! { |path| path[root_dir.length + 1..-1] } if root_dir + pretty_existing_files = existing_files.map { |path| + if root_dir + path[root_dir.length + 1..-1] + else + path + end + } # Show the files that the cookbook does have. If the user made a typo, # hopefully they'll see it here. - unless existing_files.empty? - error_message << "\n\nThis cookbook _does_ contain: ['#{existing_files.join("','")}']" + unless pretty_existing_files.empty? + error_message << "\n\nThis cookbook _does_ contain: ['#{pretty_existing_files.join("','")}']" end raise Chef::Exceptions::FileNotFound, error_message else @@ -489,7 +495,7 @@ class Chef # @deprecated This method was used by the Ruby Chef Server and is no longer # needed. There is no replacement. - def generate_manifest_with_urls(&url_generator) + def generate_manifest_with_urls Chef.log_deprecation("Deprecated method #generate_manifest_with_urls.") rendered_manifest = manifest.dup @@ -497,7 +503,7 @@ class Chef if rendered_manifest.has_key?(segment) rendered_manifest[segment].each do |manifest_record| url_options = { :cookbook_name => name.to_s, :cookbook_version => version, :checksum => manifest_record["checksum"] } - manifest_record["url"] = url_generator.call(url_options) + manifest_record["url"] = yield(url_options) end end end diff --git a/lib/chef/daemon.rb b/lib/chef/daemon.rb index 242419890c..70bdddf457 100644 --- a/lib/chef/daemon.rb +++ b/lib/chef/daemon.rb @@ -61,7 +61,7 @@ class Chef # String:: # Location of the pid file for @name def pid_file - Chef::Config[:pid_file] or "/tmp/#{@name}.pid" + Chef::Config[:pid_file] || "/tmp/#{@name}.pid" end # Suck the pid out of pid_file @@ -82,7 +82,7 @@ class Chef def change_privilege Dir.chdir("/") - if Chef::Config[:user] and Chef::Config[:group] + if Chef::Config[:user] && Chef::Config[:group] Chef::Log.info("About to change privilege to #{Chef::Config[:user]}:#{Chef::Config[:group]}") _change_privilege(Chef::Config[:user], Chef::Config[:group]) elsif Chef::Config[:user] @@ -117,7 +117,7 @@ class Chef return false end - if (uid != target_uid) or (gid != target_gid) + if (uid != target_uid) || (gid != target_gid) Process.initgroups(user, target_gid) Process::GID.change_privilege(target_gid) Process::UID.change_privilege(target_uid) diff --git a/lib/chef/data_bag_item.rb b/lib/chef/data_bag_item.rb index 6ac863a47d..d9ad771202 100644 --- a/lib/chef/data_bag_item.rb +++ b/lib/chef/data_bag_item.rb @@ -128,7 +128,6 @@ class Chef def self.from_hash(h) h.delete("chef_type") h.delete("json_class") - h.delete("name") item = new item.data_bag(h.delete("data_bag")) if h.key?("data_bag") @@ -150,6 +149,7 @@ class Chef def self.load(data_bag, name) if Chef::Config[:solo] bag = Chef::DataBag.load(data_bag) + raise Exceptions::InvalidDataBagItemID, "Item #{name} not found in data bag #{data_bag}. Other items found: #{bag.keys.join(", ")}" unless bag.include?(name) item = bag[name] else item = Chef::ServerAPI.new(Chef::Config[:chef_server_url]).get("data/#{data_bag}/#{name}") diff --git a/lib/chef/deprecation/provider/file.rb b/lib/chef/deprecation/provider/file.rb index 4db9101d8d..edb0052fdf 100644 --- a/lib/chef/deprecation/provider/file.rb +++ b/lib/chef/deprecation/provider/file.rb @@ -181,7 +181,7 @@ class Chef # Clean up after the number of backups slice_number = @new_resource.backup - backup_files = Dir[Chef::Util::PathHelper.escape_glob(prefix, ".#{@new_resource.path}") + ".chef-*"].sort { |a, b| b <=> a } + backup_files = Dir[Chef::Util::PathHelper.escape_glob_dir(prefix, ".#{@new_resource.path}") + ".chef-*"].sort { |a, b| b <=> a } if backup_files.length >= @new_resource.backup remainder = backup_files.slice(slice_number..-1) remainder.each do |backup_to_delete| diff --git a/lib/chef/deprecation/provider/remote_directory.rb b/lib/chef/deprecation/provider/remote_directory.rb index 4e28fdc3fa..5e5188f28b 100644 --- a/lib/chef/deprecation/provider/remote_directory.rb +++ b/lib/chef/deprecation/provider/remote_directory.rb @@ -33,7 +33,7 @@ class Chef # List all excluding . and .. def ls(path) - files = Dir.glob(::File.join(Chef::Util::PathHelper.escape_glob(path), "**", "*"), + files = Dir.glob(::File.join(Chef::Util::PathHelper.escape_glob_dir(path), "**", "*"), ::File::FNM_DOTMATCH) # Remove current directory and previous directory diff --git a/lib/chef/deprecation/provider/remote_file.rb b/lib/chef/deprecation/provider/remote_file.rb index 9f115a2565..b469609ffe 100644 --- a/lib/chef/deprecation/provider/remote_file.rb +++ b/lib/chef/deprecation/provider/remote_file.rb @@ -73,7 +73,7 @@ class Chef # which tricks Chef::REST into decompressing the response body. In this # case you'd end up with a tar archive (no gzip) named, e.g., foo.tgz, # which is not what you wanted. - if @new_resource.path =~ /gz$/ or source =~ /gz$/ + if @new_resource.path =~ /gz$/ || source =~ /gz$/ opts[:disable_gzip] = true end opts diff --git a/lib/chef/deprecation/warnings.rb b/lib/chef/deprecation/warnings.rb index b015669625..411e95ea39 100644 --- a/lib/chef/deprecation/warnings.rb +++ b/lib/chef/deprecation/warnings.rb @@ -22,7 +22,6 @@ class Chef def add_deprecation_warnings_for(method_names) method_names.each do |name| - m = instance_method(name) define_method(name) do |*args| message = [] message << "Method '#{name}' of '#{self.class}' is deprecated. It will be removed in Chef 13." diff --git a/lib/chef/dsl/declare_resource.rb b/lib/chef/dsl/declare_resource.rb index 9a59859d5a..e57bc0f4c4 100644 --- a/lib/chef/dsl/declare_resource.rb +++ b/lib/chef/dsl/declare_resource.rb @@ -88,9 +88,7 @@ class Chef # def build_resource(type, name, created_at = nil, run_context: self.run_context, &resource_attrs_block) created_at ||= caller[0] - Thread.exclusive do - require "chef/resource_builder" unless defined?(Chef::ResourceBuilder) - end + require "chef/resource_builder" unless defined?(Chef::ResourceBuilder) Chef::ResourceBuilder.new( type: type, diff --git a/lib/chef/encrypted_data_bag_item/assertions.rb b/lib/chef/encrypted_data_bag_item/assertions.rb index bbdcf7a721..e8f8bfcbf2 100644 --- a/lib/chef/encrypted_data_bag_item/assertions.rb +++ b/lib/chef/encrypted_data_bag_item/assertions.rb @@ -27,7 +27,7 @@ class Chef::EncryptedDataBagItem module Assertions def assert_format_version_acceptable!(format_version) - unless format_version.kind_of?(Integer) and format_version >= Chef::Config[:data_bag_decrypt_minimum_version] + unless format_version.kind_of?(Integer) && format_version >= Chef::Config[:data_bag_decrypt_minimum_version] raise UnacceptableEncryptedDataBagItemFormat, "The encrypted data bag item has format version `#{format_version}', " + "but the config setting 'data_bag_decrypt_minimum_version' requires version `#{Chef::Config[:data_bag_decrypt_minimum_version]}'" diff --git a/lib/chef/encrypted_data_bag_item/decryptor.rb b/lib/chef/encrypted_data_bag_item/decryptor.rb index a002a98a79..773ff4e154 100644 --- a/lib/chef/encrypted_data_bag_item/decryptor.rb +++ b/lib/chef/encrypted_data_bag_item/decryptor.rb @@ -92,8 +92,8 @@ class Chef::EncryptedDataBagItem plaintext = openssl_decryptor.update(encrypted_bytes) plaintext << openssl_decryptor.final rescue OpenSSL::Cipher::CipherError => e - # if the key length is less than 150 characters, and it contains slashes, we think it may be a path. - raise DecryptionFailure, "Error decrypting data bag value: '#{e.message}'. Most likely the provided key is incorrect. #{ @key.length < 255 and @key.include?('/') ? 'You may need to use --secret-file rather than --secret.' : '' }" + # if the key length is less than 255 characters, and it contains slashes, we think it may be a path. + raise DecryptionFailure, "Error decrypting data bag value: '#{e.message}'. Most likely the provided key is incorrect. #{ (@key.length < 255 && @key.include?('/')) ? 'You may need to use --secret-file rather than --secret.' : '' }" end end @@ -143,8 +143,8 @@ class Chef::EncryptedDataBagItem plaintext = openssl_decryptor.update(encrypted_bytes) plaintext << openssl_decryptor.final rescue OpenSSL::Cipher::CipherError => e - # if the key length is less than 150 characters, and it contains slashes, we think it may be a path. - raise DecryptionFailure, "Error decrypting data bag value: '#{e.message}'. Most likely the provided key is incorrect. #{ @key.length < 255 and @key.include?('/') ? 'You may need to use --secret-file rather than --secret.' : '' }" + # if the key length is less than 255 characters, and it contains slashes, we think it may be a path. + raise DecryptionFailure, "Error decrypting data bag value: '#{e.message}'. Most likely the provided key is incorrect. #{ ( @key.length < 255 && @key.include?('/')) ? 'You may need to use --secret-file rather than --secret.' : '' }" end end diff --git a/lib/chef/event_dispatch/base.rb b/lib/chef/event_dispatch/base.rb index e6bbbc929f..6c6b2fa3bb 100644 --- a/lib/chef/event_dispatch/base.rb +++ b/lib/chef/event_dispatch/base.rb @@ -139,6 +139,26 @@ class Chef def cookbook_sync_complete end + # Called when starting to collect gems from the cookbooks + def cookbook_gem_start(gems) + end + + # Called when the result of installing the bundle is to install the gem + def cookbook_gem_installing(gem, version) + end + + # Called when the result of installing the bundle is to use the gem + def cookbook_gem_using(gem, version) + end + + # Called when finished installing cookbook gems + def cookbook_gem_finished + end + + # Called when cookbook gem installation fails + def cookbook_gem_failed(exception) + end + ## TODO: add cookbook name to the API for file load callbacks ## TODO: add callbacks for overall cookbook eval start and complete. diff --git a/lib/chef/event_loggers/base.rb b/lib/chef/event_loggers/base.rb index c34ed2267d..3c11e809f6 100644 --- a/lib/chef/event_loggers/base.rb +++ b/lib/chef/event_loggers/base.rb @@ -42,8 +42,8 @@ class Chef end def self.new(name) - event_logger_class = by_name(name.to_s) or - raise UnknownEventLogger, "No event logger found for #{name} (available: #{available_event_loggers.join(', ')})" + event_logger_class = by_name(name.to_s) + raise UnknownEventLogger, "No event logger found for #{name} (available: #{available_event_loggers.join(', ')})" unless event_logger_class raise UnavailableEventLogger unless available_event_loggers.include? name.to_s event_logger_class.new end diff --git a/lib/chef/file_access_control/unix.rb b/lib/chef/file_access_control/unix.rb index eec9c62701..1746db44d3 100644 --- a/lib/chef/file_access_control/unix.rb +++ b/lib/chef/file_access_control/unix.rb @@ -117,7 +117,7 @@ class Chef end def gid_from_resource(resource) - return nil if resource == nil or resource.group.nil? + return nil if resource == nil || resource.group.nil? if resource.group.kind_of?(String) diminished_radix_complement( Etc.getgrnam(resource.group).gid ) elsif resource.group.kind_of?(Integer) @@ -168,7 +168,7 @@ class Chef end def mode_from_resource(res) - return nil if res == nil or res.mode.nil? + return nil if res == nil || res.mode.nil? (res.mode.respond_to?(:oct) ? res.mode.oct : res.mode.to_i) & 007777 end @@ -197,7 +197,7 @@ class Chef # the user has specified a permission, and it does not match the file, so fix the permission Chef::Log.debug("Found target_mode != current_mode, updating mode") return true - elsif suid_bit_set? and (should_update_group? or should_update_owner?) + elsif suid_bit_set? && (should_update_group? || should_update_owner?) return true else Chef::Log.debug("Found target_mode == current_mode, not updating mode") @@ -264,7 +264,7 @@ class Chef end def uid_from_resource(resource) - return nil if resource == nil or resource.owner.nil? + return nil if resource == nil || resource.owner.nil? if resource.owner.kind_of?(String) diminished_radix_complement( Etc.getpwnam(resource.owner).uid ) elsif resource.owner.kind_of?(Integer) diff --git a/lib/chef/file_access_control/windows.rb b/lib/chef/file_access_control/windows.rb index 7f27ef8df0..6b7184bbd3 100644 --- a/lib/chef/file_access_control/windows.rb +++ b/lib/chef/file_access_control/windows.rb @@ -319,7 +319,7 @@ class Chef def target_group return nil if resource.group.nil? - sid = get_sid(resource.group) + get_sid(resource.group) end def target_inherits @@ -328,7 +328,7 @@ class Chef def target_owner return nil if resource.owner.nil? - sid = get_sid(resource.owner) + get_sid(resource.owner) end end end diff --git a/lib/chef/file_cache.rb b/lib/chef/file_cache.rb index b4beee4a66..cefc9da1eb 100644 --- a/lib/chef/file_cache.rb +++ b/lib/chef/file_cache.rb @@ -158,9 +158,9 @@ class Chef # [String] - An array of file cache keys matching the glob def find(glob_pattern) keys = Array.new - Dir[File.join(Chef::Util::PathHelper.escape_glob(file_cache_path), glob_pattern)].each do |f| + Dir[File.join(Chef::Util::PathHelper.escape_glob_dir(file_cache_path), glob_pattern)].each do |f| if File.file?(f) - keys << f[/^#{Regexp.escape(Dir[Chef::Util::PathHelper.escape_glob(file_cache_path)].first) + File::Separator}(.+)/, 1] + keys << f[/^#{Regexp.escape(Dir[Chef::Util::PathHelper.escape_glob_dir(file_cache_path)].first) + File::Separator}(.+)/, 1] end end keys diff --git a/lib/chef/formatters/base.rb b/lib/chef/formatters/base.rb index b2a8c8099b..90925ffdb4 100644 --- a/lib/chef/formatters/base.rb +++ b/lib/chef/formatters/base.rb @@ -51,8 +51,8 @@ class Chef #-- # TODO: is it too clever to be defining new() on a module like this? def self.new(name, out, err) - formatter_class = by_name(name.to_s) or - raise UnknownFormatter, "No output formatter found for #{name} (available: #{available_formatters.join(', ')})" + formatter_class = by_name(name.to_s) + raise UnknownFormatter, "No output formatter found for #{name} (available: #{available_formatters.join(', ')})" unless formatter_class formatter_class.new(out, err) end diff --git a/lib/chef/formatters/doc.rb b/lib/chef/formatters/doc.rb index bad22370ae..d43f1993b2 100644 --- a/lib/chef/formatters/doc.rb +++ b/lib/chef/formatters/doc.rb @@ -181,6 +181,32 @@ class Chef unindent end + # Called when starting to collect gems from the cookbooks + def cookbook_gem_start(gems) + puts_line "Installing Cookbook Gems:" + indent + end + + # Called when the result of installing the bundle is to install the gem + def cookbook_gem_installing(gem, version) + puts_line "- Installing #{gem} #{version}", :green + end + + # Called when the result of installing the bundle is to use the gem + def cookbook_gem_using(gem, version) + puts_line "- Using #{gem} #{version}" + end + + # Called when finished installing cookbook gems + def cookbook_gem_finished + unindent + end + + # Called when cookbook gem installation fails + def cookbook_gem_failed(exception) + unindent + end + # Called when cookbook loading starts. def library_load_start(file_count) puts_line "Compiling Cookbooks..." diff --git a/lib/chef/formatters/error_descriptor.rb b/lib/chef/formatters/error_descriptor.rb index 0f14e6e783..1a40f785cb 100644 --- a/lib/chef/formatters/error_descriptor.rb +++ b/lib/chef/formatters/error_descriptor.rb @@ -31,7 +31,7 @@ class Chef end def section(heading, text) - @sections << { heading => (text or "") } + @sections << { heading => (text || "") } end def display(out) diff --git a/lib/chef/formatters/error_inspectors/resource_failure_inspector.rb b/lib/chef/formatters/error_inspectors/resource_failure_inspector.rb index f5936285be..94ecce88de 100644 --- a/lib/chef/formatters/error_inspectors/resource_failure_inspector.rb +++ b/lib/chef/formatters/error_inspectors/resource_failure_inspector.rb @@ -63,7 +63,7 @@ class Chef def recipe_snippet return nil if dynamic_resource? @snippet ||= begin - if file = parse_source and line = parse_line(file) + if (file = parse_source) && (line = parse_line(file)) return nil unless ::File.exists?(file) lines = IO.readlines(file) diff --git a/lib/chef/guard_interpreter/resource_guard_interpreter.rb b/lib/chef/guard_interpreter/resource_guard_interpreter.rb index c21961479c..6df60aec89 100644 --- a/lib/chef/guard_interpreter/resource_guard_interpreter.rb +++ b/lib/chef/guard_interpreter/resource_guard_interpreter.rb @@ -22,7 +22,7 @@ class Chef class GuardInterpreter class ResourceGuardInterpreter < DefaultGuardInterpreter - def initialize(parent_resource, command, opts, &block) + def initialize(parent_resource, command, opts) super(command, opts) @parent_resource = parent_resource @resource = get_interpreter_resource(parent_resource) diff --git a/lib/chef/http.rb b/lib/chef/http.rb index 4a3b0bc85e..c6afa97d23 100644 --- a/lib/chef/http.rb +++ b/lib/chef/http.rb @@ -187,7 +187,10 @@ class Chef # # If no block is given, the tempfile is returned, which means it's up to # you to unlink the tempfile when you're done with it. - def streaming_request(path, headers = {}, &block) + # + # @yield [tempfile] block to process the tempfile + # @yieldparams [tempfile<Tempfile>] tempfile + def streaming_request(path, headers = {}) url = create_url(path) response, rest_request, return_value = nil, nil, nil tempfile = nil @@ -246,7 +249,7 @@ class Chef return path if path.is_a?(URI) if path =~ /^(http|https|chefzero):\/\//i URI.parse(path) - elsif path.nil? or path.empty? + elsif path.nil? || path.empty? URI.parse(@url) else # The regular expressions used here are to make sure '@url' does not have diff --git a/lib/chef/http/authenticator.rb b/lib/chef/http/authenticator.rb index b5e28cf54d..84065bf816 100644 --- a/lib/chef/http/authenticator.rb +++ b/lib/chef/http/authenticator.rb @@ -47,7 +47,7 @@ class Chef end def handle_request(method, url, headers = {}, data = false) - headers.merge!({ "X-Ops-Server-API-Version" => @api_version }) + headers["X-Ops-Server-API-Version"] = @api_version headers.merge!(authentication_headers(method, url, data, headers)) if sign_requests? [method, url, headers, data] end diff --git a/lib/chef/http/basic_client.rb b/lib/chef/http/basic_client.rb index e0a02a05cf..58ae496418 100644 --- a/lib/chef/http/basic_client.rb +++ b/lib/chef/http/basic_client.rb @@ -104,7 +104,7 @@ class Chef # proxy before parsing. The regex /^.*:\/\// matches, for example, http://. Reusing proxy # here since we are really just trying to get the string built correctly. if String === proxy && !proxy.strip.empty? - if proxy.match(/^.*:\/\//) + if proxy =~ /^.*:\/\// proxy = URI.parse(proxy.strip) else proxy = URI.parse("#{url.scheme}://#{proxy.strip}") diff --git a/lib/chef/http/remote_request_id.rb b/lib/chef/http/remote_request_id.rb index ef8a18a1e3..a779df805e 100644 --- a/lib/chef/http/remote_request_id.rb +++ b/lib/chef/http/remote_request_id.rb @@ -25,7 +25,7 @@ class Chef end def handle_request(method, url, headers = {}, data = false) - headers.merge!({ "X-REMOTE-REQUEST-ID" => Chef::RequestID.instance.request_id }) + headers["X-REMOTE-REQUEST-ID"] = Chef::RequestID.instance.request_id [method, url, headers, data] end diff --git a/lib/chef/http/socketless_chef_zero_client.rb b/lib/chef/http/socketless_chef_zero_client.rb index c8590903f6..1acac5e758 100644 --- a/lib/chef/http/socketless_chef_zero_client.rb +++ b/lib/chef/http/socketless_chef_zero_client.rb @@ -67,7 +67,7 @@ class Chef end if block_given? - block.call(@body) + yield(@body) else super end @@ -148,7 +148,8 @@ class Chef @url.port end - def request(method, url, body, headers, &handler_block) + # FIXME: yard with @yield + def request(method, url, body, headers) request = req_to_rack(method, url, body, headers) res = ChefZero::SocketlessServerMap.request(port, request) @@ -176,7 +177,8 @@ class Chef def to_net_http(code, headers, chunked_body) body = chunked_body.join("") - msg = STATUS_MESSAGE[code] or raise "Cannot determine HTTP status message for code #{code}" + msg = STATUS_MESSAGE[code] + raise "Cannot determine HTTP status message for code #{code}" unless msg response = Net::HTTPResponse.send(:response_class, code.to_s).new("1.0", code.to_s, msg) response.instance_variable_set(:@body, body) headers.each do |name, value| diff --git a/lib/chef/http/ssl_policies.rb b/lib/chef/http/ssl_policies.rb index 51db01c232..a3692b81b6 100644 --- a/lib/chef/http/ssl_policies.rb +++ b/lib/chef/http/ssl_policies.rb @@ -77,7 +77,7 @@ class Chef http_client.cert_store.set_default_paths end if config.trusted_certs_dir - certs = Dir.glob(File.join(Chef::Util::PathHelper.escape_glob(config.trusted_certs_dir), "*.{crt,pem}")) + certs = Dir.glob(File.join(Chef::Util::PathHelper.escape_glob_dir(config.trusted_certs_dir), "*.{crt,pem}")) certs.each do |cert_file| cert = OpenSSL::X509::Certificate.new(File.read(cert_file)) add_trusted_cert(cert) @@ -118,7 +118,7 @@ class Chef class APISSLPolicy < DefaultSSLPolicy def set_verify_mode - if config[:ssl_verify_mode] == :verify_peer or config[:verify_api_cert] + if config[:ssl_verify_mode] == :verify_peer || config[:verify_api_cert] http_client.verify_mode = OpenSSL::SSL::VERIFY_PEER elsif config[:ssl_verify_mode] == :verify_none http_client.verify_mode = OpenSSL::SSL::VERIFY_NONE diff --git a/lib/chef/http/validate_content_length.rb b/lib/chef/http/validate_content_length.rb index 81d3b0fb74..c1073867d3 100644 --- a/lib/chef/http/validate_content_length.rb +++ b/lib/chef/http/validate_content_length.rb @@ -84,7 +84,6 @@ class Chef def validate(http_response, response_length) content_length = response_content_length(http_response) transfer_encoding = http_response["transfer-encoding"] - content_encoding = http_response["content-encoding"] if content_length.nil? Chef::Log.debug "HTTP server did not include a Content-Length header in response, cannot identify truncated downloads." diff --git a/lib/chef/json_compat.rb b/lib/chef/json_compat.rb index 26d3751897..f8f05a0074 100644 --- a/lib/chef/json_compat.rb +++ b/lib/chef/json_compat.rb @@ -61,7 +61,7 @@ class Chef # JSON gem requires top level object to be a Hash or Array (otherwise # you get the "must contain two octets" error). Yajl doesn't impose the # same limitation. For compatibility, we re-impose this condition. - unless obj.kind_of?(Hash) or obj.kind_of?(Array) + unless obj.kind_of?(Hash) || obj.kind_of?(Array) raise Chef::Exceptions::JSON::ParseError, "Top level JSON object must be a Hash or Array. (actual: #{obj.class})" end diff --git a/lib/chef/knife.rb b/lib/chef/knife.rb index 657216bcf0..a27a3b332b 100644 --- a/lib/chef/knife.rb +++ b/lib/chef/knife.rb @@ -145,6 +145,11 @@ class Chef end def self.subcommand_class_from(args) + if args.size == 1 && args[0].strip.downcase == "rehash" + # To prevent issues with the rehash file not pointing to the correct plugins, + # we always use the glob loader when regenerating the rehash file + @subcommand_loader = Chef::Knife::SubcommandLoader.gem_glob_loader(chef_config_dir) + end subcommand_loader.command_class_from(args) || subcommand_not_found!(args) end @@ -510,11 +515,12 @@ class Chef response.body end - def create_object(object, pretty_name = nil, object_class: nil, &block) + # FIXME: yard with @yield + def create_object(object, pretty_name = nil, object_class: nil) output = edit_data(object, object_class: object_class) if Kernel.block_given? - output = block.call(output) + output = yield(output) else output.save end @@ -526,11 +532,12 @@ class Chef output(output) if config[:print_after] end - def delete_object(klass, name, delete_name = nil, &block) + # FIXME: yard with @yield + def delete_object(klass, name, delete_name = nil) confirm("Do you really want to delete #{name}") if Kernel.block_given? - object = block.call + object = yield else object = klass.load(name) object.destroy diff --git a/lib/chef/knife/cookbook_bulk_delete.rb b/lib/chef/knife/cookbook_bulk_delete.rb index 6c2ad5a53f..bd1c8a22cc 100644 --- a/lib/chef/knife/cookbook_bulk_delete.rb +++ b/lib/chef/knife/cookbook_bulk_delete.rb @@ -61,7 +61,7 @@ class Chef cookbooks_names.each do |cookbook_name| versions = rest.get("cookbooks/#{cookbook_name}")[cookbook_name]["versions"].map { |v| v["version"] }.flatten versions.each do |version| - object = rest.delete("cookbooks/#{cookbook_name}/#{version}#{config[:purge] ? "?purge=true" : ""}") + rest.delete("cookbooks/#{cookbook_name}/#{version}#{config[:purge] ? "?purge=true" : ""}") ui.info("Deleted cookbook #{cookbook_name.ljust(25)} [#{version}]") end end diff --git a/lib/chef/knife/cookbook_metadata.rb b/lib/chef/knife/cookbook_metadata.rb index bfae9d8814..29eba6a36a 100644 --- a/lib/chef/knife/cookbook_metadata.rb +++ b/lib/chef/knife/cookbook_metadata.rb @@ -80,7 +80,6 @@ class Chef File.open(json_file, "w") do |f| f.write(Chef::JSONCompat.to_json_pretty(md)) end - generated = true Chef::Log.debug("Generated #{json_file}") rescue Exceptions::ObsoleteDependencySyntax, Exceptions::InvalidVersionConstraint => e ui.stderr.puts "ERROR: The cookbook '#{cookbook}' contains invalid or obsolete metadata syntax." diff --git a/lib/chef/knife/cookbook_site_download.rb b/lib/chef/knife/cookbook_site_download.rb index 2bdeea9781..7d0e21791d 100644 --- a/lib/chef/knife/cookbook_site_download.rb +++ b/lib/chef/knife/cookbook_site_download.rb @@ -98,11 +98,11 @@ class Chef end def replacement_cookbook - replacement = File.basename(current_cookbook_data["replacement"]) + File.basename(current_cookbook_data["replacement"]) end def specific_cookbook_version_url - "#{cookbooks_api_url}/#{@name_args[0]}/versions/#{@name_args[1].gsub('.', '_')}" + "#{cookbooks_api_url}/#{@name_args[0]}/versions/#{@name_args[1].tr('.', '_')}" end end end diff --git a/lib/chef/knife/cookbook_site_install.rb b/lib/chef/knife/cookbook_site_install.rb index 01374b9b36..802fdd792b 100644 --- a/lib/chef/knife/cookbook_site_install.rb +++ b/lib/chef/knife/cookbook_site_install.rb @@ -123,7 +123,7 @@ class Chef ui.error("Please specify a cookbook to download and install.") exit 1 elsif name_args.size >= 2 - unless name_args.last.match(/^(\d+)(\.\d+){1,2}$/) and name_args.size == 2 + unless name_args.last.match(/^(\d+)(\.\d+){1,2}$/) && name_args.size == 2 ui.error("Installing multiple cookbooks at once is not supported.") exit 1 end diff --git a/lib/chef/knife/cookbook_site_show.rb b/lib/chef/knife/cookbook_site_show.rb index a6a4c82c85..c0280cb318 100644 --- a/lib/chef/knife/cookbook_site_show.rb +++ b/lib/chef/knife/cookbook_site_show.rb @@ -33,7 +33,7 @@ class Chef when 1 noauth_rest.get("https://supermarket.chef.io/api/v1/cookbooks/#{@name_args[0]}") when 2 - noauth_rest.get("https://supermarket.chef.io/api/v1/cookbooks/#{@name_args[0]}/versions/#{name_args[1].gsub('.', '_')}") + noauth_rest.get("https://supermarket.chef.io/api/v1/cookbooks/#{@name_args[0]}/versions/#{name_args[1].tr('.', '_')}") end end diff --git a/lib/chef/knife/cookbook_upload.rb b/lib/chef/knife/cookbook_upload.rb index 72f7d9d2d9..6938ac280d 100644 --- a/lib/chef/knife/cookbook_upload.rb +++ b/lib/chef/knife/cookbook_upload.rb @@ -86,7 +86,7 @@ class Chef config[:cookbook_path] ||= Chef::Config[:cookbook_path] - if @name_args.empty? and ! config[:all] + if @name_args.empty? && ! config[:all] show_usage ui.fatal("You must specify the --all flag or at least one cookbook name") exit 1 diff --git a/lib/chef/knife/core/bootstrap_context.rb b/lib/chef/knife/core/bootstrap_context.rb index 7ad70bc627..48d2cb9e77 100644 --- a/lib/chef/knife/core/bootstrap_context.rb +++ b/lib/chef/knife/core/bootstrap_context.rb @@ -143,7 +143,7 @@ CONFIG # If the user doesn't have a client path configure, let bash use the PATH for what it was designed for client_path = @chef_config[:chef_client_path] || "chef-client" s = "#{client_path} -j /etc/chef/first-boot.json" - s << " -l debug" if @config[:verbosity] and @config[:verbosity] >= 2 + s << " -l debug" if @config[:verbosity] && @config[:verbosity] >= 2 s << " -E #{bootstrap_environment}" unless bootstrap_environment.nil? s << " --no-color" unless @config[:color] s @@ -182,9 +182,10 @@ CONFIG def first_boot (@config[:first_boot_attributes] || {}).tap do |attributes| if @config[:policy_name] && @config[:policy_group] - attributes.merge!(:policy_name => @config[:policy_name], :policy_group => @config[:policy_group]) + attributes[:policy_name] = @config[:policy_name] + attributes[:policy_group] = @config[:policy_group] else - attributes.merge!(:run_list => @run_list) + attributes[:run_list] = @run_list end attributes.merge!(:tags => @config[:tags]) if @config[:tags] && !@config[:tags].empty? @@ -198,7 +199,7 @@ CONFIG def trusted_certs_content content = "" if @chef_config[:trusted_certs_dir] - Dir.glob(File.join(Chef::Util::PathHelper.escape_glob(@chef_config[:trusted_certs_dir]), "*.{crt,pem}")).each do |cert| + Dir.glob(File.join(Chef::Util::PathHelper.escape_glob_dir(@chef_config[:trusted_certs_dir]), "*.{crt,pem}")).each do |cert| content << "cat > /etc/chef/trusted_certs/#{File.basename(cert)} <<'EOP'\n" + IO.read(File.expand_path(cert)) + "\nEOP\n" end diff --git a/lib/chef/knife/core/custom_manifest_loader.rb b/lib/chef/knife/core/custom_manifest_loader.rb index e5ebce2585..9fe51599af 100644 --- a/lib/chef/knife/core/custom_manifest_loader.rb +++ b/lib/chef/knife/core/custom_manifest_loader.rb @@ -61,7 +61,7 @@ class Chef end def subcommand_files - subcommand_files ||= (find_subcommands_via_manifest.values + site_subcommands).flatten.uniq + @subcommand_files ||= (find_subcommands_via_manifest.values + site_subcommands).flatten.uniq end end end diff --git a/lib/chef/knife/core/gem_glob_loader.rb b/lib/chef/knife/core/gem_glob_loader.rb index 78726feee7..f5eff26903 100644 --- a/lib/chef/knife/core/gem_glob_loader.rb +++ b/lib/chef/knife/core/gem_glob_loader.rb @@ -47,7 +47,7 @@ class Chef def find_subcommands_via_dirglob # The "require paths" of the core knife subcommands bundled with chef - files = Dir[File.join(Chef::Util::PathHelper.escape_glob(File.expand_path("../../../knife", __FILE__)), "*.rb")] + files = Dir[File.join(Chef::Util::PathHelper.escape_glob_dir(File.expand_path("../../../knife", __FILE__)), "*.rb")] subcommand_files = {} files.each do |knife_file| rel_path = knife_file[/#{CHEF_ROOT}#{Regexp.escape(File::SEPARATOR)}(.*)\.rb/, 1] @@ -82,7 +82,7 @@ class Chef if check_load_path files = $LOAD_PATH.map { |load_path| - Dir["#{File.expand_path glob, Chef::Util::PathHelper.escape_glob(load_path)}#{Gem.suffix_pattern}"] + Dir["#{File.expand_path glob, Chef::Util::PathHelper.escape_glob_dir(load_path)}#{Gem.suffix_pattern}"] }.flatten.select { |file| File.file? file.untaint } end @@ -116,7 +116,7 @@ class Chef spec.require_paths.first end - glob = File.join(Chef::Util::PathHelper.escape_glob(spec.full_gem_path, dirs), glob) + glob = File.join(Chef::Util::PathHelper.escape_glob_dir(spec.full_gem_path, dirs), glob) Dir[glob].map { |f| f.untaint } end diff --git a/lib/chef/knife/core/generic_presenter.rb b/lib/chef/knife/core/generic_presenter.rb index 61069cff48..f273cb5bca 100644 --- a/lib/chef/knife/core/generic_presenter.rb +++ b/lib/chef/knife/core/generic_presenter.rb @@ -86,7 +86,7 @@ class Chef require "stringio" # If you were looking for some attribute and there is only one match # just dump the attribute value - if config[:attribute] and data.length == 1 + if config[:attribute] && data.length == 1 data.values[0] else out = StringIO.new diff --git a/lib/chef/knife/core/hashed_command_loader.rb b/lib/chef/knife/core/hashed_command_loader.rb index 7b6c1c4c08..1165af6eb2 100644 --- a/lib/chef/knife/core/hashed_command_loader.rb +++ b/lib/chef/knife/core/hashed_command_loader.rb @@ -40,9 +40,29 @@ class Chef def list_commands(pref_category = nil) if pref_category || manifest[KEY]["plugins_by_category"].key?(pref_category) - { pref_category => manifest[KEY]["plugins_by_category"][pref_category] } + commands = { pref_category => manifest[KEY]["plugins_by_category"][pref_category] } else - manifest[KEY]["plugins_by_category"] + commands = manifest[KEY]["plugins_by_category"] + end + # If any of the specified plugins in the manifest dont have a valid path we will + # eventually get an error and the user will need to rehash - instead, lets just + # print out 1 error here telling them to rehash + errors = {} + commands.collect { |k, v| v }.flatten.each do |command| + paths = manifest[KEY]["plugins_paths"][command] + if paths && paths.is_a?(Array) + # It is only an error if all the paths don't exist + if paths.all? { |sc| !File.exists?(sc) } + errors[command] = paths + end + end + end + if errors.empty? + commands + else + Chef::Log.error "There are files specified in the manifest that are missing. Please rehash to update the subcommands cache. If you see this error after rehashing delete the cache at #{Chef::Knife::SubcommandLoader.plugin_manifest_path}" + Chef::Log.error "Missing files:\n\t#{errors.values.flatten.join("\n\t")}" + {} end end @@ -59,7 +79,6 @@ class Chef if File.exists?(sc) Kernel.load sc else - Chef::Log.error "The file #{sc} is missing for subcommand '#{subcommand_for_args(args)}'. Please rehash to update the subcommands cache." return false end end diff --git a/lib/chef/knife/core/node_editor.rb b/lib/chef/knife/core/node_editor.rb index 0f7e51cdf3..b009bf8652 100644 --- a/lib/chef/knife/core/node_editor.rb +++ b/lib/chef/knife/core/node_editor.rb @@ -96,7 +96,7 @@ class Chef # @api private def apply_updates(updated_data) - if node.name and node.name != updated_data["name"] + if node.name && node.name != updated_data["name"] ui.warn "Changing the name of a node results in a new node being created, #{node.name} will not be modified or removed." ui.confirm "Proceed with creation of new node" end diff --git a/lib/chef/knife/core/object_loader.rb b/lib/chef/knife/core/object_loader.rb index 04496933e4..b08483f9a2 100644 --- a/lib/chef/knife/core/object_loader.rb +++ b/lib/chef/knife/core/object_loader.rb @@ -71,14 +71,14 @@ class Chef # # @api public def find_all_objects(path) - path = File.join(Chef::Util::PathHelper.escape_glob(File.expand_path(path)), "*") + path = File.join(Chef::Util::PathHelper.escape_glob_dir(File.expand_path(path)), "*") path << ".{json,rb}" objects = Dir.glob(path) objects.map { |o| File.basename(o) } end def find_all_object_dirs(path) - path = File.join(Chef::Util::PathHelper.escape_glob(File.expand_path(path)), "*") + path = File.join(Chef::Util::PathHelper.escape_glob_dir(File.expand_path(path)), "*") objects = Dir.glob(path) objects.delete_if { |o| !File.directory?(o) } objects.map { |o| File.basename(o) } diff --git a/lib/chef/knife/core/subcommand_loader.rb b/lib/chef/knife/core/subcommand_loader.rb index 95ab219c80..0dcb54fc0d 100644 --- a/lib/chef/knife/core/subcommand_loader.rb +++ b/lib/chef/knife/core/subcommand_loader.rb @@ -58,6 +58,12 @@ class Chef end end + # There are certain situations where we want to shortcut the loader selection + # in self.for_config and force using the GemGlobLoader + def self.gem_glob_loader(chef_config_dir) + Knife::SubcommandLoader::GemGlobLoader.new(chef_config_dir) + end + def self.plugin_manifest? plugin_manifest_path && File.exist?(plugin_manifest_path) end @@ -118,7 +124,7 @@ class Chef load_command(cmd_words) result = Chef::Knife.subcommands[find_longest_key(Chef::Knife.subcommands, cmd_words, "_")] - result || Chef::Knife.subcommands[args.first.gsub("-", "_")] + result || Chef::Knife.subcommands[args.first.tr("-", "_")] end def guess_category(args) @@ -133,7 +139,7 @@ class Chef # def find_subcommands_via_dirglob # The "require paths" of the core knife subcommands bundled with chef - files = Dir[File.join(Chef::Util::PathHelper.escape_glob(File.expand_path("../../../knife", __FILE__)), "*.rb")] + files = Dir[File.join(Chef::Util::PathHelper.escape_glob_dir(File.expand_path("../../../knife", __FILE__)), "*.rb")] subcommand_files = {} files.each do |knife_file| rel_path = knife_file[/#{CHEF_ROOT}#{Regexp.escape(File::SEPARATOR)}(.*)\.rb/, 1] @@ -191,12 +197,12 @@ Please use Chef::Knife::SubcommandLoader.for_config(chef_config_dir, env)" user_specific_files = [] if chef_config_dir - user_specific_files.concat Dir.glob(File.expand_path("plugins/knife/*.rb", Chef::Util::PathHelper.escape_glob(chef_config_dir))) + user_specific_files.concat Dir.glob(File.expand_path("plugins/knife/*.rb", Chef::Util::PathHelper.escape_glob_dir(chef_config_dir))) end # finally search ~/.chef/plugins/knife/*.rb Chef::Util::PathHelper.home(".chef", "plugins", "knife") do |p| - user_specific_files.concat Dir.glob(File.join(Chef::Util::PathHelper.escape_glob(p), "*.rb")) + user_specific_files.concat Dir.glob(File.join(Chef::Util::PathHelper.escape_glob_dir(p), "*.rb")) end user_specific_files diff --git a/lib/chef/knife/core/ui.rb b/lib/chef/knife/core/ui.rb index 938942c173..67e431f1a7 100644 --- a/lib/chef/knife/core/ui.rb +++ b/lib/chef/knife/core/ui.rb @@ -140,7 +140,7 @@ class Chef def ask_question(question, opts = {}) question = question + "[#{opts[:default]}] " if opts[:default] - if opts[:default] and config[:defaults] + if opts[:default] && config[:defaults] opts[:default] else stdout.print question diff --git a/lib/chef/knife/data_bag_from_file.rb b/lib/chef/knife/data_bag_from_file.rb index e029ec4b22..30b9de3386 100644 --- a/lib/chef/knife/data_bag_from_file.rb +++ b/lib/chef/knife/data_bag_from_file.rb @@ -102,7 +102,7 @@ class Chef paths = Array.new args.each do |path| if File.directory?(path) - paths.concat(Dir.glob(File.join(Chef::Util::PathHelper.escape_glob(path), "*.json"))) + paths.concat(Dir.glob(File.join(Chef::Util::PathHelper.escape_glob_dir(path), "*.json"))) else paths << path end diff --git a/lib/chef/knife/rehash.rb b/lib/chef/knife/rehash.rb index 3e7bab7e0f..79286368f8 100644 --- a/lib/chef/knife/rehash.rb +++ b/lib/chef/knife/rehash.rb @@ -35,7 +35,10 @@ class Chef end def reload_plugins - Chef::Knife::SubcommandLoader::GemGlobLoader.new(@@chef_config_dir).load_commands + # The subcommand_loader for this knife command should _always_ be the GemGlobLoader. The GemGlobLoader loads + # plugins from disc and ensures the hash we write is always correct. By this point it should also already have + # loaded plugins and `load_commands` shouldn't have an effect. + Chef::Knife.subcommand_loader.load_commands end def generate_hash diff --git a/lib/chef/knife/search.rb b/lib/chef/knife/search.rb index 30a3db3cf2..520c9273af 100644 --- a/lib/chef/knife/search.rb +++ b/lib/chef/knife/search.rb @@ -177,7 +177,7 @@ class Chef # See lib/chef/search/query.rb for more examples of this. def create_result_filter(filter_string) final_filter = Hash.new - filter_string.gsub!(" ", "") + filter_string.delete!(" ") filters = filter_string.split(",") filters.each do |f| return_id, attr_path = f.split("=") diff --git a/lib/chef/knife/ssh.rb b/lib/chef/knife/ssh.rb index 4184171a4e..9c0f8936f0 100644 --- a/lib/chef/knife/ssh.rb +++ b/lib/chef/knife/ssh.rb @@ -424,7 +424,7 @@ class Chef end.join(" \\; ") end - tmux_name = "'knife ssh #{@name_args[0].gsub(/:/, '=')}'" + tmux_name = "'knife ssh #{@name_args[0].tr(':', '=')}'" begin server = session.servers_for.first cmd = ["tmux new-session -d -s #{tmux_name}", diff --git a/lib/chef/knife/ssl_check.rb b/lib/chef/knife/ssl_check.rb index 6dac06b27b..0995fc8a54 100644 --- a/lib/chef/knife/ssl_check.rb +++ b/lib/chef/knife/ssl_check.rb @@ -50,7 +50,7 @@ class Chef end def given_uri - (name_args[0] or Chef::Config.chef_server_url) + (name_args[0] || Chef::Config.chef_server_url) end def host diff --git a/lib/chef/knife/ssl_fetch.rb b/lib/chef/knife/ssl_fetch.rb index f694a46ac6..5af1a905d5 100644 --- a/lib/chef/knife/ssl_fetch.rb +++ b/lib/chef/knife/ssl_fetch.rb @@ -47,7 +47,7 @@ class Chef end def given_uri - (name_args[0] or Chef::Config.chef_server_url) + (name_args[0] || Chef::Config.chef_server_url) end def host diff --git a/lib/chef/knife/status.rb b/lib/chef/knife/status.rb index e7a7165faa..551d5addfc 100644 --- a/lib/chef/knife/status.rb +++ b/lib/chef/knife/status.rb @@ -98,9 +98,9 @@ class Chef output(all_nodes.sort { |n1, n2| if config[:sort_reverse] || Chef::Config[:knife][:sort_status_reverse] - (n2["ohai_time"] or 0) <=> (n1["ohai_time"] or 0) + (n2["ohai_time"] || 0) <=> (n1["ohai_time"] || 0) else - (n1["ohai_time"] or 0) <=> (n2["ohai_time"] or 0) + (n1["ohai_time"] || 0) <=> (n2["ohai_time"] || 0) end }) end diff --git a/lib/chef/log.rb b/lib/chef/log.rb index bfb5829be6..ac2baeb9d1 100644 --- a/lib/chef/log.rb +++ b/lib/chef/log.rb @@ -48,7 +48,7 @@ class Chef # Pick the first caller that is *not* part of the Chef gem, that's the # thing the user wrote. chef_gem_path = File.expand_path("../..", __FILE__) - caller(0..20).select { |c| !c.start_with?(chef_gem_path) }.first + caller(0..20).find { |c| !c.start_with?(chef_gem_path) } end def self.deprecation(msg = nil, location = caller(2..2)[0], &block) diff --git a/lib/chef/mixin/command.rb b/lib/chef/mixin/command.rb index 257ed11221..0cc3143ec7 100644 --- a/lib/chef/mixin/command.rb +++ b/lib/chef/mixin/command.rb @@ -177,13 +177,14 @@ class Chef # module_function :popen4 - def chdir_or_tmpdir(dir, &block) + # FIXME: yard with @yield + def chdir_or_tmpdir(dir) dir ||= Dir.tmpdir unless File.directory?(dir) raise Chef::Exceptions::Exec, "#{dir} does not exist or is not a directory" end Dir.chdir(dir) do - block.call + yield end end diff --git a/lib/chef/mixin/params_validate.rb b/lib/chef/mixin/params_validate.rb index 598c6c3c23..b16df41c8e 100644 --- a/lib/chef/mixin/params_validate.rb +++ b/lib/chef/mixin/params_validate.rb @@ -466,7 +466,7 @@ class Chef # "value nil" and to keep default stickiness working exactly the same # @api private class SetOrReturnProperty < Chef::Property - def get(resource) + def get(resource, nil_set: false) value = super # All values are sticky, frozen or not if !is_set?(resource) @@ -478,7 +478,7 @@ class Chef def call(resource, value = NOT_PASSED) # setting to nil does a get if value.nil? && !explicitly_accepts_nil?(resource) - get(resource) + get(resource, nil_set: true) else super end diff --git a/lib/chef/mixin/properties.rb b/lib/chef/mixin/properties.rb index 2e33d2d0e7..ae2406f1ae 100644 --- a/lib/chef/mixin/properties.rb +++ b/lib/chef/mixin/properties.rb @@ -95,10 +95,11 @@ class Chef def property(name, type = NOT_PASSED, **options) name = name.to_sym - options.each { |k, v| options[k.to_sym] = v if k.is_a?(String) } + options = options.inject({}) { |memo, (key, value)| memo[key.to_sym] = value; memo } options[:instance_variable_name] = :"@#{name}" if !options.has_key?(:instance_variable_name) - options.merge!(name: name, declared_in: self) + options[:name] = name + options[:declared_in] = self if type == NOT_PASSED # If a type is not passed, the property derives from the diff --git a/lib/chef/mixin/provides.rb b/lib/chef/mixin/provides.rb index 34a078c010..43a726de8c 100644 --- a/lib/chef/mixin/provides.rb +++ b/lib/chef/mixin/provides.rb @@ -7,12 +7,13 @@ class Chef # TODO no longer needed, remove or deprecate? include Chef::Mixin::DescendantsTracker - def provides(short_name, opts = {}, &block) + def provides(short_name, opts = {}) raise NotImplementedError, :provides end # Check whether this resource provides the resource_name DSL for the given # node. TODO remove this when we stop checking unregistered things. + # FIXME: yard with @yield def provides?(node, resource) raise NotImplementedError, :provides? end diff --git a/lib/chef/mixin/template.rb b/lib/chef/mixin/template.rb index c423ccaa42..b10e036c4e 100644 --- a/lib/chef/mixin/template.rb +++ b/lib/chef/mixin/template.rb @@ -186,7 +186,7 @@ class Chef module_names.each do |mod| context_methods = [:node, :render, :render_template, :render_template_from_string] context_methods.each do |core_method| - if mod.method_defined?(core_method) or mod.private_method_defined?(core_method) + if mod.method_defined?(core_method) || mod.private_method_defined?(core_method) Chef::Log.warn("Core template method `#{core_method}' overridden by extension module #{mod}") end end diff --git a/lib/chef/mixin/why_run.rb b/lib/chef/mixin/why_run.rb index b2aa5949c0..ea62527bdd 100644 --- a/lib/chef/mixin/why_run.rb +++ b/lib/chef/mixin/why_run.rb @@ -49,7 +49,7 @@ class Chef def add_action(descriptions, &block) @actions << [descriptions, block] if (@resource.respond_to?(:is_guard_interpreter) && @resource.is_guard_interpreter) || !Chef::Config[:why_run] - block.call + yield end events.resource_update_applied(@resource, @action, descriptions) end @@ -319,7 +319,7 @@ class Chef def run(action) @assertions[action.to_sym].each do |a| a.run(action, events, @resource) - if a.assertion_failed? and a.block_action? + if a.assertion_failed? && a.block_action? @blocked_actions << action break end diff --git a/lib/chef/mixin/wide_string.rb b/lib/chef/mixin/wide_string.rb index 4566bdd382..4342ef1650 100644 --- a/lib/chef/mixin/wide_string.rb +++ b/lib/chef/mixin/wide_string.rb @@ -34,7 +34,7 @@ class Chef ustring = (ustring + "").force_encoding("UTF-8") if ustring.respond_to?(:force_encoding) && ustring.encoding.name != "UTF-8" # ensure we have the double-null termination Windows Wide likes - ustring = ustring + "\000\000" if ustring.length == 0 or ustring[-1].chr != "\000" + ustring = ustring + "\000\000" if ustring.length == 0 || ustring[-1].chr != "\000" # encode it all as UTF-16LE AKA Windows Wide Character AKA Windows Unicode ustring = begin diff --git a/lib/chef/monkey_patches/net-ssh-multi.rb b/lib/chef/monkey_patches/net-ssh-multi.rb index b0d05a0b27..7b7b1bbf7f 100644 --- a/lib/chef/monkey_patches/net-ssh-multi.rb +++ b/lib/chef/monkey_patches/net-ssh-multi.rb @@ -119,7 +119,8 @@ if Net::SSH::Multi::Version::STRING == "1.1.0" || Net::SSH::Multi::Version::STRI count = concurrent_connections ? (concurrent_connections - open_connections) : @pending_sessions.length count.times do - session = @pending_sessions.pop or break + session = @pending_sessions.pop + break unless session # ===== PATCH START # Increment the open_connections count here to prevent # creation of connection thread again before that is diff --git a/lib/chef/monologger.rb b/lib/chef/monologger.rb index 49f744e314..8bcdae1293 100644 --- a/lib/chef/monologger.rb +++ b/lib/chef/monologger.rb @@ -42,7 +42,7 @@ class MonoLogger < Logger def initialize(log = nil) @dev = @filename = @shift_age = @shift_size = nil - if log.respond_to?(:write) and log.respond_to?(:close) + if log.respond_to?(:write) && log.respond_to?(:close) @dev = log else @dev = open_logfile(log) diff --git a/lib/chef/policy_builder/dynamic.rb b/lib/chef/policy_builder/dynamic.rb index c6c7deeee6..389f124f84 100644 --- a/lib/chef/policy_builder/dynamic.rb +++ b/lib/chef/policy_builder/dynamic.rb @@ -139,7 +139,7 @@ class Chef # # @return [PolicyBuilder::Policyfile, PolicyBuilder::ExpandNodeObject] def implementation - @implementation or raise Exceptions::InvalidPolicybuilderCall, "#load_node must be called before other policy builder methods" + @implementation || raise(Exceptions::InvalidPolicybuilderCall, "#load_node must be called before other policy builder methods") end # @api private diff --git a/lib/chef/policy_builder/expand_node_object.rb b/lib/chef/policy_builder/expand_node_object.rb index 6a006ec992..980de60dd5 100644 --- a/lib/chef/policy_builder/expand_node_object.rb +++ b/lib/chef/policy_builder/expand_node_object.rb @@ -3,7 +3,7 @@ # Author:: Tim Hinderliter (<tim@chef.io>) # Author:: Christopher Walters (<cw@chef.io>) # Author:: Daniel DeLeo (<dan@chef.io>) -# Copyright:: Copyright 2008-2016, Chef Software, Inc. +# Copyright:: Copyright 2008-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -75,12 +75,16 @@ class Chef cl.load_cookbooks cookbook_collection = Chef::CookbookCollection.new(cl) cookbook_collection.validate! + cookbook_collection.install_gems(events) + run_context = Chef::RunContext.new(node, cookbook_collection, @events) else Chef::Cookbook::FileVendor.fetch_from_remote(api_service) cookbook_hash = sync_cookbooks cookbook_collection = Chef::CookbookCollection.new(cookbook_hash) cookbook_collection.validate! + cookbook_collection.install_gems(events) + run_context = Chef::RunContext.new(node, cookbook_collection, @events) end diff --git a/lib/chef/policy_builder/policyfile.rb b/lib/chef/policy_builder/policyfile.rb index 679e3cfe47..05e5c2f3ef 100644 --- a/lib/chef/policy_builder/policyfile.rb +++ b/lib/chef/policy_builder/policyfile.rb @@ -3,7 +3,7 @@ # Author:: Tim Hinderliter (<tim@chef.io>) # Author:: Christopher Walters (<cw@chef.io>) # Author:: Daniel DeLeo (<dan@chef.io>) -# Copyright:: Copyright 2008-2016, Chef Software, Inc. +# Copyright:: Copyright 2008-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -153,6 +153,8 @@ class Chef sync_cookbooks cookbook_collection = Chef::CookbookCollection.new(cookbooks_to_sync) cookbook_collection.validate! + cookbook_collection.install_gems(events) + run_context = Chef::RunContext.new(node, cookbook_collection, events) setup_chef_class(run_context) @@ -254,10 +256,9 @@ class Chef # @api private def run_list if named_run_list_requested? - named_run_list or - raise ConfigurationError, + named_run_list || raise(ConfigurationError, "Policy '#{retrieved_policy_name}' revision '#{revision_id}' does not have named_run_list '#{named_run_list_name}'" + - "(available named_run_lists: [#{available_named_run_lists.join(', ')}])" + "(available named_run_lists: [#{available_named_run_lists.join(', ')}])") else policy["run_list"] end @@ -319,17 +320,14 @@ class Chef # @api private def deployment_group - Chef::Config[:deployment_group] or - raise ConfigurationError, "Setting `deployment_group` is not configured." + Chef::Config[:deployment_group] || raise(ConfigurationError, "Setting `deployment_group` is not configured.") end # @api private def validate_policy_config! - policy_group or - raise ConfigurationError, "Setting `policy_group` is not configured." + raise ConfigurationError, "Setting `policy_group` is not configured." unless policy_group - policy_name or - raise ConfigurationError, "Setting `policy_name` is not configured." + raise ConfigurationError, "Setting `policy_name` is not configured." unless policy_name end # @api private diff --git a/lib/chef/property.rb b/lib/chef/property.rb index 0230c8b23b..c36daa821a 100644 --- a/lib/chef/property.rb +++ b/lib/chef/property.rb @@ -87,7 +87,7 @@ class Chef # is fully initialized. # def initialize(**options) - options.each { |k, v| options[k.to_sym] = v; options.delete(k) if k.is_a?(String) } + options = options.inject({}) { |memo, (key, value)| memo[key.to_sym] = value; memo } @options = options options[:name] = options[:name].to_sym if options[:name] options[:instance_variable_name] = options[:instance_variable_name].to_sym if options[:instance_variable_name] @@ -266,7 +266,7 @@ class Chef # In Chef 12, value(nil) does a *get* instead of a set, so we # warn if the value would have been changed. In Chef 13, it will be # equivalent to value = nil. - result = get(resource) + result = get(resource, nil_set: true) # Warn about this becoming a set in Chef 13. begin @@ -311,7 +311,7 @@ class Chef # @raise Chef::Exceptions::ValidationFailed If the value is invalid for # this property, or if the value is required and not set. # - def get(resource) + def get(resource, nil_set: false) # If it's set, return it (and evaluate any lazy values) if is_set?(resource) value = get_value(resource) @@ -335,7 +335,8 @@ class Chef # # It won't do what they expect. This checks whether you try to *read* # `content` while we are compiling the resource. - if resource.respond_to?(:resource_initializing) && + if !nil_set && + resource.respond_to?(:resource_initializing) && resource.resource_initializing && resource.respond_to?(:enclosing_provider) && resource.enclosing_provider && diff --git a/lib/chef/provider/deploy.rb b/lib/chef/provider/deploy.rb index 7274ab2e8f..4c758033ac 100644 --- a/lib/chef/provider/deploy.rb +++ b/lib/chef/provider/deploy.rb @@ -242,7 +242,7 @@ class Chef end def all_releases - Dir.glob(Chef::Util::PathHelper.escape_glob(@new_resource.deploy_to) + "/releases/*").sort + Dir.glob(Chef::Util::PathHelper.escape_glob_dir(@new_resource.deploy_to) + "/releases/*").sort end def update_cached_repo diff --git a/lib/chef/provider/deploy/revision.rb b/lib/chef/provider/deploy/revision.rb index 9e2bb94f5b..f61e439486 100644 --- a/lib/chef/provider/deploy/revision.rb +++ b/lib/chef/provider/deploy/revision.rb @@ -44,7 +44,7 @@ class Chef known_releases = sorted_releases - Dir["#{Chef::Util::PathHelper.escape_glob(new_resource.deploy_to)}/releases/*"].each do |release_dir| + Dir["#{Chef::Util::PathHelper.escape_glob_dir(new_resource.deploy_to)}/releases/*"].each do |release_dir| unless known_releases.include?(release_dir) converge_by("Remove unknown release in #{release_dir}") do FileUtils.rm_rf(release_dir) @@ -87,7 +87,7 @@ class Chef end def sorted_releases_from_filesystem - Dir.glob(Chef::Util::PathHelper.escape_glob(new_resource.deploy_to) + "/releases/*").sort_by { |d| ::File.ctime(d) } + Dir.glob(Chef::Util::PathHelper.escape_glob_dir(new_resource.deploy_to) + "/releases/*").sort_by { |d| ::File.ctime(d) } end def load_cache diff --git a/lib/chef/provider/git.rb b/lib/chef/provider/git.rb index 4f17da0288..82f5ca2ba5 100644 --- a/lib/chef/provider/git.rb +++ b/lib/chef/provider/git.rb @@ -143,7 +143,7 @@ class Chef args = [] args << "-o #{remote}" unless remote == "origin" args << "--depth #{@new_resource.depth}" if @new_resource.depth - args << "--no-single-branch" if @new_resource.depth and git_minor_version >= Gem::Version.new("1.7.10") + args << "--no-single-branch" if @new_resource.depth && git_minor_version >= Gem::Version.new("1.7.10") Chef::Log.info "#{@new_resource} cloning repo #{@new_resource.repository} to #{@new_resource.destination}" diff --git a/lib/chef/provider/ifconfig.rb b/lib/chef/provider/ifconfig.rb index e73869d829..4cfb257bb9 100644 --- a/lib/chef/provider/ifconfig.rb +++ b/lib/chef/provider/ifconfig.rb @@ -168,7 +168,7 @@ class Chef end def can_generate_config? - ! @config_template.nil? and ! @config_path.nil? + ! @config_template.nil? && ! @config_path.nil? end def resource_for_config(path) diff --git a/lib/chef/provider/link.rb b/lib/chef/provider/link.rb index d184094bbb..5fce97e5b3 100644 --- a/lib/chef/provider/link.rb +++ b/lib/chef/provider/link.rb @@ -74,8 +74,8 @@ class Chef requirements.assert(:delete) do |a| a.assertion do if @current_resource.to - @current_resource.link_type == @new_resource.link_type and - (@current_resource.link_type == :symbolic or @current_resource.to != "") + @current_resource.link_type == @new_resource.link_type && + (@current_resource.link_type == :symbolic || @current_resource.to != "") else true end @@ -86,7 +86,7 @@ class Chef end def canonicalize(path) - Chef::Platform.windows? ? path.gsub("/", '\\') : path + Chef::Platform.windows? ? path.tr("/", '\\') : path end def action_create diff --git a/lib/chef/provider/mount/mount.rb b/lib/chef/provider/mount/mount.rb index 265911b54c..07da6ac361 100644 --- a/lib/chef/provider/mount/mount.rb +++ b/lib/chef/provider/mount/mount.rb @@ -133,7 +133,7 @@ class Chef end def remount_fs - if @current_resource.mounted and @new_resource.supports[:remount] + if @current_resource.mounted && @new_resource.supports[:remount] shell_out!(remount_command) @new_resource.updated_by_last_action(true) Chef::Log.debug("#{@new_resource} is remounted at #{@new_resource.mount_point}") @@ -193,7 +193,7 @@ class Chef def device_should_exist? ( @new_resource.device != "none" ) && ( not network_device? ) && - ( not %w{ cgroup tmpfs fuse }.include? @new_resource.fstype ) + ( not %w{ cgroup tmpfs fuse vboxsf }.include? @new_resource.fstype ) end private @@ -258,9 +258,9 @@ class Chef end def mount_options_unchanged? - @current_resource.fstype == @new_resource.fstype and - @current_resource.options == @new_resource.options and - @current_resource.dump == @new_resource.dump and + @current_resource.fstype == @new_resource.fstype && + @current_resource.options == @new_resource.options && + @current_resource.dump == @new_resource.dump && @current_resource.pass == @new_resource.pass end diff --git a/lib/chef/provider/mount/windows.rb b/lib/chef/provider/mount/windows.rb index 3ffe326cac..0fb5aa7645 100644 --- a/lib/chef/provider/mount/windows.rb +++ b/lib/chef/provider/mount/windows.rb @@ -80,6 +80,12 @@ class Chef end end + private + + def mount_options_unchanged? + @current_resource.device == @new_resource.device + end + end end end diff --git a/lib/chef/provider/osx_profile.rb b/lib/chef/provider/osx_profile.rb index 3e37cbc9a5..6ac67e0560 100644 --- a/lib/chef/provider/osx_profile.rb +++ b/lib/chef/provider/osx_profile.rb @@ -68,15 +68,15 @@ class Chef requirements.assert(:remove) do |a| if @new_profile_identifier a.assertion { - !@new_profile_identifier.nil? and - !@new_profile_identifier.end_with?(".mobileconfig") and + !@new_profile_identifier.nil? && + !@new_profile_identifier.end_with?(".mobileconfig") && /^\w+(?:\.\w+)+$/.match(@new_profile_identifier) } a.failure_message RuntimeError, "when removing using the identifier attribute, it must match the profile identifier" else new_profile_name = @new_resource.profile_name a.assertion { - !new_profile_name.end_with?(".mobileconfig") and + !new_profile_name.end_with?(".mobileconfig") && /^\w+(?:\.\w+)+$/.match(new_profile_name) } a.failure_message RuntimeError, "When removing by resource name, it must match the profile identifier " @@ -239,7 +239,7 @@ class Chef def profile_installed? # Profile Identifier and UUID must match a currently installed profile - if @current_resource.profile.nil? or @current_resource.profile.empty? + if @current_resource.profile.nil? || @current_resource.profile.empty? false else if @new_resource.action.include?(:remove) diff --git a/lib/chef/provider/package/freebsd/pkg.rb b/lib/chef/provider/package/freebsd/pkg.rb index b42bd62c61..78d9449454 100644 --- a/lib/chef/provider/package/freebsd/pkg.rb +++ b/lib/chef/provider/package/freebsd/pkg.rb @@ -88,7 +88,7 @@ class Chef end def file_candidate_version_path - Dir[Chef::Util::PathHelper.escape_glob("#{@new_resource.source}/#{@current_resource.package_name}") + "*"][-1].to_s + Dir[Chef::Util::PathHelper.escape_glob_dir("#{@new_resource.source}/#{@current_resource.package_name}") + "*"][-1].to_s end def file_candidate_version diff --git a/lib/chef/provider/package/homebrew.rb b/lib/chef/provider/package/homebrew.rb index c032881e70..853a354b28 100644 --- a/lib/chef/provider/package/homebrew.rb +++ b/lib/chef/provider/package/homebrew.rb @@ -53,7 +53,7 @@ class Chef def upgrade_package(name, version) current_version = current_resource.version - if current_version.nil? or current_version.empty? + if current_version.nil? || current_version.empty? install_package(name, version) elsif current_version != version brew("upgrade", new_resource.options, name) diff --git a/lib/chef/provider/package/ips.rb b/lib/chef/provider/package/ips.rb index dc83e4aa08..85053d47f2 100644 --- a/lib/chef/provider/package/ips.rb +++ b/lib/chef/provider/package/ips.rb @@ -69,7 +69,7 @@ class Chef package_name = "#{name}@#{version}" normal_command = "pkg#{expand_options(@new_resource.options)} install -q #{package_name}" command = - if @new_resource.respond_to?(:accept_license) and @new_resource.accept_license + if @new_resource.respond_to?(:accept_license) && @new_resource.accept_license normal_command.gsub("-q", "-q --accept") else normal_command diff --git a/lib/chef/provider/package/macports.rb b/lib/chef/provider/package/macports.rb index b110207d8a..7bbc68aba8 100644 --- a/lib/chef/provider/package/macports.rb +++ b/lib/chef/provider/package/macports.rb @@ -15,7 +15,7 @@ class Chef @candidate_version = macports_candidate_version - if !@new_resource.version and !@candidate_version + if !@new_resource.version && !@candidate_version raise Chef::Exceptions::Package, "Could not get a candidate version for this package -- #{@new_resource.name} does not seem to be a valid package!" end @@ -48,20 +48,20 @@ class Chef def install_package(name, version) unless @current_resource.version == version command = "port#{expand_options(@new_resource.options)} install #{name}" - command << " @#{version}" if version and !version.empty? + command << " @#{version}" if version && !version.empty? shell_out_with_timeout!(command) end end def purge_package(name, version) command = "port#{expand_options(@new_resource.options)} uninstall #{name}" - command << " @#{version}" if version and !version.empty? + command << " @#{version}" if version && !version.empty? shell_out_with_timeout!(command) end def remove_package(name, version) command = "port#{expand_options(@new_resource.options)} deactivate #{name}" - command << " @#{version}" if version and !version.empty? + command << " @#{version}" if version && !version.empty? shell_out_with_timeout!(command) end @@ -71,7 +71,7 @@ class Chef # happens otherwise... current_version = @current_resource.version - if current_version.nil? or current_version.empty? + if current_version.nil? || current_version.empty? # Macports doesn't like when you upgrade a package # that hasn't been installed. install_package(name, version) diff --git a/lib/chef/provider/package/portage.rb b/lib/chef/provider/package/portage.rb index a514dcc66c..7c52e43bff 100644 --- a/lib/chef/provider/package/portage.rb +++ b/lib/chef/provider/package/portage.rb @@ -37,8 +37,8 @@ class Chef category, pkg = %r{^#{PACKAGE_NAME_PATTERN}$}.match(@new_resource.package_name)[1, 2] - globsafe_category = category ? Chef::Util::PathHelper.escape_glob(category) : nil - globsafe_pkg = Chef::Util::PathHelper.escape_glob(pkg) + globsafe_category = category ? Chef::Util::PathHelper.escape_glob_dir(category) : nil + globsafe_pkg = Chef::Util::PathHelper.escape_glob_dir(pkg) possibilities = Dir["/var/db/pkg/#{globsafe_category || "*"}/#{globsafe_pkg}-*"].map { |d| d.sub(%r{/var/db/pkg/}, "") } versions = possibilities.map do |entry| if entry =~ %r{[^/]+/#{Regexp.escape(pkg)}\-(\d[\.\d]*((_(alpha|beta|pre|rc|p)\d*)*)?(-r\d+)?)} @@ -66,7 +66,7 @@ class Chef txt.each_line do |line| if line =~ /\*\s+#{PACKAGE_NAME_PATTERN}/ - found_package_name = $&.gsub(/\*/, "").strip + found_package_name = $&.delete("*").strip if package =~ /\// #the category is specified if found_package_name == package availables[found_package_name] = nil diff --git a/lib/chef/provider/package/rubygems.rb b/lib/chef/provider/package/rubygems.rb index 7a2db6b32b..39eff19bd0 100644 --- a/lib/chef/provider/package/rubygems.rb +++ b/lib/chef/provider/package/rubygems.rb @@ -115,7 +115,7 @@ class Chef # Compatibility note: Rubygems 1.x uses Gem::Format, 2.0 moved this # code into Gem::Package. def spec_from_file(file) - if defined?(Gem::Format) and Gem::Package.respond_to?(:open) + if defined?(Gem::Format) && Gem::Package.respond_to?(:open) Gem::Format.from_file_by_path(file).spec else Gem::Package.new(file).spec @@ -410,7 +410,7 @@ class Chef def find_gem_by_path Chef::Log.debug("#{@new_resource} searching for 'gem' binary in path: #{ENV['PATH']}") separator = ::File::ALT_SEPARATOR ? ::File::ALT_SEPARATOR : ::File::SEPARATOR - path_to_first_gem = ENV["PATH"].split(::File::PATH_SEPARATOR).select { |path| ::File.exists?(path + separator + "gem") }.first + path_to_first_gem = ENV["PATH"].split(::File::PATH_SEPARATOR).find { |path| ::File.exists?(path + separator + "gem") } raise Chef::Exceptions::FileNotFound, "Unable to find 'gem' binary in path: #{ENV['PATH']}" if path_to_first_gem.nil? path_to_first_gem + separator + "gem" end @@ -535,7 +535,7 @@ class Chef src = " --clear-sources" src << (@new_resource.source && " --source=#{@new_resource.source}" || "") else - src = @new_resource.source && " --source=#{@new_resource.source} --source=https://rubygems.org" + src = @new_resource.source && " --source=#{@new_resource.source} --source=#{Chef::Config[:rubygems_url]}" end if !version.nil? && version.length > 0 shell_out_with_timeout!("#{gem_binary_path} install #{name} -q --no-rdoc --no-ri -v \"#{version}\"#{src}#{opts}", :env => nil) diff --git a/lib/chef/provider/package/yum.rb b/lib/chef/provider/package/yum.rb index 858b430abe..dfd32fde55 100644 --- a/lib/chef/provider/package/yum.rb +++ b/lib/chef/provider/package/yum.rb @@ -73,17 +73,17 @@ class Chef # verify def isalnum(x) - isalpha(x) or isdigit(x) + isalpha(x) || isdigit(x) end def isalpha(x) v = x.ord - (v >= 65 and v <= 90) or (v >= 97 and v <= 122) + (v >= 65 && v <= 90) || (v >= 97 && v <= 122) end def isdigit(x) v = x.ord - v >= 48 and v <= 57 + v >= 48 && v <= 57 end # based on the reference spec in lib/rpmvercmp.c in rpm 4.9.0 @@ -128,17 +128,17 @@ class Chef y_pos_max = y.length - 1 y_comp = nil - while x_pos <= x_pos_max and y_pos <= y_pos_max + while x_pos <= x_pos_max && y_pos <= y_pos_max # first we skip over anything non alphanumeric - while (x_pos <= x_pos_max) and (isalnum(x[x_pos]) == false) + while (x_pos <= x_pos_max) && (isalnum(x[x_pos]) == false) x_pos += 1 # +1 over pos_max if end of string end - while (y_pos <= y_pos_max) and (isalnum(y[y_pos]) == false) + while (y_pos <= y_pos_max) && (isalnum(y[y_pos]) == false) y_pos += 1 end # if we hit the end of either we are done matching segments - if (x_pos == x_pos_max + 1) or (y_pos == y_pos_max + 1) + if (x_pos == x_pos_max + 1) || (y_pos == y_pos_max + 1) break end @@ -154,14 +154,14 @@ class Chef x_seg_pos += 1 # gather up our digits - while (x_seg_pos <= x_pos_max) and isdigit(x[x_seg_pos]) + while (x_seg_pos <= x_pos_max) && isdigit(x[x_seg_pos]) x_seg_pos += 1 end # copy the segment but not the unmatched character that x_seg_pos will # refer to x_comp = x[x_pos, x_seg_pos - x_pos] - while (y_seg_pos <= y_pos_max) and isdigit(y[y_seg_pos]) + while (y_seg_pos <= y_pos_max) && isdigit(y[y_seg_pos]) y_seg_pos += 1 end y_comp = y[y_pos, y_seg_pos - y_pos] @@ -169,12 +169,12 @@ class Chef # we are comparing strings x_seg_is_num = false - while (x_seg_pos <= x_pos_max) and isalpha(x[x_seg_pos]) + while (x_seg_pos <= x_pos_max) && isalpha(x[x_seg_pos]) x_seg_pos += 1 end x_comp = x[x_pos, x_seg_pos - x_pos] - while (y_seg_pos <= y_pos_max) and isalpha(y[y_seg_pos]) + while (y_seg_pos <= y_pos_max) && isalpha(y[y_seg_pos]) y_seg_pos += 1 end y_comp = y[y_pos, y_seg_pos - y_pos] @@ -213,7 +213,7 @@ class Chef # segments matched completely but the segment separators were different - # rpm reference code treats these as equal. - if (x_pos == x_pos_max + 1) and (y_pos == y_pos_max + 1) + if (x_pos == x_pos_max + 1) && (y_pos == y_pos_max + 1) return 0 end @@ -290,11 +290,11 @@ class Chef x = self # compare epoch - if (x.e.nil? == false and x.e > 0) and y.e.nil? + if (x.e.nil? == false && x.e > 0) && y.e.nil? return 1 - elsif x.e.nil? and (y.e.nil? == false and y.e > 0) + elsif x.e.nil? && (y.e.nil? == false && y.e > 0) return -1 - elsif x.e.nil? == false and y.e.nil? == false + elsif x.e.nil? == false && y.e.nil? == false if x.e < y.e return -1 elsif x.e > y.e @@ -303,25 +303,25 @@ class Chef end # compare version - if partial and (x.v.nil? or y.v.nil?) + if partial && (x.v.nil? || y.v.nil?) return 0 - elsif x.v.nil? == false and y.v.nil? + elsif x.v.nil? == false && y.v.nil? return 1 - elsif x.v.nil? and y.v.nil? == false + elsif x.v.nil? && y.v.nil? == false return -1 - elsif x.v.nil? == false and y.v.nil? == false + elsif x.v.nil? == false && y.v.nil? == false cmp = RPMUtils.rpmvercmp(x.v, y.v) return cmp if cmp != 0 end # compare release - if partial and (x.r.nil? or y.r.nil?) + if partial && (x.r.nil? || y.r.nil?) return 0 - elsif x.r.nil? == false and y.r.nil? + elsif x.r.nil? == false && y.r.nil? return 1 - elsif x.r.nil? and y.r.nil? == false + elsif x.r.nil? && y.r.nil? == false return -1 - elsif x.r.nil? == false and y.r.nil? == false + elsif x.r.nil? == false && y.r.nil? == false cmp = RPMUtils.rpmvercmp(x.r, y.r) return cmp end @@ -372,11 +372,11 @@ class Chef return 0 if x.nevra == y.nevra # compare name - if x.n.nil? == false and y.n.nil? + if x.n.nil? == false && y.n.nil? return 1 - elsif x.n.nil? and y.n.nil? == false + elsif x.n.nil? && y.n.nil? == false return -1 - elsif x.n.nil? == false and y.n.nil? == false + elsif x.n.nil? == false && y.n.nil? == false if x.n < y.n return -1 elsif x.n > y.n @@ -392,11 +392,11 @@ class Chef end # compare arch - if x.a.nil? == false and y.a.nil? + if x.a.nil? == false && y.a.nil? return 1 - elsif x.a.nil? and y.a.nil? == false + elsif x.a.nil? && y.a.nil? == false return -1 - elsif x.a.nil? == false and y.a.nil? == false + elsif x.a.nil? == false && y.a.nil? == false if x.a < y.a return -1 elsif x.a > y.a @@ -478,14 +478,14 @@ class Chef sense = x.version.partial_compare(y.version) # Thanks to rpmdsCompare() rpmds.c - if sense < 0 and (x.flag == :> || x.flag == :>=) || (y.flag == :<= || y.flag == :<) + if (sense < 0) && ((x.flag == :> || x.flag == :>=) || (y.flag == :<= || y.flag == :<)) return true - elsif sense > 0 and (x.flag == :< || x.flag == :<=) || (y.flag == :>= || y.flag == :>) + elsif (sense > 0) && ((x.flag == :< || x.flag == :<=) || (y.flag == :>= || y.flag == :>)) return true - elsif sense == 0 and ( - ((x.flag == :== or x.flag == :<= or x.flag == :>=) and (y.flag == :== or y.flag == :<= or y.flag == :>=)) or - (x.flag == :< and y.flag == :<) or - (x.flag == :> and y.flag == :>) + elsif sense == 0 && ( + ((x.flag == :== || x.flag == :<= || x.flag == :>=) && (y.flag == :== || y.flag == :<= || y.flag == :>=)) || + (x.flag == :< && y.flag == :<) || + (x.flag == :> && y.flag == :>) ) return true end @@ -1340,7 +1340,7 @@ class Chef old_candidate = @yum.candidate_version(package_name) new_installed = @yum.installed_version(new_package_name, new_arch) new_candidate = @yum.candidate_version(new_package_name, new_arch) - if (old_installed.nil? and old_candidate.nil?) and (new_installed or new_candidate) + if (old_installed.nil? && old_candidate.nil?) && (new_installed || new_candidate) Chef::Log.debug("Parsed out arch #{new_arch}, new package name is #{new_package_name}") return new_package_name, new_arch end @@ -1378,7 +1378,7 @@ class Chef if packages.empty? # Don't bother if we are just ensuring a package is removed - we don't need Provides data actions = Array(@new_resource.action) - unless actions.size == 1 and (actions[0] == :remove || actions[0] == :purge) + unless actions.size == 1 && (actions[0] == :remove || actions[0] == :purge) Chef::Log.debug("#{@new_resource} couldn't match #{@new_resource.package_name} in " + "installed Provides, loading available Provides - this may take a moment") @yum.reload_provides diff --git a/lib/chef/provider/registry_key.rb b/lib/chef/provider/registry_key.rb index 2e00fd08e1..e516433ac8 100644 --- a/lib/chef/provider/registry_key.rb +++ b/lib/chef/provider/registry_key.rb @@ -83,7 +83,7 @@ class Chef #If keys missing in the path and recursive == false a.assertion { !registry.keys_missing?(@current_resource.key) || @new_resource.recursive } a.failure_message(Chef::Exceptions::Win32RegNoRecursive, "Intermediate keys missing but recursive is set to false") - a.whyrun("Intermediate keys in #{@new_resource.key} go not exist. Unless they would have been created earlier, attempt to modify them would fail.") + a.whyrun("Intermediate keys in #{@new_resource.key} do not exist. Unless they would have been created earlier, attempt to modify them would fail.") end requirements.assert(:delete_key) do |a| #If key to be deleted has subkeys but recurssive == false diff --git a/lib/chef/provider/remote_directory.rb b/lib/chef/provider/remote_directory.rb index b592b13ccf..e3bc579107 100644 --- a/lib/chef/provider/remote_directory.rb +++ b/lib/chef/provider/remote_directory.rb @@ -104,7 +104,7 @@ class Chef # def purge_unmanaged_files if purge - Dir.glob(::File.join(Chef::Util::PathHelper.escape_glob(path), "**", "*"), ::File::FNM_DOTMATCH).sort!.reverse!.each do |file| + Dir.glob(::File.join(Chef::Util::PathHelper.escape_glob_dir(path), "**", "*"), ::File::FNM_DOTMATCH).sort!.reverse!.each do |file| # skip '.' and '..' next if [".", ".."].include?(Pathname.new(file).basename().to_s) diff --git a/lib/chef/provider/remote_file/cache_control_data.rb b/lib/chef/provider/remote_file/cache_control_data.rb index 7aa059f4cb..8d7de5c370 100644 --- a/lib/chef/provider/remote_file/cache_control_data.rb +++ b/lib/chef/provider/remote_file/cache_control_data.rb @@ -96,7 +96,7 @@ class Chef end def validate!(current_copy_checksum) - if current_copy_checksum.nil? or checksum != current_copy_checksum + if current_copy_checksum.nil? || checksum != current_copy_checksum reset! false else diff --git a/lib/chef/provider/remote_file/ftp.rb b/lib/chef/provider/remote_file/ftp.rb index 448acdb018..b49e84fa69 100644 --- a/lib/chef/provider/remote_file/ftp.rb +++ b/lib/chef/provider/remote_file/ftp.rb @@ -112,7 +112,7 @@ class Chef def validate_typecode! # Only support ascii and binary types - if typecode and /\A[ai]\z/ !~ typecode + if typecode && /\A[ai]\z/ !~ typecode raise ArgumentError, "invalid typecode: #{typecode.inspect}" end end diff --git a/lib/chef/provider/remote_file/http.rb b/lib/chef/provider/remote_file/http.rb index d4f2446e27..ad044f9e3c 100644 --- a/lib/chef/provider/remote_file/http.rb +++ b/lib/chef/provider/remote_file/http.rb @@ -49,10 +49,10 @@ class Chef def conditional_get_headers cache_control_headers = {} - if last_modified = cache_control_data.mtime and want_mtime_cache_control? + if (last_modified = cache_control_data.mtime) && want_mtime_cache_control? cache_control_headers["if-modified-since"] = last_modified end - if etag = cache_control_data.etag and want_etag_cache_control? + if (etag = cache_control_data.etag) && want_etag_cache_control? cache_control_headers["if-none-match"] = etag end Chef::Log.debug("Cache control headers: #{cache_control_headers.inspect}") diff --git a/lib/chef/provider/service.rb b/lib/chef/provider/service.rb index d716e44342..e693bd2eed 100644 --- a/lib/chef/provider/service.rb +++ b/lib/chef/provider/service.rb @@ -1,5 +1,6 @@ # # Author:: AJ Christensen (<aj@hjksolutions.com>) +# Author:: Davide Cavalca (<dcavalca@fb.com>) # Copyright:: Copyright 2008-2016, Chef Software, Inc. # License:: Apache License, Version 2.0 # @@ -56,9 +57,21 @@ class Chef if @new_resource.running.nil? @new_resource.running(@current_resource.running) end + if @new_resource.masked.nil? + @new_resource.masked(@current_resource.masked) + end + end + + # subclasses should override this if they do implement user services + def user_services_requirements + requirements.assert(:all_actions) do |a| + a.assertion { @new_resource.user.nil? } + a.failure_message Chef::Exceptions::UnsupportedAction, "#{self} does not support user services" + end end def shared_resource_requirements + user_services_requirements end def define_resource_requirements @@ -97,6 +110,32 @@ class Chef @new_resource.enabled(false) end + def action_mask + if @current_resource.masked + Chef::Log.debug("#{@new_resource} already masked - nothing to do") + else + converge_by("mask service #{@new_resource}") do + mask_service + Chef::Log.info("#{@new_resource} masked") + end + end + load_new_resource_state + @new_resource.masked(true) + end + + def action_unmask + if @current_resource.masked + converge_by("unmask service #{@new_resource}") do + unmask_service + Chef::Log.info("#{@new_resource} unmasked") + end + else + Chef::Log.debug("#{@new_resource} already unmasked - nothing to do") + end + load_new_resource_state + @new_resource.masked(false) + end + def action_start unless @current_resource.running converge_by("start service #{@new_resource}") do @@ -150,6 +189,14 @@ class Chef raise Chef::Exceptions::UnsupportedAction, "#{self} does not support :disable" end + def mask_service + raise Chef::Exceptions::UnsupportedAction, "#{self} does not support :mask" + end + + def unmask_service + raise Chef::Exceptions::UnsupportedAction, "#{self} does not support :unmask" + end + def start_service raise Chef::Exceptions::UnsupportedAction, "#{self} does not support :start" end diff --git a/lib/chef/provider/service/aixinit.rb b/lib/chef/provider/service/aixinit.rb index 0234673474..73c5e07715 100644 --- a/lib/chef/provider/service/aixinit.rb +++ b/lib/chef/provider/service/aixinit.rb @@ -44,7 +44,7 @@ class Chef else priority_ok = @current_resource.priority == @new_resource.priority end - if @current_resource.enabled and priority_ok + if @current_resource.enabled && priority_ok Chef::Log.debug("#{@new_resource} already enabled - nothing to do") else converge_by("enable service #{@new_resource}") do diff --git a/lib/chef/provider/service/arch.rb b/lib/chef/provider/service/arch.rb index 9c66fb4098..2fd32e37aa 100644 --- a/lib/chef/provider/service/arch.rb +++ b/lib/chef/provider/service/arch.rb @@ -33,7 +33,7 @@ class Chef::Provider::Service::Arch < Chef::Provider::Service::Init def load_current_resource raise Chef::Exceptions::Service, "Could not find /etc/rc.conf" unless ::File.exists?("/etc/rc.conf") - raise Chef::Exceptions::Service, "No DAEMONS found in /etc/rc.conf" unless ::File.read("/etc/rc.conf").match(/DAEMONS=\((.*)\)/m) + raise Chef::Exceptions::Service, "No DAEMONS found in /etc/rc.conf" unless ::File.read("/etc/rc.conf") =~ /DAEMONS=\((.*)\)/m super @current_resource.enabled(daemons.include?(@current_resource.service_name)) @@ -49,7 +49,7 @@ class Chef::Provider::Service::Arch < Chef::Provider::Service::Init # ) def daemons entries = [] - if ::File.read("/etc/rc.conf").match(/DAEMONS=\((.*)\)/m) + if ::File.read("/etc/rc.conf") =~ /DAEMONS=\((.*)\)/m entries += $1.gsub(/\\?[\r\n]/, " ").gsub(/# *[^ ]+/, " ").split(" ") if $1.length > 0 end @@ -70,7 +70,7 @@ class Chef::Provider::Service::Arch < Chef::Provider::Service::Init new_daemons = [] entries = daemons - if entries.include?(new_resource.service_name) or entries.include?("@#{new_resource.service_name}") + if entries.include?(new_resource.service_name) || entries.include?("@#{new_resource.service_name}") # exists and already enabled (or already enabled as a background service) # new_daemons += entries else @@ -100,7 +100,7 @@ class Chef::Provider::Service::Arch < Chef::Provider::Service::Init # exists and disabled # new_daemons += entries else - if entries.include?(new_resource.service_name) or entries.include?("@#{new_resource.service_name}") + if entries.include?(new_resource.service_name) || entries.include?("@#{new_resource.service_name}") # exists but enabled (or enabled as a back-ground service) # FIXME: Does arch support !@foobar ? entries.each do |daemon| diff --git a/lib/chef/provider/service/debian.rb b/lib/chef/provider/service/debian.rb index 6550c85b2a..67b71953f7 100644 --- a/lib/chef/provider/service/debian.rb +++ b/lib/chef/provider/service/debian.rb @@ -124,7 +124,7 @@ class Chef else priority_ok = @current_resource.priority == new_resource.priority end - if current_resource.enabled and priority_ok + if current_resource.enabled && priority_ok Chef::Log.debug("#{new_resource} already enabled - nothing to do") else converge_by("enable service #{new_resource}") do diff --git a/lib/chef/provider/service/gentoo.rb b/lib/chef/provider/service/gentoo.rb index 66f2f10f23..8fb6d1f9af 100644 --- a/lib/chef/provider/service/gentoo.rb +++ b/lib/chef/provider/service/gentoo.rb @@ -33,12 +33,12 @@ class Chef::Provider::Service::Gentoo < Chef::Provider::Service::Init super @current_resource.enabled( - Dir.glob("/etc/runlevels/**/#{Chef::Util::PathHelper.escape_glob(@current_resource.service_name)}").any? do |file| + Dir.glob("/etc/runlevels/**/#{Chef::Util::PathHelper.escape_glob_dir(@current_resource.service_name)}").any? do |file| @found_script = true exists = ::File.exists? file readable = ::File.readable? file Chef::Log.debug "#{@new_resource} exists: #{exists}, readable: #{readable}" - exists and readable + exists && readable end ) Chef::Log.debug "#{@new_resource} enabled: #{@current_resource.enabled}" diff --git a/lib/chef/provider/service/insserv.rb b/lib/chef/provider/service/insserv.rb index 7f92ef1eb4..76b2ee7477 100644 --- a/lib/chef/provider/service/insserv.rb +++ b/lib/chef/provider/service/insserv.rb @@ -36,7 +36,7 @@ class Chef super # Look for a /etc/rc.*/SnnSERVICE link to signify that the service would be started in a runlevel - if Dir.glob("/etc/rc**/S*#{Chef::Util::PathHelper.escape_glob(current_resource.service_name)}").empty? + if Dir.glob("/etc/rc**/S*#{Chef::Util::PathHelper.escape_glob_dir(current_resource.service_name)}").empty? current_resource.enabled false else current_resource.enabled true diff --git a/lib/chef/provider/service/macosx.rb b/lib/chef/provider/service/macosx.rb index 63485903c3..648cd9748b 100644 --- a/lib/chef/provider/service/macosx.rb +++ b/lib/chef/provider/service/macosx.rb @@ -181,7 +181,7 @@ class Chef end def set_service_status - return if @plist == nil or @service_label.to_s.empty? + return if @plist == nil || @service_label.to_s.empty? cmd = "launchctl list #{@service_label}" res = shell_out_as_user(cmd) @@ -236,7 +236,7 @@ class Chef plists = PLIST_DIRS.inject([]) do |results, dir| edir = ::File.expand_path(dir) entries = Dir.glob( - "#{edir}/*#{Chef::Util::PathHelper.escape_glob(@current_resource.service_name)}*.plist" + "#{edir}/*#{Chef::Util::PathHelper.escape_glob_dir(@current_resource.service_name)}*.plist" ) entries.any? ? results << entries : results end diff --git a/lib/chef/provider/service/openbsd.rb b/lib/chef/provider/service/openbsd.rb index c31df25e68..c60bbf170c 100644 --- a/lib/chef/provider/service/openbsd.rb +++ b/lib/chef/provider/service/openbsd.rb @@ -92,7 +92,7 @@ class Chef old_services_list = rc_conf_local.match(/^pkg_scripts="(.*)"/) old_services_list = old_services_list ? old_services_list[1].split(" ") : [] new_services_list = old_services_list + [new_resource.service_name] - if rc_conf_local.match(/^pkg_scripts="(.*)"/) + if rc_conf_local =~ /^pkg_scripts="(.*)"/ new_rcl = rc_conf_local.sub(/^pkg_scripts="(.*)"/, "pkg_scripts=\"#{new_services_list.join(' ')}\"") else new_rcl = rc_conf_local + "\n" + "pkg_scripts=\"#{new_services_list.join(' ')}\"\n" @@ -159,7 +159,7 @@ class Chef result = false var_name = builtin_service_enable_variable_name if var_name - if rc_conf.match(/^#{Regexp.escape(var_name)}=(.*)/) + if rc_conf =~ /^#{Regexp.escape(var_name)}=(.*)/ result = true end end diff --git a/lib/chef/provider/service/redhat.rb b/lib/chef/provider/service/redhat.rb index a76622ee8f..08f8e108d5 100644 --- a/lib/chef/provider/service/redhat.rb +++ b/lib/chef/provider/service/redhat.rb @@ -76,7 +76,7 @@ class Chef if ::File.exists?("/sbin/chkconfig") chkconfig = shell_out!("/sbin/chkconfig --list #{current_resource.service_name}", :returns => [0, 1]) - unless run_levels.nil? or run_levels.empty? + unless run_levels.nil? || run_levels.empty? all_levels_match = true chkconfig.stdout.split(/\s+/)[1..-1].each do |level| index = level.split(":").first @@ -100,11 +100,11 @@ class Chef # @api private def levels - (run_levels.nil? or run_levels.empty?) ? "" : "--level #{run_levels.join('')} " + (run_levels.nil? || run_levels.empty?) ? "" : "--level #{run_levels.join('')} " end def enable_service() - unless run_levels.nil? or run_levels.empty? + unless run_levels.nil? || run_levels.empty? disable_levels = current_run_levels - run_levels shell_out! "/sbin/chkconfig --level #{disable_levels.join('')} #{new_resource.service_name} off" unless disable_levels.empty? end diff --git a/lib/chef/provider/service/simple.rb b/lib/chef/provider/service/simple.rb index d76779a74b..fe4768b2e8 100644 --- a/lib/chef/provider/service/simple.rb +++ b/lib/chef/provider/service/simple.rb @@ -76,8 +76,8 @@ class Chef end requirements.assert(:all_actions) do |a| - a.assertion { @new_resource.status_command or supports[:status] or - (!ps_cmd.nil? and !ps_cmd.empty?) } + a.assertion { @new_resource.status_command || supports[:status] || + (!ps_cmd.nil? && !ps_cmd.empty?) } a.failure_message Chef::Exceptions::Service, "#{@new_resource} could not determine how to inspect the process table, please set this node's 'command.ps' attribute" end requirements.assert(:all_actions) do |a| diff --git a/lib/chef/provider/service/solaris.rb b/lib/chef/provider/service/solaris.rb index 0787392094..1e5398eba8 100644 --- a/lib/chef/provider/service/solaris.rb +++ b/lib/chef/provider/service/solaris.rb @@ -49,6 +49,11 @@ class Chef @current_resource end + def define_resource_requirements + # FIXME? need reload from service.rb + shared_resource_requirements + end + def enable_service shell_out!(default_init_command, "clear", @new_resource.service_name) if @maintenance shell_out!(default_init_command, "enable", "-s", @new_resource.service_name) diff --git a/lib/chef/provider/service/systemd.rb b/lib/chef/provider/service/systemd.rb index e70576fea7..1597d46a3d 100644 --- a/lib/chef/provider/service/systemd.rb +++ b/lib/chef/provider/service/systemd.rb @@ -1,5 +1,6 @@ # # Author:: Stephen Haynes (<sh@nomitor.com>) +# Author:: Davide Cavalca (<dcavalca@fb.com>) # Copyright:: Copyright 2011-2016, Chef Software Inc. # License:: Apache License, Version 2.0 # @@ -48,15 +49,21 @@ class Chef::Provider::Service::Systemd < Chef::Provider::Service::Simple @status_check_success = false current_resource.running(false) current_resource.enabled(false) + current_resource.masked(false) end else current_resource.running(is_active?) end current_resource.enabled(is_enabled?) + current_resource.masked(is_masked?) current_resource end + # systemd supports user services just fine + def user_services_requirements + end + def define_resource_requirements shared_resource_requirements requirements.assert(:all_actions) do |a| @@ -67,6 +74,24 @@ class Chef::Provider::Service::Systemd < Chef::Provider::Service::Simple end end + def get_systemctl_options_args + if new_resource.user + uid = node["etc"]["passwd"][new_resource.user]["uid"] + options = { + "environment" => { + "DBUS_SESSION_BUS_ADDRESS" => "unix:path=/run/user/#{uid}/bus", + }, + "user" => new_resource.user, + } + args = "--user" + else + options = {} + args = "--system" + end + + return options, args + end + def start_service if current_resource.running Chef::Log.debug("#{new_resource} already running, not starting") @@ -74,7 +99,8 @@ class Chef::Provider::Service::Systemd < Chef::Provider::Service::Simple if new_resource.start_command super else - shell_out_with_systems_locale!("#{systemctl_path} start #{new_resource.service_name}") + options, args = get_systemctl_options_args + shell_out_with_systems_locale!("#{systemctl_path} #{args} start #{new_resource.service_name}", options) end end end @@ -86,7 +112,8 @@ class Chef::Provider::Service::Systemd < Chef::Provider::Service::Simple if new_resource.stop_command super else - shell_out_with_systems_locale!("#{systemctl_path} stop #{new_resource.service_name}") + options, args = get_systemctl_options_args + shell_out_with_systems_locale!("#{systemctl_path} #{args} stop #{new_resource.service_name}", options) end end end @@ -95,7 +122,8 @@ class Chef::Provider::Service::Systemd < Chef::Provider::Service::Simple if new_resource.restart_command super else - shell_out_with_systems_locale!("#{systemctl_path} restart #{new_resource.service_name}") + options, args = get_systemctl_options_args + shell_out_with_systems_locale!("#{systemctl_path} #{args} restart #{new_resource.service_name}", options) end end @@ -104,7 +132,8 @@ class Chef::Provider::Service::Systemd < Chef::Provider::Service::Simple super else if current_resource.running - shell_out_with_systems_locale!("#{systemctl_path} reload #{new_resource.service_name}") + options, args = get_systemctl_options_args + shell_out_with_systems_locale!("#{systemctl_path} #{args} reload #{new_resource.service_name}", options) else start_service end @@ -112,19 +141,39 @@ class Chef::Provider::Service::Systemd < Chef::Provider::Service::Simple end def enable_service - shell_out!("#{systemctl_path} enable #{new_resource.service_name}") + options, args = get_systemctl_options_args + shell_out!("#{systemctl_path} #{args} enable #{new_resource.service_name}", options) end def disable_service - shell_out!("#{systemctl_path} disable #{new_resource.service_name}") + options, args = get_systemctl_options_args + shell_out!("#{systemctl_path} #{args} disable #{new_resource.service_name}", options) + end + + def mask_service + options, args = get_systemctl_options_args + shell_out!("#{systemctl_path} #{args} mask #{new_resource.service_name}", options) + end + + def unmask_service + options, args = get_systemctl_options_args + shell_out!("#{systemctl_path} #{args} unmask #{new_resource.service_name}", options) end def is_active? - shell_out("#{systemctl_path} is-active #{new_resource.service_name} --quiet").exitstatus == 0 + options, args = get_systemctl_options_args + shell_out("#{systemctl_path} #{args} is-active #{new_resource.service_name} --quiet", options).exitstatus == 0 end def is_enabled? - shell_out("#{systemctl_path} is-enabled #{new_resource.service_name} --quiet").exitstatus == 0 + options, args = get_systemctl_options_args + shell_out("#{systemctl_path} #{args} is-enabled #{new_resource.service_name} --quiet", options).exitstatus == 0 + end + + def is_masked? + options, args = get_systemctl_options_args + s = shell_out("#{systemctl_path} #{args} is-enabled #{new_resource.service_name}", options) + s.exitstatus != 0 && s.stdout.include?("masked") end private diff --git a/lib/chef/provider/service/upstart.rb b/lib/chef/provider/service/upstart.rb index edd41dba7e..3ac5ff51da 100644 --- a/lib/chef/provider/service/upstart.rb +++ b/lib/chef/provider/service/upstart.rb @@ -62,7 +62,7 @@ class Chef end platform, version = Chef::Platform.find_platform_and_version(run_context.node) - if platform == "ubuntu" && (8.04..9.04).include?(version.to_f) + if platform == "ubuntu" && (8.04..9.04).cover?(version.to_f) @upstart_job_dir = "/etc/event.d" @upstart_conf_suffix = "" else diff --git a/lib/chef/provider/user/aix.rb b/lib/chef/provider/user/aix.rb index 42798a5f62..3f168b8da3 100644 --- a/lib/chef/provider/user/aix.rb +++ b/lib/chef/provider/user/aix.rb @@ -79,7 +79,7 @@ class Chef # Aix specific handling to update users home directory. def manage_home # -m option does not work on aix, so move dir. - if updating_home? and managing_home_dir? + if updating_home? && managing_home_dir? universal_options.delete("-m") if ::File.directory?(@current_resource.home) Chef::Log.debug("Changing users home directory from #{@current_resource.home} to #{new_resource.home}") diff --git a/lib/chef/provider/user/dscl.rb b/lib/chef/provider/user/dscl.rb index fecfb73e2d..e933bf9dc0 100644 --- a/lib/chef/provider/user/dscl.rb +++ b/lib/chef/provider/user/dscl.rb @@ -331,7 +331,7 @@ user password using shadow hash.") src = current_resource.home FileUtils.mkdir_p(new_resource.home) - files = ::Dir.glob("#{Chef::Util::PathHelper.escape_glob(src)}/*", ::File::FNM_DOTMATCH) - ["#{src}/.", "#{src}/.."] + files = ::Dir.glob("#{Chef::Util::PathHelper.escape_glob_dir(src)}/*", ::File::FNM_DOTMATCH) - ["#{src}/.", "#{src}/.."] ::FileUtils.mv(files, new_resource.home, :force => true) ::FileUtils.rmdir(src) ::FileUtils.chown_R(new_resource.username, new_resource.gid.to_s, new_resource.home) diff --git a/lib/chef/provider/user/useradd.rb b/lib/chef/provider/user/useradd.rb index e2f5b5897a..3fef8d3642 100644 --- a/lib/chef/provider/user/useradd.rb +++ b/lib/chef/provider/user/useradd.rb @@ -150,7 +150,7 @@ class Chef # ::File.expand_path("///tmp") == ::File.expand_path("/tmp") => false # ::File.expand_path("\\tmp") => "C:/tmp" return true if @current_resource.home.nil? && new_resource.home - new_resource.home and Pathname.new(@current_resource.home).cleanpath != Pathname.new(new_resource.home).cleanpath + new_resource.home && Pathname.new(@current_resource.home).cleanpath != Pathname.new(new_resource.home).cleanpath end def managing_home_dir? diff --git a/lib/chef/resource/mount.rb b/lib/chef/resource/mount.rb index 44143d583c..2d85b3897c 100644 --- a/lib/chef/resource/mount.rb +++ b/lib/chef/resource/mount.rb @@ -102,7 +102,7 @@ class Chef ) if ret.is_a? String - ret.gsub(/,/, " ").split(/ /) + ret.tr(",", " ").split(/ /) else ret end diff --git a/lib/chef/resource/remote_file.rb b/lib/chef/resource/remote_file.rb index 321c3fcf4d..4a1d1c6cff 100644 --- a/lib/chef/resource/remote_file.rb +++ b/lib/chef/resource/remote_file.rb @@ -148,7 +148,7 @@ class Chef end def absolute_uri?(source) - Chef::Provider::RemoteFile::Fetcher.network_share?(source) or (source.kind_of?(String) and as_uri(source).absolute?) + Chef::Provider::RemoteFile::Fetcher.network_share?(source) || (source.kind_of?(String) && as_uri(source).absolute?) rescue URI::InvalidURIError false end diff --git a/lib/chef/resource/ruby_block.rb b/lib/chef/resource/ruby_block.rb index 0e3a980b11..87a4cfb7c5 100644 --- a/lib/chef/resource/ruby_block.rb +++ b/lib/chef/resource/ruby_block.rb @@ -34,7 +34,7 @@ class Chef end def block(&block) - if block_given? and block + if block_given? && block @block = block else @block diff --git a/lib/chef/resource/service.rb b/lib/chef/resource/service.rb index 849afebad0..1ca4b84af0 100644 --- a/lib/chef/resource/service.rb +++ b/lib/chef/resource/service.rb @@ -24,16 +24,18 @@ class Chef class Service < Chef::Resource identity_attr :service_name - state_attrs :enabled, :running + state_attrs :enabled, :running, :masked default_action :nothing - allowed_actions :enable, :disable, :start, :stop, :restart, :reload + allowed_actions :enable, :disable, :start, :stop, :restart, :reload, + :mask, :unmask def initialize(name, run_context = nil) super @service_name = name @enabled = nil @running = nil + @masked = nil @parameters = nil @pattern = service_name @start_command = nil @@ -45,6 +47,7 @@ class Chef @priority = nil @timeout = nil @run_levels = nil + @user = nil @supports = { :restart => nil, :reload => nil, :status => nil } end @@ -140,6 +143,15 @@ class Chef ) end + # if the service is masked or not + def masked(arg = nil) + set_or_return( + :masked, + arg, + :kind_of => [ TrueClass, FalseClass ] + ) + end + # Priority arguments can have two forms: # # - a simple number, in which the default start runlevels get @@ -182,6 +194,14 @@ class Chef :kind_of => [ Array ] ) end + def user(arg = nil) + set_or_return( + :user, + arg, + :kind_of => [ String ] + ) + end + def supports(args = {}) if args.is_a? Array args.each { |arg| @supports[arg] = true } diff --git a/lib/chef/resource/template.rb b/lib/chef/resource/template.rb index e33af3174b..896aa71340 100644 --- a/lib/chef/resource/template.rb +++ b/lib/chef/resource/template.rb @@ -161,7 +161,7 @@ class Chef # helpers(MyTemplateHelper) # The template code in the above example will work unmodified. def helpers(module_name = nil, &block) - if block_given? and !module_name.nil? + if block_given? && !module_name.nil? raise Exceptions::ValidationFailed, "Passing both a module and block to #helpers is not supported. Call #helpers multiple times instead" elsif block_given? diff --git a/lib/chef/resource_collection/resource_list.rb b/lib/chef/resource_collection/resource_list.rb index 20bfc7b5f0..37eb12a107 100644 --- a/lib/chef/resource_collection/resource_list.rb +++ b/lib/chef/resource_collection/resource_list.rb @@ -76,7 +76,8 @@ class Chef @resources end - def execute_each_resource(&resource_exec_block) + # FIXME: yard with @yield + def execute_each_resource @iterator = ResourceCollection::StepableIterator.for_collection(@resources) @iterator.each_with_index do |resource, idx| @insert_after_idx = idx diff --git a/lib/chef/role.rb b/lib/chef/role.rb index ed22bc87e4..331fa614f1 100644 --- a/lib/chef/role.rb +++ b/lib/chef/role.rb @@ -253,10 +253,10 @@ class Chef def self.from_disk(name) paths = Array(Chef::Config[:role_path]) paths.each do |path| - roles_files = Dir.glob(File.join(Chef::Util::PathHelper.escape_glob(path), "**", "**")) + roles_files = Dir.glob(File.join(Chef::Util::PathHelper.escape_glob_dir(path), "**", "**")) js_files = roles_files.select { |file| file.match(/\/#{name}\.json$/) } rb_files = roles_files.select { |file| file.match(/\/#{name}\.rb$/) } - if js_files.count > 1 or rb_files.count > 1 + if js_files.count > 1 || rb_files.count > 1 raise Chef::Exceptions::DuplicateRole, "Multiple roles of same type found named #{name}" end js_path, rb_path = js_files.first, rb_files.first diff --git a/lib/chef/run_context/cookbook_compiler.rb b/lib/chef/run_context/cookbook_compiler.rb index e8311a18a6..bdf3a1251c 100644 --- a/lib/chef/run_context/cookbook_compiler.rb +++ b/lib/chef/run_context/cookbook_compiler.rb @@ -186,6 +186,7 @@ class Chef def load_libraries_from_cookbook(cookbook_name) files_in_cookbook_by_segment(cookbook_name, :libraries).each do |filename| + next unless File.extname(filename) == ".rb" begin Chef::Log.debug("Loading cookbook #{cookbook_name}'s library file: #{filename}") Kernel.load(filename) diff --git a/lib/chef/run_list.rb b/lib/chef/run_list.rb index b9ec9259ca..4dea938423 100644 --- a/lib/chef/run_list.rb +++ b/lib/chef/run_list.rb @@ -105,12 +105,14 @@ class Chef @run_list_items[pos] = parse_entry(item) end - def each(&block) - @run_list_items.each { |i| block.call(i) } + # FIXME: yard with @yield + def each + @run_list_items.each { |i| yield(i) } end - def each_index(&block) - @run_list_items.each_index { |i| block.call(i) } + # FIXME: yard with @yield + def each_index + @run_list_items.each_index { |i| yield(i) } end def include?(item) diff --git a/lib/chef/search/query.rb b/lib/chef/search/query.rb index 487a54f0df..ebf13bec36 100644 --- a/lib/chef/search/query.rb +++ b/lib/chef/search/query.rb @@ -87,7 +87,7 @@ WARNDEP response = call_rest_service(type, query: query, **args_h) if block - response["rows"].each { |row| block.call(row) if row } + response["rows"].each { |row| yield(row) if row } # # args_h[:rows] and args_h[:start] are the page size and # start position requested of the search index backing the diff --git a/lib/chef/shell/model_wrapper.rb b/lib/chef/shell/model_wrapper.rb index 403f9479cf..8c3e456a9b 100644 --- a/lib/chef/shell/model_wrapper.rb +++ b/lib/chef/shell/model_wrapper.rb @@ -59,7 +59,8 @@ module Shell alias :load :show - def transform(what_to_transform, &block) + # FIXME: yard with @yield + def transform(what_to_transform) if what_to_transform == :all objects_to_transform = list_objects else diff --git a/lib/chef/util/dsc/lcm_output_parser.rb b/lib/chef/util/dsc/lcm_output_parser.rb index 2e81b363e0..bdcedff7f8 100644 --- a/lib/chef/util/dsc/lcm_output_parser.rb +++ b/lib/chef/util/dsc/lcm_output_parser.rb @@ -79,7 +79,7 @@ class Chef end when :end # Make sure we log the last line - if current_resource[:context] == :logging and info.include? current_resource[:name] + if current_resource[:context] == :logging && info.include?(current_resource[:name]) current_resource[:logs].push(info) end current_resource[:context] = nil diff --git a/lib/chef/util/dsc/resource_store.rb b/lib/chef/util/dsc/resource_store.rb index bb3480d105..be8d0b301b 100644 --- a/lib/chef/util/dsc/resource_store.rb +++ b/lib/chef/util/dsc/resource_store.rb @@ -74,7 +74,7 @@ class Chef found = rs.find_all do |r| name_matches = r["Name"].casecmp(name) == 0 if name_matches - module_name == nil || (r["Module"] and r["Module"]["Name"].casecmp(module_name) == 0) + module_name == nil || (r["Module"] && r["Module"]["Name"].casecmp(module_name) == 0) else false end diff --git a/lib/chef/util/windows/net_user.rb b/lib/chef/util/windows/net_user.rb index b0a779e44a..009252c4c1 100644 --- a/lib/chef/util/windows/net_user.rb +++ b/lib/chef/util/windows/net_user.rb @@ -119,11 +119,12 @@ class Chef::Util::Windows::NetUser < Chef::Util::Windows NetUser.net_local_group_add_member(nil, "Users", args[:name]) end - def user_modify(&proc) + # FIXME: yard with @yield + def user_modify user = get_info user[:last_logon] = user[:units_per_week] = 0 #ignored as per USER_INFO_3 doc user[:logon_hours] = nil #PBYTE field; \0 == no changes - proc.call(user) + yield(user) set_info(user) end diff --git a/lib/chef/version.rb b/lib/chef/version.rb index 6c1fe2227a..9d42fa581a 100644 --- a/lib/chef/version.rb +++ b/lib/chef/version.rb @@ -21,7 +21,7 @@ class Chef CHEF_ROOT = File.dirname(File.expand_path(File.dirname(__FILE__))) - VERSION = "12.8.0" + VERSION = "12.9.0" end # diff --git a/lib/chef/win32/api/file.rb b/lib/chef/win32/api/file.rb index 52ac4868c7..7489c94fd9 100644 --- a/lib/chef/win32/api/file.rb +++ b/lib/chef/win32/api/file.rb @@ -535,7 +535,8 @@ BOOL WINAPI VerQueryValue( # retrieves a file search handle and passes it # to +&block+ along with the find_data. also # ensures the handle is closed on exit of the block - def file_search_handle(path, &block) + # FIXME: yard with @yield + def file_search_handle(path) begin # Workaround for CHEF-4419: # Make sure paths starting with "/" has a drive letter @@ -550,7 +551,7 @@ BOOL WINAPI VerQueryValue( if handle == INVALID_HANDLE_VALUE Chef::ReservedNames::Win32::Error.raise! end - block.call(handle, find_data) + yield(handle, find_data) ensure FindClose(handle) if handle && handle != INVALID_HANDLE_VALUE end @@ -559,7 +560,8 @@ BOOL WINAPI VerQueryValue( # retrieves a file handle and passes it # to +&block+ along with the find_data. also # ensures the handle is closed on exit of the block - def file_handle(path, &block) + # FIXME: yard with @yield + def file_handle(path) begin path = canonical_encode_path(path) handle = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ, @@ -568,13 +570,14 @@ BOOL WINAPI VerQueryValue( if handle == INVALID_HANDLE_VALUE Chef::ReservedNames::Win32::Error.raise! end - block.call(handle) + yield(handle) ensure CloseHandle(handle) if handle && handle != INVALID_HANDLE_VALUE end end - def symlink_file_handle(path, &block) + # FIXME: yard with @yield + def symlink_file_handle(path) begin path = encode_path(path) handle = CreateFileW(path, FILE_READ_EA, FILE_SHARE_READ, @@ -583,7 +586,7 @@ BOOL WINAPI VerQueryValue( if handle == INVALID_HANDLE_VALUE Chef::ReservedNames::Win32::Error.raise! end - block.call(handle) + yield(handle) ensure CloseHandle(handle) if handle && handle != INVALID_HANDLE_VALUE end diff --git a/lib/chef/win32/eventlog.rb b/lib/chef/win32/eventlog.rb index 723b43fc44..4254b8ead3 100644 --- a/lib/chef/win32/eventlog.rb +++ b/lib/chef/win32/eventlog.rb @@ -16,7 +16,7 @@ # limitations under the License. # -if Chef::Platform.windows? and not Chef::Platform.windows_server_2003? +if Chef::Platform.windows? && (not Chef::Platform.windows_server_2003?) if !defined? Chef::Win32EventLogLoaded if defined? Windows::Constants [:INFINITE, :WAIT_FAILED, :FORMAT_MESSAGE_IGNORE_INSERTS, :ERROR_INSUFFICIENT_BUFFER].each do |c| diff --git a/lib/chef/win32/version.rb b/lib/chef/win32/version.rb index 85a2744645..303fe1531d 100644 --- a/lib/chef/win32/version.rb +++ b/lib/chef/win32/version.rb @@ -41,7 +41,7 @@ class Chef private_class_method :get_system_metrics def self.method_name_from_marketing_name(marketing_name) - "#{marketing_name.gsub(/\s/, '_').gsub(/\./, '_').downcase}?" + "#{marketing_name.gsub(/\s/, '_').tr('.', '_').downcase}?" # "#{marketing_name.gsub(/\s/, '_').gsub(//, '_').downcase}?" end |