Handle permissions corner cases on uninstall

* unset BSD file flags if present
* attempt ownership change if permissions changes fail

fixes #6699
fixes #6752
This commit is contained in:
Roland Walker 2014-10-23 11:00:45 -04:00
parent 3467ca89c8
commit aa4b112a90
2 changed files with 28 additions and 5 deletions

View File

@ -155,14 +155,36 @@ class Cask::Installer
# this feels like a class method, but uses @command
def permissions_rmtree(path)
if path.respond_to?(:rmtree) and path.exist?
tried_permissions = false
tried_ownership = false
begin
path.rmtree
rescue
rescue StandardError => e
# in case of permissions problems
if path.exist?
@command.run('/bin/chmod', :args => ['-R', '--', 'u+rwx', path])
@command.run('/bin/chmod', :args => ['-R', '-N', path])
path.rmtree
if path.exist? and !tried_permissions
begin
# todo Better handling for the case where path is a symlink.
# The -h and -R flags cannot be combined, and behavior is
# dependent on whether the file argument has a trailing
# slash. This should do the right thing, but is fragile.
@command.run!('/usr/bin/chflags', :args => ['-R', '--', '000', path])
@command.run!('/bin/chmod', :args => ['-R', '--', 'u+rwx', path])
@command.run!('/bin/chmod', :args => ['-R', '-N', path])
rescue StandardError => e
unless tried_ownership
# in case of ownership problems
# todo Further examine files to see if ownership is the problem
# before using sudo+chown
ohai "Using sudo to gain ownership of path '#{path}'"
current_user = Etc.getpwuid(Process.euid).name
@command.run('/usr/sbin/chown', :args => ['-R', '--', current_user, path],
:sudo => true)
tried_ownership = true
retry # permissions
end
end
tried_permissions = true
retry # rmtree
end
end
end

View File

@ -306,6 +306,7 @@ class Cask::Pkg
def _with_full_permissions(path, &block)
original_mode = (path.stat.mode % 01000).to_s(8)
# todo: similarly read and restore OS X flags (qv man chflags)
@command.run!('/bin/chmod', :args => ['--', '777', path], :sudo => true)
block.call
ensure