lib/vagrant-betterhosts/BetterHosts.rb in vagrant-betterhosts-0.2.1 vs lib/vagrant-betterhosts/BetterHosts.rb in vagrant-betterhosts-1.1.6
- old
+ new
@@ -1,74 +1,78 @@
+# The core of the plugin
require "rbconfig"
require "open3"
+require "resolv"
+require "os"
module VagrantPlugins
module BetterHosts
+ # Plugin module
module BetterHosts
- def getIps
+ def get_ips
ips = []
+ if @machine.provider_name == :docker
+ @ui.info '[vagrant-betterhosts] Docker detected, adding 127.0.0.1 and ::1 IP addresses'
+ ip = "127.0.0.1"
+ ips.push(ip) unless ip.nil? or ips.include? ip
+ ip = "::1"
+ ips.push(ip) unless ip.nil? or ips.include? ip
+ return ips
+ end
+
if @machine.config.vm.networks.length == 0
@ui.error("[vagrant-betterhosts] No ip address found for this virtual machine")
exit
end
@machine.config.vm.networks.each do |network|
key, options = network[0], network[1]
- ip = options[:ip] if (key == :private_network || key == :public_network) && options[:betterhosts] != "skip"
- ips.push(ip) if ip
if options[:betterhosts] == "skip"
@ui.info '[vagrant-betterhosts] Skipped adding host entries (config.vm.network betterhosts: "skip" is set)'
end
-
- @machine.config.vm.provider :hyperv do |v|
- timeout = @machine.provider_config.ip_address_timeout
- @ui.output("[vagrant-betterhosts] Waiting for the guest machine to report its IP address ( this might take some time, have patience )...")
- @ui.detail("Timeout: #{timeout} seconds")
-
- options = {
- vmm_server_address: @machine.provider_config.vmm_server_address,
- proxy_server_address: @machine.provider_config.proxy_server_address,
- timeout: timeout,
- machine: @machine,
- }
- network = @machine.provider.driver.read_guest_ip(options)
- if network["ip"]
- ips.push(network["ip"]) unless ips.include? network["ip"]
- end
- end
-
-
+ ip = options[:ip] if (key == :private_network || key == :public_network) && options[:betterhosts] != "skip"
+ ips.push(ip) if ip
end
+ if @machine.provider_name == :hyperv
+ ip = @machine.provider.driver.read_guest_ip["ip"]
+ @ui.info "[vagrant-betterhosts] Read guest IP #{ip} from Hyper-V provider"
+ ips.push(ip) unless ip.nil? or ips.include? ip
+ end
return ips
end
- # https://stackoverflow.com/a/13586108/1902215
def get_os_binary
- return os ||= (host_os = RbConfig::CONFIG["host_os"]
- case host_os
- when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
- :'cli.exe'
- when /darwin|mac os/
- :'cli_osx'
- when /linux/
- :'cli'
- else
- raise Error::WebDriverError, "unknown os: #{host_os.inspect}"
- end)
+ if OS.windows?
+ return 'cli.exe'
+ elsif OS.mac?
+ if Etc.uname[:version].include? 'ARM64'
+ return 'cli_arm64_osx'
+ else
+ return 'cli_amd64_osx'
+ end
+ elsif OS.linux?
+ if Etc.uname[:version].include? 'ARM64'
+ return 'cli_arm64_linux'
+ else
+ return 'cli_amd64_linux'
+ end
+ else
+ raise Error::WebDriverError, "unknown os: #{host_os.inspect}"
+ end
end
def get_cli
binary = get_os_binary
- path = File.expand_path(File.dirname(File.dirname(__FILE__))) + "/vagrant-betterhosts/bundle/"
+ path = format('%s%s', File.expand_path(File.dirname(File.dirname(__FILE__))), "/vagrant-betterhosts/bundle/")
path = "#{path}#{binary}"
return path
end
# Get a hash of hostnames indexed by ip, e.g. { 'ip1': ['host1'], 'ip2': ['host2', 'host3'] }
- def getHostnames(ips)
+ def get_hostnames(ips)
hostnames = Hash.new { |h, k| h[k] = [] }
case @machine.config.betterhosts.aliases
when Array
hostnames[ips[0]] += @machine.config.betterhosts.aliases
@@ -87,105 +91,153 @@
end
hostnames
end
- def disableClean(ip_address)
+ def disable_clean(ip_address)
unless ip_address.nil?
return @machine.config.betterhosts.disable_clean
end
return true
end
- def addHostEntries
- error = false
- errorText = ""
+ def check_hostnames_to_add(ip_address, hostnames)
+ hostnames_to_add = Array.new
+ hostnames = hostnames.split
+ # check which hostnames actually need adding
+ hostnames.each do |hostname|
+ begin
+ address = Resolv.getaddress(hostname)
+ if address != ip_address
+ hostnames_to_add.append(hostname)
+ end
+ rescue StandardError => _e
+ hostnames_to_add.append(hostname)
+ end
+ rescue StandardError => _e
+ hostnames_to_add.append(hostname)
+ end
+ return hostnames_to_add.join(' ')
+ end
+
+ def add_betterhost_entries(ip_address, hostnames)
cli = get_cli
- hostnames_by_ips = generateHostnamesByIps
+ if cli.include? ".exe"
+ clean = get_clean_parameter_by_system(ip_address, true)
+ command = "Start-Process '#{cli}' -ArgumentList \"add\",#{clean}\"#{ip_address}\",\"#{hostnames}\" -Verb RunAs"
+ stdin, stdout, stderr, wait_thr = Open3.popen3("powershell", "-Command", command)
+ else
+ clean = get_clean_parameter_by_system(ip_address, false)
+ command = "sudo '#{cli}' add #{clean} #{ip_address} #{hostnames}"
+ stdin, stdout, stderr, wait_thr = Open3.popen3(command)
+ end
+ return stdin, stdout, stderr, wait_thr, command
+ end
+
+ def add_host_entries
+ error = false
+ error_text = ''
+ command = ''
+ hostnames_by_ips = generate_hostnames_by_ips
- return if not hostnames_by_ips.any?
+ return if hostnames_by_ips.none?
+ @ui.info "[vagrant-betterhosts] Checking for host entries"
+
hostnames_by_ips.each do |ip_address, hostnames|
if ip_address.nil?
@ui.error "[vagrant-betterhosts] Error adding some hosts, no IP was provided for the following hostnames: #{hostnames}"
next
end
- @ui.info "[vagrant-betterhosts] Adding #{hostnames} for address #{ip_address}"
- if cli.include? ".exe"
- clean = "\"--clean\","
- if disableClean(ip_address)
- clean = ''
- end
- stdin, stdout, stderr, wait_thr = Open3.popen3("powershell", "-Command", "Start-Process '#{cli}' -ArgumentList \"add\",#{clean}\"#{ip_address}\",\"#{hostnames}\" -Verb RunAs")
- else
- clean = "--clean"
- if disableClean(ip_address)
- clean = ''
- end
- stdin, stdout, stderr, wait_thr = Open3.popen3("sudo '#{cli}' add #{clean} #{ip_address} #{hostnames}")
- end
- if !wait_thr.value.success?
+
+ # filter out the hosts we've already added
+ hosts_to_add = check_hostnames_to_add(ip_address, hostnames)
+ next if hosts_to_add.empty?
+
+ _stdin, _stdout, stderr, wait_thr, command = add_betterhost_entries(ip_address, hosts_to_add)
+ unless wait_thr.value.success?
error = true
- errorText = stderr.read.strip
+ error_text = stderr.read.strip
end
end
- printReadme(error, errorText)
+ print_readme(error, error_text, command)
end
- def removeHostEntries
- error = false
- errorText = ""
+ def remove_betterhost_entries(ip_address, hostnames)
cli = get_cli
- hostnames_by_ips = generateHostnamesByIps
+ if cli.include? ".exe"
+ clean = get_clean_parameter_by_system(ip_address, true)
+ command = "Start-Process '#{cli}' -ArgumentList \"remove\",#{clean}\"#{ip_address}\",\"#{hostnames}\" -Verb RunAs"
+ stdin, stdout, stderr, wait_thr = Open3.popen3("powershell", "-Command", command)
+ else
+ clean = get_clean_parameter_by_system(ip_address, false)
+ command = "sudo '#{cli}' remove #{clean} #{ip_address} #{hostnames}"
+ stdin, stdout, stderr, wait_thr = Open3.popen3(command)
+ end
+ return stdin, stdout, stderr, wait_thr, command
+ end
- return if not hostnames_by_ips.any?
+ def remove_host_entries
+ error = false
+ error_text = ''
+ command = ''
+ hostnames_by_ips = generate_hostnames_by_ips
+ return if hostnames_by_ips.none?
+
+ @ui.info "[vagrant-betterhosts] Removing hosts"
+
hostnames_by_ips.each do |ip_address, hostnames|
if ip_address.nil?
@ui.error "[vagrant-betterhosts] Error adding some hosts, no IP was provided for the following hostnames: #{hostnames}"
next
end
- if cli.include? ".exe"
- clean = "\"--clean\","
- if disableClean(ip_address)
- clean = ''
- end
- stdin, stdout, stderr, wait_thr = Open3.popen3("powershell", "-Command", "Start-Process '#{cli}' -ArgumentList \"remove\",#{clean}\"#{ip_address}\",\"#{hostnames}\" -Verb RunAs")
- else
- clean = "\"--clean\","
- if disableClean(ip_address)
- clean = ''
- end
- stdin, stdout, stderr, wait_thr = Open3.popen3("sudo '#{cli}' remove #{clean} #{ip_address} #{hostnames}")
- end
- if !wait_thr.value.success?
+
+ _stdin, _stdout, stderr, wait_thr, command = remove_betterhost_entries(ip_address, hostnames)
+ unless wait_thr.value.success?
error = true
- errorText = stderr.read.strip
+ error_text = stderr.read.strip
end
end
- printReadme(error, errorText)
+ print_readme(error, error_text, command)
end
- def printReadme(error, errorText)
- if error
- cli = get_cli
- @ui.error "[vagrant-betterhosts] Issue executing goodhosts CLI: #{errorText}"
- @ui.error "[vagrant-betterhosts] Cli path: #{cli}"
- if cli.include? ".exe"
- @ui.error "[vagrant-betterhosts] Check the readme at https://github.com/ajxb/vagrant-betterhosts#windows-uac-prompt"
- exit
- else
- @ui.error "[vagrant-betterhosts] Check the readme at https://github.com/ajxb/vagrant-betterhosts#passwordless-sudo"
- end
+ def get_clean_parameter_by_system(ip_address, is_win)
+ clean = "--clean"
+ if is_win
+ clean = "\"--clean\","
end
+
+ if disable_clean(ip_address)
+ clean = ''
+ end
+ return clean
end
- def generateHostnamesByIps()
- ips = getIps
+ def print_readme(error, error_text, command)
+ unless error
+ @ui.info "[vagrant-betterhosts] Finished processing"
+ return false
+ end
+
+ cli = get_cli
+ @ui.error "[vagrant-betterhosts] Issue executing goodhosts CLI: #{error_text}"
+ @ui.error "[vagrant-betterhosts] Command: #{command}"
+ @ui.error "[vagrant-betterhosts] Cli path: #{cli}"
+ if cli.include? ".exe"
+ @ui.error "[vagrant-betterhosts] Check the readme at https://github.com/betterhosts/vagrant#windows-uac-prompt"
+ exit
+ else
+ @ui.error "[vagrant-betterhosts] Check the readme at https://github.com/betterhosts/vagrant#passwordless-sudo"
+ end
+ end
+
+ def generate_hostnames_by_ips
+ ips = get_ips
return [] unless ips.any?
hostnames_by_ips = {}
- hostnames = getHostnames(ips)
+ hostnames = get_hostnames(ips)
ips.each do |ip|
hostnames_by_ips[ip] = hostnames[ip].join(' ') if hostnames[ip].any?
end
hostnames_by_ips