From 61ce04040ef9d084481ca25014a71fce50675e95 Mon Sep 17 00:00:00 2001 From: Jan Vansteenkiste Date: Wed, 1 May 2013 18:42:55 +0200 Subject: [PATCH 01/10] hostmanager should not run if we run it with -h --- lib/vagrant-hostmanager/command.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/vagrant-hostmanager/command.rb b/lib/vagrant-hostmanager/command.rb index b520250..831f08f 100644 --- a/lib/vagrant-hostmanager/command.rb +++ b/lib/vagrant-hostmanager/command.rb @@ -16,6 +16,8 @@ module VagrantPlugins end argv = parse_options(opts) + return if !argv + options[:provider] ||= @env.default_provider generate(@env, options[:provider].to_sym) From f058b3025f08cca3089465230c45cffd625d99c6 Mon Sep 17 00:00:00 2001 From: Jan Vansteenkiste Date: Thu, 2 May 2013 08:02:58 +0200 Subject: [PATCH 02/10] Fix small scoping issue. @logger is not available from the provisioner --- lib/vagrant-hostmanager/hosts_file.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/vagrant-hostmanager/hosts_file.rb b/lib/vagrant-hostmanager/hosts_file.rb index 99c1ca1..e7b4ce2 100644 --- a/lib/vagrant-hostmanager/hosts_file.rb +++ b/lib/vagrant-hostmanager/hosts_file.rb @@ -32,7 +32,7 @@ module VagrantPlugins host = machine.config.vm.hostname || name ip = get_ip_address.call(machine) host_aliases = machine.config.hostmanager.aliases.join("\s").chomp - @logger.info "Adding /etc/hosts entry: #{ip} #{host} #{host_aliases}" + machine.env.ui.info "Adding /etc/hosts entry: #{ip} #{host} #{host_aliases}" file << "#{ip}\t#{host}\s#{host_aliases}\n" end end From cae5f6be7dc6d5da9b3d9163db3425372d711b71 Mon Sep 17 00:00:00 2001 From: Jan Vansteenkiste Date: Thu, 2 May 2013 08:36:40 +0200 Subject: [PATCH 03/10] Add Hostmanager as a provisioner. --- README.md | 11 +++++++++++ lib/vagrant-hostmanager/plugin.rb | 7 +++++++ lib/vagrant-hostmanager/provisioner.rb | 12 ++++++++++++ 3 files changed, 30 insertions(+) create mode 100644 lib/vagrant-hostmanager/provisioner.rb diff --git a/README.md b/README.md index 62f487f..16ae137 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,17 @@ Vagrant.configure("2") do |config| end ``` +As a last option, you can also choose hostmanager as a provisioner. +This allows you to use the provisioning order to ensure that hostmanager +runs before or after provisioning. The provisioner will collect hosts from +boxes with the same provider as the running box. + +Use: + +```ruby +config.vm.provision :hostmanager +``` + Contribute ---------- Contributions are welcome. diff --git a/lib/vagrant-hostmanager/plugin.rb b/lib/vagrant-hostmanager/plugin.rb index c7bd9ca..f73ce6e 100644 --- a/lib/vagrant-hostmanager/plugin.rb +++ b/lib/vagrant-hostmanager/plugin.rb @@ -7,6 +7,8 @@ module VagrantPlugins description <<-DESC This plugin manages the /etc/hosts file for guest machines. An entry is created for each active machine using the hostname attribute. + + You can also use the hostmanager provisioner to update the hosts file. DESC config(:hostmanager) do @@ -22,6 +24,11 @@ module VagrantPlugins hook.append(Action::UpdateHostsFile) end + provisioner(:hostmanager) do + require_relative 'provisioner' + Provisioner + end + command(:hostmanager) do require_relative 'command' Command diff --git a/lib/vagrant-hostmanager/provisioner.rb b/lib/vagrant-hostmanager/provisioner.rb new file mode 100644 index 0000000..65d43db --- /dev/null +++ b/lib/vagrant-hostmanager/provisioner.rb @@ -0,0 +1,12 @@ +module VagrantPlugins + module HostManager + class Provisioner < Vagrant.plugin('2', :provisioner) + include HostsFile + + def provision + generate(@machine.env, @machine.box.provider.to_sym) + update(@machine) + end + end + end +end From c98ddd338e9affacea897524af8bbc504c6f6554 Mon Sep 17 00:00:00 2001 From: Shawn Dahlen Date: Thu, 2 May 2013 15:12:36 -0400 Subject: [PATCH 04/10] Bump version for release --- lib/vagrant-hostmanager/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/vagrant-hostmanager/version.rb b/lib/vagrant-hostmanager/version.rb index dc96dc4..1526729 100644 --- a/lib/vagrant-hostmanager/version.rb +++ b/lib/vagrant-hostmanager/version.rb @@ -1,5 +1,5 @@ module VagrantPlugins module HostManager - VERSION = '0.2.0' + VERSION = '0.3.0' end end From 3a96f5e170844011deeb24fcb1dc993a322f9d32 Mon Sep 17 00:00:00 2001 From: Jan Vansteenkiste Date: Thu, 2 May 2013 21:26:05 +0200 Subject: [PATCH 05/10] use more I18n and do not repeat ourselves while doing config checks --- lib/vagrant-hostmanager/config.rb | 34 ++++++++++++++++++++------- lib/vagrant-hostmanager/hosts_file.rb | 6 ++++- locales/en.yml | 4 ++++ 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/lib/vagrant-hostmanager/config.rb b/lib/vagrant-hostmanager/config.rb index feeeeaa..20be3c8 100644 --- a/lib/vagrant-hostmanager/config.rb +++ b/lib/vagrant-hostmanager/config.rb @@ -15,29 +15,45 @@ module VagrantPlugins def finalize! @ignore_private_ip = false if @ignore_private_ip == UNSET_VALUE + @aliases = [ @aliases ].flatten end def validate(machine) errors = Array.new # check if enabled option is either true or false - if ![TrueClass, FalseClass].include?(enabled.class) - errors << "A value for hostmanager.enabled can be true or false." - end + errors << validate_bool('hostmanager.enabled', enabled) - # check if ignore_private_ip option is either true or false - if ![TrueClass, FalseClass].include?(ignore_private_ip.class) && - @ignore_private_ip != UNSET_VALUE - errors << "A value for hostmanager.ignore_private_ip can be true or false." + # check if ignore_private_ip option is either true or false (or UNSET_VALUE) + if @ignore_private_ip != UNSET_VALUE + errors << validate_bool('hostmanager.ignore_private_ip', ignore_private_ip) end # check if aliases option is an Array - if !machine.config.hostmanager.aliases.kind_of?(Array) - errors << "A value for hostmanager.aliases must be an Array." + if !machine.config.hostmanager.aliases.kind_of?(Array) and + !machine.config.hostmanager.aliases.kind_of?(String) + errors << I18n.t('vagrant_hostmanager.config.not_an_array_or_string', { + :config_key => 'hostmanager.aliases', + :is_class => aliases.class.to_s, + }) end + errors.compact! { "HostManager configuration" => errors } end + + private + def validate_bool(key, value) + if ![TrueClass, FalseClass].include?(value.class) + I18n.t('vagrant_hostmanager.config.not_a_bool', { + :config_key => key, + :value => value.class.to_s, + }) + else + nil + end + end + end end end diff --git a/lib/vagrant-hostmanager/hosts_file.rb b/lib/vagrant-hostmanager/hosts_file.rb index e7b4ce2..d45d770 100644 --- a/lib/vagrant-hostmanager/hosts_file.rb +++ b/lib/vagrant-hostmanager/hosts_file.rb @@ -32,7 +32,11 @@ module VagrantPlugins host = machine.config.vm.hostname || name ip = get_ip_address.call(machine) host_aliases = machine.config.hostmanager.aliases.join("\s").chomp - machine.env.ui.info "Adding /etc/hosts entry: #{ip} #{host} #{host_aliases}" + machine.env.ui.info I18n.t('vagrant_hostmanager.action.add_host', { + :ip => ip, + :host => host, + :aliases => host_aliases, + }) file << "#{ip}\t#{host}\s#{host_aliases}\n" end end diff --git a/locales/en.yml b/locales/en.yml index f8d2ea2..337d096 100644 --- a/locales/en.yml +++ b/locales/en.yml @@ -1,4 +1,8 @@ en: vagrant_hostmanager: action: + add_host: "Adding /etc/hosts entry: %{ip} %{host} %{aliases}" update: "[%{name}] Updating /etc/hosts file" + config: + not_a_bool: "A value for %{config_key} can only be true or false, not type '%{value}'" + not_an_array_or_string: "A value for %{config_key} must be an Array or String, not type '%{is_class}'" From b67661407fd2d8c71ca302a149b2ca5fbecb7cec Mon Sep 17 00:00:00 2001 From: Jan Vansteenkiste Date: Thu, 2 May 2013 21:44:02 +0200 Subject: [PATCH 06/10] Respond to "vagrant hostmanager -v" and display our version --- lib/vagrant-hostmanager/command.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/vagrant-hostmanager/command.rb b/lib/vagrant-hostmanager/command.rb index 831f08f..a3cebd6 100644 --- a/lib/vagrant-hostmanager/command.rb +++ b/lib/vagrant-hostmanager/command.rb @@ -8,6 +8,8 @@ module VagrantPlugins opts = OptionParser.new do |o| o.banner = 'Usage: vagrant hostmanager [vm-name]' o.separator '' + o.version = VagrantPlugins::HostManager::VERSION + o.program_name = 'vagrant hostmanager' o.on('--provider provider', String, 'Update machines with the specific provider.') do |provider| From 6e4a2ae96761c930a3c0997a9e7b076b803888f0 Mon Sep 17 00:00:00 2001 From: Jan Vansteenkiste Date: Mon, 6 May 2013 08:29:25 +0200 Subject: [PATCH 07/10] Abstract the get_machines part. Prepare for include offline. --- lib/vagrant-hostmanager/hosts_file.rb | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/vagrant-hostmanager/hosts_file.rb b/lib/vagrant-hostmanager/hosts_file.rb index d45d770..1a175d1 100644 --- a/lib/vagrant-hostmanager/hosts_file.rb +++ b/lib/vagrant-hostmanager/hosts_file.rb @@ -24,9 +24,7 @@ module VagrantPlugins path = env.tmp_path.join('hosts') File.open(path, 'w') do |file| file << "127.0.0.1\tlocalhost\slocalhost.localdomain\n" - - # add a hosts entry for each active machine matching the provider - env.active_machines.each do |name, p| + get_machines(env, provider).each do |name, p| if provider == p machines << machine = env.machine(name, provider) host = machine.config.vm.hostname || name @@ -57,6 +55,14 @@ module VagrantPlugins machine.communicate.sudo("mv /tmp/hosts /etc/hosts") end end + + private + # Returns an array with the same structure as env.active_machines: + # [ [:machine, :virtualbox], [:foo, :virtualbox] ] + def get_machines(env, provider) + env.active_machines + end + end end end From 0b3e60cb5db2789885dfdb5b7eb9d09cfa1b4b82 Mon Sep 17 00:00:00 2001 From: Jan Vansteenkiste Date: Mon, 6 May 2013 08:31:31 +0200 Subject: [PATCH 08/10] Added new include_offline configuration item --- README.md | 5 +++++ lib/vagrant-hostmanager/config.rb | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/README.md b/README.md index 16ae137..0f11188 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,10 @@ to true. A machine's host name is defined by `config.vm.hostname`. If this is not set, it falls back to the symbol defining the machine in the Vagrantfile. +When using include_offline set to true, only boxes that are up or have a +private ip configured will be added to the hosts file. You will receive a +warning on skipped boxes. + In addition, the `hostmanager.aliases` configuration attribute can be used to provide aliases for your host names. @@ -49,6 +53,7 @@ Example configuration: Vagrant.configure("2") do |config| config.hostmanager.enabled = true config.hostmanager.ignore_private_ip = false + config.hostmanager.include_offline = true config.vm.define "example-box" do |node| node.vm.hostname = "example-box-hostname" node.vm.network :private_network, ip: "192.168.42.42" diff --git a/lib/vagrant-hostmanager/config.rb b/lib/vagrant-hostmanager/config.rb index 20be3c8..5244db3 100644 --- a/lib/vagrant-hostmanager/config.rb +++ b/lib/vagrant-hostmanager/config.rb @@ -4,13 +4,16 @@ module VagrantPlugins attr_accessor :enabled attr_accessor :ignore_private_ip attr_accessor :aliases + attr_accessor :include_offline alias_method :enabled?, :enabled + alias_method :include_offline?, :include_offline def initialize @enabled = false @ignore_private_ip = UNSET_VALUE @aliases = Array.new + @include_offline = false end def finalize! @@ -24,6 +27,9 @@ module VagrantPlugins # check if enabled option is either true or false errors << validate_bool('hostmanager.enabled', enabled) + # check if include_offline is either true or false + errors << validate_bool('hostmanager.include_offline', include_offline) + # check if ignore_private_ip option is either true or false (or UNSET_VALUE) if @ignore_private_ip != UNSET_VALUE errors << validate_bool('hostmanager.ignore_private_ip', ignore_private_ip) From 00b8e75a7d6fad55dcae9614b11fbfa7661f81b8 Mon Sep 17 00:00:00 2001 From: Jan Vansteenkiste Date: Mon, 6 May 2013 08:32:02 +0200 Subject: [PATCH 09/10] Support include_offline boxes. If include_offline is enabled, we loop over all available boxes picking those with the correct provider. If a box has no private ip set or is offline, it is skipped (a warning is shown). The lambda that gets the ip will return nil for the boxes. --- lib/vagrant-hostmanager/hosts_file.rb | 41 ++++++++++++++++++++------- locales/en.yml | 1 + 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/lib/vagrant-hostmanager/hosts_file.rb b/lib/vagrant-hostmanager/hosts_file.rb index 1a175d1..505b82e 100644 --- a/lib/vagrant-hostmanager/hosts_file.rb +++ b/lib/vagrant-hostmanager/hosts_file.rb @@ -17,7 +17,7 @@ module VagrantPlugins next if ip end end - ip || machine.ssh_info[:host] + ip || (machine.ssh_info ? machine.ssh_info[:host] : nil) end # create the temporary hosts file @@ -29,17 +29,22 @@ module VagrantPlugins machines << machine = env.machine(name, provider) host = machine.config.vm.hostname || name ip = get_ip_address.call(machine) - host_aliases = machine.config.hostmanager.aliases.join("\s").chomp - machine.env.ui.info I18n.t('vagrant_hostmanager.action.add_host', { - :ip => ip, - :host => host, - :aliases => host_aliases, - }) - file << "#{ip}\t#{host}\s#{host_aliases}\n" + if ip + host_aliases = machine.config.hostmanager.aliases.join("\s").chomp + machine.env.ui.info I18n.t('vagrant_hostmanager.action.add_host', { + :ip => ip, + :host => host, + :aliases => host_aliases, + }) + file << "#{ip}\t#{host}\s#{host_aliases}\n" + else + machine.env.ui.warn I18n.t('vagrant_hostmanager.action.host_no_ip', { + :name => name, + }) + end end end end - machines end @@ -57,10 +62,26 @@ module VagrantPlugins end private + # Either use the active machines, or loop over all available machines and + # get those with the same provider (aka, ignore boxes that throw MachineNotFound errors). + # # Returns an array with the same structure as env.active_machines: # [ [:machine, :virtualbox], [:foo, :virtualbox] ] def get_machines(env, provider) - env.active_machines + if env.config_global.hostmanager.include_offline? + machines = [] + env.machine_names.each do |name| + begin + m = env.machine(name, provider) + machines << [name, provider] + rescue Vagrant::Errors::MachineNotFound => ex + # ignore this box. + end + end + machines + else + env.active_machines + end end end diff --git a/locales/en.yml b/locales/en.yml index 337d096..758b7d3 100644 --- a/locales/en.yml +++ b/locales/en.yml @@ -2,6 +2,7 @@ en: vagrant_hostmanager: action: add_host: "Adding /etc/hosts entry: %{ip} %{host} %{aliases}" + host_no_ip: "Could not determine ip for machine '%{name}': no private ip configured or machine not up." update: "[%{name}] Updating /etc/hosts file" config: not_a_bool: "A value for %{config_key} can only be true or false, not type '%{value}'" From a078935cb09fbc9ff140022a89e6565958091f5d Mon Sep 17 00:00:00 2001 From: Shawn Dahlen Date: Tue, 7 May 2013 10:26:31 -0400 Subject: [PATCH 10/10] Bump version for release. --- lib/vagrant-hostmanager/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/vagrant-hostmanager/version.rb b/lib/vagrant-hostmanager/version.rb index 1526729..bf8a05a 100644 --- a/lib/vagrant-hostmanager/version.rb +++ b/lib/vagrant-hostmanager/version.rb @@ -1,5 +1,5 @@ module VagrantPlugins module HostManager - VERSION = '0.3.0' + VERSION = '0.4.0' end end