chef-provisioning-vsphere 0.4.2 → 0.5.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: 0d79d0a2cda2ae2c35a26785805165a0449db2ab
4
- data.tar.gz: f70880364d9a538115a8b7eeae608971ea9e4246
3
+ metadata.gz: 990036a8b6dcc42e111ed4acb92aa90c5fe59f1d
4
+ data.tar.gz: 2767a8e7fd769b90954e57b06eecccfa0fd29736
5
5
  SHA512:
6
- metadata.gz: 573d1b2bd5a273e6edd62728e1dd7054f6859d7663f6533b0ad69e89b3af02f45fecd6515066751d3b5ac9afa71041bf9941c5c71aedecca1551974c97d4ccf8
7
- data.tar.gz: 2ba913e525d49af3799a44aebca5131ebb4eac8f369158f19c8a299d1045017a9697f5c8e1f38b69f28cb683bc9c467ea911836829b1c34a703a5d9282856b75
6
+ metadata.gz: 0784aeb6843b433d16f5aa93aee499e55ed0aad8b2dd6b8c6378258d9c504ac78fcac3d6cf7e4abdda19e580b6c58ce8a58853db7d2342ab38a943f51e91329c
7
+ data.tar.gz: e68182faff627baf71b3b0074cc14fac995908123f0bcdef2e263b70cd147496a40fb299b7d9797fd31da826f37176bc7ab9781bd6fb8a2b045a913b6742f0b2
data/Gemfile CHANGED
@@ -2,4 +2,4 @@
2
2
  source "https://rubygems.org"
3
3
  gemspec
4
4
 
5
- gem "chef", "~> 12.1"
5
+ gem "chef", "~> 12.3"
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2015 CenturyLink
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -11,7 +11,7 @@ Gem::Specification.new do |s|
11
11
  s.authors = ['CenturyLink Cloud']
12
12
  s.email = 'matt.wrock@CenturyLinkCloud.com'
13
13
  s.homepage = 'https://github.com/tier3/chef-provisioning-vsphere'
14
- s.license = 'Apache 2.0'
14
+ s.license = 'MIT'
15
15
 
16
16
  s.bindir = 'bin'
17
17
  s.executables = %w( )
@@ -5,9 +5,10 @@ class Chef
5
5
  module DSL
6
6
  module Recipe
7
7
  def with_vsphere_driver(driver_options, &block)
8
- url, config = ChefProvisioningVsphere::VsphereDriver.canonicalize_url(nil, {:driver_options => driver_options})
9
- with_driver url, driver_options, &block
8
+ url = ChefProvisioningVsphere::VsphereDriver.canonicalize_url(
9
+ nil, driver_options)[0]
10
+ with_driver url, driver_options, &block
10
11
  end
11
12
  end
12
13
  end
13
- end
14
+ end
@@ -17,51 +17,20 @@ module ChefProvisioningVsphere
17
17
  VsphereDriver.new(driver_url, config)
18
18
  end
19
19
 
20
+ # Create a new Vsphere provisioner.
21
+ #
22
+ # ## Parameters
23
+ # connect_options - hash of options to be passed to RbVmomi::VIM.connect
24
+ # :host - required - hostname of the vSphere API server
25
+ # :port - optional - port on the vSphere API server (default: 443)
26
+ # :path - optional - path on the vSphere API server (default: /sdk)
27
+ # :use_ssl - optional - true to use ssl in connection to vSphere API server (default: true)
28
+ # :insecure - optional - true to ignore ssl certificate validation errors in connection to vSphere API server (default: false)
29
+ # :user - required - user name to use in connection to vSphere API server
30
+ # :password - required - password to use in connection to vSphere API server
20
31
  def self.canonicalize_url(driver_url, config)
21
32
  config = symbolize_keys(config)
22
- new_defaults = {
23
- :driver_options => { :connect_options => { :port => 443,
24
- :use_ssl => true,
25
- :insecure => false,
26
- :path => '/sdk'
27
- } },
28
- :machine_options => { :start_timeout => 600,
29
- :create_timeout => 600,
30
- :ready_timeout => 300,
31
- :bootstrap_options => { :ssh => { :port => 22,
32
- :user => 'root' },
33
- :key_name => 'metal_default',
34
- :tags => {} } }
35
- }
36
-
37
- new_connect_options = {}
38
- new_connect_options[:provider] = 'vsphere'
39
- if !driver_url.nil?
40
- uri = URI(driver_url)
41
- new_connect_options[:host] = uri.host
42
- new_connect_options[:port] = uri.port
43
- if uri.path && uri.path.length > 0
44
- new_connect_options[:path] = uri.path
45
- end
46
- new_connect_options[:use_ssl] = uri.use_ssl
47
- new_connect_options[:insecure] = uri.insecure
48
- end
49
- new_connect_options = new_connect_options.merge(config[:driver_options])
50
-
51
- new_config = { :driver_options => { :connect_options => new_connect_options }}
52
- config = Cheffish::MergedConfig.new(new_config, config, new_defaults)
53
-
54
- required_options = [:host, :user, :password]
55
- missing_options = []
56
- required_options.each do |opt|
57
- missing_options << opt unless config[:driver_options][:connect_options].has_key?(opt)
58
- end
59
- unless missing_options.empty?
60
- raise "missing required options: #{missing_options.join(', ')}"
61
- end
62
-
63
- url = URI::VsphereUrl.from_config(config[:driver_options][:connect_options]).to_s
64
- [ url, config ]
33
+ [ driver_url || URI::VsphereUrl.from_config(config).to_s, config ]
65
34
  end
66
35
 
67
36
  def self.symbolize_keys(h)
@@ -73,22 +42,23 @@ module ChefProvisioningVsphere
73
42
  ] : h
74
43
  end
75
44
 
76
- # Create a new Vsphere provisioner.
77
- #
78
- # ## Parameters
79
- # connect_options - hash of options to be passed to RbVmomi::VIM.connect
80
- # :host - required - hostname of the vSphere API server
81
- # :port - optional - port on the vSphere API server (default: 443)
82
- # :path - optional - path on the vSphere API server (default: /sdk)
83
- # :use_ssl - optional - true to use ssl in connection to vSphere API server (default: true)
84
- # :insecure - optional - true to ignore ssl certificate validation errors in connection to vSphere API server (default: false)
85
- # :user - required - user name to use in connection to vSphere API server
86
- # :password - required - password to use in connection to vSphere API server
87
- # :proxy_host - optional - http proxy host to use in connection to vSphere API server (default: none)
88
- # :proxy_port - optional - http proxy port to use in connection to vSphere API server (default: none)
89
45
  def initialize(driver_url, config)
90
46
  super(driver_url, config)
91
- @connect_options = config[:driver_options][:connect_options].to_hash
47
+
48
+ uri = URI(driver_url)
49
+ @connect_options = {
50
+ provider: 'vsphere',
51
+ host: uri.host,
52
+ port: uri.port,
53
+ use_ssl: uri.use_ssl,
54
+ insecure: uri.insecure,
55
+ path: uri.path
56
+ }
57
+
58
+ if driver_options
59
+ @connect_options[:user] = driver_options[:user]
60
+ @connect_options[:password] = driver_options[:password]
61
+ end
92
62
  end
93
63
 
94
64
  attr_reader :connect_options
@@ -141,38 +111,38 @@ module ChefProvisioningVsphere
141
111
  #
142
112
  def allocate_machine(action_handler, machine_spec, machine_options)
143
113
  if machine_spec.location
144
- Chef::Log.warn "Checking to see if #{machine_spec.location} has been created..."
114
+ Chef::Log.warn(
115
+ "Checking to see if #{machine_spec.location} has been created...")
145
116
  vm = vm_for(machine_spec)
146
117
  if vm
147
- Chef::Log.warn "returning existing machine"
118
+ Chef::Log.warn 'returning existing machine'
148
119
  return vm
149
120
  else
150
- Chef::Log.warn "Machine #{machine_spec.name} (#{machine_spec.location['server_id']} on #{driver_url}) no longer exists. Recreating ..."
121
+ Chef::Log.warn machine_msg(
122
+ machine_spec.name,
123
+ machine_spec.location['server_id'],
124
+ 'no longer exists. Recreating ...'
125
+ )
151
126
  end
152
127
  end
153
- bootstrap_options = bootstrap_options_for(machine_spec, machine_options)
154
- vm = nil
128
+ bootstrap_options = machine_options[:bootstrap_options]
155
129
 
156
- if bootstrap_options[:ssh]
157
- wait_on_port = bootstrap_options[:ssh][:port]
158
- raise "Must specify bootstrap_options[:ssh][:port]" if wait_on_port.nil?
159
- else
160
- raise 'bootstrapping is currently supported for ssh only'
161
- # wait_on_port = bootstrap_options['winrm']['port']
162
- end
130
+ action_handler.report_progress full_description(
131
+ machine_spec, bootstrap_options)
132
+
133
+ vm = find_or_create_vm(bootstrap_options, machine_spec, action_handler)
163
134
 
164
- description = [ "creating machine #{machine_spec.name} on #{driver_url}" ]
165
- bootstrap_options.each_pair { |key,value| description << " #{key}: #{value.inspect}" }
166
- action_handler.report_progress description
135
+ add_machine_spec_location(vm, machine_spec)
167
136
 
168
- vm = find_vm(bootstrap_options[:datacenter], bootstrap_options[:vm_folder], machine_spec.name)
169
- server_id = nil
170
- if vm
171
- Chef::Log.info "machine already created: #{bootstrap_options[:vm_folder]}/#{machine_spec.name}"
172
- else
173
- vm = clone_vm(action_handler, bootstrap_options)
174
- end
137
+ action_handler.performed_action(machine_msg(
138
+ machine_spec.name,
139
+ vm.config.instanceUuid,
140
+ 'created'
141
+ ))
142
+ vm
143
+ end
175
144
 
145
+ def add_machine_spec_location(vm, machine_spec)
176
146
  machine_spec.location = {
177
147
  'driver_url' => driver_url,
178
148
  'driver_version' => VERSION,
@@ -181,100 +151,199 @@ module ChefProvisioningVsphere
181
151
  'allocated_at' => Time.now.utc.to_s,
182
152
  'ipaddress' => vm.guest.ipAddress
183
153
  }
184
- machine_spec.location['key_name'] = bootstrap_options[:key_name] if bootstrap_options[:key_name]
185
- %w(ssh_username sudo use_private_ip_for_ssh ssh_gateway).each do |key|
186
- machine_spec.location[key] = machine_options[key.to_sym] if machine_options[key.to_sym]
187
- end
154
+ end
188
155
 
189
- action_handler.performed_action "machine #{machine_spec.name} created as #{machine_spec.location['server_id']} on #{driver_url}"
156
+ def find_or_create_vm(bootstrap_options, machine_spec, action_handler)
157
+ vm = find_vm(
158
+ bootstrap_options[:datacenter],
159
+ bootstrap_options[:vm_folder],
160
+ machine_spec.name
161
+ )
162
+ server_id = nil
163
+ if vm
164
+ Chef::Log.info machine_msg(
165
+ machine_spec.name,
166
+ vm.config.instanceUuid,
167
+ 'already created'
168
+ )
169
+ else
170
+ vm = clone_vm(action_handler, bootstrap_options, machine_spec.name)
171
+ end
190
172
  vm
191
173
  end
192
174
 
175
+ def full_description(machine_spec, bootstrap_options)
176
+ description = [ "creating machine #{machine_spec.name} on #{driver_url}" ]
177
+ bootstrap_options.to_hash.each_pair do |key,value|
178
+ description << " #{key}: #{value.inspect}"
179
+ end
180
+ description
181
+ end
182
+
183
+ def machine_msg(name, id, action)
184
+ "Machine - #{action} - #{name} (#{id} on #{driver_url})"
185
+ end
186
+
193
187
  def ready_machine(action_handler, machine_spec, machine_options)
194
188
  start_machine(action_handler, machine_spec, machine_options)
195
189
  vm = vm_for(machine_spec)
196
190
  if vm.nil?
197
- raise "Machine #{machine_spec.name} does not have a server associated with it, or server does not exist."
191
+ raise "Machine #{machine_spec.name} does not have a server "\
192
+ 'associated with it, or server does not exist.'
198
193
  end
199
194
 
200
- wait_until_ready(action_handler, machine_spec, machine_options, vm)
195
+ bootstrap_options = machine_options[:bootstrap_options]
201
196
 
202
- bootstrap_options = bootstrap_options_for(machine_spec, machine_options)
197
+ transport_respond?(
198
+ machine_options,
199
+ vm,
200
+ action_handler,
201
+ machine_spec
202
+ )
203
203
 
204
- transport = nil
205
- vm_ip = ip_for(bootstrap_options, vm)
206
- if !vm_ip.nil?
207
- transport = transport_for(machine_spec, machine_options, vm)
204
+ machine = machine_for(machine_spec,machine_options)
205
+ setup_extra_nics(action_handler, bootstrap_options, vm, machine)
206
+
207
+ if has_static_ip(bootstrap_options) && !is_windows?(vm)
208
+ setup_ubuntu_dns(machine, bootstrap_options, machine_spec)
208
209
  end
209
210
 
210
- if transport.nil? || !transport.available? || !(vm.guest.net.map { |net| net.ipAddress}.flatten).include?(vm_ip)
211
- action_handler.report_progress "waiting up to #{machine_options[:ready_timeout]} seconds for customizations to complete and find #{vm_ip}"
212
- now = Time.now.utc
211
+ machine
212
+ end
213
213
 
214
- until (Time.now.utc - now) > machine_options[:ready_timeout] || (vm.guest.net.map { |net| net.ipAddress}.flatten).include?(vm_ip) do
215
- action_handler.report_progress "IP addresses on #{machine_spec.name} are #{vm.guest.net.map { |net| net.ipAddress}.flatten}"
216
- vm_ip = ip_for(bootstrap_options, vm) if vm_ip.nil?
217
- sleep 5
218
- end
219
- if !(vm.guest.net.map { |net| net.ipAddress}.flatten).include?(vm_ip)
220
- action_handler.report_progress "rebooting..."
221
- if vm.guest.toolsRunningStatus != "guestToolsRunning"
222
- action_handler.report_progress "tools have stopped. current power state is #{vm.runtime.powerState} and tools state is #{vm.guest.toolsRunningStatus}. powering up server..."
223
- start_vm(vm)
224
- else
225
- restart_server(action_handler, machine_spec, vm)
226
- end
227
- now = Time.now.utc
228
- until (Time.now.utc - now) > 90 || (vm.guest.net.map { |net| net.ipAddress}.flatten).include?(vm_ip) do
229
- vm_ip = ip_for(bootstrap_options, vm) if vm_ip.nil?
230
- print "-"
231
- sleep 5
232
- end
214
+ def setup_extra_nics(action_handler, bootstrap_options, vm, machine)
215
+ new_nics = add_extra_nic(
216
+ action_handler,
217
+ vm_template_for(bootstrap_options),
218
+ bootstrap_options,
219
+ vm
220
+ )
221
+ if is_windows?(vm) && !new_nics.nil?
222
+ new_nics.each do |nic|
223
+ nic_label = nic.device.deviceInfo.label
224
+ machine.execute_always(
225
+ "Disable-Netadapter -Name '#{nic_label}' -Confirm:$false")
233
226
  end
234
- machine_spec.location['ipaddress'] = vm.guest.ipAddress
235
- action_handler.report_progress "IP address obtained: #{machine_spec.location['ipaddress']}"
236
227
  end
228
+ end
237
229
 
238
- domain = bootstrap_options[:customization_spec][:domain]
239
- if vm.config.guestId.start_with?('win') && domain != 'local'
240
- now = Time.now.utc
241
- trimmed_name = machine_spec.name.byteslice(0,15)
242
- expected_name="#{trimmed_name}.#{domain}"
243
- action_handler.report_progress "waiting to domain join and be named #{expected_name}"
244
- until (Time.now.utc - now) > 30 || (vm.guest.hostName == expected_name) do
245
- print "."
246
- sleep 5
247
- end
230
+ def transport_respond?(
231
+ machine_options,
232
+ vm,
233
+ action_handler,
234
+ machine_spec
235
+ )
236
+ bootstrap_options = machine_options[:bootstrap_options]
237
+
238
+ # this waits for vmware tools to start and the vm to presebnt an ip
239
+ # This may just be the ip of a newly cloned machine
240
+ # Customization below may change this to a valid ip
241
+ wait_until_ready(action_handler, machine_spec, machine_options, vm)
242
+
243
+ # find the ip we actually want
244
+ # this will be the static ip to assign
245
+ # or the ip reported back by the vm if using dhcp
246
+ # it *may* be nil if just cloned
247
+ vm_ip = ip_to_bootstrap(bootstrap_options, vm)
248
+ transport = nil
249
+ unless vm_ip.nil?
250
+ transport = transport_for(machine_spec, bootstrap_options[:ssh], vm_ip)
251
+ end
252
+
253
+ unless !transport.nil? && transport.available? && has_ip?(vm_ip, vm)
254
+ attempt_ip(machine_options, action_handler, vm, machine_spec)
248
255
  end
256
+ machine_spec.location['ipaddress'] = vm.guest.ipAddress
257
+ action_handler.report_progress(
258
+ "IP address obtained: #{machine_spec.location['ipaddress']}")
259
+
260
+ wait_for_domain(bootstrap_options, vm, machine_spec, action_handler)
249
261
 
250
262
  begin
251
263
  wait_for_transport(action_handler, machine_spec, machine_options, vm)
252
264
  rescue Timeout::Error
253
- # Only ever reboot once, and only if it's been less than 10 minutes since we stopped waiting
254
- if machine_spec.location['started_at'] || remaining_wait_time(machine_spec, machine_options) < -(10*60)
265
+ # Only ever reboot once, and only if it's been less than 10 minutes
266
+ # since we stopped waiting
267
+ if machine_spec.location['started_at'] ||
268
+ remaining_wait_time(machine_spec, machine_options) < -(10*60)
255
269
  raise
256
270
  else
257
- Chef::Log.warn "Machine #{machine_spec.name} (#{server.config.instanceUuid} on #{driver_url}) was started but SSH did not come up. Rebooting machine in an attempt to unstick it ..."
271
+ Chef::Log.warn(machine_msg(
272
+ machine_spec.name,
273
+ vm.config.instanceUuid,
274
+ 'started but SSH did not come up. Rebooting...'
275
+ ))
258
276
  restart_server(action_handler, machine_spec, vm)
259
277
  wait_until_ready(action_handler, machine_spec, machine_options, vm)
260
278
  wait_for_transport(action_handler, machine_spec, machine_options, vm)
261
279
  end
262
280
  end
281
+ end
263
282
 
264
- machine = machine_for(machine_spec, machine_options, vm)
283
+ def attempt_ip(machine_options, action_handler, vm, machine_spec)
284
+ vm_ip = ip_to_bootstrap(machine_options[:bootstrap_options], vm)
285
+
286
+ wait_for_ip(vm, machine_options, action_handler)
287
+
288
+ unless has_ip?(vm_ip, vm)
289
+ action_handler.report_progress "rebooting..."
290
+ if vm.guest.toolsRunningStatus != "guestToolsRunning"
291
+ msg = 'tools have stopped. current power state is '
292
+ msg << vm.runtime.powerState
293
+ msg << ' and tools state is '
294
+ msg << vm.guest.toolsRunningStatus
295
+ msg << '. powering up server...'
296
+ action_handler.report_progress(msg.join)
297
+ start_vm(vm)
298
+ else
299
+ restart_server(action_handler, machine_spec, vm)
300
+ end
301
+ wait_for_ip(vm, machine_options, action_handler)
302
+ end
303
+ end
265
304
 
266
- new_nics = add_extra_nic(action_handler, vm_template_for(bootstrap_options), bootstrap_options, vm)
267
- if is_windows?(vm) && !new_nics.nil?
268
- new_nics.each do |nic|
269
- machine.execute_always("Disable-Netadapter -Name '#{nic.device.deviceInfo.label}' -Confirm:$false")
305
+ def wait_for_domain(bootstrap_options, vm, machine_spec, action_handler)
306
+ return unless bootstrap_options[:customization_spec]
307
+ return unless bootstrap_options[:customization_spec][:domain]
308
+
309
+ domain = bootstrap_options[:customization_spec][:domain]
310
+ if is_windows?(vm) && domain != 'local'
311
+ start = Time.now.utc
312
+ trimmed_name = machine_spec.name.byteslice(0,15)
313
+ expected_name="#{trimmed_name}.#{domain}"
314
+ action_handler.report_progress(
315
+ "waiting to domain join and be named #{expected_name}")
316
+ until (Time.now.utc - start) > 30 ||
317
+ (vm.guest.hostName == expected_name) do
318
+ print '.'
319
+ sleep 5
270
320
  end
271
321
  end
322
+ end
272
323
 
273
- if has_static_ip(bootstrap_options) && !is_windows?(vm)
274
- setup_ubuntu_dns(machine, bootstrap_options, machine_spec)
324
+ def wait_for_ip(vm, machine_options, action_handler)
325
+ bootstrap_options = machine_options[:bootstrap_options]
326
+ vm_ip = ip_to_bootstrap(bootstrap_options, vm)
327
+ ready_timeout = machine_options[:ready_timeout] || 300
328
+ msg = "waiting up to #{ready_timeout} seconds for customization"
329
+ msg << " and find #{vm_ip}" unless vm_ip == vm.guest.ipAddress
330
+ action_handler.report_progress msg
331
+
332
+ start = Time.now.utc
333
+ until (Time.now.utc - start) > ready_timeout || has_ip?(vm_ip, vm) do
334
+ action_handler.report_progress(
335
+ "IP addresses found: #{all_ips_for(vm)}")
336
+ vm_ip ||= ip_to_bootstrap(bootstrap_options, vm)
337
+ sleep 5
275
338
  end
339
+ end
276
340
 
277
- machine
341
+ def all_ips_for(vm)
342
+ vm.guest.net.map { |net| net.ipAddress}.flatten
343
+ end
344
+
345
+ def has_ip?(ip, vm)
346
+ all_ips_for(vm).include?(ip)
278
347
  end
279
348
 
280
349
  # Connect to machine without acquiring it
@@ -313,8 +382,7 @@ module ChefProvisioningVsphere
313
382
  vm = vm_for(machine_spec)
314
383
  if vm
315
384
  action_handler.perform_action "Power on VM [#{vm.parent.name}/#{vm.name}]" do
316
- bootstrap_options = bootstrap_options_for(machine_spec, machine_options)
317
- start_vm(vm, bootstrap_options[:ssh][:port])
385
+ start_vm(vm, machine_options[:bootstrap_options][:ssh][:port])
318
386
  end
319
387
  end
320
388
  end
@@ -330,27 +398,27 @@ module ChefProvisioningVsphere
330
398
  protected
331
399
 
332
400
  def setup_ubuntu_dns(machine, bootstrap_options, machine_spec)
333
- host_lookup = machine.execute_always('host google.com')
334
- if host_lookup.exitstatus != 0
335
- if host_lookup.stdout.include?("setlocale: LC_ALL")
336
- machine.execute_always('locale-gen en_US && update-locale LANG=en_US')
337
- end
338
- distro = machine.execute_always("lsb_release -i | sed -e 's/Distributor ID://g'").stdout.strip
339
- Chef::Log.info "Found distro:#{distro}"
340
- if distro == 'Ubuntu'
341
- distro_version = (machine.execute_always("lsb_release -r | sed -e s/[^0-9.]//g")).stdout.strip.to_f
342
- Chef::Log.info "Found distro version:#{distro_version}"
343
- if distro_version>= 12.04
344
- Chef::Log.info "Ubuntu version 12.04 or greater. Need to patch DNS."
345
- interfaces_file = "/etc/network/interfaces"
346
- nameservers = bootstrap_options[:customization_spec][:ipsettings][:dnsServerList].join(' ')
347
- machine.execute_always("if ! cat #{interfaces_file} | grep -q dns-search ; then echo 'dns-search #{bootstrap_options[:customization_spec][:domain]}' >> #{interfaces_file} ; fi")
348
- machine.execute_always("if ! cat #{interfaces_file} | grep -q dns-nameservers ; then echo 'dns-nameservers #{nameservers}' >> #{interfaces_file} ; fi")
349
- machine.execute_always('/etc/init.d/networking restart')
350
- machine.execute_always('apt-get -qq update')
351
- end
401
+ host_lookup = machine.execute_always('host google.com')
402
+ if host_lookup.exitstatus != 0
403
+ if host_lookup.stdout.include?("setlocale: LC_ALL")
404
+ machine.execute_always('locale-gen en_US && update-locale LANG=en_US')
405
+ end
406
+ distro = machine.execute_always("lsb_release -i | sed -e 's/Distributor ID://g'").stdout.strip
407
+ Chef::Log.info "Found distro:#{distro}"
408
+ if distro == 'Ubuntu'
409
+ distro_version = (machine.execute_always("lsb_release -r | sed -e s/[^0-9.]//g")).stdout.strip.to_f
410
+ Chef::Log.info "Found distro version:#{distro_version}"
411
+ if distro_version>= 12.04
412
+ Chef::Log.info "Ubuntu version 12.04 or greater. Need to patch DNS."
413
+ interfaces_file = "/etc/network/interfaces"
414
+ nameservers = bootstrap_options[:customization_spec][:ipsettings][:dnsServerList].join(' ')
415
+ machine.execute_always("if ! cat #{interfaces_file} | grep -q dns-search ; then echo 'dns-search #{bootstrap_options[:customization_spec][:domain]}' >> #{interfaces_file} ; fi")
416
+ machine.execute_always("if ! cat #{interfaces_file} | grep -q dns-nameservers ; then echo 'dns-nameservers #{nameservers}' >> #{interfaces_file} ; fi")
417
+ machine.execute_always('/etc/init.d/networking restart')
418
+ machine.execute_always('apt-get -qq update')
352
419
  end
353
420
  end
421
+ end
354
422
  end
355
423
 
356
424
  def has_static_ip(bootstrap_options)
@@ -368,18 +436,20 @@ module ChefProvisioningVsphere
368
436
 
369
437
  def remaining_wait_time(machine_spec, machine_options)
370
438
  if machine_spec.location['started_at']
371
- machine_options[:start_timeout] - (Time.now.utc - Time.parse(machine_spec.location['started_at']))
439
+ (machine_options[:start_timeout] || 600) -
440
+ (Time.now.utc - Time.parse(machine_spec.location['started_at']))
372
441
  else
373
- machine_options[:create_timeout] - (Time.now.utc - Time.parse(machine_spec.location['allocated_at']))
442
+ (machine_options[:create_timeout] || 600) -
443
+ (Time.now.utc - Time.parse(machine_spec.location['allocated_at']))
374
444
  end
375
445
  end
376
446
 
377
447
  def wait_until_ready(action_handler, machine_spec, machine_options, vm)
378
448
  if vm.guest.toolsRunningStatus != "guestToolsRunning"
379
- perform_action = true
380
449
  if action_handler.should_perform_actions
381
450
  action_handler.report_progress "waiting for #{machine_spec.name} (#{vm.config.instanceUuid} on #{driver_url}) to be ready ..."
382
- until remaining_wait_time(machine_spec, machine_options) < 0 || (vm.guest.toolsRunningStatus == "guestToolsRunning" && (vm.guest.ipAddress.nil? || vm.guest.ipAddress.length > 0)) do
451
+ until remaining_wait_time(machine_spec, machine_options) < 0 ||
452
+ (vm.guest.toolsRunningStatus == "guestToolsRunning" && !vm.guest.ipAddress.nil? && vm.guest.ipAddress.length > 0) do
383
453
  print "."
384
454
  sleep 5
385
455
  end
@@ -396,32 +466,21 @@ module ChefProvisioningVsphere
396
466
  end
397
467
  end
398
468
 
399
- def bootstrap_options_for(machine_spec, machine_options)
400
- bootstrap_options = machine_options[:bootstrap_options] || {}
401
- bootstrap_options = bootstrap_options.to_hash
402
- tags = {
403
- 'Name' => machine_spec.name,
404
- 'BootstrapId' => machine_spec.id,
405
- 'BootstrapHost' => Socket.gethostname,
406
- 'BootstrapUser' => Etc.getlogin
407
- }
408
- # User-defined tags override the ones we set
409
- tags.merge!(bootstrap_options[:tags]) if bootstrap_options[:tags]
410
- bootstrap_options.merge!({ :tags => tags })
411
- bootstrap_options[:name] ||= machine_spec.name
412
- bootstrap_options
413
- end
414
-
415
- def clone_vm(action_handler, bootstrap_options)
416
- vm_name = bootstrap_options[:name]
417
- datacenter = bootstrap_options[:datacenter]
469
+ def clone_vm(action_handler, bootstrap_options, machine_name)
470
+ datacenter = bootstrap_options[:datacenter]
418
471
 
419
- vm = find_vm(datacenter, bootstrap_options[:vm_folder], vm_name)
472
+ vm = find_vm(datacenter, bootstrap_options[:vm_folder], machine_name)
420
473
  return vm if vm
421
474
 
422
475
  vm_template = vm_template_for(bootstrap_options)
423
476
 
424
- do_vm_clone(action_handler, datacenter, vm_template, vm_name, bootstrap_options)
477
+ do_vm_clone(
478
+ action_handler,
479
+ datacenter,
480
+ vm_template,
481
+ machine_name,
482
+ bootstrap_options
483
+ )
425
484
  end
426
485
 
427
486
  def vm_template_for(bootstrap_options)
@@ -431,16 +490,23 @@ module ChefProvisioningVsphere
431
490
  find_vm(datacenter, template_folder, template_name) or raise("vSphere VM Template not found [#{template_folder}/#{template_name}]")
432
491
  end
433
492
 
434
- def machine_for(machine_spec, machine_options, vm = nil)
435
- vm ||= vm_for(machine_spec)
436
- if !vm
493
+ def machine_for(machine_spec, machine_options)
494
+ if machine_spec.location.nil?
437
495
  raise "Server for node #{machine_spec.name} has not been created!"
438
496
  end
439
497
 
498
+ transport = transport_for(
499
+ machine_spec,
500
+ machine_options[:bootstrap_options][:ssh]
501
+ )
502
+ strategy = convergence_strategy_for(machine_spec, machine_options)
503
+
440
504
  if machine_spec.location['is_windows']
441
- Chef::Provisioning::Machine::WindowsMachine.new(machine_spec, transport_for(machine_spec, machine_options, vm), convergence_strategy_for(machine_spec, machine_options))
505
+ Chef::Provisioning::Machine::WindowsMachine.new(
506
+ machine_spec, transport, strategy)
442
507
  else
443
- Chef::Provisioning::Machine::UnixMachine.new(machine_spec, transport_for(machine_spec, machine_options, vm), convergence_strategy_for(machine_spec, machine_options))
508
+ Chef::Provisioning::Machine::UnixMachine.new(
509
+ machine_spec, transport, strategy)
444
510
  end
445
511
  end
446
512
 
@@ -466,7 +532,10 @@ module ChefProvisioningVsphere
466
532
  end
467
533
 
468
534
  def wait_for_transport(action_handler, machine_spec, machine_options, vm)
469
- transport = transport_for(machine_spec, machine_options, vm)
535
+ transport = transport_for(
536
+ machine_spec,
537
+ machine_options[:bootstrap_options][:ssh]
538
+ )
470
539
  if !transport.available?
471
540
  if action_handler.should_perform_actions
472
541
  action_handler.report_progress "waiting for #{machine_spec.name} (#{vm.config.instanceUuid} on #{driver_url}) to be connectable (transport up and running) ..."
@@ -481,41 +550,48 @@ module ChefProvisioningVsphere
481
550
  end
482
551
  end
483
552
 
484
- def transport_for(machine_spec, machine_options, vm)
485
- if is_windows?(vm)
486
- create_winrm_transport(machine_spec, machine_options, vm)
553
+ def transport_for(
554
+ machine_spec,
555
+ remoting_options,
556
+ ip = machine_spec.location['ipaddress']
557
+ )
558
+ if machine_spec.location['is_windows']
559
+ create_winrm_transport(ip, remoting_options)
487
560
  else
488
- create_ssh_transport(machine_spec, machine_options, vm)
561
+ create_ssh_transport(ip, remoting_options)
489
562
  end
490
563
  end
491
564
 
492
- def create_winrm_transport(machine_spec, machine_options, vm)
565
+ def create_winrm_transport(host, options)
493
566
  require 'chef/provisioning/transport/winrm'
494
- bootstrap_options = bootstrap_options_for(machine_spec, machine_options)
495
- ssh_options = bootstrap_options[:ssh]
496
- remote_host = machine_spec.location['ipaddress'] || ip_for(bootstrap_options, vm)
497
-
498
- winrm_options = {:user => "#{ssh_options[:user]}", :pass => ssh_options[:password]}
499
- if ssh_options[:user].include?("\\")
500
- winrm_options[:disable_sspi] = true
501
- else
502
- winrm_options[:basic_auth_only] = true
503
- end
567
+ opt = options[:user].include?("\\") ? :disable_sspi : :basic_auth_only
568
+ winrm_options = {
569
+ user: "#{options[:user]}",
570
+ pass: options[:password],
571
+ opt => true
572
+ }
504
573
 
505
- Chef::Provisioning::Transport::WinRM.new("http://#{remote_host}:5985/wsman", :plaintext, winrm_options, config)
574
+ Chef::Provisioning::Transport::WinRM.new(
575
+ "http://#{host}:5985/wsman",
576
+ :plaintext,
577
+ winrm_options,
578
+ config
579
+ )
506
580
  end
507
581
 
508
- def create_ssh_transport(machine_spec, machine_options, vm)
582
+ def create_ssh_transport(host, options)
509
583
  require 'chef/provisioning/transport/ssh'
510
- bootstrap_options = bootstrap_options_for(machine_spec, machine_options)
511
- ssh_options = bootstrap_options[:ssh]
512
- ssh_user = ssh_options[:user]
513
- remote_host = machine_spec.location['ipaddress'] || ip_for(bootstrap_options, vm)
514
-
515
- Chef::Provisioning::Transport::SSH.new(remote_host, ssh_user, ssh_options, {}, config)
584
+ ssh_user = options[:user]
585
+ Chef::Provisioning::Transport::SSH.new(
586
+ host,
587
+ ssh_user,
588
+ options,
589
+ {},
590
+ config
591
+ )
516
592
  end
517
593
 
518
- def ip_for(bootstrap_options, vm)
594
+ def ip_to_bootstrap(bootstrap_options, vm)
519
595
  if has_static_ip(bootstrap_options)
520
596
  bootstrap_options[:customization_spec][:ipsettings][:ip]
521
597
  else