diff --git a/Gemfile b/Gemfile index 14137ea..9018418 100644 --- a/Gemfile +++ b/Gemfile @@ -1,7 +1,7 @@ source 'https://rubygems.org' group :development do - gem 'vagrant', :git => 'git://github.com/mitchellh/vagrant.git', :tag => 'v1.6.2' + gem 'vagrant', :git => 'git://github.com/mitchellh/vagrant.git', :tag => 'v1.9.4' end group :plugins do diff --git a/README.md b/README.md index 4951d86..c308e36 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Vagrant Host Manager [![Gem](https://img.shields.io/gem/dtv/vagrant-hostmanager.svg)](https://rubygems.org/gems/vagrant-hostmanager) [![Twitter](https://img.shields.io/twitter/url/https/github.com/devopsgroup-io/vagrant-hostmanager.svg?style=social)](https://twitter.com/intent/tweet?text=Check%20out%20this%20awesome%20Vagrant%20plugin%21&url=https%3A%2F%2Fgithub.com%devopsgroup-io%2Fvagrant-hostmanager&hashtags=vagrant%hostmanager&original_referer=) -`vagrant-hostmanager` is a plugin that manages the `hosts` file on guest machines (and optionally the host). Its goal is to enable resolution of multi-machine environments deployed with a cloud provider where IP addresses are not known in advance. +`vagrant-hostmanager` is a plugin that manages the `/etc/hosts` file on guest machines (and optionally the host). Its goal is to enable resolution of multi-machine environments deployed with a cloud provider where IP addresses are not known in advance. Installation ------------ @@ -16,7 +16,7 @@ Install the plugin following the typical Vagrant 1.1 procedure: Usage ----- -To update the `hosts` file on each active machine, run the following +To update the `/etc/hosts` file on each active machine, run the following command: $ vagrant hostmanager @@ -24,14 +24,14 @@ command: The plugin hooks into the `vagrant up` and `vagrant destroy` commands automatically. When a machine enters or exits the running state , all active -machines with the same provider will have their `hosts` file updated +machines with the same provider will have their `/etc/hosts` file updated accordingly. Set the `hostmanager.enabled` attribute to `true` in the Vagrantfile to activate this behavior. -To update the host's `hosts` file, set the `hostmanager.manage_host` +To update the host's `/etc/hosts` file, set the `hostmanager.manage_host` attribute to `true`. -To update the guests' `hosts` file, set the `hostmanager.manage_guest` +To update the guests' `/etc/hosts` file, set the `hostmanager.manage_guest` attribute to `true`. A machine's IP address is defined by either the static IP for a private @@ -90,14 +90,14 @@ config.vm.provision :hostmanager Custom IP resolver ------------------ -You can customize how vagrant-hostmanager resolves IP address -for each machine. This might be handy in the case of the AWS provider, -where the host name is stored in the ssh_info hash of each machine. -This causes a generation of an invalid `hosts` file. +You can customize way, how host manager resolves IP address +for each machine. This might be handy in case of aws provider, +where host name is stored in ssh_info hash of each machine. +This causes generation of invalid /etc/hosts file. -A custom IP resolver gives you the oportunity to calculate IP address -for each machine by yourself, giving you access to the machine that is -updating `hosts`. For example: +Custom IP resolver gives you oportunity to calculate IP address +for each machine by yourself, giving You also access to the machine that is +updating /etc/hosts. For example: ```ruby config.hostmanager.ip_resolver = proc do |vm, resolving_vm| @@ -188,11 +188,12 @@ To contribute, fork then clone the repository, and then the following: **Developing** -1. Install [Bundler](http://bundler.io/) -2. Currently the Bundler version is locked to 1.6.9, please install this version. - * `sudo gem install bundler -v '1.6.9'` +1. Ideally, install the version of Vagrant as defined in the `Gemfile` +1. Install [Ruby](https://www.ruby-lang.org/en/documentation/installation/) +2. Currently the Bundler version is locked to 1.14.6, please install this version. + * `gem install bundler -v '1.14.6'` 3. Then install vagrant-hostmanager dependancies: - * `bundle _1.6.9_ install` + * `bundle _1.14.6_ install` **Testing** diff --git a/lib/vagrant-hostmanager/hosts_file/updater.rb b/lib/vagrant-hostmanager/hosts_file/updater.rb index 409cbf4..fdae4d9 100644 --- a/lib/vagrant-hostmanager/hosts_file/updater.rb +++ b/lib/vagrant-hostmanager/hosts_file/updater.rb @@ -18,16 +18,20 @@ module VagrantPlugins return unless machine.communicate.ready? if (machine.communicate.test("uname -s | grep SunOS")) - realhostfile = '/etc/inet/hosts' + realhostfile = "/etc/inet/hosts" + line_endings = "lf" elsif (machine.communicate.test("test -d $Env:SystemRoot")) windir = "" machine.communicate.execute("echo %SYSTEMROOT%", {:shell => :cmd}) do |type, contents| windir << contents.gsub("\r\n", '') if type == :stdout end realhostfile = "#{windir}\\System32\\drivers\\etc\\hosts" + line_endings = "crlf" else - realhostfile = '/etc/hosts' + realhostfile = "/etc/hosts" + line_endings = "lf" end + # download and modify file with Vagrant-managed entries file = @global_env.tmp_path.join("hosts.#{machine.name}") machine.communicate.download(realhostfile, file) @@ -35,8 +39,7 @@ module VagrantPlugins @logger.debug("file is: #{file.to_s}") @logger.debug("class of file is: #{file.class}") - if update_file(file, machine, false) - + if update_file(file, machine, false, line_endings) # upload modified file and remove temporary file machine.communicate.upload(file.to_s, '/tmp/hosts') if windir @@ -57,38 +60,40 @@ module VagrantPlugins class << self include WindowsSupport unless include? WindowsSupport end - hosts_location = "#{ENV['WINDIR']}\\System32\\drivers\\etc\\hosts" copy_proc = Proc.new { windows_copy_file(file, hosts_location) } + line_endings = "crlf" else hosts_location = '/etc/hosts' copy_proc = Proc.new { `[ -w #{hosts_location} ] && cat #{file} > #{hosts_location} || sudo cp #{file} #{hosts_location}` } + line_endings = "lf" end FileUtils.cp(hosts_location, file) - if update_file(file) + + if update_file(file, nil, true, line_endings) copy_proc.call end end private - def update_file(file, resolving_machine = nil, include_id = true) + def update_file(file, resolving_machine = nil, include_id = true, line_endings) file = Pathname.new(file) old_file_content = file.read - new_file_content = update_content(old_file_content, resolving_machine, include_id) + new_file_content = update_content(old_file_content, resolving_machine, include_id, line_endings) file.open('wb') { |io| io.write(new_file_content) } old_file_content != new_file_content end - def update_content(file_content, resolving_machine, include_id) + def update_content(file_content, resolving_machine, include_id, line_endings) id = include_id ? " id: #{read_or_create_id}" : "" header = "## vagrant-hostmanager-start#{id}\n" footer = "## vagrant-hostmanager-end\n" body = get_machines .map { |machine| get_hosts_file_entry(machine, resolving_machine) } .join - get_new_content(header, footer, body, file_content) + get_new_content(header, footer, body, file_content, line_endings) end def get_hosts_file_entry(machine, resolving_machine) @@ -137,7 +142,7 @@ module VagrantPlugins .reject(&:nil?) end - def get_new_content(header, footer, body, old_content) + def get_new_content(header, footer, body, old_content, line_endings) if body.empty? block = "\n" else @@ -148,7 +153,14 @@ module VagrantPlugins footer_pattern = Regexp.quote(footer) pattern = Regexp.new("\n*#{header_pattern}.*?#{footer_pattern}\n*", Regexp::MULTILINE) # Replace existing block or append - old_content.match(pattern) ? old_content.sub(pattern, block) : old_content.rstrip + block + content = old_content.match(pattern) ? old_content.sub(pattern, block) : old_content.rstrip + block + if line_endings == "crlf" + content.encode(content.encoding, :universal_encoding => true).encode(content.encoding, :crlf_newline => true) + elsif line_endings == "lf" + content.encode(content.encoding, :universal_encoding => true) + else + content.encode(content.encoding, :universal_encoding => true) + end end def read_or_create_id diff --git a/locales/en.yml b/locales/en.yml index 0070d70..42b37a5 100644 --- a/locales/en.yml +++ b/locales/en.yml @@ -1,10 +1,10 @@ en: vagrant_hostmanager: action: - update_guests: "Updating /etc/hosts file on active guest machines..." - update_guest: "[%{name}] Updating /etc/hosts file..." - update_host: "Updating /etc/hosts file on host machine (password may be required)..." + update_guests: "[vagrant-hostmanager:guests] Updating hosts file on active guest virtual machines..." + update_guest: "[vagrant-hostmanager:guest] Updating hosts file on the virtual machine %{name}..." + update_host: "[vagrant-hostmanager:host] Updating hosts file on your workstation (password may be required)..." 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}'" - not_a_proc: "A value for %{config_key} must be a Proc, not type '%{is_class}'" + not_a_bool: "[vagrant-hostmanager:config:error] A value for %{config_key} can only be true or false, not type '%{value}'" + not_an_array_or_string: "[vagrant-hostmanager:config:error] A value for %{config_key} must be an Array or String, not type '%{is_class}'" + not_a_proc: "[vagrant-hostmanager:config:error] A value for %{config_key} must be a Proc, not type '%{is_class}'"