vagrant-hosts-provisioner 1.0.1 → 2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b5ec1e1905eebb2cba20f837e02d69768aae2be1
4
- data.tar.gz: f94c9dfb5897c79b6abee8d059df11f4f12692fa
3
+ metadata.gz: b9682f369371d62fb9d52045d0b5349578adb9da
4
+ data.tar.gz: acabdb3efdbc7691a848fee0bcca1ce86c235adc
5
5
  SHA512:
6
- metadata.gz: d8da804b098709c4b7d0b09e195dc164835593477e5964353a8bb07f13673156a0c7dfa3952039999ea9800fa61f1dd00f41db0600141f03f8a9a1ad08d70a64
7
- data.tar.gz: c84600221267b52ecb30c12ff3bc0133ab29b74dba35189936f7caaaf7b6c572a6b0c233b22965b9e9e9fceede35f0022834e27ec704aa034243cc253930e9db
6
+ metadata.gz: 62771fda68d297ee2b465f9ae7beaa93a47c15a16f12dd0a504cfcdc23292cc336563d00e60d3314f04acc33537afd27c80cdf96e94cac816370c3e816b3b9b5
7
+ data.tar.gz: 61875020970a84ba8facc499bc5422b501b01e0129b6daa447776e2b765cbc7344623984206591101231835ae66270e5c2e2c9ba9b116bca37619d515d483dcb
data/README.md CHANGED
@@ -1,7 +1,6 @@
1
1
  # VagrantPlugins::HostsProvisioner
2
2
 
3
- A Vagrant provisioner for managing the /etc/hosts file of the host and guest machines. This plugin is currently being used by [#Dashboard VM](https://github.com/mdkholy/Dashboard)..
4
-
3
+ A Vagrant provisioner for managing the /etc/hosts file of the host and guest machines.
5
4
  ## Installation
6
5
 
7
6
  Install into vagrant's isolated RubyGems instance using:
@@ -10,7 +9,22 @@ Install into vagrant's isolated RubyGems instance using:
10
9
 
11
10
  ## Usage
12
11
 
13
- TODO: Write usage instructions here
12
+ Example configuration:
13
+
14
+ ```ruby
15
+ config.vm.provision :hostsupdate, run: 'always' do |host|
16
+ host.hostname = 'demo-hostname'
17
+ host.manage_guest = true
18
+ host.manage_host = true
19
+ host.aliases = [
20
+ 'hostname-aliase1',
21
+ 'hostname-aliase2'
22
+ ]
23
+ host.files = [
24
+ 'config/hosts.json'
25
+ ]
26
+ end
27
+ ```
14
28
 
15
29
  ## Contributing
16
30
 
@@ -5,8 +5,6 @@ require "vagrant-hosts-provisioner/version"
5
5
  module VagrantPlugins
6
6
  module HostsProvisioner
7
7
  # This returns the path to the source of this plugin.
8
- #
9
- # @return [Pathname]
10
8
  def self.source_root
11
9
  @source_root ||= Pathname.new(File.expand_path('../../', __FILE__))
12
10
  end
@@ -0,0 +1,25 @@
1
+ require_relative 'action/add'
2
+ require_relative 'action/remove'
3
+
4
+ module VagrantPlugins
5
+ module HostsProvisioner
6
+ module Action
7
+ include Vagrant::Action::Builtin
8
+
9
+ def self.add
10
+ Vagrant::Action::Builder.new.tap do |builder|
11
+ builder.use ConfigValidate
12
+ builder.use Add
13
+ end
14
+ end
15
+
16
+ def self.remove
17
+ Vagrant::Action::Builder.new.tap do |builder|
18
+ builder.use ConfigValidate
19
+ builder.use Remove
20
+ end
21
+ end
22
+
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,24 @@
1
+ module VagrantPlugins
2
+ module HostsProvisioner
3
+ module Action
4
+ class Add
5
+
6
+ def initialize(app, env)
7
+ @app = app
8
+ @machine = env[:machine]
9
+ @config = @machine.env.vagrantfile.config
10
+ end
11
+
12
+ def call(env)
13
+ @config.vm.provisioners.each do |provisioner|
14
+ if provisioner.name == :hostsupdate
15
+ Hosts.new(@machine, provisioner.config).add
16
+ end
17
+ end
18
+ @app.call(env)
19
+ end
20
+
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,24 @@
1
+ module VagrantPlugins
2
+ module HostsProvisioner
3
+ module Action
4
+ class Remove
5
+
6
+ def initialize(app, env)
7
+ @app = app
8
+ @machine = env[:machine]
9
+ @config = @machine.env.vagrantfile.config
10
+ end
11
+
12
+ def call(env)
13
+ @config.vm.provisioners.each do |provisioner|
14
+ if provisioner.name == :hostsupdate
15
+ Hosts.new(@machine, provisioner.config).remove
16
+ end
17
+ end
18
+ @app.call(env)
19
+ end
20
+
21
+ end
22
+ end
23
+ end
24
+ end
@@ -1,6 +1,7 @@
1
1
  module VagrantPlugins
2
2
  module HostsProvisioner
3
3
  class Config < Vagrant.plugin("2", :config)
4
+ attr_accessor :id
4
5
  attr_accessor :hostname
5
6
  attr_accessor :manage_guest
6
7
  attr_accessor :manage_host
@@ -8,6 +9,7 @@ module VagrantPlugins
8
9
  attr_accessor :files
9
10
 
10
11
  def initialize
12
+ @id = UNSET_VALUE
11
13
  @hostname = UNSET_VALUE
12
14
  @manage_guest = UNSET_VALUE
13
15
  @manage_host = UNSET_VALUE
@@ -16,6 +18,7 @@ module VagrantPlugins
16
18
  end
17
19
 
18
20
  def finalize!
21
+ @id = 0 if @id == UNSET_VALUE
19
22
  @hostname = nil if @hostname == UNSET_VALUE
20
23
  @manage_guest = false if @manage_guest == UNSET_VALUE
21
24
  @manage_host = false if @manage_host == UNSET_VALUE
@@ -29,16 +32,18 @@ module VagrantPlugins
29
32
  def validate(machine)
30
33
  errors = []
31
34
 
35
+ errors << validate_number('id', id)
36
+ errors << validate_bool_or_string('hostname', hostname)
32
37
  errors << validate_bool('manage_guest', manage_guest)
33
38
  errors << validate_bool('manage_host', manage_host)
34
- errors << validate_array_or_string('aliases', aliases)
35
39
  errors << validate_array_or_string('files', files)
40
+ errors << validate_array_or_string('aliases', aliases)
36
41
  errors.compact!
37
42
 
38
43
  { "HostsProvisioner configuration" => errors }
39
44
  end
40
45
 
41
- # Checks if a option is boolean
46
+ # Checks if a option is Boolean
42
47
  def validate_bool(key, value)
43
48
  if ![TrueClass, FalseClass].include?(value.class) && value != UNSET_VALUE
44
49
  I18n.t('vagrant_hostsprovisioner.error.invalid_bool', {
@@ -50,9 +55,21 @@ module VagrantPlugins
50
55
  end
51
56
  end
52
57
 
53
- # Checks if a option is an Array
58
+ # Checks if a option is a Number
59
+ def validate_number(key, value)
60
+ if !value.kind_of?(Fixnum) && !value.kind_of?(NilClass)
61
+ I18n.t('vagrant_hostsprovisioner.error.not_a_number', {
62
+ :config_key => key,
63
+ :invalid_class => value.class.to_s
64
+ })
65
+ else
66
+ nil
67
+ end
68
+ end
69
+
70
+ # Checks if a option is an Array or String
54
71
  def validate_array_or_string(key, value)
55
- if !aliases.kind_of?(Array) && !aliases.kind_of?(String)
72
+ if !value.kind_of?(Array) && !value.kind_of?(String) && !value.kind_of?(NilClass)
56
73
  I18n.t('vagrant_hostsprovisioner.error.not_an_array_or_string', {
57
74
  :config_key => key,
58
75
  :invalid_class => value.class.to_s
@@ -62,6 +79,30 @@ module VagrantPlugins
62
79
  end
63
80
  end
64
81
 
82
+ # Checks if a option is a String or Boolean
83
+ def validate_bool_or_string(key, value)
84
+ if ![TrueClass, FalseClass].include?(value.class) && !value.kind_of?(String) && !value.kind_of?(NilClass)
85
+ I18n.t('vagrant_hostsprovisioner.error.not_a_bool_or_string', {
86
+ :config_key => key,
87
+ :invalid_class => value.class.to_s
88
+ })
89
+ else
90
+ nil
91
+ end
92
+ end
93
+
94
+ # Checks if a option is a String
95
+ def validate_string(key, value)
96
+ if !value.kind_of?(String) && !value.kind_of?(NilClass)
97
+ I18n.t('vagrant_hostsprovisioner.error.not_a_string', {
98
+ :config_key => key,
99
+ :invalid_class => value.class.to_s
100
+ })
101
+ else
102
+ nil
103
+ end
104
+ end
105
+
65
106
  end
66
107
  end
67
108
  end
@@ -0,0 +1,264 @@
1
+ require 'tempfile'
2
+
3
+ module VagrantPlugins
4
+ module HostsProvisioner
5
+ class Hosts
6
+
7
+ def initialize(machine, config)
8
+ @machine = machine
9
+ @config = config
10
+ end
11
+
12
+ def add
13
+ # Update the guest machine if manage_guest is enabled
14
+ if @config.manage_guest
15
+ update_guest
16
+ end
17
+
18
+ # Update the host machine if manage_host is enabled
19
+ if @config.manage_host
20
+ update_host(false)
21
+ end
22
+ end
23
+
24
+ def remove
25
+ if @config.manage_host
26
+ update_host(true)
27
+ end
28
+ end
29
+
30
+ def update_guest
31
+ return unless @machine.communicate.ready?
32
+
33
+ handle_comm(:stdout, I18n.t("vagrant_hostsprovisioner.provisioner.update_guest"))
34
+
35
+ if (@machine.communicate.test("uname -s | grep SunOS"))
36
+ realhostfile = '/etc/inet/hosts'
37
+ move_cmd = 'mv'
38
+ elsif (@machine.communicate.test("test -d $Env:SystemRoot"))
39
+ windir = ""
40
+ @machine.communicate.execute("echo %SYSTEMROOT%", {:shell => :cmd}) do |type, contents|
41
+ windir << contents.gsub("\r\n", '') if type == :stdout
42
+ end
43
+ realhostfile = "#{windir}\\System32\\drivers\\etc\\hosts"
44
+ move_cmd = 'mv -force'
45
+ else
46
+ realhostfile = '/etc/hosts'
47
+ move_cmd = 'mv -f'
48
+ end
49
+
50
+ # download and modify file with Vagrant-managed entries
51
+ file = @machine.env.tmp_path.join("hosts.#{@machine.name}")
52
+ @machine.communicate.download(realhostfile, file)
53
+ if update_file(file, false, false)
54
+ # upload modified file and remove temporary file
55
+ @machine.communicate.upload(file, '/tmp/hosts')
56
+ @machine.communicate.sudo("#{move_cmd} /tmp/hosts #{realhostfile}")
57
+ handle_comm(:stdout, I18n.t("vagrant_hostsprovisioner.provisioner.hosts_file_updated", {:file => realhostfile}))
58
+ end
59
+
60
+ begin
61
+ FileUtils.rm(file)
62
+ rescue Exception => e
63
+ end
64
+ end
65
+
66
+ def update_host(clean)
67
+ # copy and modify hosts file on host with Vagrant-managed entries
68
+ file = @machine.env.tmp_path.join('hosts.local')
69
+
70
+ if clean == true
71
+ handle_comm(:stdout, I18n.t("vagrant_hostsprovisioner.provisioner.clean_host"))
72
+ else
73
+ handle_comm(:stdout, I18n.t("vagrant_hostsprovisioner.provisioner.update_host"))
74
+ end
75
+
76
+ if WindowsSupport.windows?
77
+ # lazily include windows Module
78
+ class << self
79
+ include WindowsSupport unless include? WindowsSupport
80
+ end
81
+
82
+ hosts_location = "#{ENV['WINDIR']}\\System32\\drivers\\etc\\hosts"
83
+ copy_proc = Proc.new { windows_copy_file(file, hosts_location) }
84
+ else
85
+ hosts_location = '/etc/hosts'
86
+ copy_proc = Proc.new { `sudo cp #{file} #{hosts_location}` }
87
+ end
88
+
89
+ FileUtils.cp(hosts_location, file)
90
+ if update_file(file, true, clean)
91
+ copy_proc.call
92
+ handle_comm(:stdout, I18n.t("vagrant_hostsprovisioner.provisioner.hosts_file_updated", {:file => hosts_location}))
93
+ end
94
+ end
95
+
96
+ def update_file(file, include_id, clean)
97
+ file = Pathname.new(file)
98
+ old_file_content = file.read
99
+ new_file_content = update_content(old_file_content, include_id, clean)
100
+ file.open('w') { |io| io.write(new_file_content) }
101
+ old_file_content != new_file_content
102
+ end
103
+
104
+ def update_content(file_content, include_id, clean)
105
+ id = include_id ? " id: #{read_or_create_id}" : ""
106
+ header = "## vagrant-hosts-provisioner-start#{id}\n"
107
+ footer = "## vagrant-hosts-provisioner-end\n"
108
+ body = clean ? "" : get_hosts_file_entry
109
+ get_new_content(header, footer, body, file_content)
110
+ end
111
+
112
+ def get_hosts_file_entry
113
+ # Get the vm ip address
114
+ ip = get_ip_address
115
+
116
+ # Return empy string if we don't have an ip address
117
+ if ip === nil
118
+ handle_comm(:stderr, I18n.t("vagrant_hostsprovisioner.error.no_vm_ip"))
119
+ return ''
120
+ end
121
+
122
+ hosts = []
123
+
124
+ # Add the machine hostname
125
+ unless @config.hostname === false
126
+ hosts.push(@config.hostname || @machine.config.vm.hostname || @machine.name)
127
+ end
128
+
129
+ # Add the defined aliases
130
+ hosts.concat(@config.aliases)
131
+
132
+ # Add the contents of the defined hosts files
133
+ if @config.files.count > 0
134
+ hosts.concat(get_files_data)
135
+ end
136
+
137
+ # Remove duplicates
138
+ hosts = hosts.uniq
139
+
140
+ # Limit the number of hosts per line to 8
141
+ lines = []
142
+ hosts.each_slice(8) do |chnk|
143
+ lines.push("#{ip}\t" + chnk.join(' ').strip)
144
+ end
145
+
146
+ # Join lines
147
+ hosts = lines.join("\n").strip
148
+
149
+ "#{hosts}\n"
150
+ end
151
+
152
+ def get_files_data
153
+ require 'json'
154
+ data = []
155
+ @config.files.each do |file|
156
+ if file.kind_of?(String) && file != ""
157
+ file_path = File.join(@machine.env.root_path, file)
158
+ if File.exist?(file_path)
159
+ file_data = JSON.parse(File.read(file_path))
160
+ data.concat([ file_data ].flatten)
161
+ else
162
+ handle_comm(:stderr, I18n.t("vagrant_hostsprovisioner.error.file_not_found", {:file => file.to_s}))
163
+ end
164
+ end
165
+ end
166
+ data.collect(&:strip)
167
+ end
168
+
169
+ def get_ip_address
170
+ ip = nil
171
+ @machine.config.vm.networks.each do |network|
172
+ key, options = network[0], network[1]
173
+ ip = options[:ip] if key == :private_network
174
+ break if ip
175
+ end
176
+ # If no ip is defined in private_network then use the ssh host ip instead
177
+ ip || (@machine.ssh_info ? @machine.ssh_info[:host] : nil)
178
+ end
179
+
180
+ def get_new_content(header, footer, body, old_content)
181
+ if body.empty?
182
+ block = "\n"
183
+ else
184
+ block = "\n\n" + header + body + footer + "\n"
185
+ end
186
+ # Pattern for finding existing block
187
+ header_pattern = Regexp.quote(header)
188
+ footer_pattern = Regexp.quote(footer)
189
+ pattern = Regexp.new("\n*#{header_pattern}.*?#{footer_pattern}\n*", Regexp::MULTILINE)
190
+ # Replace existing block or append
191
+ old_content.match(pattern) ? old_content.sub(pattern, block) : old_content.rstrip + block
192
+ end
193
+
194
+ def read_or_create_id
195
+ file = Pathname.new("#{@machine.env.local_data_path}/hostsprovisioner/#{@machine.name}")
196
+ if (file.file?)
197
+ id = file.read.strip
198
+ else
199
+ id = SecureRandom.uuid
200
+ file.dirname.mkpath
201
+ file.open('w') { |f| f.write(id) }
202
+ end
203
+ id + "-" + @config.id.to_s
204
+ end
205
+
206
+ ## Windows support for copying files, requesting elevated privileges if necessary
207
+ module WindowsSupport
208
+ require 'rbconfig'
209
+
210
+ def self.windows?
211
+ RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/
212
+ end
213
+
214
+ require 'win32ole' if windows?
215
+
216
+ def windows_copy_file(source, dest)
217
+ begin
218
+ # First, try Ruby copy
219
+ FileUtils.cp(source, dest)
220
+ rescue Errno::EACCES
221
+ # Access denied, try with elevated privileges
222
+ windows_copy_file_elevated(source, dest)
223
+ end
224
+ end
225
+
226
+ private
227
+
228
+ def windows_copy_file_elevated(source, dest)
229
+ # copy command only supports backslashes as separators
230
+ source, dest = [source, dest].map { |s| s.to_s.gsub(/\//, '\\') }
231
+
232
+ # run 'cmd /C copy ...' with elevated privilege, minimized
233
+ copy_cmd = "copy \"#{source}\" \"#{dest}\""
234
+ WIN32OLE.new('Shell.Application').ShellExecute('cmd', "/C #{copy_cmd}", nil, 'runas', 7)
235
+
236
+ # Unfortunately, ShellExecute does not give us a status code,
237
+ # and it is non-blocking so we can't reliably compare the file contents
238
+ # to see if they were copied.
239
+ #
240
+ # If the user rejects the UAC prompt, vagrant will silently continue
241
+ # without updating the hostsfile.
242
+ end
243
+ end
244
+
245
+ # This handles outputting the communication data back to the UI
246
+ def handle_comm(type, data)
247
+ if [:stderr, :stdout].include?(type)
248
+ # Output the data with the proper color based on the stream.
249
+ color = type == :stdout ? :green : :red
250
+
251
+ # Clear out the newline since we add one
252
+ data = data.chomp
253
+ return if data.empty?
254
+
255
+ options = {}
256
+ options[:color] = color
257
+
258
+ @machine.ui.info(data.chomp, options)
259
+ end
260
+ end
261
+
262
+ end
263
+ end
264
+ end
@@ -15,14 +15,35 @@ module VagrantPlugins
15
15
  DESC
16
16
 
17
17
  config(:hostsupdate, :provisioner) do
18
- require File.expand_path("../config", __FILE__)
18
+ require_relative 'config'
19
19
  Config
20
20
  end
21
21
 
22
22
  provisioner(:hostsupdate) do
23
- require File.expand_path("../provisioner", __FILE__)
23
+ require_relative 'provisioner'
24
24
  Provisioner
25
25
  end
26
+
27
+ action_hook(:hostsupdate, :machine_action_resume) do |hook|
28
+ require_relative 'action'
29
+ hook.append(Action.add)
30
+ end
31
+
32
+ action_hook(:hostsupdate, :machine_action_suspend) do |hook|
33
+ require_relative 'action'
34
+ hook.prepend(Action.remove)
35
+ end
36
+
37
+ action_hook(:hostsupdate, :machine_action_halt) do |hook|
38
+ require_relative 'action'
39
+ hook.prepend(Action.remove)
40
+ end
41
+
42
+ action_hook(:hostsupdate, :machine_action_destroy) do |hook|
43
+ require_relative 'action'
44
+ hook.prepend(Action.remove)
45
+ end
46
+
26
47
  end
27
48
  end
28
49
  end
@@ -1,239 +1,16 @@
1
- require 'tempfile'
1
+ require File.expand_path("../hosts", __FILE__)
2
2
 
3
3
  module VagrantPlugins
4
4
  module HostsProvisioner
5
5
  class Provisioner < Vagrant.plugin('2', :provisioner)
6
6
 
7
7
  def initialize(machine, config)
8
+ @hosts = Hosts.new(machine, config)
8
9
  super
9
10
  end
10
11
 
11
12
  def provision
12
- # Update the guest machine if manage_guest is enabled
13
- if @config.manage_guest
14
- update_guest
15
- end
16
-
17
- # Update the host machine if manage_host is enabled
18
- if @config.manage_host
19
- update_host
20
- end
21
- end
22
-
23
- def update_guest
24
- return unless @machine.communicate.ready?
25
-
26
- handle_comm(:stdout, I18n.t("vagrant_hostsprovisioner.provisioner.update_guest"))
27
-
28
- if (@machine.communicate.test("uname -s | grep SunOS"))
29
- realhostfile = '/etc/inet/hosts'
30
- move_cmd = 'mv'
31
- elsif (@machine.communicate.test("test -d $Env:SystemRoot"))
32
- windir = ""
33
- @machine.communicate.execute("echo %SYSTEMROOT%", {:shell => :cmd}) do |type, contents|
34
- windir << contents.gsub("\r\n", '') if type == :stdout
35
- end
36
- realhostfile = "#{windir}\\System32\\drivers\\etc\\hosts"
37
- move_cmd = 'mv -force'
38
- else
39
- realhostfile = '/etc/hosts'
40
- move_cmd = 'mv -f'
41
- end
42
-
43
- # download and modify file with Vagrant-managed entries
44
- file = @machine.env.tmp_path.join("hosts.#{@machine.name}")
45
- @machine.communicate.download(realhostfile, file)
46
- if update_file(file, false)
47
- # upload modified file and remove temporary file
48
- @machine.communicate.upload(file, '/tmp/hosts')
49
- @machine.communicate.sudo("#{move_cmd} /tmp/hosts #{realhostfile}")
50
- handle_comm(:stdout, I18n.t("vagrant_hostsprovisioner.provisioner.hosts_file_updated", {:file => realhostfile}))
51
- end
52
-
53
- begin
54
- FileUtils.rm(file)
55
- rescue Exception => e
56
- end
57
- end
58
-
59
- def update_host
60
- # copy and modify hosts file on host with Vagrant-managed entries
61
- file = @machine.env.tmp_path.join('hosts.local')
62
-
63
- handle_comm(:stdout, I18n.t("vagrant_hostsprovisioner.provisioner.update_host"))
64
-
65
- if WindowsSupport.windows?
66
- # lazily include windows Module
67
- class << self
68
- include WindowsSupport unless include? WindowsSupport
69
- end
70
-
71
- hosts_location = "#{ENV['WINDIR']}\\System32\\drivers\\etc\\hosts"
72
- copy_proc = Proc.new { windows_copy_file(file, hosts_location) }
73
- else
74
- hosts_location = '/etc/hosts'
75
- copy_proc = Proc.new { `sudo cp #{file} #{hosts_location}` }
76
- end
77
-
78
- FileUtils.cp(hosts_location, file)
79
- if update_file(file, true)
80
- copy_proc.call
81
- handle_comm(:stdout, I18n.t("vagrant_hostsprovisioner.provisioner.hosts_file_updated", {:file => hosts_location}))
82
- end
83
- end
84
-
85
- def update_file(file, include_id)
86
- file = Pathname.new(file)
87
- old_file_content = file.read
88
- new_file_content = update_content(old_file_content, include_id)
89
- file.open('w') { |io| io.write(new_file_content) }
90
- old_file_content != new_file_content
91
- end
92
-
93
- def update_content(file_content, include_id)
94
- id = include_id ? " id: #{read_or_create_id}" : ""
95
- header = "## vagrant-hosts-provisioner-start#{id}\n"
96
- footer = "## vagrant-hosts-provisioner-end\n"
97
- body = get_hosts_file_entry
98
- get_new_content(header, footer, body, file_content)
99
- end
100
-
101
- def get_hosts_file_entry
102
- # Get the vm ip address
103
- ip = get_ip_address
104
-
105
- # Return empy string if we don't have an ip address
106
- if ip === nil
107
- handle_comm(:stderr, I18n.t("vagrant_hostsprovisioner.error.no_vm_ip"))
108
- return ''
109
- end
110
-
111
- # Add the machine hostname
112
- hosts = []
113
- unless @config.hostname === false
114
- hosts.push(@config.hostname || @machine.config.vm.hostname || @machine.name)
115
- end
116
-
117
- # Add the defined aliases
118
- hosts.concat(@config.aliases)
119
-
120
- # Add the contents of the defined hosts files
121
- if @config.files.count > 0
122
- hosts.concat(get_files_data)
123
- end
124
-
125
- # Remove duplicates
126
- hosts = hosts.uniq.join(' ').strip
127
-
128
- "#{ip}\t#{hosts}\n"
129
- end
130
-
131
- def get_files_data
132
- require 'json'
133
- data = []
134
- @config.files.each do |file|
135
- file_path = File.join(@machine.env.root_path, file)
136
- if File.exist?(file_path)
137
- file_data = JSON.parse(File.read(file_path))
138
- data.concat([ file_data ].flatten)
139
- else
140
- handle_comm(:stderr, I18n.t("vagrant_hostsprovisioner.error.file_not_found", {:file => file.to_s}))
141
- end
142
- end
143
- data.collect(&:strip)
144
- end
145
-
146
- def get_ip_address
147
- ip = nil
148
- @machine.config.vm.networks.each do |network|
149
- key, options = network[0], network[1]
150
- ip = options[:ip] if key == :private_network
151
- break if ip
152
- end
153
- # If no ip is defined in private_network then use the ssh host ip instead
154
- ip || (@machine.ssh_info ? @machine.ssh_info[:host] : nil)
155
- end
156
-
157
- def get_new_content(header, footer, body, old_content)
158
- if body.empty?
159
- block = "\n"
160
- else
161
- block = "\n\n" + header + body + footer + "\n"
162
- end
163
- # Pattern for finding existing block
164
- header_pattern = Regexp.quote(header)
165
- footer_pattern = Regexp.quote(footer)
166
- pattern = Regexp.new("\n*#{header_pattern}.*?#{footer_pattern}\n*", Regexp::MULTILINE)
167
- # Replace existing block or append
168
- old_content.match(pattern) ? old_content.sub(pattern, block) : old_content.rstrip + block
169
- end
170
-
171
- def read_or_create_id
172
- file = Pathname.new("#{@machine.env.local_data_path}/hostsprovisioner/#{@machine.name}")
173
- if (file.file?)
174
- id = file.read.strip
175
- else
176
- id = SecureRandom.uuid
177
- file.dirname.mkpath
178
- file.open('w') { |f| f.write(id) }
179
- end
180
- id
181
- end
182
-
183
- ## Windows support for copying files, requesting elevated privileges if necessary
184
- module WindowsSupport
185
- require 'rbconfig'
186
-
187
- def self.windows?
188
- RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/
189
- end
190
-
191
- require 'win32ole' if windows?
192
-
193
- def windows_copy_file(source, dest)
194
- begin
195
- # First, try Ruby copy
196
- FileUtils.cp(source, dest)
197
- rescue Errno::EACCES
198
- # Access denied, try with elevated privileges
199
- windows_copy_file_elevated(source, dest)
200
- end
201
- end
202
-
203
- private
204
-
205
- def windows_copy_file_elevated(source, dest)
206
- # copy command only supports backslashes as separators
207
- source, dest = [source, dest].map { |s| s.to_s.gsub(/\//, '\\') }
208
-
209
- # run 'cmd /C copy ...' with elevated privilege, minimized
210
- copy_cmd = "copy \"#{source}\" \"#{dest}\""
211
- WIN32OLE.new('Shell.Application').ShellExecute('cmd', "/C #{copy_cmd}", nil, 'runas', 7)
212
-
213
- # Unfortunately, ShellExecute does not give us a status code,
214
- # and it is non-blocking so we can't reliably compare the file contents
215
- # to see if they were copied.
216
- #
217
- # If the user rejects the UAC prompt, vagrant will silently continue
218
- # without updating the hostsfile.
219
- end
220
- end
221
-
222
- # This handles outputting the communication data back to the UI
223
- def handle_comm(type, data)
224
- if [:stderr, :stdout].include?(type)
225
- # Output the data with the proper color based on the stream.
226
- color = type == :stdout ? :green : :red
227
-
228
- # Clear out the newline since we add one
229
- data = data.chomp
230
- return if data.empty?
231
-
232
- options = {}
233
- options[:color] = color
234
-
235
- @machine.ui.info(data.chomp, options)
236
- end
13
+ @hosts.add
237
14
  end
238
15
 
239
16
  end
@@ -1,5 +1,5 @@
1
1
  module VagrantPlugins
2
2
  module HostsProvisioner
3
- VERSION = "1.0.1"
3
+ VERSION = "2.0"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vagrant-hosts-provisioner
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: '2.0'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mohamed Elkholy
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-08-31 00:00:00.000000000 Z
11
+ date: 2015-03-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -52,7 +52,11 @@ files:
52
52
  - README.md
53
53
  - Rakefile
54
54
  - lib/vagrant-hosts-provisioner.rb
55
+ - lib/vagrant-hosts-provisioner/action.rb
56
+ - lib/vagrant-hosts-provisioner/action/add.rb
57
+ - lib/vagrant-hosts-provisioner/action/remove.rb
55
58
  - lib/vagrant-hosts-provisioner/config.rb
59
+ - lib/vagrant-hosts-provisioner/hosts.rb
56
60
  - lib/vagrant-hosts-provisioner/plugin.rb
57
61
  - lib/vagrant-hosts-provisioner/provisioner.rb
58
62
  - lib/vagrant-hosts-provisioner/version.rb
@@ -84,7 +88,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
84
88
  version: '0'
85
89
  requirements: []
86
90
  rubyforge_project: vagrant-hosts-provisioner
87
- rubygems_version: 2.4.1
91
+ rubygems_version: 2.4.5
88
92
  signing_key:
89
93
  specification_version: 4
90
94
  summary: A Vagrant provisioner for managing the /etc/hosts file of the host and guest