From ae33856215fe7a738040ee8d741e5f65855808b4 Mon Sep 17 00:00:00 2001 From: Tom J Nowell Date: Tue, 30 Dec 2025 17:22:09 +0000 Subject: [PATCH 1/2] Replace DNS resolution with hosts file checking Changes: - Removed dependency on 'resolv' library - Added hosts_entry_exists?() method using CLI check command - Updated check_hostnames_to_add() to use hosts file checking Benefits: - No sudo required for checking if hosts exist - Only requests sudo when hosts are actually missing - Checks hosts file directly instead of DNS resolution - Prevents unnecessary privilege escalation How it works: - Uses bundled CLI binary's check command (read-only, no sudo) - CLI check command reads /etc/hosts directly - Returns success if IP/hostname mapping exists - Only adds hosts that are actually missing This resolves VVV pain point: - No more unnecessary sudo prompts on `vagrant up` - Vagrant only requests sudo when hosts need to be added - Existing hosts in /etc/hosts are properly detected Note: Requires CLI with batch check support Will work with individual checks for backward compatibility --- lib/vagrant-goodhosts/GoodHosts.rb | 36 ++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/lib/vagrant-goodhosts/GoodHosts.rb b/lib/vagrant-goodhosts/GoodHosts.rb index cd71002..00700f8 100644 --- a/lib/vagrant-goodhosts/GoodHosts.rb +++ b/lib/vagrant-goodhosts/GoodHosts.rb @@ -1,7 +1,6 @@ # The core of the plugin require "rbconfig" require "open3" -require "resolv" require "os" module VagrantPlugins @@ -98,22 +97,35 @@ def disable_clean(ip_address) return true end + # Check if a specific IP/hostname mapping exists in the hosts file + # Uses the CLI check command instead of DNS resolution + def hosts_entry_exists?(ip_address, hostname) + cli = get_cli + # Use check command - no sudo needed for read-only operation + if cli.include? ".exe" + # Windows: direct command execution + stdout, stderr, status = Open3.capture3("\"#{cli}\" check \"#{ip_address}\" \"#{hostname}\"") + else + # Unix/macOS: no sudo needed for check + stdout, stderr, status = Open3.capture3("'#{cli}' check '#{ip_address}' '#{hostname}'") + end + return status.success? + rescue StandardError => e + @ui.warn "[vagrant-goodhosts] Error checking host entry: #{e.message}" + return false + end + 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_arr = hostnames.split + + # Check each hostname using the CLI check command + hostnames_arr.each do |hostname| + unless hosts_entry_exists?(ip_address, hostname) hostnames_to_add.append(hostname) end - rescue StandardError => _e - hostnames_to_add.append(hostname) end + return hostnames_to_add.join(' ') end From a3c90457cf99314a1a91fdb7f5771cc6952c6c90 Mon Sep 17 00:00:00 2001 From: Tom J Nowell Date: Mon, 26 Jan 2026 14:52:16 +0000 Subject: [PATCH 2/2] fix(linter): prefix unused variables with underscore RuboCop was flagging stdout and stderr as useless assignments in hosts_entry_exists? since only the exit status is checked. --- lib/vagrant-goodhosts/GoodHosts.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/vagrant-goodhosts/GoodHosts.rb b/lib/vagrant-goodhosts/GoodHosts.rb index 00700f8..08c9ffb 100644 --- a/lib/vagrant-goodhosts/GoodHosts.rb +++ b/lib/vagrant-goodhosts/GoodHosts.rb @@ -104,10 +104,10 @@ def hosts_entry_exists?(ip_address, hostname) # Use check command - no sudo needed for read-only operation if cli.include? ".exe" # Windows: direct command execution - stdout, stderr, status = Open3.capture3("\"#{cli}\" check \"#{ip_address}\" \"#{hostname}\"") + _stdout, _stderr, status = Open3.capture3("\"#{cli}\" check \"#{ip_address}\" \"#{hostname}\"") else # Unix/macOS: no sudo needed for check - stdout, stderr, status = Open3.capture3("'#{cli}' check '#{ip_address}' '#{hostname}'") + _stdout, _stderr, status = Open3.capture3("'#{cli}' check '#{ip_address}' '#{hostname}'") end return status.success? rescue StandardError => e