vagrant-libvirt 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +134 -23
  3. data/lib/vagrant-libvirt/action/clean_machine_folder.rb +4 -0
  4. data/lib/vagrant-libvirt/action/create_domain.rb +11 -3
  5. data/lib/vagrant-libvirt/action/create_domain_volume.rb +7 -2
  6. data/lib/vagrant-libvirt/action/create_network_interfaces.rb +8 -2
  7. data/lib/vagrant-libvirt/action/create_networks.rb +12 -8
  8. data/lib/vagrant-libvirt/action/destroy_domain.rb +2 -0
  9. data/lib/vagrant-libvirt/action/destroy_networks.rb +2 -0
  10. data/lib/vagrant-libvirt/action/forward_ports.rb +7 -5
  11. data/lib/vagrant-libvirt/action/halt_domain.rb +4 -34
  12. data/lib/vagrant-libvirt/action/handle_box_image.rb +18 -13
  13. data/lib/vagrant-libvirt/action/handle_storage_pool.rb +7 -1
  14. data/lib/vagrant-libvirt/action/is_created.rb +2 -0
  15. data/lib/vagrant-libvirt/action/is_running.rb +2 -0
  16. data/lib/vagrant-libvirt/action/is_suspended.rb +2 -0
  17. data/lib/vagrant-libvirt/action/message_already_created.rb +2 -0
  18. data/lib/vagrant-libvirt/action/message_not_created.rb +2 -0
  19. data/lib/vagrant-libvirt/action/message_not_running.rb +2 -0
  20. data/lib/vagrant-libvirt/action/message_not_suspended.rb +2 -0
  21. data/lib/vagrant-libvirt/action/message_will_not_destroy.rb +2 -0
  22. data/lib/vagrant-libvirt/action/package_domain.rb +133 -68
  23. data/lib/vagrant-libvirt/action/prepare_nfs_settings.rb +2 -0
  24. data/lib/vagrant-libvirt/action/prepare_nfs_valid_ids.rb +2 -0
  25. data/lib/vagrant-libvirt/action/prune_nfs_exports.rb +2 -0
  26. data/lib/vagrant-libvirt/action/read_mac_addresses.rb +2 -0
  27. data/lib/vagrant-libvirt/action/remove_libvirt_image.rb +2 -0
  28. data/lib/vagrant-libvirt/action/remove_stale_volume.rb +2 -0
  29. data/lib/vagrant-libvirt/action/resume_domain.rb +2 -0
  30. data/lib/vagrant-libvirt/action/set_boot_order.rb +8 -2
  31. data/lib/vagrant-libvirt/action/set_name_of_domain.rb +3 -1
  32. data/lib/vagrant-libvirt/action/share_folders.rb +2 -0
  33. data/lib/vagrant-libvirt/action/shutdown_domain.rb +49 -0
  34. data/lib/vagrant-libvirt/action/start_domain.rb +26 -17
  35. data/lib/vagrant-libvirt/action/suspend_domain.rb +2 -0
  36. data/lib/vagrant-libvirt/action/wait_till_up.rb +2 -0
  37. data/lib/vagrant-libvirt/action.rb +34 -4
  38. data/lib/vagrant-libvirt/cap/mount_9p.rb +2 -0
  39. data/lib/vagrant-libvirt/cap/mount_virtiofs.rb +2 -0
  40. data/lib/vagrant-libvirt/cap/nic_mac_addresses.rb +2 -0
  41. data/lib/vagrant-libvirt/cap/public_address.rb +2 -0
  42. data/lib/vagrant-libvirt/cap/synced_folder_9p.rb +5 -2
  43. data/lib/vagrant-libvirt/cap/synced_folder_virtiofs.rb +5 -2
  44. data/lib/vagrant-libvirt/config.rb +58 -24
  45. data/lib/vagrant-libvirt/driver.rb +67 -12
  46. data/lib/vagrant-libvirt/errors.rb +2 -0
  47. data/lib/vagrant-libvirt/plugin.rb +2 -0
  48. data/lib/vagrant-libvirt/provider.rb +2 -0
  49. data/lib/vagrant-libvirt/templates/domain.xml.erb +4 -2
  50. data/lib/vagrant-libvirt/templates/public_interface.xml.erb +1 -0
  51. data/lib/vagrant-libvirt/util/byte_number.rb +71 -0
  52. data/lib/vagrant-libvirt/util/collection.rb +2 -0
  53. data/lib/vagrant-libvirt/util/erb_template.rb +2 -0
  54. data/lib/vagrant-libvirt/util/error_codes.rb +2 -0
  55. data/lib/vagrant-libvirt/util/network_util.rb +3 -0
  56. data/lib/vagrant-libvirt/util/nfs.rb +2 -0
  57. data/lib/vagrant-libvirt/util/storage_util.rb +1 -0
  58. data/lib/vagrant-libvirt/util/timer.rb +2 -0
  59. data/lib/vagrant-libvirt/util/ui.rb +1 -0
  60. data/lib/vagrant-libvirt/util.rb +2 -0
  61. data/lib/vagrant-libvirt/version +1 -1
  62. data/lib/vagrant-libvirt/version.rb +2 -0
  63. data/lib/vagrant-libvirt.rb +2 -0
  64. data/locales/en.yml +2 -0
  65. data/spec/spec_helper.rb +2 -0
  66. data/spec/support/binding_proc.rb +2 -0
  67. data/spec/support/environment_helper.rb +2 -0
  68. data/spec/support/libvirt_context.rb +2 -0
  69. data/spec/support/matchers/have_file_content.rb +2 -0
  70. data/spec/support/sharedcontext.rb +3 -0
  71. data/spec/support/temporary_dir.rb +12 -0
  72. data/spec/unit/action/clean_machine_folder_spec.rb +16 -4
  73. data/spec/unit/action/create_domain_spec/additional_disks_domain.xml +61 -0
  74. data/spec/unit/action/create_domain_spec/default_domain.xml +55 -0
  75. data/spec/unit/action/create_domain_spec.rb +68 -32
  76. data/spec/unit/action/create_domain_volume_spec/one_disk_in_storage.xml +1 -1
  77. data/spec/unit/action/create_domain_volume_spec/three_disks_in_storage_disk_0.xml +1 -1
  78. data/spec/unit/action/create_domain_volume_spec/three_disks_in_storage_disk_1.xml +1 -1
  79. data/spec/unit/action/create_domain_volume_spec/three_disks_in_storage_disk_2.xml +1 -1
  80. data/spec/unit/action/create_domain_volume_spec.rb +10 -4
  81. data/spec/unit/action/destroy_domain_spec.rb +8 -2
  82. data/spec/unit/action/forward_ports_spec.rb +2 -0
  83. data/spec/unit/action/halt_domain_spec.rb +30 -57
  84. data/spec/unit/action/handle_box_image_spec.rb +104 -24
  85. data/spec/unit/action/package_domain_spec.rb +304 -0
  86. data/spec/unit/action/set_name_of_domain_spec.rb +2 -0
  87. data/spec/unit/action/shutdown_domain_spec.rb +131 -0
  88. data/spec/unit/action/start_domain_spec/existing.xml +62 -0
  89. data/spec/unit/action/start_domain_spec.rb +18 -28
  90. data/spec/unit/action/wait_till_up_spec.rb +2 -0
  91. data/spec/unit/action_spec.rb +96 -0
  92. data/spec/unit/config_spec.rb +56 -3
  93. data/spec/unit/driver_spec.rb +155 -0
  94. data/spec/unit/templates/domain_all_settings.xml +4 -0
  95. data/spec/unit/templates/domain_spec.rb +2 -0
  96. data/spec/unit/util/byte_number_spec.rb +28 -0
  97. metadata +59 -38
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'digest/md5'
2
4
  require 'vagrant/util/retryable'
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'digest/md5'
2
4
  require 'vagrant/util/retryable'
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module VagrantPlugins
2
4
  module ProviderLibvirt
3
5
  module Cap
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module VagrantPlugins
2
4
  module ProviderLibvirt
3
5
  module Cap
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'log4r'
2
4
  require 'ostruct'
3
5
  require 'nokogiri'
@@ -45,7 +47,6 @@ module VagrantPlugins
45
47
 
46
48
  machine.ui.info "================\nMachine id: #{machine.id}\nShould be mounting folders\n #{id}, opts: #{folder_opts}"
47
49
 
48
- #xml = to_xml('filesystem', folder_opts)
49
50
  xml = Nokogiri::XML::Builder.new do |xml|
50
51
  xml.filesystem(type: 'mount', accessmode: folder_opts[:accessmode]) do
51
52
  xml.driver(type: 'path', wrpolicy: 'immediate')
@@ -58,7 +59,9 @@ module VagrantPlugins
58
59
  Nokogiri::XML::Node::SaveOptions::NO_EMPTY_TAGS |
59
60
  Nokogiri::XML::Node::SaveOptions::FORMAT
60
61
  )
61
- # puts "<<<<< XML:\n #{xml}\n >>>>>"
62
+ @logger.debug {
63
+ "Attaching Synced Folder device with XML:\n#{xml}"
64
+ }
62
65
  @conn.lookup_domain_by_uuid(machine.id).attach_device(xml, 0)
63
66
  end
64
67
  rescue => e
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'log4r'
2
4
  require 'ostruct'
3
5
  require 'nokogiri'
@@ -44,7 +46,6 @@ module VagrantPlugins
44
46
 
45
47
  machine.ui.info "================\nMachine id: #{machine.id}\nShould be mounting folders\n #{id}, opts: #{folder_opts}"
46
48
 
47
- #xml = to_xml('filesystem', folder_opts)
48
49
  xml = Nokogiri::XML::Builder.new do |xml|
49
50
  xml.filesystem(type: 'mount', accessmode: 'passthrough') do
50
51
  xml.driver(type: 'virtiofs')
@@ -57,7 +58,9 @@ module VagrantPlugins
57
58
  Nokogiri::XML::Node::SaveOptions::NO_EMPTY_TAGS |
58
59
  Nokogiri::XML::Node::SaveOptions::FORMAT
59
60
  )
60
- # puts "<<<<< XML:\n #{xml}\n >>>>>"
61
+ @logger.debug {
62
+ "Attaching Synced Folder device with XML:\n#{xml}"
63
+ }
61
64
  @conn.lookup_domain_by_uuid(machine.id).attach_device(xml, 0)
62
65
  end
63
66
  rescue => e
@@ -1,12 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cgi'
4
+
1
5
  require 'vagrant'
2
6
 
3
7
  class Numeric
4
8
  Alphabet = ('a'..'z').to_a
5
9
  def vdev
6
- s = ''
10
+ s = String.new
7
11
  q = self
8
12
  (q, r = (q - 1).divmod(26)) && s.prepend(Alphabet[r]) until q.zero?
9
- 'vd' + s
13
+ "vd#{s}"
10
14
  end
11
15
  end
12
16
 
@@ -189,10 +193,14 @@ module VagrantPlugins
189
193
  # Use QEMU session instead of system
190
194
  attr_accessor :qemu_use_session
191
195
 
196
+ # Use QEMU Agent to get ip address
197
+ attr_accessor :qemu_use_agent
198
+
192
199
  def initialize
193
200
  @uri = UNSET_VALUE
194
201
  @driver = UNSET_VALUE
195
202
  @host = UNSET_VALUE
203
+ @port = UNSET_VALUE
196
204
  @connect_via_ssh = UNSET_VALUE
197
205
  @username = UNSET_VALUE
198
206
  @password = UNSET_VALUE
@@ -327,6 +335,9 @@ module VagrantPlugins
327
335
  @qemu_env = UNSET_VALUE
328
336
 
329
337
  @qemu_use_session = UNSET_VALUE
338
+
339
+ # Use Qemu agent to get ip address
340
+ @qemu_use_agent = UNSET_VALUE
330
341
  end
331
342
 
332
343
  def boot(device)
@@ -349,7 +360,7 @@ module VagrantPlugins
349
360
  # hda - hdc
350
361
  curr = 'a'.ord
351
362
  while curr <= 'd'.ord
352
- dev = 'hd' + curr.chr
363
+ dev = "hd#{curr.chr}"
353
364
  if exist[dev]
354
365
  curr += 1
355
366
  next
@@ -552,7 +563,7 @@ module VagrantPlugins
552
563
  end
553
564
 
554
565
  @usbctl_dev[:model] = options[:model]
555
- @usbctl_dev[:ports] = options[:ports]
566
+ @usbctl_dev[:ports] = options[:ports] if options[:ports]
556
567
  end
557
568
 
558
569
  def usb(options = {})
@@ -742,24 +753,24 @@ module VagrantPlugins
742
753
  if @connect_via_ssh == true
743
754
  finalize_id_ssh_key_file
744
755
 
745
- uri << '+ssh://'
746
- uri << @username + '@' if @username && @username != UNSET_VALUE
756
+ uri += '+ssh://'
757
+ uri += "#{@username}@" if @username && @username != UNSET_VALUE
747
758
 
748
- uri << ( @host && @host != UNSET_VALUE ? @host : 'localhost' )
759
+ uri += (@host && @host != UNSET_VALUE ? @host : 'localhost')
749
760
 
750
761
  params['no_verify'] = '1'
751
762
  params['keyfile'] = @id_ssh_key_file if @id_ssh_key_file
752
763
  else
753
- uri << '://'
754
- uri << @host if @host && @host != UNSET_VALUE
764
+ uri += '://'
765
+ uri += @host if @host && @host != UNSET_VALUE
755
766
  end
756
767
 
757
- uri << virt_path
768
+ uri += virt_path
758
769
 
759
770
  # set path to Libvirt socket
760
771
  params['socket'] = @socket if @socket
761
772
 
762
- uri << "?" + params.map{|pair| pair.join('=')}.join('&') if !params.empty?
773
+ uri += '?' + params.map { |pair| pair.join('=') }.join('&') unless params.empty?
763
774
  uri
764
775
  end
765
776
 
@@ -904,9 +915,6 @@ module VagrantPlugins
904
915
  # Watchdog device
905
916
  @watchdog_dev = {} if @watchdog_dev == UNSET_VALUE
906
917
 
907
- # USB controller
908
- @usbctl_dev = {} if @usbctl_dev == UNSET_VALUE
909
-
910
918
  # USB device passthrough
911
919
  @usbs = [] if @usbs == UNSET_VALUE
912
920
 
@@ -914,6 +922,11 @@ module VagrantPlugins
914
922
  @redirdevs = [] if @redirdevs == UNSET_VALUE
915
923
  @redirfilters = [] if @redirfilters == UNSET_VALUE
916
924
 
925
+ # USB controller
926
+ if @usbctl_dev == UNSET_VALUE
927
+ @usbctl_dev = if !@usbs.empty? or !@redirdevs.empty? then {:model => 'qemu-xhci'} else {} end
928
+ end
929
+
917
930
  # smartcard device
918
931
  @smartcard_dev = {} if @smartcard_dev == UNSET_VALUE
919
932
 
@@ -931,6 +944,8 @@ module VagrantPlugins
931
944
 
932
945
  # Additional QEMU commandline environment variables
933
946
  @qemu_env = {} if @qemu_env == UNSET_VALUE
947
+
948
+ @qemu_use_agent = true if @qemu_use_agent != UNSET_VALUE
934
949
  end
935
950
 
936
951
  def validate(machine)
@@ -944,6 +959,17 @@ module VagrantPlugins
944
959
  end
945
960
  end
946
961
 
962
+
963
+ if @qemu_use_agent == true
964
+ # if qemu agent is used to optain domain ip configuration, at least
965
+ # one qemu channel has to be configured. As there are various options,
966
+ # error out and leave configuration to the user
967
+ unless machine.provider_config.channels.any? { |channel| channel[:target_name].start_with?("org.qemu.guest_agent") }
968
+ errors << "qemu agent option enabled, but no qemu agent channel configured: please add at least one qemu agent channel to vagrant config"
969
+ end
970
+ end
971
+
972
+
947
973
  machine.provider_config.disks.each do |disk|
948
974
  if disk[:path] && (disk[:path][0] == '/')
949
975
  errors << "absolute volume paths like '#{disk[:path]}' not yet supported"
@@ -952,11 +978,10 @@ module VagrantPlugins
952
978
 
953
979
  machine.config.vm.networks.each do |_type, opts|
954
980
  if opts[:mac]
955
- opts[:mac].downcase!
956
- if opts[:mac] =~ /\A([0-9a-f]{12})\z/
981
+ if opts[:mac] =~ /\A([0-9a-fA-F]{12})\z/
957
982
  opts[:mac] = opts[:mac].scan(/../).join(':')
958
983
  end
959
- unless opts[:mac] =~ /\A([0-9a-f]{2}:){5}([0-9a-f]{2})\z/
984
+ unless opts[:mac] =~ /\A([0-9a-fA-F]{2}:){5}([0-9a-fA-F]{2})\z/
960
985
  errors << "Configured NIC MAC '#{opts[:mac]}' is not in 'xx:xx:xx:xx:xx:xx' or 'xxxxxxxxxxxx' format"
961
986
  end
962
987
  end
@@ -1014,9 +1039,16 @@ module VagrantPlugins
1014
1039
  end
1015
1040
  end
1016
1041
 
1017
- # Extract host and username values from uri if provided, otherwise nil
1042
+ # Extract host values from uri if provided, otherwise nil
1018
1043
  @host = uri.host
1019
- @username = uri.user
1044
+ @port = uri.port
1045
+ # only override username if there is a value provided
1046
+ @username = nil if @username == UNSET_VALUE
1047
+ @username = uri.user if uri.user
1048
+ if uri.query
1049
+ params = CGI.parse(uri.query)
1050
+ @id_ssh_key_file = params['keyfile'].first if params.has_key?('keyfile')
1051
+ end
1020
1052
 
1021
1053
  finalize_id_ssh_key_file
1022
1054
  end
@@ -1024,7 +1056,7 @@ module VagrantPlugins
1024
1056
  def resolve_ssh_key_file(key_file)
1025
1057
  # set ssh key for access to Libvirt host
1026
1058
  # if no slash, prepend $HOME/.ssh/
1027
- key_file.prepend("#{ENV['HOME']}/.ssh/") if key_file && key_file !~ /\A\//
1059
+ key_file = "#{ENV['HOME']}/.ssh/#{key_file}" if key_file && key_file !~ /\A\//
1028
1060
 
1029
1061
  key_file
1030
1062
  end
@@ -1053,15 +1085,17 @@ module VagrantPlugins
1053
1085
  if @connect_via_ssh
1054
1086
  if @proxy_command == UNSET_VALUE
1055
1087
  proxy_command = "ssh '#{@host}' "
1056
- proxy_command << "-l '#{@username}' " if @username
1057
- proxy_command << "-i '#{@id_ssh_key_file}' " if @id_ssh_key_file
1058
- proxy_command << '-W %h:%p'
1088
+ proxy_command += "-p #{@port} " if @port
1089
+ proxy_command += "-l '#{@username}' " if @username
1090
+ proxy_command += "-i '#{@id_ssh_key_file}' " if @id_ssh_key_file
1091
+ proxy_command += '-W %h:%p'
1059
1092
  else
1060
1093
  inputs = { host: @host }
1094
+ inputs << { port: @port } if @port
1061
1095
  inputs[:username] = @username if @username
1062
1096
  inputs[:id_ssh_key_file] = @id_ssh_key_file if @id_ssh_key_file
1063
1097
 
1064
- proxy_command = @proxy_command
1098
+ proxy_command = String.new(@proxy_command)
1065
1099
  # avoid needing to escape '%' symbols
1066
1100
  inputs.each do |key, value|
1067
1101
  proxy_command.gsub!("{#{key}}", value)
@@ -1,17 +1,22 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'fog/libvirt'
2
4
  require 'libvirt'
3
5
  require 'log4r'
6
+ require 'json'
4
7
 
5
8
  module VagrantPlugins
6
9
  module ProviderLibvirt
7
10
  class Driver
8
- # store the connection at the process level
11
+ # store the connection at the instance level as this will be per
12
+ # thread and allows for individual machines to use different
13
+ # connection settings.
9
14
  #
10
15
  # possibly this should be a connection pool using the connection
11
- # settings as a key to allow per machine connection attributes
12
- # to be used.
13
- @@connection = nil
14
- @@system_connection = nil
16
+ # settings as a key to allow identical connections to be reused
17
+ # across machines.
18
+ @connection = nil
19
+ @system_connection = nil
15
20
 
16
21
  def initialize(machine)
17
22
  @logger = Log4r::Logger.new('vagrant_libvirt::driver')
@@ -21,7 +26,7 @@ module VagrantPlugins
21
26
  def connection
22
27
  # If already connected to Libvirt, just use it and don't connect
23
28
  # again.
24
- return @@connection if @@connection
29
+ return @connection if @connection
25
30
 
26
31
  # Get config options for Libvirt provider.
27
32
  config = @machine.provider_config
@@ -40,24 +45,24 @@ module VagrantPlugins
40
45
 
41
46
  @logger.info("Connecting to Libvirt (#{uri}) ...")
42
47
  begin
43
- @@connection = Fog::Compute.new(conn_attr)
48
+ @connection = Fog::Compute.new(conn_attr)
44
49
  rescue Fog::Errors::Error => e
45
50
  raise Errors::FogLibvirtConnectionError,
46
51
  error_message: e.message
47
52
  end
48
53
 
49
- @@connection
54
+ @connection
50
55
  end
51
56
 
52
57
  def system_connection
53
58
  # If already connected to Libvirt, just use it and don't connect
54
59
  # again.
55
- return @@system_connection if @@system_connection
60
+ return @system_connection if @system_connection
56
61
 
57
62
  config = @machine.provider_config
58
63
 
59
- @@system_connection = Libvirt::open_read_only(config.system_uri)
60
- @@system_connection
64
+ @system_connection = Libvirt::open(config.system_uri)
65
+ @system_connection
61
66
  end
62
67
 
63
68
  def get_domain(machine)
@@ -97,6 +102,12 @@ module VagrantPlugins
97
102
  return get_ipaddress_from_system domain.mac
98
103
  end
99
104
 
105
+ # attempt to get ip address from qemu agent
106
+ if @machine.provider_config.qemu_use_agent == true
107
+ @logger.info('Get IP via qemu agent')
108
+ return get_ipaddress_from_qemu_agent(domain, machine.id)
109
+ end
110
+
100
111
  # Get IP address from dhcp leases table
101
112
  begin
102
113
  ip_address = get_ipaddress_from_domain(domain)
@@ -126,7 +137,17 @@ module VagrantPlugins
126
137
  # TODO: terminated no longer appears to be a valid fog state, remove?
127
138
  return :not_created if domain.nil? || domain.state.to_sym == :terminated
128
139
 
129
- domain.state.tr('-', '_').to_sym
140
+ state = domain.state.tr('-', '_').to_sym
141
+ if state == :running
142
+ begin
143
+ get_domain_ipaddress(machine, domain)
144
+ rescue Fog::Errors::TimeoutError => e
145
+ @logger.debug("Machine #{machine.id} running but no IP address available: #{e}.")
146
+ return :inaccessible
147
+ end
148
+ end
149
+
150
+ return state
130
151
  end
131
152
 
132
153
  private
@@ -144,6 +165,40 @@ module VagrantPlugins
144
165
  ip_address
145
166
  end
146
167
 
168
+ def get_ipaddress_from_qemu_agent(domain, machine_id)
169
+ ip_address = nil
170
+ addresses = nil
171
+ dom = system_connection.lookup_domain_by_uuid(machine_id)
172
+ begin
173
+ response = dom.qemu_agent_command('{"execute":"guest-network-get-interfaces"}', timeout=10)
174
+ @logger.debug("Got Response from qemu agent")
175
+ @logger.debug(response)
176
+ addresses = JSON.parse(response)
177
+ rescue => e
178
+ @logger.debug("Unable to receive IP via qemu agent: [%s]" % e.message)
179
+ end
180
+
181
+ unless addresses.nil?
182
+ addresses["return"].each{ |interface|
183
+ if domain.mac == interface["hardware-address"]
184
+ @logger.debug("Found mathing interface: [%s]" % interface["name"])
185
+ if interface.has_key?("ip-addresses")
186
+ interface["ip-addresses"].each{ |ip|
187
+ # returning ipv6 addresses might break windows guests because
188
+ # winrm cant handle connection, winrm fails with "invalid uri"
189
+ if ip["ip-address-type"] == "ipv4"
190
+ ip_address = ip["ip-address"]
191
+ @logger.debug("Return IP: [%s]" % ip_address)
192
+ break
193
+ end
194
+ }
195
+ end
196
+ end
197
+ }
198
+ end
199
+ ip_address
200
+ end
201
+
147
202
  def get_ipaddress_from_domain(domain)
148
203
  ip_address = nil
149
204
  domain.wait_for(2) do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'vagrant'
2
4
 
3
5
  module VagrantPlugins
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  begin
2
4
  require 'vagrant'
3
5
  rescue LoadError
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'vagrant'
2
4
 
3
5
  module VagrantPlugins
@@ -113,8 +113,9 @@
113
113
  <% if @emulator_path %>
114
114
  <emulator><%= @emulator_path %></emulator>
115
115
  <% end %>
116
- <% @domain_volumes.each do |volume| -%>
116
+ <% @domain_volumes.each_with_index do |volume, index| -%>
117
117
  <disk type='file' device='disk'>
118
+ <alias name='ua-box-volume-<%= index -%>'/>
118
119
  <driver name='qemu' type='qcow2' <%=
119
120
  @disk_driver_opts.empty? ? "cache='#{volume[:cache]}'" :
120
121
  @disk_driver_opts.reject { |k,v| v.nil? }
@@ -126,8 +127,9 @@
126
127
  </disk>
127
128
  <% end -%>
128
129
  <%# additional disks -%>
129
- <% @disks.each do |d| -%>
130
+ <% @disks.each_with_index do |d, index| -%>
130
131
  <disk type='file' device='disk'>
132
+ <alias name='ua-disk-volume-<%= index -%>'/>
131
133
  <driver name='qemu' type='<%= d[:type] %>' <%=
132
134
  d.select { |k,_| [:cache, :io, :copy_on_read, :discard, :detect_zeroes].include? k }
133
135
  .reject { |k,v| v.nil? }
@@ -1,4 +1,5 @@
1
1
  <interface type='<%= @type %>'<% if @trust_guest_rx_filters %> trustGuestRxFilters='yes'<% end %>>
2
+ <alias name='ua-net-<%= @iface_number %>'/>
2
3
  <% if @mac %>
3
4
  <mac address='<%= @mac %>'/>
4
5
  <% end %>
@@ -0,0 +1,71 @@
1
+ class ByteNumber < Numeric
2
+ def initialize(int)
3
+ @int = int
4
+ end
5
+
6
+ def to_s
7
+ @int.to_s
8
+ end
9
+
10
+ def to_i
11
+ @int
12
+ end
13
+
14
+ def to_f
15
+ @int.to_f
16
+ end
17
+
18
+ def to_B
19
+ to_i
20
+ end
21
+
22
+ def to_KB
23
+ _compute_unit_to_n_kilo(1)
24
+ end
25
+
26
+ def to_MB
27
+ _compute_unit_to_n_kilo(2)
28
+ end
29
+
30
+ def to_GB
31
+ _compute_unit_to_n_kilo(3)
32
+ end
33
+
34
+ def coerce(other)
35
+ to_i.coerce(other)
36
+ end
37
+
38
+ def <=>(other)
39
+ to_i <=> other
40
+ end
41
+
42
+ def +(other)
43
+ to_i + other
44
+ end
45
+
46
+ def -(other)
47
+ to_i - other
48
+ end
49
+
50
+ def *(other)
51
+ to_i * other
52
+ end
53
+
54
+ def /(other)
55
+ to_i / other
56
+ end
57
+
58
+ def pow(n)
59
+ self.class.new(to_i ** n)
60
+ end
61
+
62
+ def self.from_GB(value)
63
+ self.new(value*(1024**3))
64
+ end
65
+
66
+ private
67
+ def _compute_unit_to_n_kilo(n=0)
68
+ (to_f/(1024 ** n)).ceil
69
+ end
70
+ end
71
+
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module VagrantPlugins
2
4
  module ProviderLibvirt
3
5
  module Util
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module VagrantPlugins
2
4
  module ProviderLibvirt
3
5
  module Util
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Ripped from http://libvirt.org/html/libvirt-virterror.html#virErrorNumber.
2
4
  module VagrantPlugins
3
5
  module ProviderLibvirt
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'ipaddr'
2
4
  require 'nokogiri'
3
5
  require 'vagrant/util/network_ip'
@@ -18,6 +20,7 @@ module VagrantPlugins
18
20
 
19
21
  def configured_networks(env, logger)
20
22
  qemu_use_session = env[:machine].provider_config.qemu_use_session
23
+ qemu_use_agent = env[:machine].provider_config.qemu_use_agent
21
24
  management_network_device = env[:machine].provider_config.management_network_device
22
25
  management_network_name = env[:machine].provider_config.management_network_name
23
26
  management_network_address = env[:machine].provider_config.management_network_address
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module VagrantPlugins
2
4
  module ProviderLibvirt
3
5
  module Util
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
 
2
3
  module VagrantPlugins
3
4
  module ProviderLibvirt
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module VagrantPlugins
2
4
  module ProviderLibvirt
3
5
  module Util
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
 
2
3
  module VagrantPlugins
3
4
  module ProviderLibvirt
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module VagrantPlugins
2
4
  module ProviderLibvirt
3
5
  module Util
@@ -1 +1 @@
1
- 0.5.0
1
+ 0.6.0
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'open3'
2
4
  require 'tmpdir'
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'pathname'
2
4
 
3
5
  module VagrantPlugins
data/locales/en.yml CHANGED
@@ -29,6 +29,8 @@ en:
29
29
  Poweroff domain.
30
30
  destroy_domain: |-
31
31
  Removing domain...
32
+ shutdown_domain: |-
33
+ Attempting direct shutdown of domain...
32
34
  halt_domain: |-
33
35
  Halting domain...
34
36
  resuming_domain: |-
data/spec/spec_helper.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'simplecov'
2
4
  require 'simplecov-lcov'
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  ##
2
4
  # A simple extension of the Proc class that supports setting a custom binding
3
5
  # and evaluates everything in the Proc using the new binding.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'ostruct'
2
4
  require 'pathname'
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'fog/libvirt'
2
4
 
3
5
  shared_context 'libvirt' do