summaryrefslogtreecommitdiff
path: root/lib/chef
diff options
context:
space:
mode:
Diffstat (limited to 'lib/chef')
-rw-r--r--lib/chef/application.rb6
-rw-r--r--lib/chef/application/apply.rb4
-rw-r--r--lib/chef/chef_fs/chef_fs_data_store.rb54
-rw-r--r--lib/chef/chef_fs/config.rb67
-rw-r--r--lib/chef/chef_fs/file_system/chef_repository_file_system_root_dir.rb18
-rw-r--r--lib/chef/chef_fs/file_system/chef_server_root_dir.rb31
-rw-r--r--lib/chef/client.rb9
-rw-r--r--lib/chef/config.rb45
-rw-r--r--lib/chef/dsl/reboot_pending.rb9
-rw-r--r--lib/chef/knife/core/bootstrap_context.rb6
-rw-r--r--lib/chef/mixin/shell_out.rb46
-rw-r--r--lib/chef/platform/rebooter.rb54
-rw-r--r--lib/chef/provider/ifconfig.rb31
-rw-r--r--lib/chef/provider/link.rb2
-rw-r--r--lib/chef/provider/package/aix.rb16
-rw-r--r--lib/chef/provider/package/ips.rb20
-rw-r--r--lib/chef/provider/package/macports.rb16
-rw-r--r--lib/chef/provider/package/pacman.rb8
-rw-r--r--lib/chef/provider/package/portage.rb8
-rw-r--r--lib/chef/provider/package/rpm.rb16
-rw-r--r--lib/chef/provider/package/solaris.rb16
-rw-r--r--lib/chef/provider/reboot.rb69
-rw-r--r--lib/chef/provider/service/debian.rb20
-rw-r--r--lib/chef/provider/service/freebsd.rb6
-rw-r--r--lib/chef/provider/service/gentoo.rb4
-rw-r--r--lib/chef/provider/service/init.rb8
-rw-r--r--lib/chef/provider/service/insserv.rb6
-rw-r--r--lib/chef/provider/service/macosx.rb4
-rw-r--r--lib/chef/provider/service/simple.rb8
-rw-r--r--lib/chef/provider/service/solaris.rb2
-rw-r--r--lib/chef/provider/service/systemd.rb18
-rw-r--r--lib/chef/provider/service/upstart.rb12
-rw-r--r--lib/chef/provider/subversion.rb12
-rw-r--r--lib/chef/provider/whyrun_safe_ruby_block.rb2
-rw-r--r--lib/chef/providers.rb1
-rw-r--r--lib/chef/resource/reboot.rb48
-rw-r--r--lib/chef/resources.rb1
-rw-r--r--lib/chef/run_context.rb25
-rw-r--r--lib/chef/win32/api/file.rb6
39 files changed, 545 insertions, 189 deletions
diff --git a/lib/chef/application.rb b/lib/chef/application.rb
index 5b1d53d741..0430d4acfa 100644
--- a/lib/chef/application.rb
+++ b/lib/chef/application.rb
@@ -46,6 +46,7 @@ class Chef::Application
configure_chef
configure_logging
configure_proxy_environment_variables
+ configure_encoding
end
# Get this party started
@@ -175,6 +176,11 @@ class Chef::Application
configure_no_proxy
end
+ # Sets the default external encoding to UTF-8 (users can change this, but they shouldn't)
+ def configure_encoding
+ Encoding.default_external = Chef::Config[:ruby_encoding]
+ end
+
# Called prior to starting the application, by the run method
def setup_application
raise Chef::Exceptions::Application, "#{self.to_s}: you must override setup_application"
diff --git a/lib/chef/application/apply.rb b/lib/chef/application/apply.rb
index ab35b35389..ea9154c6f2 100644
--- a/lib/chef/application/apply.rb
+++ b/lib/chef/application/apply.rb
@@ -134,6 +134,10 @@ class Chef::Application::Apply < Chef::Application
@recipe_text = STDIN.read
temp_recipe_file
else
+ if !ARGV[0]
+ puts opt_parser
+ Chef::Application.exit! "No recipe file provided", 1
+ end
@recipe_filename = ARGV[0]
@recipe_text,@recipe_fh = read_recipe_file @recipe_filename
end
diff --git a/lib/chef/chef_fs/chef_fs_data_store.rb b/lib/chef/chef_fs/chef_fs_data_store.rb
index 09a66a9ab2..484ab07390 100644
--- a/lib/chef/chef_fs/chef_fs_data_store.rb
+++ b/lib/chef/chef_fs/chef_fs_data_store.rb
@@ -27,7 +27,61 @@ require 'fileutils'
class Chef
module ChefFS
+ #
+ # Translation layer between chef-zero's DataStore (a place where it expects
+ # files to be stored) and ChefFS (the user's repository directory layout).
+ #
+ # chef-zero expects the data store to store files *its* way--for example, it
+ # expects get("nodes/blah") to return the JSON text for the blah node, and
+ # it expects get("cookbooks/blah/1.0.0") to return the JSON definition of
+ # the blah cookbook version 1.0.0.
+ #
+ # The repository is defined the way the *user* wants their layout. These
+ # two things are very similar in layout (for example, nodes are stored under
+ # the nodes/ directory and their filename is the name of the node).
+ #
+ # However, there are a few differences that make this more than just a raw
+ # file store:
+ #
+ # 1. Cookbooks are stored much differently.
+ # - chef-zero places JSON text with the checksums for the cookbook at
+ # /cookbooks/NAME/VERSION, and expects the JSON to contain URLs to the
+ # actual files, which are stored elsewhere.
+ # - The repository contains an actual directory with just the cookbook
+ # files and a metadata.rb containing a version #. There is no JSON to
+ # be found.
+ # - Further, if versioned_cookbooks is false, that directory is named
+ # /cookbooks/NAME and only one version exists. If versioned_cookbooks
+ # is true, the directory is named /cookbooks/NAME-VERSION.
+ # - Therefore, ChefFSDataStore calculates the cookbook JSON by looking at
+ # the files in the cookbook and checksumming them, and reading metadata.rb
+ # for the version and dependency information.
+ # - ChefFSDataStore also modifies the cookbook file URLs so that they point
+ # to /file_store/repo/<filename> (the path to the actual file under the
+ # repository root). For example, /file_store/repo/apache2/metadata.rb or
+ # /file_store/repo/cookbooks/apache2/recipes/default.rb).
+ #
+ # 2. Sandboxes don't exist in the repository.
+ # - ChefFSDataStore lets cookbooks be uploaded into a temporary memory
+ # storage, and when the cookbook is committed, copies the files onto the
+ # disk in the correct place (/cookbooks/apache2/recipes/default.rb).
+ # 3. Data bags:
+ # - The Chef server expects data bags in /data/BAG/ITEM
+ # - The repository stores data bags in /data_bags/BAG/ITEM
+ #
+ # 4. JSON filenames are generally NAME.json in the repository (e.g. /nodes/foo.json).
+ #
class ChefFSDataStore
+ #
+ # Create a new ChefFSDataStore
+ #
+ # ==== Arguments
+ #
+ # [chef_fs]
+ # A +ChefFS::FileSystem+ object representing the repository root.
+ # Generally will be a +ChefFS::FileSystem::ChefRepositoryFileSystemRoot+
+ # object, created from +ChefFS::Config.local_fs+.
+ #
def initialize(chef_fs)
@chef_fs = chef_fs
@memory_store = ChefZero::DataStore::MemoryStore.new
diff --git a/lib/chef/chef_fs/config.rb b/lib/chef/chef_fs/config.rb
index ca273b2cca..fcad6c919f 100644
--- a/lib/chef/chef_fs/config.rb
+++ b/lib/chef/chef_fs/config.rb
@@ -22,9 +22,74 @@ require 'chef/chef_fs/path_utils'
class Chef
module ChefFS
#
- # Helpers to take Chef::Config and create chef_fs and local_fs from it
+ # Helpers to take Chef::Config and create chef_fs and local_fs (ChefFS
+ # objects representing the server and local repository, respectively).
#
class Config
+ #
+ # Create a new Config object which can produce a chef_fs and local_fs.
+ #
+ # ==== Arguments
+ #
+ # [chef_config]
+ # A hash that looks suspiciously like +Chef::Config+. These hash keys
+ # include:
+ #
+ # :chef_repo_path::
+ # The root where all local chef object data is stored. Mirrors
+ # +Chef::Config.chef_repo_path+
+ # :cookbook_path, node_path, ...::
+ # Paths to cookbooks/, nodes/, data_bags/, etc. Mirrors
+ # +Chef::Config.cookbook_path+, etc. Defaults to
+ # +<chef_repo_path>/cookbooks+, etc.
+ # :repo_mode::
+ # The directory format on disk. 'everything', 'hosted_everything' and
+ # 'static'. Default: autodetected based on whether the URL has
+ # "/organizations/NAME."
+ # :versioned_cookbooks::
+ # If true, the repository contains cookbooks with versions in their
+ # name (apache2-1.0.0). If false, the repository just has one version
+ # of each cookbook and the directory has the cookbook name (apache2).
+ # Default: +false+
+ # :chef_server_url::
+ # The URL to the Chef server, e.g. https://api.opscode.com/organizations/foo.
+ # Used as the server for the remote chef_fs, and to "guess" repo_mode
+ # if not specified.
+ # :node_name:: The username to authenticate to the Chef server with.
+ # :client_key:: The private key for the user for authentication
+ # :environment:: The environment in which you are presently working
+ # :repo_mode::
+ # The repository mode, :hosted_everything, :everything or :static.
+ # This determines the set of subdirectories the Chef server will offer
+ # up.
+ # :versioned_cookbooks:: Whether or not to include versions in cookbook names
+ #
+ # [cwd]
+ # The current working directory to base relative Chef paths from.
+ # Defaults to +Dir.pwd+.
+ #
+ # [options]
+ # A hash of other, not-suspiciously-like-chef-config options:
+ # :cookbook_version::
+ # When downloading cookbooks, download this cookbook version instead
+ # of the latest.
+ #
+ # [ui]
+ # The object to print output to, with "output", "warn" and "error"
+ # (looks a little like a Chef::Knife::UI object, obtainable from
+ # Chef::Knife.ui).
+ #
+ # ==== Example
+ #
+ # require 'chef/chef_fs/config'
+ # config = Chef::ChefFS::Config.new
+ # config.chef_fs.child('cookbooks').children.each do |cookbook|
+ # puts "Cookbook on server: #{cookbook.name}"
+ # end
+ # config.local_fs.child('cookbooks').children.each do |cookbook|
+ # puts "Local cookbook: #{cookbook.name}"
+ # end
+ #
def initialize(chef_config = Chef::Config, cwd = Dir.pwd, options = {}, ui = nil)
@chef_config = chef_config
@cwd = cwd
diff --git a/lib/chef/chef_fs/file_system/chef_repository_file_system_root_dir.rb b/lib/chef/chef_fs/file_system/chef_repository_file_system_root_dir.rb
index 050da60389..ac272d4c1a 100644
--- a/lib/chef/chef_fs/file_system/chef_repository_file_system_root_dir.rb
+++ b/lib/chef/chef_fs/file_system/chef_repository_file_system_root_dir.rb
@@ -42,15 +42,17 @@ class Chef
# Create a new Chef Repository File System root.
#
# == Parameters
- # - child_paths - a hash of child paths, e.g.:
- # "nodes" => [ '/var/nodes', '/home/jkeiser/nodes' ],
- # "roles" => [ '/var/roles' ],
- # ...
- # - root_paths - an array of paths representing the top level, where
- # org.json, members.json, and invites.json will be stored.
- # - chef_config - a hash of options that looks suspiciously like the ones
+ # [child_paths]
+ # A hash of child paths, e.g.:
+ # "nodes" => [ '/var/nodes', '/home/jkeiser/nodes' ],
+ # "roles" => [ '/var/roles' ],
+ # ...
+ # [root_paths]
+ # An array of paths representing the top level, where
+ # +org.json+, +members.json+, and +invites.json+ will be stored.
+ # [chef_config] - a hash of options that looks suspiciously like the ones
# stored in Chef::Config, containing at least these keys:
- # - :versioned_cookbooks - whether to include versions in cookbook names
+ # :versioned_cookbooks:: whether to include versions in cookbook names
def initialize(child_paths, root_paths=[], chef_config=Chef::Config)
super("", nil)
@child_paths = child_paths
diff --git a/lib/chef/chef_fs/file_system/chef_server_root_dir.rb b/lib/chef/chef_fs/file_system/chef_server_root_dir.rb
index 61a224c307..370308ee0a 100644
--- a/lib/chef/chef_fs/file_system/chef_server_root_dir.rb
+++ b/lib/chef/chef_fs/file_system/chef_server_root_dir.rb
@@ -46,19 +46,24 @@ class Chef
#
# == Parameters
#
- # - root_name - a friendly name for the root, for printing--like "remote" or "chef_central".
- # - chef_config - a hash with options that look suspiciously like Chef::Config, including the
- # following keys:
- # - :chef_server_url - the URL to the Chef server or top of the organization
- # - :node_name - the username to authenticate to the Chef server with
- # - :client_key - the private key for the user for authentication
- # - :environment - the environment in which you are presently working
- # - :repo_mode - the repository mode, :hosted_everything, :everything or :static.
- # This determines the set of subdirectories the Chef server
- # will offer up.
- # - :versioned_cookbooks - whether or not to include versions in cookbook names
- # - options - other options:
- # - :cookbook_version - when cookbooks are retrieved, grab this version for them.
+ # [root_name]
+ # A friendly name for the root, for printing--like "remote" or "chef_central".
+ # [chef_config]
+ # A hash with options that look suspiciously like Chef::Config, including the
+ # following keys:
+ # :chef_server_url:: The URL to the Chef server or top of the organization
+ # :node_name:: The username to authenticate to the Chef server with
+ # :client_key:: The private key for the user for authentication
+ # :environment:: The environment in which you are presently working
+ # :repo_mode::
+ # The repository mode, :hosted_everything, :everything or :static.
+ # This determines the set of subdirectories the Chef server will
+ # offer up.
+ # :versioned_cookbooks:: whether or not to include versions in cookbook names
+ # [options]
+ # Other options:
+ # :cookbook_version:: when cookbooks are retrieved, grab this version for them.
+ # :freeze:: freeze cookbooks on upload
#
def initialize(root_name, chef_config, options = {})
super("", nil)
diff --git a/lib/chef/client.rb b/lib/chef/client.rb
index 2de3ca3e64..161ecddb0f 100644
--- a/lib/chef/client.rb
+++ b/lib/chef/client.rb
@@ -44,6 +44,7 @@ require 'chef/resource_reporter'
require 'chef/run_lock'
require 'chef/policy_builder'
require 'chef/request_id'
+require 'chef/platform/rebooter'
require 'ohai'
require 'rbconfig'
@@ -427,7 +428,9 @@ class Chef
run_context = setup_run_context
- converge(run_context)
+ catch (:end_client_run_early) do
+ converge(run_context)
+ end
save_updated_node
@@ -435,6 +438,10 @@ class Chef
Chef::Log.info("Chef Run complete in #{run_status.elapsed_time} seconds")
run_completed_successfully
@events.run_completed(node)
+
+ # rebooting has to be the last thing we do, no exceptions.
+ Chef::Platform::Rebooter.reboot_if_needed!(node)
+
true
rescue Exception => e
# CHEF-3336: Send the error first in case something goes wrong below and we don't know why
diff --git a/lib/chef/config.rb b/lib/chef/config.rb
index 4e71645dcc..1963a95aab 100644
--- a/lib/chef/config.rb
+++ b/lib/chef/config.rb
@@ -587,6 +587,51 @@ class Chef
default :normal_attribute_whitelist, nil
default :override_attribute_whitelist, nil
+ # Chef requires an English-language UTF-8 locale to function properly. We attempt
+ # to use the 'locale -a' command and search through a list of preferences until we
+ # find one that we can use. On Ubuntu systems we should find 'C.UTF-8' and be
+ # able to use that even if there is no English locale on the server, but Mac, Solaris,
+ # AIX, etc do not have that locale. We then try to find an English locale and fall
+ # back to 'C' if we do not. The choice of fallback is pick-your-poison. If we try
+ # to do the work to return a non-US UTF-8 locale then we fail inside of providers when
+ # things like 'svn info' return Japanese and we can't parse them. OTOH, if we pick 'C' then
+ # we will blow up on UTF-8 characters. Between the warn we throw and the Encoding
+ # exception that ruby will throw it is more obvious what is broken if we drop UTF-8 by
+ # default rather than drop English.
+ #
+ # If there is no 'locale -a' then we return 'en_US.UTF-8' since that is the most commonly
+ # available English UTF-8 locale. However, all modern POSIXen should support 'locale -a'.
+ default :internal_locale do
+ begin
+ locales = `locale -a`.split
+ case
+ when locales.include?('C.UTF-8')
+ 'C.UTF-8'
+ when locales.include?('en_US.UTF-8')
+ 'en_US.UTF-8'
+ when locales.include?('en.UTF-8')
+ 'en.UTF-8'
+ when guesses = locales.select { |l| l =~ /^en_.*UTF-8$'/ }
+ guesses.first
+ else
+ Chef::Log.warn "Please install an English UTF-8 locale for Chef to use, falling back to C locale and disabling UTF-8 support."
+ 'C'
+ end
+ rescue
+ Chef::Log.warn "No usable locale -a command found, assuming you have en_US.UTF-8 installed."
+ 'en_US.UTF-8'
+ end
+ end
+
+ # Force UTF-8 Encoding, for when we fire up in the 'C' locale or other strange locales (e.g.
+ # japanese windows encodings). If we do not do this, then knife upload will fail when a cookbook's
+ # README.md has UTF-8 characters that do not encode in whatever surrounding encoding we have been
+ # passed. Effectively, the Chef Ecosystem is globally UTF-8 by default. Anyone who wants to be
+ # able to upload Shift_JIS or ISO-8859-1 files needs to mark *those* files explicitly with
+ # magic tags to make ruby correctly identify the encoding being used. Changing this default will
+ # break Chef community cookbooks and is very highly discouraged.
+ default :ruby_encoding, Encoding::UTF_8
+
# If installed via an omnibus installer, this gives the path to the
# "embedded" directory which contains all of the software packaged with
# omnibus. This is used to locate the cacert.pem file on windows.
diff --git a/lib/chef/dsl/reboot_pending.rb b/lib/chef/dsl/reboot_pending.rb
index 9f80d38c61..a81debce99 100644
--- a/lib/chef/dsl/reboot_pending.rb
+++ b/lib/chef/dsl/reboot_pending.rb
@@ -27,10 +27,13 @@ class Chef
include Chef::DSL::PlatformIntrospection
# Returns true if the system needs a reboot or is expected to reboot
- # Raises UnsupportedPlatform if this functionality isn't provided yet
+ # Note that we will silently miss any other platform-specific reboot notices besides Windows+Ubuntu.
def reboot_pending?
- if platform?("windows")
+ # don't break when used as a mixin in contexts without #node (e.g. specs).
+ if self.respond_to?(:node, true) && node.run_context.reboot_requested?
+ true
+ elsif platform?("windows")
# PendingFileRenameOperations contains pairs (REG_MULTI_SZ) of filenames that cannot be updated
# due to a file being in use (usually a temporary file and a system file)
# \??\c:\temp\test.sys!\??\c:\winnt\system32\test.sys
@@ -53,7 +56,7 @@ class Chef
# This should work for Debian as well if update-notifier-common happens to be installed. We need an API for that.
File.exists?('/var/run/reboot-required')
else
- raise Chef::Exceptions::UnsupportedPlatform.new(node[:platform])
+ false
end
end
end
diff --git a/lib/chef/knife/core/bootstrap_context.rb b/lib/chef/knife/core/bootstrap_context.rb
index 6bc48636c5..87c25ca160 100644
--- a/lib/chef/knife/core/bootstrap_context.rb
+++ b/lib/chef/knife/core/bootstrap_context.rb
@@ -44,8 +44,10 @@ class Chef
def encrypted_data_bag_secret
knife_config[:secret] || begin
- if knife_config[:secret_file] && File.exist?(knife_config[:secret_file])
- IO.read(File.expand_path(knife_config[:secret_file]))
+ secret_file_path = knife_config[:secret_file]
+ expanded_secret_file_path = File.expand_path(secret_file_path.to_s)
+ if secret_file_path && File.exist?(expanded_secret_file_path)
+ IO.read(expanded_secret_file_path)
else
nil
end
diff --git a/lib/chef/mixin/shell_out.rb b/lib/chef/mixin/shell_out.rb
index 881c94b862..82772b584a 100644
--- a/lib/chef/mixin/shell_out.rb
+++ b/lib/chef/mixin/shell_out.rb
@@ -30,32 +30,39 @@ class Chef
# Generally speaking, 'extend Chef::Mixin::ShellOut' in your recipes and include 'Chef::Mixin::ShellOut' in your LWRPs
# You can also call Mixlib::Shellout.new directly, but you lose all of the above functionality
+ # we use 'en_US.UTF-8' by default because we parse localized strings in English as an API and
+ # generally must support UTF-8 unicode.
def shell_out(*command_args)
- cmd = Mixlib::ShellOut.new(*run_command_compatible_options(command_args))
- cmd.live_stream ||= io_for_live_stream
- cmd.run_command
- cmd
+ args = command_args.dup
+ if args.last.is_a?(Hash)
+ options = args.pop.dup
+ env_key = options.has_key?(:env) ? :env : :environment
+ options[env_key] ||= {}
+ options[env_key] = options[env_key].dup
+ options[env_key]['LC_ALL'] ||= Chef::Config[:internal_locale] unless options[env_key].has_key?('LC_ALL')
+ args << options
+ else
+ args << { :environment => { 'LC_ALL' => Chef::Config[:internal_locale] } }
+ end
+
+ shell_out_command(*args)
end
+ # call shell_out (using en_US.UTF-8) and raise errors
def shell_out!(*command_args)
- cmd= shell_out(*command_args)
+ cmd = shell_out(*command_args)
cmd.error!
cmd
end
- # environment['LC_ALL'] should be nil or what the user specified
def shell_out_with_systems_locale(*command_args)
- args = command_args.dup
- if args.last.is_a?(Hash)
- options = args.last
- env_key = options.has_key?(:env) ? :env : :environment
- options[env_key] ||= {}
- options[env_key]['LC_ALL'] ||= nil
- else
- args << { :environment => { 'LC_ALL' => nil } }
- end
+ shell_out_command(*command_args)
+ end
- shell_out(*args)
+ def shell_out_with_systems_locale!(*command_args)
+ cmd = shell_out_with_systems_locale(*command_args)
+ cmd.error!
+ cmd
end
DEPRECATED_OPTIONS =
@@ -82,6 +89,13 @@ class Chef
private
+ def shell_out_command(*command_args)
+ cmd = Mixlib::ShellOut.new(*run_command_compatible_options(command_args))
+ cmd.live_stream ||= io_for_live_stream
+ cmd.run_command
+ cmd
+ end
+
def deprecate_option(old_option, new_option)
Chef::Log.logger.warn "DEPRECATION: Chef::Mixin::ShellOut option :#{old_option} is deprecated. Use :#{new_option}"
end
diff --git a/lib/chef/platform/rebooter.rb b/lib/chef/platform/rebooter.rb
new file mode 100644
index 0000000000..b46f0e394c
--- /dev/null
+++ b/lib/chef/platform/rebooter.rb
@@ -0,0 +1,54 @@
+#
+# Author:: Chris Doherty <cdoherty@getchef.com>)
+# Copyright:: Copyright (c) 2014 Chef, 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 'chef/dsl/reboot_pending'
+require 'chef/log'
+require 'chef/platform'
+
+class Chef
+ class Platform
+ module Rebooter
+ extend Chef::Mixin::ShellOut
+
+ class << self
+
+ def reboot!(node)
+ reboot_info = node.run_context.reboot_info
+
+ cmd = if Chef::Platform.windows?
+ # should this do /f as well? do we then need a minimum delay to let apps quit?
+ "shutdown /r /t #{reboot_info[:delay_mins]} /c \"#{reboot_info[:reason]}\""
+ else
+ # probably Linux-only.
+ "shutdown -r +#{reboot_info[:delay_mins]} \"#{reboot_info[:reason]}\""
+ end
+
+ Chef::Log.warn "Rebooting server at a recipe's request. Details: #{reboot_info.inspect}"
+ shell_out!(cmd)
+ end
+
+ # this is a wrapper function so Chef::Client only needs a single line of code.
+ def reboot_if_needed!(node)
+ if node.run_context.reboot_requested?
+ reboot!(node)
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/chef/provider/ifconfig.rb b/lib/chef/provider/ifconfig.rb
index 31f88e5406..ac52100b56 100644
--- a/lib/chef/provider/ifconfig.rb
+++ b/lib/chef/provider/ifconfig.rb
@@ -19,6 +19,7 @@
require 'chef/log'
require 'chef/mixin/command'
require 'chef/provider'
+require 'chef/resource/file'
require 'chef/exceptions'
require 'erb'
@@ -109,11 +110,11 @@ class Chef
:command => command
)
Chef::Log.info("#{@new_resource} added")
- # Write out the config files
- generate_config
end
end
end
+ # Write out the config files
+ generate_config
end
def action_enable
@@ -140,12 +141,12 @@ class Chef
run_command(
:command => command
)
- delete_config
Chef::Log.info("#{@new_resource} deleted")
end
else
Chef::Log.debug("#{@new_resource} does not exist - nothing to do")
end
+ delete_config
end
def action_disable
@@ -168,27 +169,25 @@ class Chef
! @config_template.nil? and ! @config_path.nil?
end
+ def resource_for_config(path)
+ Chef::Resource::File.new(path, run_context)
+ end
+
def generate_config
return unless can_generate_config?
b = binding
template = ::ERB.new(@config_template)
- converge_by ("generate configuration file : #{@config_path}") do
- network_file = ::File.new(@config_path, "w")
- network_file.puts(template.result(b))
- network_file.close
- end
- Chef::Log.info("#{@new_resource} created configuration file")
+ config = resource_for_config(@config_path)
+ config.content(template.result(b))
+ config.run_action(:create)
+ @new_resource.updated_by_last_action(true) if config.updated?
end
def delete_config
return unless can_generate_config?
- require 'fileutils'
- if ::File.exist?(@config_path)
- converge_by ("delete the #{@config_path}") do
- FileUtils.rm_f(@config_path, :verbose => false)
- end
- end
- Chef::Log.info("#{@new_resource} deleted configuration file")
+ config = resource_for_config(@config_path)
+ config.run_action(:delete)
+ @new_resource.updated_by_last_action(true) if config.updated?
end
private
diff --git a/lib/chef/provider/link.rb b/lib/chef/provider/link.rb
index d6602c2e03..af2fe4a84f 100644
--- a/lib/chef/provider/link.rb
+++ b/lib/chef/provider/link.rb
@@ -83,7 +83,7 @@ class Chef
end
def canonicalize(path)
- Chef::Platform.windows? ? path.gsub('/', '\\') : path
+ Chef::Util::PathHelper.canonical_path(path)
end
def action_create
diff --git a/lib/chef/provider/package/aix.rb b/lib/chef/provider/package/aix.rb
index 9fb87d6ea0..da3e6d1684 100644
--- a/lib/chef/provider/package/aix.rb
+++ b/lib/chef/provider/package/aix.rb
@@ -112,14 +112,10 @@ class Chef
def install_package(name, version)
Chef::Log.debug("#{@new_resource} package install options: #{@new_resource.options}")
if @new_resource.options.nil?
- run_command_with_systems_locale(
- :command => "installp -aYF -d #{@new_resource.source} #{@new_resource.package_name}"
- )
+ shell_out!( "installp -aYF -d #{@new_resource.source} #{@new_resource.package_name}" )
Chef::Log.debug("#{@new_resource} installed version #{@new_resource.version} from: #{@new_resource.source}")
else
- run_command_with_systems_locale(
- :command => "installp -aYF #{expand_options(@new_resource.options)} -d #{@new_resource.source} #{@new_resource.package_name}"
- )
+ shell_out!( "installp -aYF #{expand_options(@new_resource.options)} -d #{@new_resource.source} #{@new_resource.package_name}" )
Chef::Log.debug("#{@new_resource} installed version #{@new_resource.version} from: #{@new_resource.source}")
end
end
@@ -128,14 +124,10 @@ class Chef
def remove_package(name, version)
if @new_resource.options.nil?
- run_command_with_systems_locale(
- :command => "installp -u #{name}"
- )
+ shell_out!( "installp -u #{name}" )
Chef::Log.debug("#{@new_resource} removed version #{@new_resource.version}")
else
- run_command_with_systems_locale(
- :command => "installp -u #{expand_options(@new_resource.options)} #{name}"
- )
+ shell_out!( "installp -u #{expand_options(@new_resource.options)} #{name}" )
Chef::Log.debug("#{@new_resource} removed version #{@new_resource.version}")
end
end
diff --git a/lib/chef/provider/package/ips.rb b/lib/chef/provider/package/ips.rb
index 92b41b3627..4090507303 100644
--- a/lib/chef/provider/package/ips.rb
+++ b/lib/chef/provider/package/ips.rb
@@ -65,15 +65,13 @@ class Chef
def install_package(name, version)
package_name = "#{name}@#{version}"
normal_command = "pkg#{expand_options(@new_resource.options)} install -q #{package_name}"
- if @new_resource.respond_to?(:accept_license) and @new_resource.accept_license
- command = normal_command.gsub('-q', '-q --accept')
- else
- command = normal_command
- end
- begin
- run_command_with_systems_locale(:command => command)
- rescue
- end
+ command =
+ if @new_resource.respond_to?(:accept_license) and @new_resource.accept_license
+ normal_command.gsub('-q', '-q --accept')
+ else
+ normal_command
+ end
+ shell_out(command)
end
def upgrade_package(name, version)
@@ -82,9 +80,7 @@ class Chef
def remove_package(name, version)
package_name = "#{name}@#{version}"
- run_command_with_systems_locale(
- :command => "pkg#{expand_options(@new_resource.options)} uninstall -q #{package_name}"
- )
+ shell_out!( "pkg#{expand_options(@new_resource.options)} uninstall -q #{package_name}" )
end
end
end
diff --git a/lib/chef/provider/package/macports.rb b/lib/chef/provider/package/macports.rb
index 6ef303ee4f..05247e6d31 100644
--- a/lib/chef/provider/package/macports.rb
+++ b/lib/chef/provider/package/macports.rb
@@ -45,27 +45,21 @@ class Chef
unless @current_resource.version == version
command = "port#{expand_options(@new_resource.options)} install #{name}"
command << " @#{version}" if version and !version.empty?
- run_command_with_systems_locale(
- :command => command
- )
+ shell_out!(command)
end
end
def purge_package(name, version)
command = "port#{expand_options(@new_resource.options)} uninstall #{name}"
command << " @#{version}" if version and !version.empty?
- run_command_with_systems_locale(
- :command => command
- )
+ shell_out!(command)
end
def remove_package(name, version)
command = "port#{expand_options(@new_resource.options)} deactivate #{name}"
command << " @#{version}" if version and !version.empty?
- run_command_with_systems_locale(
- :command => command
- )
+ shell_out!(command)
end
def upgrade_package(name, version)
@@ -78,9 +72,7 @@ class Chef
# that hasn't been installed.
install_package(name, version)
elsif current_version != version
- run_command_with_systems_locale(
- :command => "port#{expand_options(@new_resource.options)} upgrade #{name} @#{version}"
- )
+ shell_out!( "port#{expand_options(@new_resource.options)} upgrade #{name} @#{version}" )
end
end
diff --git a/lib/chef/provider/package/pacman.rb b/lib/chef/provider/package/pacman.rb
index 2e8bb7850b..1014ebcaa5 100644
--- a/lib/chef/provider/package/pacman.rb
+++ b/lib/chef/provider/package/pacman.rb
@@ -86,9 +86,7 @@ class Chef
end
def install_package(name, version)
- run_command_with_systems_locale(
- :command => "pacman --sync --noconfirm --noprogressbar#{expand_options(@new_resource.options)} #{name}"
- )
+ shell_out!( "pacman --sync --noconfirm --noprogressbar#{expand_options(@new_resource.options)} #{name}" )
end
def upgrade_package(name, version)
@@ -96,9 +94,7 @@ class Chef
end
def remove_package(name, version)
- run_command_with_systems_locale(
- :command => "pacman --remove --noconfirm --noprogressbar#{expand_options(@new_resource.options)} #{name}"
- )
+ shell_out!( "pacman --remove --noconfirm --noprogressbar#{expand_options(@new_resource.options)} #{name}" )
end
def purge_package(name, version)
diff --git a/lib/chef/provider/package/portage.rb b/lib/chef/provider/package/portage.rb
index 6a3587558a..7e0eebd0d9 100644
--- a/lib/chef/provider/package/portage.rb
+++ b/lib/chef/provider/package/portage.rb
@@ -110,9 +110,7 @@ class Chef
pkg = "~#{name}-#{$1}"
end
- run_command_with_systems_locale(
- :command => "emerge -g --color n --nospinner --quiet#{expand_options(@new_resource.options)} #{pkg}"
- )
+ shell_out!( "emerge -g --color n --nospinner --quiet#{expand_options(@new_resource.options)} #{pkg}" )
end
def upgrade_package(name, version)
@@ -126,9 +124,7 @@ class Chef
pkg = "#{@new_resource.package_name}"
end
- run_command_with_systems_locale(
- :command => "emerge --unmerge --color n --nospinner --quiet#{expand_options(@new_resource.options)} #{pkg}"
- )
+ shell_out!( "emerge --unmerge --color n --nospinner --quiet#{expand_options(@new_resource.options)} #{pkg}" )
end
def purge_package(name, version)
diff --git a/lib/chef/provider/package/rpm.rb b/lib/chef/provider/package/rpm.rb
index bbb561bd15..c0a6444252 100644
--- a/lib/chef/provider/package/rpm.rb
+++ b/lib/chef/provider/package/rpm.rb
@@ -90,13 +90,9 @@ class Chef
def install_package(name, version)
unless @current_resource.version
- run_command_with_systems_locale(
- :command => "rpm #{@new_resource.options} -i #{@new_resource.source}"
- )
+ shell_out!( "rpm #{@new_resource.options} -i #{@new_resource.source}" )
else
- run_command_with_systems_locale(
- :command => "rpm #{@new_resource.options} -U #{@new_resource.source}"
- )
+ shell_out!( "rpm #{@new_resource.options} -U #{@new_resource.source}" )
end
end
@@ -104,13 +100,9 @@ class Chef
def remove_package(name, version)
if version
- run_command_with_systems_locale(
- :command => "rpm #{@new_resource.options} -e #{name}-#{version}"
- )
+ shell_out!( "rpm #{@new_resource.options} -e #{name}-#{version}" )
else
- run_command_with_systems_locale(
- :command => "rpm #{@new_resource.options} -e #{name}"
- )
+ shell_out!( "rpm #{@new_resource.options} -e #{name}" )
end
end
diff --git a/lib/chef/provider/package/solaris.rb b/lib/chef/provider/package/solaris.rb
index 0f45b61e18..19f844b66a 100644
--- a/lib/chef/provider/package/solaris.rb
+++ b/lib/chef/provider/package/solaris.rb
@@ -112,9 +112,7 @@ class Chef
else
command = "pkgadd -n -d #{@new_resource.source} all"
end
- run_command_with_systems_locale(
- :command => command
- )
+ shell_out!(command)
Chef::Log.debug("#{@new_resource} installed version #{@new_resource.version} from: #{@new_resource.source}")
else
if ::File.directory?(@new_resource.source) # CHEF-4469
@@ -122,23 +120,17 @@ class Chef
else
command = "pkgadd -n#{expand_options(@new_resource.options)} -d #{@new_resource.source} all"
end
- run_command_with_systems_locale(
- :command => command
- )
+ shell_out!(command)
Chef::Log.debug("#{@new_resource} installed version #{@new_resource.version} from: #{@new_resource.source}")
end
end
def remove_package(name, version)
if @new_resource.options.nil?
- run_command_with_systems_locale(
- :command => "pkgrm -n #{name}"
- )
+ shell_out!( "pkgrm -n #{name}" )
Chef::Log.debug("#{@new_resource} removed version #{@new_resource.version}")
else
- run_command_with_systems_locale(
- :command => "pkgrm -n#{expand_options(@new_resource.options)} #{name}"
- )
+ shell_out!( "pkgrm -n#{expand_options(@new_resource.options)} #{name}" )
Chef::Log.debug("#{@new_resource} removed version #{@new_resource.version}")
end
end
diff --git a/lib/chef/provider/reboot.rb b/lib/chef/provider/reboot.rb
new file mode 100644
index 0000000000..8dde4653ec
--- /dev/null
+++ b/lib/chef/provider/reboot.rb
@@ -0,0 +1,69 @@
+#
+# Author:: Chris Doherty <cdoherty@getchef.com>)
+# Copyright:: Copyright (c) 2014 Chef, 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 'chef/log'
+require 'chef/provider'
+
+class Chef
+ class Provider
+ class Reboot < Chef::Provider
+
+ def whyrun_supported?
+ true
+ end
+
+ def load_current_resource
+ @current_resource ||= Chef::Resource::Reboot.new(@new_resource.name)
+ @current_resource.reason(@new_resource.reason)
+ @current_resource.delay_mins(@new_resource.delay_mins)
+ @current_resource
+ end
+
+ def request_reboot
+ node.run_context.request_reboot(
+ :delay_mins => @new_resource.delay_mins,
+ :reason => @new_resource.reason,
+ :timestamp => Time.now,
+ :requested_by => @new_resource.name
+ )
+ end
+
+ def action_request_reboot
+ converge_by("request a system reboot to occur if the run succeeds") do
+ Chef::Log.warn "Reboot requested:'#{@new_resource.name}'"
+ request_reboot
+ end
+ end
+
+ def action_reboot_now
+ converge_by("rebooting the system immediately") do
+ Chef::Log.warn "Rebooting system immediately, requested by '#{@new_resource.name}'"
+ request_reboot
+ throw :end_client_run_early
+ end
+ end
+
+ def action_cancel
+ converge_by("cancel any existing end-of-run reboot request") do
+ Chef::Log.warn "Reboot canceled: '#{@new_resource.name}'"
+ node.run_context.cancel_reboot
+ end
+ end
+ end
+ end
+end
diff --git a/lib/chef/provider/service/debian.rb b/lib/chef/provider/service/debian.rb
index 06fe7fc480..1ebef90349 100644
--- a/lib/chef/provider/service/debian.rb
+++ b/lib/chef/provider/service/debian.rb
@@ -130,15 +130,15 @@ class Chef
def enable_service
if @new_resource.priority.is_a? Integer
- run_command(:command => "/usr/sbin/update-rc.d -f #{@new_resource.service_name} remove")
- run_command(:command => "/usr/sbin/update-rc.d #{@new_resource.service_name} defaults #{@new_resource.priority} #{100 - @new_resource.priority}")
+ shell_out!("/usr/sbin/update-rc.d -f #{@new_resource.service_name} remove")
+ shell_out!("/usr/sbin/update-rc.d #{@new_resource.service_name} defaults #{@new_resource.priority} #{100 - @new_resource.priority}")
elsif @new_resource.priority.is_a? Hash
# we call the same command regardless of we're enabling or disabling
# users passing a Hash are responsible for setting their own start priorities
set_priority
else # No priority, go with update-rc.d defaults
- run_command(:command => "/usr/sbin/update-rc.d -f #{@new_resource.service_name} remove")
- run_command(:command => "/usr/sbin/update-rc.d #{@new_resource.service_name} defaults")
+ shell_out!("/usr/sbin/update-rc.d -f #{@new_resource.service_name} remove")
+ shell_out!("/usr/sbin/update-rc.d #{@new_resource.service_name} defaults")
end
end
@@ -146,16 +146,16 @@ class Chef
def disable_service
if @new_resource.priority.is_a? Integer
# Stop processes in reverse order of start using '100 - start_priority'
- run_command(:command => "/usr/sbin/update-rc.d -f #{@new_resource.service_name} remove")
- run_command(:command => "/usr/sbin/update-rc.d -f #{@new_resource.service_name} stop #{100 - @new_resource.priority} 2 3 4 5 .")
+ shell_out!("/usr/sbin/update-rc.d -f #{@new_resource.service_name} remove")
+ shell_out!("/usr/sbin/update-rc.d -f #{@new_resource.service_name} stop #{100 - @new_resource.priority} 2 3 4 5 .")
elsif @new_resource.priority.is_a? Hash
# we call the same command regardless of we're enabling or disabling
# users passing a Hash are responsible for setting their own stop priorities
set_priority
else
# no priority, using '100 - 20 (update-rc.d default)' to stop in reverse order of start
- run_command(:command => "/usr/sbin/update-rc.d -f #{@new_resource.service_name} remove")
- run_command(:command => "/usr/sbin/update-rc.d -f #{@new_resource.service_name} stop 80 2 3 4 5 .")
+ shell_out!("/usr/sbin/update-rc.d -f #{@new_resource.service_name} remove")
+ shell_out!("/usr/sbin/update-rc.d -f #{@new_resource.service_name} stop 80 2 3 4 5 .")
end
end
@@ -166,8 +166,8 @@ class Chef
priority = o[1]
args += "#{action} #{priority} #{level} . "
end
- run_command(:command => "/usr/sbin/update-rc.d -f #{@new_resource.service_name} remove")
- run_command(:command => "/usr/sbin/update-rc.d #{@new_resource.service_name} #{args}")
+ shell_out!("/usr/sbin/update-rc.d -f #{@new_resource.service_name} remove")
+ shell_out!("/usr/sbin/update-rc.d #{@new_resource.service_name} #{args}")
end
end
end
diff --git a/lib/chef/provider/service/freebsd.rb b/lib/chef/provider/service/freebsd.rb
index 7b69957cc6..08d58232e1 100644
--- a/lib/chef/provider/service/freebsd.rb
+++ b/lib/chef/provider/service/freebsd.rb
@@ -78,7 +78,7 @@ class Chef
if new_resource.start_command
super
else
- shell_out!("#{init_command} faststart")
+ shell_out_with_systems_locale!("#{init_command} faststart")
end
end
@@ -86,7 +86,7 @@ class Chef
if new_resource.stop_command
super
else
- shell_out!("#{init_command} faststop")
+ shell_out_with_systems_locale!("#{init_command} faststop")
end
end
@@ -94,7 +94,7 @@ class Chef
if new_resource.restart_command
super
elsif new_resource.supports[:restart]
- shell_out!("#{init_command} fastrestart")
+ shell_out_with_systems_locale!("#{init_command} fastrestart")
else
stop_service
sleep 1
diff --git a/lib/chef/provider/service/gentoo.rb b/lib/chef/provider/service/gentoo.rb
index 1559c7893f..a68abfebc9 100644
--- a/lib/chef/provider/service/gentoo.rb
+++ b/lib/chef/provider/service/gentoo.rb
@@ -58,10 +58,10 @@ class Chef::Provider::Service::Gentoo < Chef::Provider::Service::Init
end
def enable_service()
- run_command(:command => "/sbin/rc-update add #{@new_resource.service_name} default")
+ shell_out!("/sbin/rc-update add #{@new_resource.service_name} default")
end
def disable_service()
- run_command(:command => "/sbin/rc-update del #{@new_resource.service_name} default")
+ shell_out!("/sbin/rc-update del #{@new_resource.service_name} default")
end
end
diff --git a/lib/chef/provider/service/init.rb b/lib/chef/provider/service/init.rb
index 23d9dde80a..5d8bb5bb38 100644
--- a/lib/chef/provider/service/init.rb
+++ b/lib/chef/provider/service/init.rb
@@ -50,7 +50,7 @@ class Chef
if @new_resource.start_command
super
else
- shell_out!("#{default_init_command} start")
+ shell_out_with_systems_locale!("#{default_init_command} start")
end
end
@@ -58,7 +58,7 @@ class Chef
if @new_resource.stop_command
super
else
- shell_out!("#{default_init_command} stop")
+ shell_out_with_systems_locale!("#{default_init_command} stop")
end
end
@@ -66,7 +66,7 @@ class Chef
if @new_resource.restart_command
super
elsif @new_resource.supports[:restart]
- shell_out!("#{default_init_command} restart")
+ shell_out_with_systems_locale!("#{default_init_command} restart")
else
stop_service
sleep 1
@@ -78,7 +78,7 @@ class Chef
if @new_resource.reload_command
super
elsif @new_resource.supports[:reload]
- shell_out!("#{default_init_command} reload")
+ shell_out_with_systems_locale!("#{default_init_command} reload")
end
end
end
diff --git a/lib/chef/provider/service/insserv.rb b/lib/chef/provider/service/insserv.rb
index 35767ee7b9..f4c85dd9d3 100644
--- a/lib/chef/provider/service/insserv.rb
+++ b/lib/chef/provider/service/insserv.rb
@@ -37,12 +37,12 @@ class Chef
end
def enable_service()
- run_command(:command => "/sbin/insserv -r -f #{@new_resource.service_name}")
- run_command(:command => "/sbin/insserv -d -f #{@new_resource.service_name}")
+ shell_out!("/sbin/insserv -r -f #{@new_resource.service_name}")
+ shell_out!("/sbin/insserv -d -f #{@new_resource.service_name}")
end
def disable_service()
- run_command(:command => "/sbin/insserv -r -f #{@new_resource.service_name}")
+ shell_out!("/sbin/insserv -r -f #{@new_resource.service_name}")
end
end
end
diff --git a/lib/chef/provider/service/macosx.rb b/lib/chef/provider/service/macosx.rb
index 36930ee4ac..cf5e554559 100644
--- a/lib/chef/provider/service/macosx.rb
+++ b/lib/chef/provider/service/macosx.rb
@@ -83,7 +83,7 @@ class Chef
if @new_resource.start_command
super
else
- shell_out!("launchctl load -w '#{@plist}'", :user => @owner_uid, :group => @owner_gid)
+ shell_out_with_systems_locale!("launchctl load -w '#{@plist}'", :user => @owner_uid, :group => @owner_gid)
end
end
end
@@ -95,7 +95,7 @@ class Chef
if @new_resource.stop_command
super
else
- shell_out!("launchctl unload '#{@plist}'", :user => @owner_uid, :group => @owner_gid)
+ shell_out_with_systems_locale!("launchctl unload '#{@plist}'", :user => @owner_uid, :group => @owner_gid)
end
end
end
diff --git a/lib/chef/provider/service/simple.rb b/lib/chef/provider/service/simple.rb
index 0eb983a0bf..bd51d15f84 100644
--- a/lib/chef/provider/service/simple.rb
+++ b/lib/chef/provider/service/simple.rb
@@ -85,16 +85,16 @@ class Chef
end
def start_service
- shell_out!(@new_resource.start_command)
+ shell_out_with_systems_locale!(@new_resource.start_command)
end
def stop_service
- shell_out!(@new_resource.stop_command)
+ shell_out_with_systems_locale!(@new_resource.stop_command)
end
def restart_service
if @new_resource.restart_command
- shell_out!(@new_resource.restart_command)
+ shell_out_with_systems_locale!(@new_resource.restart_command)
else
stop_service
sleep 1
@@ -103,7 +103,7 @@ class Chef
end
def reload_service
- shell_out!(@new_resource.reload_command)
+ shell_out_with_systems_locale!(@new_resource.reload_command)
end
protected
diff --git a/lib/chef/provider/service/solaris.rb b/lib/chef/provider/service/solaris.rb
index 0c47a3462b..f0584dcf6d 100644
--- a/lib/chef/provider/service/solaris.rb
+++ b/lib/chef/provider/service/solaris.rb
@@ -56,7 +56,7 @@ class Chef
alias_method :start_service, :enable_service
def reload_service
- shell_out!("#{default_init_command} refresh #{@new_resource.service_name}")
+ shell_out_with_systems_locale!("#{default_init_command} refresh #{@new_resource.service_name}")
end
def restart_service
diff --git a/lib/chef/provider/service/systemd.rb b/lib/chef/provider/service/systemd.rb
index 6231603d03..31feee65d4 100644
--- a/lib/chef/provider/service/systemd.rb
+++ b/lib/chef/provider/service/systemd.rb
@@ -28,7 +28,7 @@ class Chef::Provider::Service::Systemd < Chef::Provider::Service::Simple
if @new_resource.status_command
Chef::Log.debug("#{@new_resource} you have specified a status command, running..")
- unless shell_out_with_systems_locale(@new_resource.status_command).error?
+ unless shell_out(@new_resource.status_command).error?
@current_resource.running(true)
else
@status_check_success = false
@@ -61,7 +61,7 @@ class Chef::Provider::Service::Systemd < Chef::Provider::Service::Simple
if @new_resource.start_command
super
else
- shell_out_with_systems_locale("/bin/systemctl start #{@new_resource.service_name}")
+ shell_out_with_systems_locale!("/bin/systemctl start #{@new_resource.service_name}")
end
end
end
@@ -73,7 +73,7 @@ class Chef::Provider::Service::Systemd < Chef::Provider::Service::Simple
if @new_resource.stop_command
super
else
- shell_out_with_systems_locale("/bin/systemctl stop #{@new_resource.service_name}")
+ shell_out_with_systems_locale!("/bin/systemctl stop #{@new_resource.service_name}")
end
end
end
@@ -82,7 +82,7 @@ class Chef::Provider::Service::Systemd < Chef::Provider::Service::Simple
if @new_resource.restart_command
super
else
- shell_out_with_systems_locale("/bin/systemctl restart #{@new_resource.service_name}")
+ shell_out_with_systems_locale!("/bin/systemctl restart #{@new_resource.service_name}")
end
end
@@ -91,7 +91,7 @@ class Chef::Provider::Service::Systemd < Chef::Provider::Service::Simple
super
else
if @current_resource.running
- shell_out_with_systems_locale("/bin/systemctl reload #{@new_resource.service_name}")
+ shell_out_with_systems_locale!("/bin/systemctl reload #{@new_resource.service_name}")
else
start_service
end
@@ -99,18 +99,18 @@ class Chef::Provider::Service::Systemd < Chef::Provider::Service::Simple
end
def enable_service
- shell_out_with_systems_locale("/bin/systemctl enable #{@new_resource.service_name}")
+ shell_out!("/bin/systemctl enable #{@new_resource.service_name}")
end
def disable_service
- shell_out_with_systems_locale("/bin/systemctl disable #{@new_resource.service_name}")
+ shell_out!("/bin/systemctl disable #{@new_resource.service_name}")
end
def is_active?
- shell_out_with_systems_locale("/bin/systemctl is-active #{@new_resource.service_name} --quiet").exitstatus == 0
+ shell_out("/bin/systemctl is-active #{@new_resource.service_name} --quiet").exitstatus == 0
end
def is_enabled?
- shell_out_with_systems_locale("/bin/systemctl is-enabled #{@new_resource.service_name} --quiet").exitstatus == 0
+ shell_out("/bin/systemctl is-enabled #{@new_resource.service_name} --quiet").exitstatus == 0
end
end
diff --git a/lib/chef/provider/service/upstart.rb b/lib/chef/provider/service/upstart.rb
index c81a8a50dc..670bf9e5f8 100644
--- a/lib/chef/provider/service/upstart.rb
+++ b/lib/chef/provider/service/upstart.rb
@@ -97,10 +97,10 @@ class Chef
Chef::Log.debug("#{@new_resource} you have specified a status command, running..")
begin
- if run_command_with_systems_locale(:command => @new_resource.status_command) == 0
+ if shell_out!(@new_resource.status_command) == 0
@current_resource.running true
end
- rescue Chef::Exceptions::Exec
+ rescue
@command_success = false
@current_resource.running false
nil
@@ -153,7 +153,7 @@ class Chef
if @new_resource.start_command
super
else
- run_command_with_systems_locale(:command => "/sbin/start #{@job}")
+ shell_out_with_systems_locale!("/sbin/start #{@job}")
end
end
end
@@ -167,7 +167,7 @@ class Chef
if @new_resource.stop_command
super
else
- run_command_with_systems_locale(:command => "/sbin/stop #{@job}")
+ shell_out_with_systems_locale!("/sbin/stop #{@job}")
end
end
end
@@ -179,7 +179,7 @@ class Chef
# Older versions of upstart would fail on restart if the service was currently stopped, check for that. LP:430883
else
if @current_resource.running
- run_command_with_systems_locale(:command => "/sbin/restart #{@job}")
+ shell_out_with_systems_locale!("/sbin/restart #{@job}")
else
start_service
end
@@ -191,7 +191,7 @@ class Chef
super
else
# upstart >= 0.6.3-4 supports reload (HUP)
- run_command_with_systems_locale(:command => "/sbin/reload #{@job}")
+ shell_out_with_systems_locale!("/sbin/reload #{@job}")
end
end
diff --git a/lib/chef/provider/subversion.rb b/lib/chef/provider/subversion.rb
index 81ed639c53..6cf31c8ec8 100644
--- a/lib/chef/provider/subversion.rb
+++ b/lib/chef/provider/subversion.rb
@@ -60,7 +60,7 @@ class Chef
def action_checkout
if target_dir_non_existent_or_empty?
converge_by("perform checkout of #{@new_resource.repository} into #{@new_resource.destination}") do
- run_command(run_options(:command => checkout_command))
+ shell_out!(run_options(command: checkout_command))
end
else
Chef::Log.debug "#{@new_resource} checkout destination #{@new_resource.destination} already exists or is a non-empty directory - nothing to do"
@@ -77,7 +77,7 @@ class Chef
def action_force_export
converge_by("export #{@new_resource.repository} into #{@new_resource.destination}") do
- run_command(run_options(:command => export_command))
+ shell_out!(run_options(command: export_command))
end
end
@@ -88,7 +88,7 @@ class Chef
Chef::Log.debug "#{@new_resource} current revision: #{current_rev} target revision: #{revision_int}"
unless current_revision_matches_target_revision?
converge_by("sync #{@new_resource.destination} from #{@new_resource.repository}") do
- run_command(run_options(:command => sync_command))
+ shell_out!(run_options(command: sync_command))
Chef::Log.info "#{@new_resource} updated to revision: #{revision_int}"
end
end
@@ -100,14 +100,14 @@ class Chef
def sync_command
c = scm :update, @new_resource.svn_arguments, verbose, authentication, "-r#{revision_int}", @new_resource.destination
Chef::Log.debug "#{@new_resource} updated working copy #{@new_resource.destination} to revision #{@new_resource.revision}"
- c
+ c
end
def checkout_command
c = scm :checkout, @new_resource.svn_arguments, verbose, authentication,
"-r#{revision_int}", @new_resource.repository, @new_resource.destination
Chef::Log.info "#{@new_resource} checked out #{@new_resource.repository} at revision #{@new_resource.revision} to #{@new_resource.destination}"
- c
+ c
end
def export_command
@@ -116,7 +116,7 @@ class Chef
"-r#{revision_int}" << @new_resource.repository << @new_resource.destination
c = scm :export, *args
Chef::Log.info "#{@new_resource} exported #{@new_resource.repository} at revision #{@new_resource.revision} to #{@new_resource.destination}"
- c
+ c
end
# If the specified revision isn't an integer ("HEAD" for example), look
diff --git a/lib/chef/provider/whyrun_safe_ruby_block.rb b/lib/chef/provider/whyrun_safe_ruby_block.rb
index 4b491a4f60..e5f35debd7 100644
--- a/lib/chef/provider/whyrun_safe_ruby_block.rb
+++ b/lib/chef/provider/whyrun_safe_ruby_block.rb
@@ -19,7 +19,7 @@
class Chef
class Provider
class WhyrunSafeRubyBlock < Chef::Provider::RubyBlock
- def action_create
+ def action_run
@new_resource.block.call
@new_resource.updated_by_last_action(true)
@run_context.events.resource_update_applied(@new_resource, :create, "execute the whyrun_safe_ruby_block #{@new_resource.name}")
diff --git a/lib/chef/providers.rb b/lib/chef/providers.rb
index 3c9e94e6f7..1b0ff3ffff 100644
--- a/lib/chef/providers.rb
+++ b/lib/chef/providers.rb
@@ -39,6 +39,7 @@ require 'chef/provider/mdadm'
require 'chef/provider/mount'
require 'chef/provider/package'
require 'chef/provider/powershell_script'
+require 'chef/provider/reboot'
require 'chef/provider/remote_directory'
require 'chef/provider/remote_file'
require 'chef/provider/route'
diff --git a/lib/chef/resource/reboot.rb b/lib/chef/resource/reboot.rb
new file mode 100644
index 0000000000..d6caafdea8
--- /dev/null
+++ b/lib/chef/resource/reboot.rb
@@ -0,0 +1,48 @@
+#
+# Author:: Chris Doherty <cdoherty@getchef.com>)
+# Copyright:: Copyright (c) 2014 Chef, 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 'chef/resource'
+
+# In using this resource via notifications, it's important to *only* use
+# immediate notifications. Delayed notifications produce unintuitive and
+# probably undesired results.
+class Chef
+ class Resource
+ class Reboot < Chef::Resource
+ def initialize(name, run_context=nil)
+ super
+ @resource_name = :reboot
+ @provider = Chef::Provider::Reboot
+ @allowed_actions = [:request_reboot, :reboot_now, :cancel]
+
+ @reason = "Reboot by Chef"
+ @delay_mins = 0
+
+ # no default action.
+ end
+
+ def reason(arg=nil)
+ set_or_return(:reason, arg, :kind_of => String)
+ end
+
+ def delay_mins(arg=nil)
+ set_or_return(:delay_mins, arg, :kind_of => Fixnum)
+ end
+ end
+ end
+end
diff --git a/lib/chef/resources.rb b/lib/chef/resources.rb
index 93ff682288..8c2f71bd30 100644
--- a/lib/chef/resources.rb
+++ b/lib/chef/resources.rb
@@ -53,6 +53,7 @@ require 'chef/resource/perl'
require 'chef/resource/portage_package'
require 'chef/resource/powershell_script'
require 'chef/resource/python'
+require 'chef/resource/reboot'
require 'chef/resource/registry_key'
require 'chef/resource/remote_directory'
require 'chef/resource/remote_file'
diff --git a/lib/chef/run_context.rb b/lib/chef/run_context.rb
index 3dd53f0f8f..bbe2f9eba0 100644
--- a/lib/chef/run_context.rb
+++ b/lib/chef/run_context.rb
@@ -61,6 +61,9 @@ class Chef
# Event dispatcher for this run.
attr_reader :events
+ # Hash of factoids for a reboot request.
+ attr_reader :reboot_info
+
# Creates a new Chef::RunContext object and populates its fields. This object gets
# used by the Chef Server to generate a fully compiled recipe list for a node.
#
@@ -76,6 +79,7 @@ class Chef
@loaded_recipes = {}
@loaded_attributes = {}
@events = events
+ @reboot_info = {}
@node.run_context = self
@@ -271,6 +275,27 @@ ERROR_MESSAGE
end
end
+ # there are options for how to handle multiple calls to these functions:
+ # 1. first call always wins (never change @reboot_info once set).
+ # 2. last call always wins (happily change @reboot_info whenever).
+ # 3. raise an exception on the first conflict.
+ # 4. disable reboot after this run if anyone ever calls :cancel.
+ # 5. raise an exception on any second call.
+ # 6. ?
+ def request_reboot(reboot_info)
+ Chef::Log::info "Changing reboot status from #{@reboot_info.inspect} to #{reboot_info.inspect}"
+ @reboot_info = reboot_info
+ end
+
+ def cancel_reboot
+ Chef::Log::info "Changing reboot status from #{@reboot_info.inspect} to {}"
+ @reboot_info = {}
+ end
+
+ def reboot_requested?
+ @reboot_info.size > 0
+ end
+
private
def loaded_recipe(cookbook, recipe)
diff --git a/lib/chef/win32/api/file.rb b/lib/chef/win32/api/file.rb
index 7a8dafd8b5..da9713e119 100644
--- a/lib/chef/win32/api/file.rb
+++ b/lib/chef/win32/api/file.rb
@@ -459,11 +459,7 @@ BOOL WINAPI DeviceIoControl(
# to be passed to the *W vesion of WinAPI File
# functions
def encode_path(path)
- (path_prepender << path.gsub(::File::SEPARATOR, ::File::ALT_SEPARATOR)).to_wstring
- end
-
- def path_prepender
- "\\\\?\\"
+ Chef::Util::PathHelper.canonical_path(path).to_wstring
end
# retrieves a file search handle and passes it