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
|
objective of using Vagrant as a cloud management interface for development
|
||||||
and production environments.
|
and production environments.
|
||||||
|
|
||||||
The plugin has been tested with Vagrant 1.1.4.
|
The plugin has been tested with Vagrant 1.1.5.
|
||||||
|
|
||||||
Installation
|
Installation
|
||||||
------------
|
------------
|
||||||
Install the plugin following the typical Vagrant 1.1 procedure:
|
Install the plugin following the typical Vagrant 1.1 procedure:
|
||||||
|
|
||||||
vagrant plugin install vagrant-hostmanager
|
$ vagrant plugin install vagrant-hostmanager
|
||||||
|
|
||||||
Usage
|
Usage
|
||||||
-----
|
-----
|
||||||
The plugin hooks into the `vagrant up` and `vagrant destroy` commands
|
To update the `/etc/hosts` file on each active machine, run the following
|
||||||
automatically updating the `/etc/hosts` file on each active machine that
|
command:
|
||||||
is using the same provider.
|
|
||||||
|
$ 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
|
A machine's IP address is defined by either the static IP for a private
|
||||||
network configuration or by the SSH host configuration.
|
network configuration or by the SSH host configuration.
|
||||||
|
|
|
@ -1,66 +1,31 @@
|
||||||
|
require 'vagrant-hostmanager/hosts_file'
|
||||||
|
|
||||||
module VagrantPlugins
|
module VagrantPlugins
|
||||||
module HostManager
|
module HostManager
|
||||||
module Action
|
module Action
|
||||||
class UpdateHostsFile
|
class UpdateHostsFile
|
||||||
|
include HostsFile
|
||||||
|
|
||||||
def initialize(app, env)
|
def initialize(app, env)
|
||||||
@app, @env = app, env
|
@app = app
|
||||||
|
@machine = env[:machine]
|
||||||
@translator = Helpers::Translator.new('action.update_hosts_file')
|
@translator = Helpers::Translator.new('action.update_hosts_file')
|
||||||
@logger =
|
@logger =
|
||||||
Log4r::Logger.new('vagrant_hostmanager::action::update')
|
Log4r::Logger.new('vagrant_hostmanager::action::update')
|
||||||
end
|
end
|
||||||
|
|
||||||
def call(env)
|
def call(env)
|
||||||
global_env = env[:machine].env
|
# check config to see if the hosts file should updated automatically
|
||||||
current_provider = env[:machine].provider_name
|
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
|
# update /etc/hosts file on each active machine
|
||||||
# are using the same provider as the current one
|
machines.each { |machine| update(machine) }
|
||||||
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
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@app.call(env)
|
@app.call(env)
|
||||||
end
|
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
|
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.
|
created for each active machine using the hostname attribute.
|
||||||
DESC
|
DESC
|
||||||
|
|
||||||
action_hook(:hostmanager_up, :machine_action_up) do |hook|
|
def self.update(hook)
|
||||||
setup_i18n
|
setup_i18n
|
||||||
setup_logging
|
setup_logging
|
||||||
hook.append(Action::UpdateHostsFile)
|
hook.append(Action::UpdateHostsFile)
|
||||||
end
|
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_i18n
|
||||||
setup_logging
|
setup_logging
|
||||||
hook.append(Action::UpdateHostsFile)
|
require_relative 'command'
|
||||||
|
Command
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.setup_i18n
|
def self.setup_i18n
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
module VagrantPlugins
|
module VagrantPlugins
|
||||||
module HostManager
|
module HostManager
|
||||||
VERSION = '0.0.3'
|
VERSION = '0.0.4'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
en:
|
en:
|
||||||
vagrant_hostmanager:
|
vagrant_hostmanager:
|
||||||
action:
|
hosts_file:
|
||||||
update_hosts_file:
|
update: "[%{name}] Updating /etc/hosts file"
|
||||||
update: "Updating /etc/hosts file on %{name}"
|
|
||||||
|
|
|
@ -6,12 +6,13 @@ vagrant ssh server1 -c 'cat /etc/hosts'
|
||||||
echo "[server2] /etc/hosts file:"
|
echo "[server2] /etc/hosts file:"
|
||||||
vagrant ssh server2 -c 'cat /etc/hosts'
|
vagrant ssh server2 -c 'cat /etc/hosts'
|
||||||
|
|
||||||
vagrant halt
|
vagrant hostmanager
|
||||||
vagrant up
|
|
||||||
|
|
||||||
vagrant destroy server1 -f
|
echo "[server1] /etc/hosts file:"
|
||||||
|
vagrant ssh server1 -c 'cat /etc/hosts'
|
||||||
echo "[server2] /etc/hosts file:"
|
echo "[server2] /etc/hosts file:"
|
||||||
vagrant ssh server2 -c 'cat /etc/hosts'
|
vagrant ssh server2 -c 'cat /etc/hosts'
|
||||||
vagrant destroy server2 -f
|
|
||||||
|
vagrant destroy -f
|
||||||
|
|
||||||
cd ..
|
cd ..
|
||||||
|
|
Loading…
Reference in New Issue