Explicitly define LF or CRLF line endings for hosts and guests when defining the hosts file content.
This commit is contained in:
parent
e97bc6fd16
commit
42bfe1f82b
2
Gemfile
2
Gemfile
|
@ -1,7 +1,7 @@
|
||||||
source 'https://rubygems.org'
|
source 'https://rubygems.org'
|
||||||
|
|
||||||
group :development do
|
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
|
end
|
||||||
|
|
||||||
group :plugins do
|
group :plugins do
|
||||||
|
|
33
README.md
33
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)
|
[![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=)
|
[![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
|
Installation
|
||||||
------------
|
------------
|
||||||
|
@ -16,7 +16,7 @@ Install the plugin following the typical Vagrant 1.1 procedure:
|
||||||
|
|
||||||
Usage
|
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:
|
command:
|
||||||
|
|
||||||
$ vagrant hostmanager
|
$ vagrant hostmanager
|
||||||
|
@ -24,14 +24,14 @@ command:
|
||||||
The plugin hooks into the `vagrant up` and `vagrant destroy` commands
|
The plugin hooks into the `vagrant up` and `vagrant destroy` commands
|
||||||
automatically.
|
automatically.
|
||||||
When a machine enters or exits the running state , all active
|
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
|
accordingly. Set the `hostmanager.enabled` attribute to `true` in the
|
||||||
Vagrantfile to activate this behavior.
|
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`.
|
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`.
|
attribute to `true`.
|
||||||
|
|
||||||
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
|
||||||
|
@ -90,14 +90,14 @@ config.vm.provision :hostmanager
|
||||||
Custom IP resolver
|
Custom IP resolver
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
You can customize how vagrant-hostmanager resolves IP address
|
You can customize way, how host manager resolves IP address
|
||||||
for each machine. This might be handy in the case of the AWS provider,
|
for each machine. This might be handy in case of aws provider,
|
||||||
where the host name is stored in the ssh_info hash of each machine.
|
where host name is stored in ssh_info hash of each machine.
|
||||||
This causes a generation of an invalid `hosts` file.
|
This causes generation of invalid /etc/hosts file.
|
||||||
|
|
||||||
A custom IP resolver gives you the oportunity to calculate IP address
|
Custom IP resolver gives you oportunity to calculate IP address
|
||||||
for each machine by yourself, giving you access to the machine that is
|
for each machine by yourself, giving You also access to the machine that is
|
||||||
updating `hosts`. For example:
|
updating /etc/hosts. For example:
|
||||||
|
|
||||||
```ruby
|
```ruby
|
||||||
config.hostmanager.ip_resolver = proc do |vm, resolving_vm|
|
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**
|
**Developing**
|
||||||
|
|
||||||
1. Install [Bundler](http://bundler.io/)
|
1. Ideally, install the version of Vagrant as defined in the `Gemfile`
|
||||||
2. Currently the Bundler version is locked to 1.6.9, please install this version.
|
1. Install [Ruby](https://www.ruby-lang.org/en/documentation/installation/)
|
||||||
* `sudo gem install bundler -v '1.6.9'`
|
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:
|
3. Then install vagrant-hostmanager dependancies:
|
||||||
* `bundle _1.6.9_ install`
|
* `bundle _1.14.6_ install`
|
||||||
|
|
||||||
**Testing**
|
**Testing**
|
||||||
|
|
||||||
|
|
|
@ -18,16 +18,20 @@ module VagrantPlugins
|
||||||
return unless machine.communicate.ready?
|
return unless machine.communicate.ready?
|
||||||
|
|
||||||
if (machine.communicate.test("uname -s | grep SunOS"))
|
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"))
|
elsif (machine.communicate.test("test -d $Env:SystemRoot"))
|
||||||
windir = ""
|
windir = ""
|
||||||
machine.communicate.execute("echo %SYSTEMROOT%", {:shell => :cmd}) do |type, contents|
|
machine.communicate.execute("echo %SYSTEMROOT%", {:shell => :cmd}) do |type, contents|
|
||||||
windir << contents.gsub("\r\n", '') if type == :stdout
|
windir << contents.gsub("\r\n", '') if type == :stdout
|
||||||
end
|
end
|
||||||
realhostfile = "#{windir}\\System32\\drivers\\etc\\hosts"
|
realhostfile = "#{windir}\\System32\\drivers\\etc\\hosts"
|
||||||
|
line_endings = "crlf"
|
||||||
else
|
else
|
||||||
realhostfile = '/etc/hosts'
|
realhostfile = "/etc/hosts"
|
||||||
|
line_endings = "lf"
|
||||||
end
|
end
|
||||||
|
|
||||||
# download and modify file with Vagrant-managed entries
|
# download and modify file with Vagrant-managed entries
|
||||||
file = @global_env.tmp_path.join("hosts.#{machine.name}")
|
file = @global_env.tmp_path.join("hosts.#{machine.name}")
|
||||||
machine.communicate.download(realhostfile, file)
|
machine.communicate.download(realhostfile, file)
|
||||||
|
@ -35,8 +39,7 @@ module VagrantPlugins
|
||||||
@logger.debug("file is: #{file.to_s}")
|
@logger.debug("file is: #{file.to_s}")
|
||||||
@logger.debug("class of file is: #{file.class}")
|
@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
|
# upload modified file and remove temporary file
|
||||||
machine.communicate.upload(file.to_s, '/tmp/hosts')
|
machine.communicate.upload(file.to_s, '/tmp/hosts')
|
||||||
if windir
|
if windir
|
||||||
|
@ -57,38 +60,40 @@ module VagrantPlugins
|
||||||
class << self
|
class << self
|
||||||
include WindowsSupport unless include? WindowsSupport
|
include WindowsSupport unless include? WindowsSupport
|
||||||
end
|
end
|
||||||
|
|
||||||
hosts_location = "#{ENV['WINDIR']}\\System32\\drivers\\etc\\hosts"
|
hosts_location = "#{ENV['WINDIR']}\\System32\\drivers\\etc\\hosts"
|
||||||
copy_proc = Proc.new { windows_copy_file(file, hosts_location) }
|
copy_proc = Proc.new { windows_copy_file(file, hosts_location) }
|
||||||
|
line_endings = "crlf"
|
||||||
else
|
else
|
||||||
hosts_location = '/etc/hosts'
|
hosts_location = '/etc/hosts'
|
||||||
copy_proc = Proc.new { `[ -w #{hosts_location} ] && cat #{file} > #{hosts_location} || sudo cp #{file} #{hosts_location}` }
|
copy_proc = Proc.new { `[ -w #{hosts_location} ] && cat #{file} > #{hosts_location} || sudo cp #{file} #{hosts_location}` }
|
||||||
|
line_endings = "lf"
|
||||||
end
|
end
|
||||||
|
|
||||||
FileUtils.cp(hosts_location, file)
|
FileUtils.cp(hosts_location, file)
|
||||||
if update_file(file)
|
|
||||||
|
if update_file(file, nil, true, line_endings)
|
||||||
copy_proc.call
|
copy_proc.call
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
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)
|
file = Pathname.new(file)
|
||||||
old_file_content = file.read
|
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) }
|
file.open('wb') { |io| io.write(new_file_content) }
|
||||||
old_file_content != new_file_content
|
old_file_content != new_file_content
|
||||||
end
|
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}" : ""
|
id = include_id ? " id: #{read_or_create_id}" : ""
|
||||||
header = "## vagrant-hostmanager-start#{id}\n"
|
header = "## vagrant-hostmanager-start#{id}\n"
|
||||||
footer = "## vagrant-hostmanager-end\n"
|
footer = "## vagrant-hostmanager-end\n"
|
||||||
body = get_machines
|
body = get_machines
|
||||||
.map { |machine| get_hosts_file_entry(machine, resolving_machine) }
|
.map { |machine| get_hosts_file_entry(machine, resolving_machine) }
|
||||||
.join
|
.join
|
||||||
get_new_content(header, footer, body, file_content)
|
get_new_content(header, footer, body, file_content, line_endings)
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_hosts_file_entry(machine, resolving_machine)
|
def get_hosts_file_entry(machine, resolving_machine)
|
||||||
|
@ -137,7 +142,7 @@ module VagrantPlugins
|
||||||
.reject(&:nil?)
|
.reject(&:nil?)
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_new_content(header, footer, body, old_content)
|
def get_new_content(header, footer, body, old_content, line_endings)
|
||||||
if body.empty?
|
if body.empty?
|
||||||
block = "\n"
|
block = "\n"
|
||||||
else
|
else
|
||||||
|
@ -148,7 +153,14 @@ module VagrantPlugins
|
||||||
footer_pattern = Regexp.quote(footer)
|
footer_pattern = Regexp.quote(footer)
|
||||||
pattern = Regexp.new("\n*#{header_pattern}.*?#{footer_pattern}\n*", Regexp::MULTILINE)
|
pattern = Regexp.new("\n*#{header_pattern}.*?#{footer_pattern}\n*", Regexp::MULTILINE)
|
||||||
# Replace existing block or append
|
# 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
|
end
|
||||||
|
|
||||||
def read_or_create_id
|
def read_or_create_id
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
en:
|
en:
|
||||||
vagrant_hostmanager:
|
vagrant_hostmanager:
|
||||||
action:
|
action:
|
||||||
update_guests: "Updating /etc/hosts file on active guest machines..."
|
update_guests: "[vagrant-hostmanager:guests] Updating hosts file on active guest virtual machines..."
|
||||||
update_guest: "[%{name}] Updating /etc/hosts file..."
|
update_guest: "[vagrant-hostmanager:guest] Updating hosts file on the virtual machine %{name}..."
|
||||||
update_host: "Updating /etc/hosts file on host machine (password may be required)..."
|
update_host: "[vagrant-hostmanager:host] Updating hosts file on your workstation (password may be required)..."
|
||||||
config:
|
config:
|
||||||
not_a_bool: "A value for %{config_key} can only be true or false, not type '%{value}'"
|
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: "A value for %{config_key} must be an Array or String, not type '%{is_class}'"
|
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: "A value for %{config_key} must be a Proc, not type '%{is_class}'"
|
not_a_proc: "[vagrant-hostmanager:config:error] A value for %{config_key} must be a Proc, not type '%{is_class}'"
|
||||||
|
|
Loading…
Reference in New Issue