vagrant-hosts-provisioner 1.0.1 → 2.0

Sign up to get free protection for your applications and to get access to all the features.
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