Class: Chef::FileContentManagement::Deploy::MvUnix
- Inherits:
-
Object
- Object
- Chef::FileContentManagement::Deploy::MvUnix
- Defined in:
- lib/chef/file_content_management/deploy/mv_unix.rb
Overview
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).
Instance Method Summary collapse
Instance Method Details
#create(file) ⇒ Object
30 31 32 33 34 35 |
# File 'lib/chef/file_content_management/deploy/mv_unix.rb', line 30 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.trace("Touching #{file} to create it") FileUtils.touch(file) end |
#deploy(src, dst) ⇒ Object
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/chef/file_content_management/deploy/mv_unix.rb', line 37 def deploy(src, dst) # we are only responsible for content so restore the dst files perms Chef::Log.trace("Reading modes from #{dst} file") stat = ::File.stat(dst) mode = stat.mode & 07777 uid = stat.uid gid = stat.gid Chef::Log.trace("Applying mode = #{mode.to_s(8)}, uid = #{uid}, gid = #{gid} to #{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 command # (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 # i own the inode, so should be able to at least chmod it # NOTE: this must come last due to POSIX stripping sticky mode bits on chown/chgrp ::File.chmod(mode, src) Chef::Log.trace("Moving temporary file #{src} into place at #{dst}") FileUtils.mv(src, dst) end |