Merge pull request #48 from pbitty/windows_elevate_privileges
elevate privileges in Windows host if necessary
This commit is contained in:
commit
af19868ee6
16
README.md
16
README.md
|
@ -91,6 +91,22 @@ config.hostmanager.ip_resolver = proc do |vm|
|
|||
end
|
||||
```
|
||||
|
||||
Windows support
|
||||
---------------
|
||||
|
||||
Hostmanager will detect Windows guests and hosts and use the appropriate
|
||||
path for the ```hosts``` file: ```%WINDIR%\System32\drivers\etc\hosts```
|
||||
|
||||
By default on a Windows host, the ```hosts``` file is not writable without
|
||||
elevated privileges. If hostmanager detects that it cannot overwrite the file,
|
||||
it will attempt to do so with elevated privileges, causing the
|
||||
[UAC](http://en.wikipedia.org/wiki/User_Account_Control) prompt to appear.
|
||||
|
||||
### UAC limitations
|
||||
|
||||
Due to limitations caused by UAC, cancelling out of the UAC prompt will not cause any
|
||||
visible errors, however the ```hosts``` file will not be updated.
|
||||
|
||||
Contribute
|
||||
----------
|
||||
Contributions are welcome.
|
||||
|
|
|
@ -34,19 +34,23 @@ module VagrantPlugins
|
|||
def update_host
|
||||
# copy and modify hosts file on host with Vagrant-managed entries
|
||||
file = @global_env.tmp_path.join('hosts.local')
|
||||
# add a "if windows..."
|
||||
hosts_location = '/etc/hosts'
|
||||
copy_cmd = 'sudo cp'
|
||||
# handles the windows hosts file...
|
||||
if ENV['SystemRoot'] != nil
|
||||
|
||||
if WindowsSupport.windows?
|
||||
# lazily include windows Module
|
||||
class << self
|
||||
include WindowsSupport unless include? WindowsSupport
|
||||
end
|
||||
|
||||
hosts_location = "#{ENV['WINDIR']}\\System32\\drivers\\etc\\hosts"
|
||||
copy_cmd = 'cp'
|
||||
copy_proc = Proc.new { windows_copy_file(file, hosts_location) }
|
||||
else
|
||||
hosts_location = '/etc/hosts'
|
||||
copy_proc = Proc.new { `sudo cp #{file} #{hosts_location}` }
|
||||
end
|
||||
|
||||
FileUtils.cp(hosts_location, file)
|
||||
update_file(file)
|
||||
|
||||
# copy modified file using sudo for permission
|
||||
`#{copy_cmd} #{file} #{hosts_location}`
|
||||
copy_proc.call
|
||||
end
|
||||
|
||||
private
|
||||
|
@ -122,6 +126,45 @@ module VagrantPlugins
|
|||
@global_env.active_machines
|
||||
end
|
||||
end
|
||||
|
||||
## Windows support for copying files, requesting elevated privileges if necessary
|
||||
module WindowsSupport
|
||||
require 'rbconfig'
|
||||
|
||||
def self.windows?
|
||||
RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/
|
||||
end
|
||||
|
||||
require 'win32ole' if windows?
|
||||
|
||||
def windows_copy_file(source, dest)
|
||||
begin
|
||||
# First, try Ruby copy
|
||||
FileUtils.cp(source, dest)
|
||||
rescue Errno::EACCES
|
||||
# Access denied, try with elevated privileges
|
||||
windows_copy_file_elevated(source, dest)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def windows_copy_file_elevated(source, dest)
|
||||
# copy command only supports backslashes as separators
|
||||
source, dest = [source, dest].map { |s| s.to_s.gsub(/\//, '\\') }
|
||||
|
||||
# run 'cmd /C copy ...' with elevated privilege, minimized
|
||||
copy_cmd = "copy \"#{source}\" \"#{dest}\""
|
||||
WIN32OLE.new('Shell.Application').ShellExecute('cmd', "/C #{copy_cmd}", nil, 'runas', 7)
|
||||
|
||||
# Unfortunately, ShellExecute does not give us a status code,
|
||||
# and it is non-blocking so we can't reliably compare the file contents
|
||||
# to see if they were copied.
|
||||
#
|
||||
# If the user rejects the UAC prompt, vagrant will silently continue
|
||||
# without updating the hostsfile.
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue