summaryrefslogtreecommitdiff
path: root/lib/chef/file_content_management/deploy/mv_unix.rb
diff options
context:
space:
mode:
authorsersut <serdar@opscode.com>2013-05-16 12:32:23 -0700
committersersut <serdar@opscode.com>2013-05-16 12:32:23 -0700
commite46f99d074e2d83cdb08831d752f3b161c076a76 (patch)
tree3e50468e4bf4a236a689d73b2bf097bfded84350 /lib/chef/file_content_management/deploy/mv_unix.rb
parent273d10f2fe8cef115982398858ff34f92a250018 (diff)
downloadchef-e46f99d074e2d83cdb08831d752f3b161c076a76.tar.gz
Move file content management logic outside of providers under Chef::FileContentManagement for reusability in the future.
Diffstat (limited to 'lib/chef/file_content_management/deploy/mv_unix.rb')
-rw-r--r--lib/chef/file_content_management/deploy/mv_unix.rb77
1 files changed, 77 insertions, 0 deletions
diff --git a/lib/chef/file_content_management/deploy/mv_unix.rb b/lib/chef/file_content_management/deploy/mv_unix.rb
new file mode 100644
index 0000000000..548571eb1b
--- /dev/null
+++ b/lib/chef/file_content_management/deploy/mv_unix.rb
@@ -0,0 +1,77 @@
+#
+# 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 FileContentManagement
+ 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
+