diff options
author | sersut <serdar@opscode.com> | 2013-05-16 12:32:23 -0700 |
---|---|---|
committer | sersut <serdar@opscode.com> | 2013-05-16 12:32:23 -0700 |
commit | e46f99d074e2d83cdb08831d752f3b161c076a76 (patch) | |
tree | 3e50468e4bf4a236a689d73b2bf097bfded84350 /lib/chef/provider | |
parent | 273d10f2fe8cef115982398858ff34f92a250018 (diff) | |
download | chef-e46f99d074e2d83cdb08831d752f3b161c076a76.tar.gz |
Move file content management logic outside of providers under Chef::FileContentManagement for reusability in the future.
Diffstat (limited to 'lib/chef/provider')
-rw-r--r-- | lib/chef/provider/cookbook_file/content.rb | 8 | ||||
-rw-r--r-- | lib/chef/provider/file.rb | 3 | ||||
-rw-r--r-- | lib/chef/provider/file/content.rb | 8 | ||||
-rw-r--r-- | lib/chef/provider/file/deploy.rb | 21 | ||||
-rw-r--r-- | lib/chef/provider/file/deploy/cp.rb | 44 | ||||
-rw-r--r-- | lib/chef/provider/file/deploy/mv_unix.rb | 78 | ||||
-rw-r--r-- | lib/chef/provider/file/deploy/mv_windows.rb | 76 | ||||
-rw-r--r-- | lib/chef/provider/file/tempfile.rb | 61 | ||||
-rw-r--r-- | lib/chef/provider/file_content_base.rb | 56 | ||||
-rw-r--r-- | lib/chef/provider/remote_file/content.rb | 4 | ||||
-rw-r--r-- | lib/chef/provider/remote_file/ftp.rb | 4 | ||||
-rw-r--r-- | lib/chef/provider/remote_file/local_file.rb | 2 | ||||
-rw-r--r-- | lib/chef/provider/template/content.rb | 4 |
13 files changed, 17 insertions, 352 deletions
diff --git a/lib/chef/provider/cookbook_file/content.rb b/lib/chef/provider/cookbook_file/content.rb index 0554ef3843..cb777dd916 100644 --- a/lib/chef/provider/cookbook_file/content.rb +++ b/lib/chef/provider/cookbook_file/content.rb @@ -16,13 +16,13 @@ # limitations under the License. # -require 'chef/provider/file_content_base' -require 'chef/provider/file/tempfile' +require 'chef/file_content_management/content_base' +require 'chef/file_content_management/tempfile' class Chef class Provider class CookbookFile - class Content < Chef::Provider::FileContentBase + class Content < Chef::FileContentManagement::ContentBase private @@ -32,7 +32,7 @@ class Chef if file_cache_location.nil? nil else - tempfile = Chef::Provider::File::Tempfile.new(@new_resource).tempfile + tempfile = Chef::FileContentManagement::Tempfile.new(@new_resource).tempfile tempfile.close Chef::Log.debug("#{@new_resource} staging #{file_cache_location} to #{tempfile.path}") FileUtils.cp(file_cache_location, tempfile.path) diff --git a/lib/chef/provider/file.rb b/lib/chef/provider/file.rb index 29c4fcc445..794e8208a6 100644 --- a/lib/chef/provider/file.rb +++ b/lib/chef/provider/file.rb @@ -30,6 +30,7 @@ require 'chef/util/backup' require 'chef/util/diff' require 'chef/deprecation/provider/file' require 'chef/deprecation/warnings' +require 'chef/file_content_management/deploy' # The Tao of File Providers: # - the content provider must always return a tempfile that we can delete/mv @@ -57,7 +58,7 @@ class Chef def initialize(new_resource, run_context) @content_class ||= Chef::Provider::File::Content if new_resource.respond_to?(:deploy_with) - @deployment_strategy = Chef::Provider::File::Deploy.strategy(new_resource.deploy_with) + @deployment_strategy = Chef::FileContentManagement::Deploy.strategy(new_resource.deploy_with) end super end diff --git a/lib/chef/provider/file/content.rb b/lib/chef/provider/file/content.rb index 3b83555d7f..f82bc49db4 100644 --- a/lib/chef/provider/file/content.rb +++ b/lib/chef/provider/file/content.rb @@ -16,16 +16,16 @@ # limitations under the License. # -require 'chef/provider/file_content_base' -require 'chef/provider/file/tempfile' +require 'chef/file_content_management/content_base' +require 'chef/file_content_management/tempfile' class Chef class Provider class File - class Content < Chef::Provider::FileContentBase + class Content < Chef::FileContentManagement::ContentBase def file_for_provider if @new_resource.content - tempfile = Chef::Provider::File::Tempfile.new(@new_resource).tempfile + tempfile = Chef::FileContentManagement::Tempfile.new(@new_resource).tempfile tempfile.write(@new_resource.content) tempfile.close tempfile diff --git a/lib/chef/provider/file/deploy.rb b/lib/chef/provider/file/deploy.rb deleted file mode 100644 index d6be159c07..0000000000 --- a/lib/chef/provider/file/deploy.rb +++ /dev/null @@ -1,21 +0,0 @@ - - -class Chef - class Provider - class File - class Deploy - def self.strategy(deploy_with) - case deploy_with - when :move - Chef::Platform.windows? ? MvWindows.new() : MvUnix.new() - when :copy - Cp.new() - else - raise "invalid deployment strategy use :move or :copy" - end - end - end - end - end -end - diff --git a/lib/chef/provider/file/deploy/cp.rb b/lib/chef/provider/file/deploy/cp.rb deleted file mode 100644 index 109b2b137f..0000000000 --- a/lib/chef/provider/file/deploy/cp.rb +++ /dev/null @@ -1,44 +0,0 @@ -# -# Author:: Lamont Granquist (<lamont@opscode.com>) -# Copyright:: Copyright (c) 2013 Opscode, 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. -# - -# -# 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 - class Provider - class File - class Deploy - class Cp - def create(file) - Chef::Log.debug("touching #{file} to create it") - FileUtils.touch(file) - end - - def deploy(src, dst) - Chef::Log.debug("copying temporary file #{src} into place at #{dst}") - FileUtils.cp(src, dst) - end - end - end - end - end -end diff --git a/lib/chef/provider/file/deploy/mv_unix.rb b/lib/chef/provider/file/deploy/mv_unix.rb deleted file mode 100644 index 2ff78f301d..0000000000 --- a/lib/chef/provider/file/deploy/mv_unix.rb +++ /dev/null @@ -1,78 +0,0 @@ -# -# Author:: Lamont Granquist (<lamont@opscode.com>) -# Copyright:: Copyright (c) 2013 Opscode, 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. -# - -# -# PURPOSE: this strategy is atomic, and attempts to preserve file modes -# -# NOTE: there is no preserve flag to FileUtils.mv, and we want to preserve the dst file -# modes rather than the src file modes (preserve = true is what mv does already, we -# would like preserve = false which is tricky). -# - -class Chef - class Provider - class File - class Deploy - class MvUnix - def create(file) - # this is very simple, but it ensures that ownership and file modes take - # good defaults, in particular mode needs to obey umask on create - Chef::Log.debug("touching #{file} to create it") - FileUtils.touch(file) - 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("applying mode = #{mode.to_s(8)}, uid = #{uid}, gid = #{gid} to #{src}") - - # i own the inode, so should be able to at least chmod it - ::File.chmod(mode, src) - - # we may be running as non-root in which case because we are doing an mv we cannot preserve - # the file modes. after the mv we have a different inode and if we don't have rights to - # chown/chgrp on the inode then we can't fix the ownership. - # - # in the case where i'm running chef-solo on my homedir as myself and some root-shell - # work has caused dotfiles of mine to change to root-owned, i'm fine with this not being - # exceptional, and i think most use cases will consider this to not be exceptional, and - # the right thing is to fix the ownership of the file to the user running the commmand - # (which requires write perms to the directory, or mv will throw an exception) - begin - ::File.chown(uid, nil, src) - rescue Errno::EPERM - Chef::Log.warn("Could not set uid = #{uid} on #{src}, file modes not preserved") - end - begin - ::File.chown(nil, gid, src) - rescue Errno::EPERM - Chef::Log.warn("Could not set gid = #{gid} on #{src}, file modes not preserved") - end - - Chef::Log.debug("moving temporary file #{src} into place at #{dst}") - FileUtils.mv(src, dst) - end - end - end - end - end -end diff --git a/lib/chef/provider/file/deploy/mv_windows.rb b/lib/chef/provider/file/deploy/mv_windows.rb deleted file mode 100644 index 92ba97babb..0000000000 --- a/lib/chef/provider/file/deploy/mv_windows.rb +++ /dev/null @@ -1,76 +0,0 @@ -# -# Author:: Lamont Granquist (<lamont@opscode.com>) -# Copyright:: Copyright (c) 2013 Opscode, 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. -# - -# -# We update the contents of the file, using mv for atomicity, while maintaining all the -# ACL information on the dst file. -# - -require 'chef/win32/security' - -class Chef - class Provider - class File - class Deploy - class MvWindows - - Security = Chef::ReservedNames::Win32::Security - ACL = Security::ACL - - def create(file) - Chef::Log.debug("touching #{file} to create it") - FileUtils.touch(file) - end - - def deploy(src, dst) - dst_so = Security::SecurableObject.new(dst) - - # FIXME: catch exception when we can't elevate privs? - dst_sd = dst_so.security_descriptor(true) # get the sd with the SACL - - if dst_sd.dacl_present? - apply_dacl = ACL.create(dst_sd.dacl.select { |ace| !ace.inherited? }) - end - if dst_sd.sacl_present? - apply_sacl = ACL.create(dst_sd.sacl.select { |ace| !ace.inherited? }) - end - - Chef::Log.debug("applying owner #{dst_sd.owner} to staged file") - Chef::Log.debug("applying group #{dst_sd.group} to staged file") - Chef::Log.debug("applying dacl #{dst_sd.dacl} to staged file") if dst_sd.dacl_present? - Chef::Log.debug("applying dacl inheritance to staged file") if dst_sd.dacl_inherits? - Chef::Log.debug("applying sacl #{dst_sd.sacl} to staged file") if dst_sd.sacl_present? - Chef::Log.debug("applying sacl inheritance to staged file") if dst_sd.sacl_inherits? - - so = Security::SecurableObject.new(src) - - so.set_dacl(apply_dacl, dst_sd.dacl_inherits?) if dst_sd.dacl_present? - - so.group = dst_sd.group - - so.owner = dst_sd.owner - - so.set_sacl(apply_sacl, dst_sd.sacl_inherits?) if dst_sd.sacl_present? - - FileUtils.mv(src, dst) - end - end - end - end - end -end diff --git a/lib/chef/provider/file/tempfile.rb b/lib/chef/provider/file/tempfile.rb deleted file mode 100644 index af98e2e4d7..0000000000 --- a/lib/chef/provider/file/tempfile.rb +++ /dev/null @@ -1,61 +0,0 @@ -# -# Author:: Lamont Granquist (<lamont@opscode.com>) -# Copyright:: Copyright (c) 2013 Opscode, 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 "tempfile" - -class Chef - class Provider - class File - class Tempfile - - attr_reader :new_resource - - def initialize(new_resource) - @new_resource = new_resource - end - - def tempfile - @tempfile ||= tempfile_open - end - - private - - def tempfile_open - tf = ::Tempfile.open(tempfile_basename, tempfile_dirname) - tf.binmode if new_resource.binmode - tf - end - - # - # These are important for windows to get permissions right, and may - # be useful for SELinux and other ACL approaches. Please use them - # as the arguments to Tempfile.new() consistently. - # - def tempfile_basename - basename = ::File.basename(@new_resource.name) - basename.insert 0, "." unless Chef::Platform.windows? # dotfile if we're not on windows - basename - end - - def tempfile_dirname - Chef::Config[:file_deployment_uses_destdir] ? ::File.dirname(@new_resource.path) : Dir::tmpdir - end - end - end - end -end diff --git a/lib/chef/provider/file_content_base.rb b/lib/chef/provider/file_content_base.rb deleted file mode 100644 index 3f91d480e5..0000000000 --- a/lib/chef/provider/file_content_base.rb +++ /dev/null @@ -1,56 +0,0 @@ -# -# Author:: Lamont Granquist (<lamont@opscode.com>) -# Copyright:: Copyright (c) 2013 Opscode, 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. -# - -class Chef - class Provider - class FileContentBase - - attr_reader :run_context - attr_reader :new_resource - attr_reader :current_resource - - def initialize(new_resource, current_resource, run_context) - @new_resource = new_resource - @current_resource = current_resource - @run_context = run_context - @tempfile_loaded = false - end - - def tempfile - # tempfile may be nil, so we cannot use ||= here - if @tempfile_loaded - @tempfile - else - @tempfile_loaded = true - @tempfile = file_for_provider - end - end - - private - - # - # Return something that looks like a File or Tempfile and - # you must assume the provider will unlink this file. Copy - # the contents to a Tempfile if you need to. - # - def file_for_provider - raise "class must implement file_for_provider!" - end - end - end -end diff --git a/lib/chef/provider/remote_file/content.rb b/lib/chef/provider/remote_file/content.rb index ca8e2744d5..c7f91057ab 100644 --- a/lib/chef/provider/remote_file/content.rb +++ b/lib/chef/provider/remote_file/content.rb @@ -20,13 +20,13 @@ require 'rest_client' require 'uri' require 'tempfile' -require 'chef/provider/file_content_base' +require 'chef/file_content_management/content_base' require 'chef/provider/remote_file/util' class Chef class Provider class RemoteFile - class Content < Chef::Provider::FileContentBase + class Content < Chef::FileContentManagement::ContentBase attr_reader :raw_file_source diff --git a/lib/chef/provider/remote_file/ftp.rb b/lib/chef/provider/remote_file/ftp.rb index 354eb83038..4408005241 100644 --- a/lib/chef/provider/remote_file/ftp.rb +++ b/lib/chef/provider/remote_file/ftp.rb @@ -22,7 +22,7 @@ require 'net/ftp' require 'chef/provider/remote_file' require 'chef/provider/remote_file/util' require 'chef/provider/remote_file/result' -require 'chef/provider/file/tempfile' +require 'chef/file_content_management/tempfile' class Chef class Provider @@ -98,7 +98,7 @@ class Chef # Fetches using Net::FTP, returns a Tempfile with the content def get - tempfile = Chef::Provider::File::Tempfile.new(@new_resource).tempfile + tempfile = Chef::FileContentManagement::Tempfile.new(@new_resource).tempfile if @typecode ftp.voidcmd("TYPE #{@typecode.upcase}") end diff --git a/lib/chef/provider/remote_file/local_file.rb b/lib/chef/provider/remote_file/local_file.rb index 69e615ae88..c0f3af2495 100644 --- a/lib/chef/provider/remote_file/local_file.rb +++ b/lib/chef/provider/remote_file/local_file.rb @@ -50,7 +50,7 @@ class Chef Chef::Log.debug("#{new_resource} mtime on #{uri.path} has not been updated, not deploying") nil else - tempfile = Chef::Provider::File::Tempfile.new(new_resource).tempfile + tempfile = Chef::FileContentManagement::Tempfile.new(new_resource).tempfile Chef::Log.debug("#{new_resource} staging #{uri.path} to #{tempfile.path}") FileUtils.cp(uri.path, tempfile.path) tempfile diff --git a/lib/chef/provider/template/content.rb b/lib/chef/provider/template/content.rb index 1d9b33fdb9..756db4642c 100644 --- a/lib/chef/provider/template/content.rb +++ b/lib/chef/provider/template/content.rb @@ -17,12 +17,12 @@ # require 'chef/mixin/template' -require 'chef/provider/file_content_base' +require 'chef/file_content_management/content_base' class Chef class Provider class Template - class Content < Chef::Provider::FileContentBase + class Content < Chef::FileContentManagement::ContentBase include Chef::Mixin::Template |