Skip to content

Commit 42bfe1f

Browse files
committed
Explicitly define LF or CRLF line endings for hosts and guests when defining the hosts file content.
1 parent e97bc6f commit 42bfe1f

File tree

4 files changed

+48
-35
lines changed

4 files changed

+48
-35
lines changed

Gemfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
source 'https://rubygems.org'
22

33
group :development do
4-
gem 'vagrant', :git => 'git://github.com/mitchellh/vagrant.git', :tag => 'v1.6.2'
4+
gem 'vagrant', :git => 'git://github.com/mitchellh/vagrant.git', :tag => 'v1.9.4'
55
end
66

77
group :plugins do

README.md

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ Vagrant Host Manager
66
[![Gem](https://img.shields.io/gem/dtv/vagrant-hostmanager.svg)](https://rubygems.org/gems/vagrant-hostmanager)
77
[![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=)
88

9-
`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.
9+
`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.
1010

1111
Installation
1212
------------
@@ -16,22 +16,22 @@ Install the plugin following the typical Vagrant 1.1 procedure:
1616

1717
Usage
1818
-----
19-
To update the `hosts` file on each active machine, run the following
19+
To update the `/etc/hosts` file on each active machine, run the following
2020
command:
2121

2222
$ vagrant hostmanager
2323

2424
The plugin hooks into the `vagrant up` and `vagrant destroy` commands
2525
automatically.
2626
When a machine enters or exits the running state , all active
27-
machines with the same provider will have their `hosts` file updated
27+
machines with the same provider will have their `/etc/hosts` file updated
2828
accordingly. Set the `hostmanager.enabled` attribute to `true` in the
2929
Vagrantfile to activate this behavior.
3030

31-
To update the host's `hosts` file, set the `hostmanager.manage_host`
31+
To update the host's `/etc/hosts` file, set the `hostmanager.manage_host`
3232
attribute to `true`.
3333

34-
To update the guests' `hosts` file, set the `hostmanager.manage_guest`
34+
To update the guests' `/etc/hosts` file, set the `hostmanager.manage_guest`
3535
attribute to `true`.
3636

3737
A machine's IP address is defined by either the static IP for a private
@@ -90,14 +90,14 @@ config.vm.provision :hostmanager
9090
Custom IP resolver
9191
------------------
9292

93-
You can customize how vagrant-hostmanager resolves IP address
94-
for each machine. This might be handy in the case of the AWS provider,
95-
where the host name is stored in the ssh_info hash of each machine.
96-
This causes a generation of an invalid `hosts` file.
93+
You can customize way, how host manager resolves IP address
94+
for each machine. This might be handy in case of aws provider,
95+
where host name is stored in ssh_info hash of each machine.
96+
This causes generation of invalid /etc/hosts file.
9797

98-
A custom IP resolver gives you the oportunity to calculate IP address
99-
for each machine by yourself, giving you access to the machine that is
100-
updating `hosts`. For example:
98+
Custom IP resolver gives you oportunity to calculate IP address
99+
for each machine by yourself, giving You also access to the machine that is
100+
updating /etc/hosts. For example:
101101

102102
```ruby
103103
config.hostmanager.ip_resolver = proc do |vm, resolving_vm|
@@ -188,11 +188,12 @@ To contribute, fork then clone the repository, and then the following:
188188
189189
**Developing**
190190
191-
1. Install [Bundler](http://bundler.io/)
192-
2. Currently the Bundler version is locked to 1.6.9, please install this version.
193-
* `sudo gem install bundler -v '1.6.9'`
191+
1. Ideally, install the version of Vagrant as defined in the `Gemfile`
192+
1. Install [Ruby](https://www.ruby-lang.org/en/documentation/installation/)
193+
2. Currently the Bundler version is locked to 1.14.6, please install this version.
194+
* `gem install bundler -v '1.14.6'`
194195
3. Then install vagrant-hostmanager dependancies:
195-
* `bundle _1.6.9_ install`
196+
* `bundle _1.14.6_ install`
196197
197198
**Testing**
198199

lib/vagrant-hostmanager/hosts_file/updater.rb

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,25 +18,28 @@ def update_guest(machine)
1818
return unless machine.communicate.ready?
1919

2020
if (machine.communicate.test("uname -s | grep SunOS"))
21-
realhostfile = '/etc/inet/hosts'
21+
realhostfile = "/etc/inet/hosts"
22+
line_endings = "lf"
2223
elsif (machine.communicate.test("test -d $Env:SystemRoot"))
2324
windir = ""
2425
machine.communicate.execute("echo %SYSTEMROOT%", {:shell => :cmd}) do |type, contents|
2526
windir << contents.gsub("\r\n", '') if type == :stdout
2627
end
2728
realhostfile = "#{windir}\\System32\\drivers\\etc\\hosts"
29+
line_endings = "crlf"
2830
else
29-
realhostfile = '/etc/hosts'
31+
realhostfile = "/etc/hosts"
32+
line_endings = "lf"
3033
end
34+
3135
# download and modify file with Vagrant-managed entries
3236
file = @global_env.tmp_path.join("hosts.#{machine.name}")
3337
machine.communicate.download(realhostfile, file)
3438

3539
@logger.debug("file is: #{file.to_s}")
3640
@logger.debug("class of file is: #{file.class}")
3741

38-
if update_file(file, machine, false)
39-
42+
if update_file(file, machine, false, line_endings)
4043
# upload modified file and remove temporary file
4144
machine.communicate.upload(file.to_s, '/tmp/hosts')
4245
if windir
@@ -57,38 +60,40 @@ def update_host
5760
class << self
5861
include WindowsSupport unless include? WindowsSupport
5962
end
60-
6163
hosts_location = "#{ENV['WINDIR']}\\System32\\drivers\\etc\\hosts"
6264
copy_proc = Proc.new { windows_copy_file(file, hosts_location) }
65+
line_endings = "crlf"
6366
else
6467
hosts_location = '/etc/hosts'
6568
copy_proc = Proc.new { `[ -w #{hosts_location} ] && cat #{file} > #{hosts_location} || sudo cp #{file} #{hosts_location}` }
69+
line_endings = "lf"
6670
end
6771

6872
FileUtils.cp(hosts_location, file)
69-
if update_file(file)
73+
74+
if update_file(file, nil, true, line_endings)
7075
copy_proc.call
7176
end
7277
end
7378

7479
private
7580

76-
def update_file(file, resolving_machine = nil, include_id = true)
81+
def update_file(file, resolving_machine = nil, include_id = true, line_endings)
7782
file = Pathname.new(file)
7883
old_file_content = file.read
79-
new_file_content = update_content(old_file_content, resolving_machine, include_id)
84+
new_file_content = update_content(old_file_content, resolving_machine, include_id, line_endings)
8085
file.open('wb') { |io| io.write(new_file_content) }
8186
old_file_content != new_file_content
8287
end
8388

84-
def update_content(file_content, resolving_machine, include_id)
89+
def update_content(file_content, resolving_machine, include_id, line_endings)
8590
id = include_id ? " id: #{read_or_create_id}" : ""
8691
header = "## vagrant-hostmanager-start#{id}\n"
8792
footer = "## vagrant-hostmanager-end\n"
8893
body = get_machines
8994
.map { |machine| get_hosts_file_entry(machine, resolving_machine) }
9095
.join
91-
get_new_content(header, footer, body, file_content)
96+
get_new_content(header, footer, body, file_content, line_endings)
9297
end
9398

9499
def get_hosts_file_entry(machine, resolving_machine)
@@ -137,7 +142,7 @@ def get_machines
137142
.reject(&:nil?)
138143
end
139144

140-
def get_new_content(header, footer, body, old_content)
145+
def get_new_content(header, footer, body, old_content, line_endings)
141146
if body.empty?
142147
block = "\n"
143148
else
@@ -148,7 +153,14 @@ def get_new_content(header, footer, body, old_content)
148153
footer_pattern = Regexp.quote(footer)
149154
pattern = Regexp.new("\n*#{header_pattern}.*?#{footer_pattern}\n*", Regexp::MULTILINE)
150155
# Replace existing block or append
151-
old_content.match(pattern) ? old_content.sub(pattern, block) : old_content.rstrip + block
156+
content = old_content.match(pattern) ? old_content.sub(pattern, block) : old_content.rstrip + block
157+
if line_endings == "crlf"
158+
content.encode(content.encoding, :universal_encoding => true).encode(content.encoding, :crlf_newline => true)
159+
elsif line_endings == "lf"
160+
content.encode(content.encoding, :universal_encoding => true)
161+
else
162+
content.encode(content.encoding, :universal_encoding => true)
163+
end
152164
end
153165

154166
def read_or_create_id

locales/en.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
en:
22
vagrant_hostmanager:
33
action:
4-
update_guests: "Updating /etc/hosts file on active guest machines..."
5-
update_guest: "[%{name}] Updating /etc/hosts file..."
6-
update_host: "Updating /etc/hosts file on host machine (password may be required)..."
4+
update_guests: "[vagrant-hostmanager:guests] Updating hosts file on active guest virtual machines..."
5+
update_guest: "[vagrant-hostmanager:guest] Updating hosts file on the virtual machine %{name}..."
6+
update_host: "[vagrant-hostmanager:host] Updating hosts file on your workstation (password may be required)..."
77
config:
8-
not_a_bool: "A value for %{config_key} can only be true or false, not type '%{value}'"
9-
not_an_array_or_string: "A value for %{config_key} must be an Array or String, not type '%{is_class}'"
10-
not_a_proc: "A value for %{config_key} must be a Proc, not type '%{is_class}'"
8+
not_a_bool: "[vagrant-hostmanager:config:error] A value for %{config_key} can only be true or false, not type '%{value}'"
9+
not_an_array_or_string: "[vagrant-hostmanager:config:error] A value for %{config_key} must be an Array or String, not type '%{is_class}'"
10+
not_a_proc: "[vagrant-hostmanager:config:error] A value for %{config_key} must be a Proc, not type '%{is_class}'"

0 commit comments

Comments
 (0)