From 67644a6de052ba7768a95f2242779cc542512f27 Mon Sep 17 00:00:00 2001 From: Brian Johnson Date: Thu, 2 May 2013 14:26:49 -0700 Subject: [PATCH] Add management of hostsfile on the host machine. --- .../action/delete_local_entry.rb | 30 ++++++++ .../action/update_local_entry.rb | 34 +++++++++ lib/vagrant-hostmanager/command.rb | 1 + lib/vagrant-hostmanager/config.rb | 7 ++ lib/vagrant-hostmanager/hosts_file.rb | 74 +++++++++++++++---- lib/vagrant-hostmanager/plugin.rb | 4 + 6 files changed, 134 insertions(+), 16 deletions(-) create mode 100644 lib/vagrant-hostmanager/action/delete_local_entry.rb create mode 100644 lib/vagrant-hostmanager/action/update_local_entry.rb diff --git a/lib/vagrant-hostmanager/action/delete_local_entry.rb b/lib/vagrant-hostmanager/action/delete_local_entry.rb new file mode 100644 index 0000000..7022b06 --- /dev/null +++ b/lib/vagrant-hostmanager/action/delete_local_entry.rb @@ -0,0 +1,30 @@ +require 'vagrant-hostmanager/hosts_file' + +module VagrantPlugins + module HostManager + module Action + class DeleteLocalEntry + include HostsFile + + def initialize(app, env) + @app = app + @machine = env[:machine] + @logger = Log4r::Logger.new('vagrant::hostmanager::delete_local_entry') + end + + def call(env) + + @logger.info 'delete called' + # check config to see if the hosts file should be updated automatically + return @app.call(env) unless @machine.config.hostmanager.enabled? + @logger.info 'Updating /etc/hosts file automatically' + + # delete entry for id + delete_local(@machine) + + @app.call(env) + end + end + end + end +end diff --git a/lib/vagrant-hostmanager/action/update_local_entry.rb b/lib/vagrant-hostmanager/action/update_local_entry.rb new file mode 100644 index 0000000..abe2ed1 --- /dev/null +++ b/lib/vagrant-hostmanager/action/update_local_entry.rb @@ -0,0 +1,34 @@ +require 'vagrant-hostmanager/hosts_file' + +module VagrantPlugins + module HostManager + module Action + class UpdateLocalEntry + include HostsFile + + def initialize(app, env) + @app = app + @machine = env[:machine] + @logger = Log4r::Logger.new('vagrant::hostmanager::update_local_entry') + end + + def call(env) + # check if machine is already active + @logger.info "Called update" + return @app.call(env) if @machine.id + + # check config to see if the hosts file should be update automatically + return @app.call(env) unless @machine.config.hostmanager.enabled? + @logger.info 'Updating /etc/hosts file automatically' + + # continue the action stack so the machine will be created + @app.call(env) + + # delete entry for id + update_local(@machine) + + end + end + end + end +end diff --git a/lib/vagrant-hostmanager/command.rb b/lib/vagrant-hostmanager/command.rb index b520250..5a75621 100644 --- a/lib/vagrant-hostmanager/command.rb +++ b/lib/vagrant-hostmanager/command.rb @@ -22,6 +22,7 @@ module VagrantPlugins with_target_vms(argv, options) do |machine| update(machine) + update_local(machine) end end end diff --git a/lib/vagrant-hostmanager/config.rb b/lib/vagrant-hostmanager/config.rb index feeeeaa..cb5aace 100644 --- a/lib/vagrant-hostmanager/config.rb +++ b/lib/vagrant-hostmanager/config.rb @@ -2,6 +2,7 @@ module VagrantPlugins module HostManager class Config < Vagrant.plugin('2', :config) attr_accessor :enabled + attr_accessor :manage_local attr_accessor :ignore_private_ip attr_accessor :aliases @@ -9,6 +10,7 @@ module VagrantPlugins def initialize @enabled = false + @manage_local = true @ignore_private_ip = UNSET_VALUE @aliases = Array.new end @@ -25,6 +27,11 @@ module VagrantPlugins errors << "A value for hostmanager.enabled can be true or false." end + # check if manage_local option is either true or false + if ![TrueClass, FalseClass].include?(manage_local.class) + errors << "A value for hostmanager.manage_local can be true or false." + end + # check if ignore_private_ip option is either true or false if ![TrueClass, FalseClass].include?(ignore_private_ip.class) && @ignore_private_ip != UNSET_VALUE diff --git a/lib/vagrant-hostmanager/hosts_file.rb b/lib/vagrant-hostmanager/hosts_file.rb index 99c1ca1..6f92f58 100644 --- a/lib/vagrant-hostmanager/hosts_file.rb +++ b/lib/vagrant-hostmanager/hosts_file.rb @@ -7,18 +7,6 @@ module VagrantPlugins def generate(env, provider) machines = [] - # define a lambda for looking up a machine's ip address - get_ip_address = lambda do |machine| - ip = nil - if machine.config.hostmanager.ignore_private_ip != true - machine.config.vm.networks.each do |network| - key, options = network[0], network[1] - ip = options[:ip] if key == :private_network - next if ip - end - end - ip || machine.ssh_info[:host] - end # create the temporary hosts file path = env.tmp_path.join('hosts') @@ -30,10 +18,12 @@ module VagrantPlugins if provider == p machines << machine = env.machine(name, provider) host = machine.config.vm.hostname || name - ip = get_ip_address.call(machine) + id = machine.id + ip = get_ip_address(machine) host_aliases = machine.config.hostmanager.aliases.join("\s").chomp - @logger.info "Adding /etc/hosts entry: #{ip} #{host} #{host_aliases}" - file << "#{ip}\t#{host}\s#{host_aliases}\n" + host_entry = "#{ip}\t#{host}\s#{host_aliases}\n" + @logger.info "Adding /etc/hosts entry: #{ip} #{host} #{host_aliases} #{id}" + file << "#{host_entry}" end end end @@ -41,6 +31,58 @@ module VagrantPlugins machines end + # define a lambda for looking up a machine's ip address + def get_ip_address(machine) + ip = nil + if machine.config.hostmanager.ignore_private_ip != true + machine.config.vm.networks.each do |network| + key, options = network[0], network[1] + ip = options[:ip] if key == :private_network + next if ip + end + end + ip || machine.ssh_info[:host] + end + + def update_local(machine) + return if machine.id.nil? + tmplocal=machine.env.tmp_path.join('hosts.local') + delete_local(machine) + + host = machine.config.vm.hostname || name + id = machine.id + ip = get_ip_address(machine) + host_aliases = machine.config.hostmanager.aliases.join("\s").chomp + host_entry = "#{ip}\t#{host}\s#{host_aliases}\s# VAGRANT: #{id}\n" + @logger.info "Adding /etc/hosts entry: #{ip} #{host} #{host_aliases} # #{id} - #{tmplocal}" + File.open(tmplocal,'a') do |tmpfile| + tmpfile << host_entry + end + publish_local(machine.env) + + + end + + def delete_local(machine) + return if machine.id.nil? + tmplocal=machine.env.tmp_path.join('hosts.local') + File.open(tmplocal, 'w') do |tmpfile| + File.open('/etc/hosts','r').each_line do |line| + if line.match(/#{machine.id}$/).nil? + @logger.info "Found #{machine.id} in hosts file" + tmpfile << line + end + end + end + publish_local(machine.env) + end + + def publish_local(env) + @logger.info `sudo cp -v /etc/hosts /etc/hosts.bak` + @logger.info `sudo cp -v #{env.tmp_path.join('hosts.local')} /etc/hosts` + end + + # Copy the temporary hosts file to the specified machine overwritting # the existing /etc/hosts file. def update(machine) @@ -50,7 +92,7 @@ module VagrantPlugins :name => machine.name }) machine.communicate.upload(path, '/tmp/hosts') - machine.communicate.sudo("mv /tmp/hosts /etc/hosts") + machine.communicate.sudo("mv /tmp/hosts /etc/hosts.hostmanager") end end end diff --git a/lib/vagrant-hostmanager/plugin.rb b/lib/vagrant-hostmanager/plugin.rb index c7bd9ca..197dce8 100644 --- a/lib/vagrant-hostmanager/plugin.rb +++ b/lib/vagrant-hostmanager/plugin.rb @@ -1,4 +1,6 @@ require 'vagrant-hostmanager/action/update_hosts_file' +require 'vagrant-hostmanager/action/update_local_entry' +require 'vagrant-hostmanager/action/delete_local_entry' module VagrantPlugins module HostManager @@ -16,9 +18,11 @@ module VagrantPlugins action_hook(:hostmanager, :machine_action_up) do |hook| hook.prepend(Action::UpdateHostsFile) + hook.prepend(Action::UpdateLocalEntry) end action_hook(:hostmanager, :machine_action_destroy) do |hook| + hook.prepend(Action::DeleteLocalEntry) hook.append(Action::UpdateHostsFile) end