vagrant-cloudstack 0.10.0 → 1.0.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.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +1 -1
  4. data/CHANGELOG.md +8 -0
  5. data/Gemfile +5 -2
  6. data/README.md +48 -10
  7. data/build_rpm.sh +1 -1
  8. data/coverage/.last_run.json +5 -0
  9. data/coverage/.resultset.json +569 -0
  10. data/coverage/.resultset.json.lock +0 -0
  11. data/coverage/assets/0.10.0/application.css +799 -0
  12. data/coverage/assets/0.10.0/application.js +1707 -0
  13. data/coverage/assets/0.10.0/colorbox/border.png +0 -0
  14. data/coverage/assets/0.10.0/colorbox/controls.png +0 -0
  15. data/coverage/assets/0.10.0/colorbox/loading.gif +0 -0
  16. data/coverage/assets/0.10.0/colorbox/loading_background.png +0 -0
  17. data/coverage/assets/0.10.0/favicon_green.png +0 -0
  18. data/coverage/assets/0.10.0/favicon_red.png +0 -0
  19. data/coverage/assets/0.10.0/favicon_yellow.png +0 -0
  20. data/coverage/assets/0.10.0/loading.gif +0 -0
  21. data/coverage/assets/0.10.0/magnify.png +0 -0
  22. data/coverage/assets/0.10.0/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  23. data/coverage/assets/0.10.0/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  24. data/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  25. data/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  26. data/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  27. data/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  28. data/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  29. data/coverage/assets/0.10.0/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  30. data/coverage/assets/0.10.0/smoothness/images/ui-icons_222222_256x240.png +0 -0
  31. data/coverage/assets/0.10.0/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  32. data/coverage/assets/0.10.0/smoothness/images/ui-icons_454545_256x240.png +0 -0
  33. data/coverage/assets/0.10.0/smoothness/images/ui-icons_888888_256x240.png +0 -0
  34. data/coverage/assets/0.10.0/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  35. data/coverage/index.html +3438 -0
  36. data/lib/vagrant-cloudstack/action.rb +2 -3
  37. data/lib/vagrant-cloudstack/action/read_ssh_info.rb +14 -6
  38. data/lib/vagrant-cloudstack/action/run_instance.rb +205 -32
  39. data/lib/vagrant-cloudstack/action/terminate_instance.rb +78 -12
  40. data/lib/vagrant-cloudstack/config.rb +65 -1
  41. data/lib/vagrant-cloudstack/version.rb +1 -1
  42. data/locales/en.yml +10 -0
  43. data/spec/spec_helper.rb +5 -0
  44. data/spec/vagrant-cloudstack/config_spec.rb +67 -26
  45. data/vagrant-cloudstack.gemspec +3 -3
  46. metadata +60 -29
  47. data/lib/vagrant-cloudstack/action/sync_folders.rb +0 -88
@@ -55,7 +55,7 @@ module VagrantPlugins
55
55
  end
56
56
 
57
57
  b2.use Provision
58
- b2.use SyncFolders
58
+ b2.use SyncedFolders
59
59
  end
60
60
  end
61
61
  end
@@ -114,7 +114,7 @@ module VagrantPlugins
114
114
  def self.action_prepare_boot
115
115
  Vagrant::Action::Builder.new.tap do |b|
116
116
  b.use Provision
117
- b.use SyncFolders
117
+ b.use SyncedFolders
118
118
  b.use WarnNetworks
119
119
  end
120
120
  end
@@ -177,7 +177,6 @@ module VagrantPlugins
177
177
  autoload :RunInstance, action_root.join("run_instance")
178
178
  autoload :StartInstance, action_root.join("start_instance")
179
179
  autoload :StopInstance, action_root.join("stop_instance")
180
- autoload :SyncFolders, action_root.join("sync_folders")
181
180
  autoload :TimedProvision, action_root.join("timed_provision")
182
181
  autoload :WaitForState, action_root.join("wait_for_state")
183
182
  autoload :WarnNetworks, action_root.join("warn_networks")
@@ -34,9 +34,10 @@ module VagrantPlugins
34
34
  domain_config = machine.provider_config.get_domain_config(domain)
35
35
 
36
36
  pf_ip_address_id = domain_config.pf_ip_address_id
37
+ pf_ip_address = domain_config.pf_ip_address
37
38
  pf_public_port = domain_config.pf_public_port
38
39
 
39
- if pf_ip_address_id and pf_public_port
40
+ if not pf_ip_address and pf_ip_address_id and pf_public_port
40
41
  begin
41
42
  response = cloudstack.list_public_ip_addresses({:id => pf_ip_address_id})
42
43
  rescue Fog::Compute::Cloudstack::Error => e
@@ -52,11 +53,18 @@ module VagrantPlugins
52
53
  end
53
54
  end
54
55
 
55
- unless pf_ip_address.nil?
56
- return {:host => pf_ip_address, :port => pf_public_port}
57
- else
58
- return {:host => server.nics[0]['ipaddress'], :port => 22}
59
- end
56
+ ssh_info = {
57
+ :host => pf_ip_address || server.nics[0]['ipaddress'],
58
+ :port => pf_public_port
59
+ }
60
+
61
+ ssh_info = ssh_info.merge({
62
+ :private_key_path => domain_config.ssh_key,
63
+ :password => nil
64
+ }) unless domain_config.ssh_key.nil?
65
+ ssh_info = ssh_info.merge({ :username => domain_config.ssh_user }) unless domain_config.ssh_user.nil?
66
+
67
+ return ssh_info
60
68
  end
61
69
  end
62
70
  end
@@ -36,15 +36,22 @@ module VagrantPlugins
36
36
  template_id = domain_config.template_id
37
37
  template_name = domain_config.template_name
38
38
  keypair = domain_config.keypair
39
+ static_nat = domain_config.static_nat
39
40
  pf_ip_address_id = domain_config.pf_ip_address_id
41
+ pf_ip_address = domain_config.pf_ip_address
40
42
  pf_public_port = domain_config.pf_public_port
41
43
  pf_private_port = domain_config.pf_private_port
44
+ pf_open_firewall = domain_config.pf_open_firewall
45
+ port_forwarding_rules = domain_config.port_forwarding_rules
46
+ firewall_rules = domain_config.firewall_rules
42
47
  display_name = domain_config.display_name
43
48
  group = domain_config.group
44
49
  security_group_ids = domain_config.security_group_ids
45
50
  security_group_names = domain_config.security_group_names
46
51
  security_groups = domain_config.security_groups
47
52
  user_data = domain_config.user_data
53
+ ssh_key = domain_config.ssh_key
54
+ ssh_user = domain_config.ssh_user
48
55
 
49
56
  # If for some reason the user have specified both network_name and network_id, take the id since that is
50
57
  # more specific than the name. But always try to fetch the name of the network to present to the user.
@@ -130,7 +137,7 @@ module VagrantPlugins
130
137
  }
131
138
 
132
139
  if network_type == "Advanced"
133
- options['network_ids'] = [network_id]
140
+ options['network_ids'] = [network_id] if !network_id.nil?
134
141
  elsif network_type == "Basic"
135
142
  options['security_group_ids'] = security_group_ids
136
143
  end
@@ -189,9 +196,34 @@ module VagrantPlugins
189
196
 
190
197
  @logger.info("Time to instance ready: #{env[:metrics]["instance_ready_time"]}")
191
198
 
192
- if pf_ip_address_id and pf_public_port and pf_private_port
193
- create_port_forwarding_rule(env, pf_ip_address_id,
194
- pf_public_port, pf_private_port)
199
+ if !static_nat.empty?
200
+ static_nat.each do |rule|
201
+ enable_static_nat(env, rule)
202
+ end
203
+ end
204
+
205
+ if (pf_ip_address_id or pf_ip_address) and pf_public_port and pf_private_port
206
+ port_forwarding_rule = {
207
+ :ipaddressid => pf_ip_address_id,
208
+ :ipaddress => pf_ip_address,
209
+ :protocol => "tcp",
210
+ :publicport => pf_public_port,
211
+ :privateport => pf_private_port,
212
+ :openfirewall => pf_open_firewall
213
+ }
214
+ create_port_forwarding_rule(env, port_forwarding_rule)
215
+ end
216
+
217
+ if !port_forwarding_rules.empty?
218
+ port_forwarding_rules.each do |port_forwarding_rule|
219
+ create_port_forwarding_rule(env, port_forwarding_rule)
220
+ end
221
+ end
222
+
223
+ if !firewall_rules.empty?
224
+ firewall_rules.each do |firewall_rule|
225
+ create_firewall_rule(env, firewall_rule)
226
+ end
195
227
  end
196
228
 
197
229
  if !env[:interrupted]
@@ -264,39 +296,93 @@ module VagrantPlugins
264
296
  end
265
297
  end
266
298
 
267
- def create_port_forwarding_rule(env, pf_ip_address_id, pf_public_port, pf_private_port)
268
- env[:ui].info(I18n.t("vagrant_cloudstack.creating_port_forwarding_rule"))
299
+ def enable_static_nat(env, rule)
300
+ env[:ui].info(I18n.t("vagrant_cloudstack.enabling_static_nat"))
301
+
302
+ ip_address_id = rule[:ipaddressid]
303
+ ip_address = rule[:ipaddress]
304
+
305
+ if ip_address_id.nil? and ip_address.nil?
306
+ @logger.info("IP address is not specified. Skip enabling static nat.")
307
+ env[:ui].info(I18n.t("IP address is not specified. Skip enabling static nat."))
308
+ return
309
+ end
310
+
311
+ if ip_address_id.nil? and ip_address
312
+ ip_address_id = ip_to_id(env, ip_address)
313
+ elsif ip_address_id
314
+ ip_address = id_to_ip(env, ip_address_id)
315
+ end
316
+
317
+ env[:ui].info(" -- IP address : #{ip_address} (#{ip_address_id})")
318
+
319
+ options = {
320
+ :command => "enableStaticNat",
321
+ :ipaddressid => ip_address_id,
322
+ :virtualmachineid => env[:machine].id
323
+ }
269
324
 
270
325
  begin
271
- response = env[:cloudstack_compute].list_public_ip_addresses({:id => pf_ip_address_id})
326
+ resp = env[:cloudstack_compute].request(options)
327
+ is_success = resp["enablestaticnatresponse"]["success"]
328
+
329
+ if is_success != "true"
330
+ env[:ui].warn(" -- Failed to enable static nat: #{resp["enablestaticnatresponse"]["errortext"]}")
331
+ return
332
+ end
272
333
  rescue Fog::Compute::Cloudstack::Error => e
273
334
  raise Errors::FogError, :message => e.message
274
335
  end
275
336
 
276
- if response["listpublicipaddressesresponse"]["count"] == 0
277
- @logger.info("IP address #{pf_ip_address_id} not exists. Skip creating port forwarding rule.")
278
- env[:ui].info(I18n.t("IP address #{pf_ip_address_id} not exists. Skip creating port forwarding rule."))
337
+ # Save ipaddress id to the data dir so it can be disabled when the instance is destroyed
338
+ static_nat_file = env[:machine].data_dir.join('static_nat')
339
+ static_nat_file.open('a+') do |f|
340
+ f.write("#{ip_address_id}\n")
341
+ end
342
+ end
343
+
344
+ def create_port_forwarding_rule(env, rule)
345
+ env[:ui].info(I18n.t("vagrant_cloudstack.creating_port_forwarding_rule"))
346
+
347
+ ip_address_id = rule[:ipaddressid]
348
+ ip_address = rule[:ipaddress]
349
+
350
+ if ip_address_id.nil? and ip_address.nil?
351
+ @logger.info("IP address is not specified. Skip creating port forwarding rule.")
352
+ env[:ui].info(I18n.t("IP address is not specified. Skip creating port forwarding rule."))
279
353
  return
280
354
  end
281
355
 
282
- pf_ip_address = response["listpublicipaddressesresponse"]["publicipaddress"][0]["ipaddress"]
356
+ if ip_address_id.nil? and ip_address
357
+ ip_address_id = ip_to_id(env, ip_address)
358
+ elsif ip_address_id
359
+ ip_address = id_to_ip(env, ip_address_id)
360
+ end
283
361
 
284
- env[:ui].info(" -- IP address ID: #{pf_ip_address_id}")
285
- env[:ui].info(" -- IP address: #{pf_ip_address}")
286
- env[:ui].info(" -- Public port: #{pf_public_port}")
287
- env[:ui].info(" -- Private port: #{pf_private_port}")
362
+ env[:ui].info(" -- IP address : #{ip_address} (#{ip_address_id})")
363
+ env[:ui].info(" -- Protocol : #{rule[:protocol]}")
364
+ env[:ui].info(" -- Public port : #{rule[:publicport]}")
365
+ env[:ui].info(" -- Private port : #{rule[:privateport]}")
366
+ env[:ui].info(" -- Open Firewall : #{rule[:openfirewall]}")
288
367
 
289
368
  options = {
290
- :ipaddressid => pf_ip_address_id,
291
- :publicport => pf_public_port,
292
- :privateport => pf_private_port,
293
- :protocol => "tcp",
294
- :virtualmachineid => env[:machine].id,
295
- :openfirewall => "true"
369
+ :ipaddressid => ip_address_id,
370
+ :publicport => rule[:publicport],
371
+ :privateport => rule[:privateport],
372
+ :protocol => rule[:protocol],
373
+ :openfirewall => rule[:openfirewall],
374
+ :virtualmachineid => env[:machine].id
296
375
  }
297
376
 
298
377
  begin
299
- job_id = env[:cloudstack_compute].create_port_forwarding_rule(options)["createportforwardingruleresponse"]["jobid"]
378
+ resp = env[:cloudstack_compute].create_port_forwarding_rule(options)
379
+ job_id = resp["createportforwardingruleresponse"]["jobid"]
380
+
381
+ if job_id.nil?
382
+ env[:ui].warn(" -- Failed to create port forwarding rule: #{resp["createportforwardingruleresponse"]["errortext"]}")
383
+ return
384
+ end
385
+
300
386
  while true
301
387
  response = env[:cloudstack_compute].query_async_job_result({:jobid => job_id})
302
388
  if response["queryasyncjobresultresponse"]["jobstatus"] != 0
@@ -312,8 +398,74 @@ module VagrantPlugins
312
398
 
313
399
  # Save port forwarding rule id to the data dir so it can be released when the instance is destroyed
314
400
  port_forwarding_file = env[:machine].data_dir.join('port_forwarding')
315
- port_forwarding_file.open('w+') do |f|
316
- f.write(port_forwarding_rule["id"])
401
+ port_forwarding_file.open('a+') do |f|
402
+ f.write("#{port_forwarding_rule["id"]}\n")
403
+ end
404
+ end
405
+
406
+ def create_firewall_rule(env, rule)
407
+ env[:ui].info(I18n.t("vagrant_cloudstack.creating_firewall_rule"))
408
+
409
+ ip_address_id = rule[:ipaddressid]
410
+ ip_address = rule[:ipaddress]
411
+
412
+ if ip_address_id.nil? and ip_address.nil?
413
+ @logger.info("IP address is not specified. Skip creating firewall rule.")
414
+ env[:ui].info(I18n.t("IP address is not specified. Skip creating firewall rule."))
415
+ return
416
+ end
417
+
418
+ if ip_address_id.nil? and ip_address
419
+ ip_address_id = ip_to_id(env, ip_address)
420
+ elsif ip_address_id
421
+ ip_address = id_to_ip(env, ip_address_id)
422
+ end
423
+
424
+ env[:ui].info(" -- IP address : #{ip_address} (#{ip_address_id})")
425
+ env[:ui].info(" -- Protocol : #{rule[:protocol]}")
426
+ env[:ui].info(" -- CIDR list : #{rule[:cidrlist]}")
427
+ env[:ui].info(" -- Start port : #{rule[:startport]}")
428
+ env[:ui].info(" -- End port : #{rule[:endport]}")
429
+ env[:ui].info(" -- ICMP code : #{rule[:icmpcode]}")
430
+ env[:ui].info(" -- ICMP type : #{rule[:icmptype]}")
431
+
432
+ options = {
433
+ :command => "createFirewallRule",
434
+ :ipaddressid => ip_address_id,
435
+ :protocol => rule[:protocol],
436
+ :cidrlist => rule[:cidrlist],
437
+ :startport => rule[:startport],
438
+ :endeport => rule[:endport],
439
+ :icmpcode => rule[:icmpcode],
440
+ :icmptype => rule[:icmptype]
441
+ }
442
+
443
+ begin
444
+ resp = env[:cloudstack_compute].request(options)
445
+ job_id = resp["createfirewallruleresponse"]["jobid"]
446
+
447
+ if job_id.nil?
448
+ env[:ui].warn(" -- Failed to create firewall rule: #{resp["createfirewallruleresponse"]["errortext"]}")
449
+ return
450
+ end
451
+
452
+ while true
453
+ response = env[:cloudstack_compute].query_async_job_result({:jobid => job_id})
454
+ if response["queryasyncjobresultresponse"]["jobstatus"] != 0
455
+ firewall_rule = response["queryasyncjobresultresponse"]["jobresult"]["firewallrule"]
456
+ break
457
+ else
458
+ sleep 2
459
+ end
460
+ end
461
+ rescue Fog::Compute::Cloudstack::Error => e
462
+ raise Errors::FogError, :message => e.message
463
+ end
464
+
465
+ # Save firewall rule id to the data dir so it can be released when the instance is destroyed
466
+ firewall_file = env[:machine].data_dir.join('firewall')
467
+ firewall_file.open('a+') do |f|
468
+ f.write("#{firewall_rule["id"]}\n")
317
469
  end
318
470
  end
319
471
 
@@ -328,23 +480,44 @@ module VagrantPlugins
328
480
  private
329
481
 
330
482
  def translate_from_to(env, resource_type, options)
331
- pluralised_type = "#{resource_type}s"
332
- full_response = env[:cloudstack_compute].send("list_#{pluralised_type}".to_sym, options)
483
+ if resource_type == "public_ip_address"
484
+ pluralised_type = "public_ip_addresses"
485
+ else
486
+ pluralised_type = "#{resource_type}s"
487
+ end
488
+
489
+ full_response = env[:cloudstack_compute].send("list_#{pluralised_type}".to_sym, options)
333
490
  full_response["list#{pluralised_type.tr('_', '')}response"][resource_type.tr('_', '')]
334
491
  end
335
492
 
336
- def name_to_id(env, resource_name, resource_type, options={})
337
- env[:ui].info("Fetching UUID for #{resource_type} named '#{resource_name}'")
493
+ def resourcefield_to_id(env, resource_type, resource_field, resource_field_value, options={})
494
+ env[:ui].info("Fetching UUID for #{resource_type} with #{resource_field} '#{resource_field_value}'")
338
495
  full_response = translate_from_to(env, resource_type, options)
339
- result = full_response.find { |type| type["name"] == resource_name }
496
+ result = full_response.find {|type| type[resource_field] == resource_field_value }
340
497
  result['id']
341
498
  end
342
499
 
343
- def id_to_name(env, resource_id, resource_type, options={})
344
- env[:ui].info("Fetching name for #{resource_type} with UUID '#{resource_id}'")
500
+ def id_to_resourcefield(env, resource_id, resource_type, resource_field, options={})
501
+ env[:ui].info("Fetching #{resource_field} for #{resource_type} with UUID '#{resource_id}'")
345
502
  options = options.merge({'id' => resource_id})
346
503
  full_response = translate_from_to(env, resource_type, options)
347
- full_response[0]['name']
504
+ full_response[0][resource_field]
505
+ end
506
+
507
+ def name_to_id(env, resource_name, resource_type, options={})
508
+ resourcefield_to_id(env, resource_type, 'name', resource_name, options)
509
+ end
510
+
511
+ def id_to_name(env, resource_id, resource_type, options={})
512
+ id_to_resourcefield(env, resource_id, resource_type, 'name', options)
513
+ end
514
+
515
+ def ip_to_id(env, ip_address, options={})
516
+ resourcefield_to_id(env, 'public_ip_address', 'ipaddress', ip_address, options)
517
+ end
518
+
519
+ def id_to_ip(env, ip_address_id, options={})
520
+ id_to_resourcefield(env, ip_address_id, 'public_ip_address', 'ipaddress', options)
348
521
  end
349
522
  end
350
523
  end
@@ -11,29 +11,90 @@ module VagrantPlugins
11
11
  end
12
12
 
13
13
  def call(env)
14
+ # Disable Static NAT
15
+ env[:ui].info(I18n.t("vagrant_cloudstack.disabling_static_nat"))
16
+ static_nat_file = env[:machine].data_dir.join("static_nat")
17
+ if static_nat_file.file?
18
+ File.open(static_nat_file, "r").each_line do |line|
19
+ ip_address_id = line.strip
20
+ begin
21
+ options = {
22
+ :command => "disableStaticNat",
23
+ :ipaddressid => ip_address_id
24
+ }
25
+ resp = env[:cloudstack_compute].request(options)
26
+ job_id = resp["disablestaticnatresponse"]["jobid"]
27
+ while true
28
+ response = env[:cloudstack_compute].query_async_job_result({:jobid => job_id})
29
+ if response["queryasyncjobresultresponse"]["jobstatus"] != 0
30
+ break
31
+ else
32
+ sleep 2
33
+ end
34
+ end
35
+ rescue Fog::Compute::Cloudstack::Error => e
36
+ raise Errors::FogError, :message => e.message
37
+ end
38
+ end
39
+ static_nat_file.delete
40
+ end
41
+
14
42
  # Delete the Port forwarding rule
15
43
  env[:ui].info(I18n.t("vagrant_cloudstack.deleting_port_forwarding_rule"))
16
44
  port_forwarding_file = env[:machine].data_dir.join("port_forwarding")
17
45
  if port_forwarding_file.file?
18
- rule_id = port_forwarding_file.read
19
- begin
20
- job_id = env[:cloudstack_compute].delete_port_forwarding_rule({:id => rule_id})["deleteportforwardingruleresponse"]["jobid"]
21
- while true
22
- response = env[:cloudstack_compute].query_async_job_result({:jobid => job_id})
23
- if response["queryasyncjobresultresponse"]["jobstatus"] != 0
24
- break
25
- else
26
- sleep 2
46
+ File.open(port_forwarding_file, "r").each_line do |line|
47
+ rule_id = line.strip
48
+ begin
49
+ resp = env[:cloudstack_compute].delete_port_forwarding_rule({:id => rule_id})
50
+ job_id = resp["deleteportforwardingruleresponse"]["jobid"]
51
+ while true
52
+ response = env[:cloudstack_compute].query_async_job_result({:jobid => job_id})
53
+ if response["queryasyncjobresultresponse"]["jobstatus"] != 0
54
+ break
55
+ else
56
+ sleep 2
57
+ end
27
58
  end
59
+ rescue Fog::Compute::Cloudstack::Error => e
60
+ raise Errors::FogError, :message => e.message
28
61
  end
29
- rescue Fog::Compute::Cloudstack::Error => e
30
- raise Errors::FogError, :message => e.message
31
62
  end
32
63
  port_forwarding_file.delete
33
64
  end
34
65
 
66
+ # Delete the Firewall rule
67
+ env[:ui].info(I18n.t("vagrant_cloudstack.deleting_firewall_rule"))
68
+ firewall_file = env[:machine].data_dir.join("firewall")
69
+ if firewall_file.file?
70
+ File.open(firewall_file, "r").each_line do |line|
71
+ rule_id = line.strip
72
+ begin
73
+ options = {
74
+ :command => "deleteFirewallRule",
75
+ :id => rule_id
76
+ }
77
+ resp = env[:cloudstack_compute].request(options)
78
+ job_id = resp["deletefirewallruleresponse"]["jobid"]
79
+ while true
80
+ response = env[:cloudstack_compute].query_async_job_result({:jobid => job_id})
81
+ if response["queryasyncjobresultresponse"]["jobstatus"] != 0
82
+ break
83
+ else
84
+ sleep 2
85
+ end
86
+ end
87
+ rescue Fog::Compute::Cloudstack::Error => e
88
+ raise Errors::FogError, :message => e.message
89
+ end
90
+ end
91
+ firewall_file.delete
92
+ end
93
+
35
94
  # Destroy the server and remove the tracking ID
36
- server = env[:cloudstack_compute].servers.get(env[:machine].id)
95
+ unless env[:machine].id.nil?
96
+ server = env[:cloudstack_compute].servers.get(env[:machine].id)
97
+
37
98
  env[:ui].info(I18n.t("vagrant_cloudstack.terminating"))
38
99
 
39
100
  job = server.destroy
@@ -47,6 +108,11 @@ module VagrantPlugins
47
108
  end
48
109
  end
49
110
 
111
+ else
112
+ env[:ui].info(I18n.t("vagrant_cloudstack.no_instance_found"))
113
+ return
114
+ end
115
+
50
116
  security_groups_file = env[:machine].data_dir.join("security_groups")
51
117
  if security_groups_file.file?
52
118
  File.open(security_groups_file, "r").each_line do |line|