Implement command to update /etc/hosts files.
This commit disables automatic updates by default instead preferring the user to execute the hostmanager sub-command. The user can enable auto updates via configuration.
This commit is contained in:
parent
5865b1ac27
commit
39c197d7cc
22
README.md
22
README.md
|
@ -11,19 +11,31 @@ The current implementation is a proof-of-concept supporting the larger
|
|||
objective of using Vagrant as a cloud management interface for development
|
||||
and production environments.
|
||||
|
||||
The plugin has been tested with Vagrant 1.1.4.
|
||||
The plugin has been tested with Vagrant 1.1.5.
|
||||
|
||||
Installation
|
||||
------------
|
||||
Install the plugin following the typical Vagrant 1.1 procedure:
|
||||
|
||||
vagrant plugin install vagrant-hostmanager
|
||||
$ vagrant plugin install vagrant-hostmanager
|
||||
|
||||
Usage
|
||||
-----
|
||||
The plugin hooks into the `vagrant up` and `vagrant destroy` commands
|
||||
automatically updating the `/etc/hosts` file on each active machine that
|
||||
is using the same provider.
|
||||
To update the `/etc/hosts` file on each active machine, run the following
|
||||
command:
|
||||
|
||||
$ vagrant hostmanager
|
||||
|
||||
The plugin may hook into the `vagrant up` and `vagrant destroy` commands
|
||||
automatically to update the `/etc/hosts` file on each active machine that
|
||||
is using the same provider. To enable this, add the following configuration
|
||||
to your Vagrant file:
|
||||
|
||||
```ruby
|
||||
Vagrant.configure('2') do |config|
|
||||
config.hostmanager.auto_update = true
|
||||
end
|
||||
```
|
||||
|
||||
A machine's IP address is defined by either the static IP for a private
|
||||
network configuration or by the SSH host configuration.
|
||||
|
|
|
@ -1,66 +1,31 @@
|
|||
require 'vagrant-hostmanager/hosts_file'
|
||||
|
||||
module VagrantPlugins
|
||||
module HostManager
|
||||
module Action
|
||||
class UpdateHostsFile
|
||||
include HostsFile
|
||||
|
||||
def initialize(app, env)
|
||||
@app, @env = app, env
|
||||
@app = app
|
||||
@machine = env[:machine]
|
||||
@translator = Helpers::Translator.new('action.update_hosts_file')
|
||||
@logger =
|
||||
@logger =
|
||||
Log4r::Logger.new('vagrant_hostmanager::action::update')
|
||||
end
|
||||
|
||||
def call(env)
|
||||
global_env = env[:machine].env
|
||||
current_provider = env[:machine].provider_name
|
||||
# check config to see if the hosts file should updated automatically
|
||||
if @machine.config.hostmanager.auto_update
|
||||
# generate temporary hosts file
|
||||
machines = generate(@machine.env, @machine.provider_name)
|
||||
|
||||
# build a list of host entries based on active machines that
|
||||
# are using the same provider as the current one
|
||||
matching_machines = []
|
||||
entries = {}
|
||||
entries['127.0.0.1'] = 'localhost'
|
||||
global_env.active_machines.each do |name, provider|
|
||||
if provider == current_provider
|
||||
machine = global_env.machine(name, provider)
|
||||
host = machine.config.vm.hostname || name
|
||||
entries[get_ip_address(machine)] = host
|
||||
matching_machines << machine
|
||||
end
|
||||
end
|
||||
|
||||
# generate hosts file
|
||||
path = env[:tmp_path].join('hosts')
|
||||
File.open(path, 'w') do |file|
|
||||
entries.each_pair do |ip, host|
|
||||
@logger.info "Adding /etc/hosts entry: #{ip} #{host}"
|
||||
file << "#{ip}\t#{host}\n"
|
||||
end
|
||||
end
|
||||
|
||||
# copy the hosts file to each matching machine
|
||||
# TODO append hostname to loopback address
|
||||
matching_machines.each do |machine|
|
||||
if machine.communicate.ready?
|
||||
env[:ui].info @translator.t('update', { :name => machine.name })
|
||||
machine.communicate.upload(path, '/tmp/hosts')
|
||||
machine.communicate.sudo("mv /tmp/hosts /etc/hosts")
|
||||
end
|
||||
# update /etc/hosts file on each active machine
|
||||
machines.each { |machine| update(machine) }
|
||||
end
|
||||
|
||||
@app.call(env)
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def get_ip_address(machine)
|
||||
ip = nil
|
||||
machine.config.vm.networks.each do |network|
|
||||
key, options = network[0], network[1]
|
||||
ip = options[:ip] if key == :private_network
|
||||
next if ip
|
||||
end
|
||||
|
||||
ip || machine.ssh_info[:host]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
module VagrantPlugins
|
||||
module HostManager
|
||||
class Command < Vagrant.plugin('2', :command)
|
||||
include HostsFile
|
||||
|
||||
def execute
|
||||
options = {}
|
||||
opts = OptionParser.new do |o|
|
||||
o.banner = 'Usage: vagrant hostmanager [vm-name]'
|
||||
o.separator ''
|
||||
|
||||
o.on('--provider provider', String,
|
||||
'Update machines with the specific provider.') do |provider|
|
||||
options[:provider] = provider
|
||||
end
|
||||
end
|
||||
|
||||
argv = parse_options(opts)
|
||||
options[:provider] ||= @env.default_provider
|
||||
|
||||
generate(@env, options[:provider])
|
||||
|
||||
with_target_vms(argv[1..-1], :provider => options[:provider]) do |machine|
|
||||
update(machine)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,20 @@
|
|||
module VagrantPlugins
|
||||
module HostManager
|
||||
class Config < Vagrant.plugin('2', :config)
|
||||
attr_accessor :auto_update
|
||||
|
||||
def initialize
|
||||
@auto_update = false
|
||||
end
|
||||
|
||||
def validate(machine)
|
||||
errors = []
|
||||
if !(!!@auto_update == @auto_update)
|
||||
errors << 'auto_update must be a boolean'
|
||||
end
|
||||
|
||||
{ 'hostmanager' => errors }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,57 @@
|
|||
module VagrantPlugins
|
||||
module HostManager
|
||||
module HostsFile
|
||||
# Generate a hosts file containing the the active machines
|
||||
# in the Vagrant environment backed by the specified provider.
|
||||
# The file is written to the Vagrant temporary path.
|
||||
def generate(env, provider)
|
||||
machines = []
|
||||
|
||||
# define a lambda for looking up a machine's ip address
|
||||
get_ip_address = lambda do |machine|
|
||||
ip = nil
|
||||
machine.config.vm.networks.each do |network|
|
||||
key, options = network[0], network[1]
|
||||
ip = options[:ip] if key == :private_network
|
||||
next if ip
|
||||
end
|
||||
ip || machine.ssh_info[:host]
|
||||
end
|
||||
|
||||
# create the temporary hosts file
|
||||
path = env.tmp_path.join('hosts')
|
||||
File.open(path, 'w') do |file|
|
||||
file << "127.0.0.1\tlocalhost\n"
|
||||
|
||||
# add a hosts entry for each active machine matching the provider
|
||||
env.active_machines.each do |name, p|
|
||||
if provider == p
|
||||
machines << machine = env.machine(name, provider)
|
||||
host = machine.config.vm.hostname || name
|
||||
ip = get_ip_address.call(machine)
|
||||
@logger.info "Adding /etc/hosts entry: #{ip} #{host}"
|
||||
file << "#{ip}\t#{host}\n"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
machines
|
||||
end
|
||||
|
||||
# Copy the temporary hosts file to the specified machine overwritting
|
||||
# the existing /etc/hosts file.
|
||||
def update(machine)
|
||||
path = machine.env.tmp_path.join('hosts')
|
||||
if machine.communicate.ready?
|
||||
machine.env.ui.info translator.t('update', { :name => machine.name })
|
||||
machine.communicate.upload(path, '/tmp/hosts')
|
||||
machine.communicate.sudo("mv /tmp/hosts /etc/hosts")
|
||||
end
|
||||
end
|
||||
|
||||
def translator
|
||||
Helpers::Translator.new('hosts_file')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -10,16 +10,26 @@ module VagrantPlugins
|
|||
created for each active machine using the hostname attribute.
|
||||
DESC
|
||||
|
||||
action_hook(:hostmanager_up, :machine_action_up) do |hook|
|
||||
def self.update(hook)
|
||||
setup_i18n
|
||||
setup_logging
|
||||
hook.append(Action::UpdateHostsFile)
|
||||
end
|
||||
|
||||
action_hook(:hostmanger_destroy, :machine_action_destroy) do |hook|
|
||||
config(:hostmanager) do
|
||||
require_relative 'config'
|
||||
Config
|
||||
end
|
||||
|
||||
action_hook(:hostmanager_up, :machine_action_up, &method(:update))
|
||||
action_hook(:hostmanger_destroy, :machine_action_destroy, &method(:update))
|
||||
|
||||
# TODO remove duplication of i18n and logging setup
|
||||
command(:hostmanager) do
|
||||
setup_i18n
|
||||
setup_logging
|
||||
hook.append(Action::UpdateHostsFile)
|
||||
require_relative 'command'
|
||||
Command
|
||||
end
|
||||
|
||||
def self.setup_i18n
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
module VagrantPlugins
|
||||
module HostManager
|
||||
VERSION = '0.0.3'
|
||||
VERSION = '0.0.4'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
en:
|
||||
vagrant_hostmanager:
|
||||
action:
|
||||
update_hosts_file:
|
||||
update: "Updating /etc/hosts file on %{name}"
|
||||
hosts_file:
|
||||
update: "[%{name}] Updating /etc/hosts file"
|
||||
|
|
|
@ -6,12 +6,13 @@ vagrant ssh server1 -c 'cat /etc/hosts'
|
|||
echo "[server2] /etc/hosts file:"
|
||||
vagrant ssh server2 -c 'cat /etc/hosts'
|
||||
|
||||
vagrant halt
|
||||
vagrant up
|
||||
vagrant hostmanager
|
||||
|
||||
vagrant destroy server1 -f
|
||||
echo "[server1] /etc/hosts file:"
|
||||
vagrant ssh server1 -c 'cat /etc/hosts'
|
||||
echo "[server2] /etc/hosts file:"
|
||||
vagrant ssh server2 -c 'cat /etc/hosts'
|
||||
vagrant destroy server2 -f
|
||||
|
||||
vagrant destroy -f
|
||||
|
||||
cd ..
|
||||
|
|
Loading…
Reference in New Issue