From 9b109f4ca4a2ab32d81dc39bfb8d1586610d4d74 Mon Sep 17 00:00:00 2001 From: Lamont Granquist Date: Tue, 9 Apr 2013 14:46:40 -0700 Subject: move the deploy switching stuff out of the resource and into the lower level objects. clean up cp_unix a little bit. --- lib/chef/provider/file.rb | 4 +++- lib/chef/provider/file/deploy.rb | 25 +++++++++++++++++++++++++ lib/chef/provider/file/deploy/cp_unix.rb | 22 +++++++++++++--------- lib/chef/providers.rb | 1 + lib/chef/resource/file.rb | 7 ------- 5 files changed, 42 insertions(+), 17 deletions(-) create mode 100644 lib/chef/provider/file/deploy.rb (limited to 'lib') diff --git a/lib/chef/provider/file.rb b/lib/chef/provider/file.rb index 98d7e4c393..8d59278e52 100644 --- a/lib/chef/provider/file.rb +++ b/lib/chef/provider/file.rb @@ -50,7 +50,9 @@ class Chef def initialize(new_resource, run_context) @content_class ||= Chef::Provider::File::Content - @deployment_strategy = new_resource.deployment_strategy.new() if new_resource.respond_to?(:deployment_strategy) + if new_resource.respond_to?(:deployment_strategy) + @deployment_strategy = Chef::Provider::File::Deploy.strategy(new_resource.deployment_strategy) + end super end diff --git a/lib/chef/provider/file/deploy.rb b/lib/chef/provider/file/deploy.rb new file mode 100644 index 0000000000..50cc6e4b6e --- /dev/null +++ b/lib/chef/provider/file/deploy.rb @@ -0,0 +1,25 @@ + + +class Chef + class Provider + class File + class Deploy + def self.strategy(deployment_strategy) + deployment_strategy ||= Chef::Config[:file_deployment_strategy] + deployment_strategy ||= Chef::Platform.windows? ? :mv_windows : :mv_unix + case deployment_strategy + when :mv_windows + Chef::Provider::File::Deploy::MvWindows.new() + when :mv_unix + Chef::Provider::File::Deploy::MvUnix.new() + when :cp_unix + Chef::Provider::File::Deploy::CpUnix.new() + else + raise "invalid deployment strategy use :mv_unix, :mv_windows or :cp_unix" + end + end + end + end + end +end + diff --git a/lib/chef/provider/file/deploy/cp_unix.rb b/lib/chef/provider/file/deploy/cp_unix.rb index 1640c68538..e27a679b96 100644 --- a/lib/chef/provider/file/deploy/cp_unix.rb +++ b/lib/chef/provider/file/deploy/cp_unix.rb @@ -17,10 +17,10 @@ # # -# PURPOSE: this strategy should be cross-platform and maintain SELinux contexts -# and windows ACL inheritance, but it uses cp and is both slower and is -# not atomic and may result in a corrupted destination file in low -# disk or power outage situations. +# PURPOSE: This strategy preserves the inode, and will preserve modes + ownership +# even if the user running chef cannot create that ownership (but has +# rights to the file). It is vulnerable to crashes in the middle of +# writing the file which could result in corruption or zero-length files. # class Chef @@ -34,16 +34,20 @@ class Chef end def deploy(src, dst) - # we are only responsible for content so restore the dst files perms + Chef::Log.debug("reading modes from #{dst} file") mode = ::File.stat(dst).mode & 07777 uid = ::File.stat(dst).uid gid = ::File.stat(dst).gid - Chef::Log.debug("saved mode = #{mode.to_s(8)}, uid = #{uid}, gid = #{gid} from #{dst}") + Chef::Log.debug("read mode = #{mode.to_s(8)}, uid = #{uid}, gid = #{gid} to #{dst}") + Chef::Log.debug("copying temporary file #{src} into place at #{dst}") FileUtils.cp(src, dst) - ::File.chmod(mode, dst) - ::File.chown(uid, gid, dst) - Chef::Log.debug("restored mode = #{mode.to_s(8)}, uid = #{uid}, gid = #{gid} to #{dst}") + + Chef::Log.debug("reading modes from #{dst} file") + mode = ::File.stat(dst).mode & 07777 + uid = ::File.stat(dst).uid + gid = ::File.stat(dst).gid + Chef::Log.debug("read mode = #{mode.to_s(8)}, uid = #{uid}, gid = #{gid} to #{dst}") end end end diff --git a/lib/chef/providers.rb b/lib/chef/providers.rb index 07efed8f9a..8acf99c31e 100644 --- a/lib/chef/providers.rb +++ b/lib/chef/providers.rb @@ -116,6 +116,7 @@ require 'chef/provider/file/content' require 'chef/provider/remote_file/content' require 'chef/provider/cookbook_file/content' require 'chef/provider/template/content' +require 'chef/provider/file/deploy' require 'chef/provider/file/deploy/cp_unix' require 'chef/provider/file/deploy/mv_unix' require 'chef/provider/file/deploy/mv_windows' diff --git a/lib/chef/resource/file.rb b/lib/chef/resource/file.rb index 3f4b5d60a6..d0a33d7c02 100644 --- a/lib/chef/resource/file.rb +++ b/lib/chef/resource/file.rb @@ -46,13 +46,6 @@ class Chef @action = "create" @allowed_actions.push(:create, :delete, :touch, :create_if_missing) @provider = Chef::Provider::File - @deployment_strategy = Chef::Config[:file_deployment_strategy] - @deployment_strategy ||= if Chef::Platform.windows? - Chef::Provider::File::Deploy::MvWindows - else - Chef::Provider::File::Deploy::MvUnix - end - @binmode = Platform.windows? ? true : false @diff = nil end -- cgit v1.2.1