vagrant-libvirt 0.6.3 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +65 -13
- data/lib/vagrant-libvirt/action/cleanup_on_failure.rb +76 -0
- data/lib/vagrant-libvirt/action/create_domain.rb +56 -10
- data/lib/vagrant-libvirt/action/create_network_interfaces.rb +5 -1
- data/lib/vagrant-libvirt/action/create_networks.rb +24 -0
- data/lib/vagrant-libvirt/action/destroy_domain.rb +106 -21
- data/lib/vagrant-libvirt/action/destroy_networks.rb +1 -1
- data/lib/vagrant-libvirt/action/forward_ports.rb +12 -11
- data/lib/vagrant-libvirt/action/prepare_nfs_settings.rb +1 -1
- data/lib/vagrant-libvirt/action/start_domain.rb +36 -0
- data/lib/vagrant-libvirt/action/wait_till_up.rb +6 -32
- data/lib/vagrant-libvirt/action.rb +72 -83
- data/lib/vagrant-libvirt/config.rb +85 -30
- data/lib/vagrant-libvirt/driver.rb +11 -9
- data/lib/vagrant-libvirt/errors.rb +12 -0
- data/lib/vagrant-libvirt/templates/domain.xml.erb +228 -218
- data/lib/vagrant-libvirt/templates/private_network.xml.erb +4 -1
- data/lib/vagrant-libvirt/util/network_util.rb +15 -3
- data/lib/vagrant-libvirt/util/nfs.rb +2 -0
- data/lib/vagrant-libvirt/util/resolvers.rb +80 -0
- data/lib/vagrant-libvirt/version +1 -1
- data/locales/en.yml +17 -0
- data/spec/spec_helper.rb +36 -23
- data/spec/support/libvirt_context.rb +7 -4
- data/spec/support/sharedcontext.rb +1 -1
- data/spec/unit/action/cleanup_on_failure_spec.rb +131 -0
- data/spec/unit/action/create_domain_spec/additional_disks_domain.xml +6 -18
- data/spec/unit/action/create_domain_spec/custom_disk_settings.xml +43 -0
- data/spec/unit/action/create_domain_spec/default_domain.xml +6 -18
- data/spec/unit/action/create_domain_spec/two_disk_settings.xml +49 -0
- data/spec/unit/action/create_domain_spec.rb +51 -7
- data/spec/unit/action/create_domain_volume_spec.rb +5 -3
- data/spec/unit/action/destroy_domain_spec/additional_disks_domain.xml +47 -0
- data/spec/unit/action/destroy_domain_spec/box_multiple_disks.xml +55 -0
- data/spec/unit/action/destroy_domain_spec/box_multiple_disks_and_additional_and_custom_disks.xml +72 -0
- data/spec/unit/action/destroy_domain_spec/box_multiple_disks_and_additional_and_custom_disks_no_aliases.xml +67 -0
- data/spec/unit/action/destroy_domain_spec/box_multiple_disks_and_additional_disks.xml +67 -0
- data/spec/unit/action/destroy_domain_spec/cdrom_domain.xml +48 -0
- data/spec/unit/action/destroy_domain_spec.rb +134 -30
- data/spec/unit/action/forward_ports_spec.rb +10 -2
- data/spec/unit/action/prepare_nfs_settings_spec.rb +59 -0
- data/spec/unit/action/shutdown_domain_spec.rb +1 -1
- data/spec/unit/action/start_domain_spec/clock_timer_rtc.xml +6 -18
- data/spec/unit/action/start_domain_spec/default.xml +6 -18
- data/spec/unit/action/start_domain_spec/default_added_tpm_path.xml +6 -18
- data/spec/unit/action/start_domain_spec/default_added_tpm_version.xml +6 -18
- data/spec/unit/action/start_domain_spec/existing.xml +1 -1
- data/spec/unit/action/wait_till_up_spec.rb +4 -43
- data/spec/unit/action_spec.rb +2 -0
- data/spec/unit/config_spec.rb +133 -26
- data/spec/unit/driver_spec.rb +154 -10
- data/spec/unit/templates/domain_all_settings.xml +56 -77
- data/spec/unit/templates/domain_cpu_mode_passthrough.xml +39 -0
- data/spec/unit/templates/domain_custom_cpu_model.xml +6 -18
- data/spec/unit/templates/domain_defaults.xml +6 -18
- data/spec/unit/templates/domain_spec.rb +39 -13
- data/spec/unit/templates/tpm/version_1.2.xml +6 -18
- data/spec/unit/templates/tpm/version_2.0.xml +6 -18
- data/spec/unit/util/resolvers_spec.rb +116 -0
- metadata +40 -41
@@ -4,15 +4,8 @@ require 'cgi'
|
|
4
4
|
|
5
5
|
require 'vagrant'
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
def vdev
|
10
|
-
s = String.new
|
11
|
-
q = self
|
12
|
-
(q, r = (q - 1).divmod(26)) && s.prepend(Alphabet[r]) until q.zero?
|
13
|
-
"vd#{s}"
|
14
|
-
end
|
15
|
-
end
|
7
|
+
require 'vagrant-libvirt/errors'
|
8
|
+
require 'vagrant-libvirt/util/resolvers'
|
16
9
|
|
17
10
|
module VagrantPlugins
|
18
11
|
module ProviderLibvirt
|
@@ -69,6 +62,7 @@ module VagrantPlugins
|
|
69
62
|
attr_accessor :management_network_pci_slot
|
70
63
|
attr_accessor :management_network_domain
|
71
64
|
attr_accessor :management_network_mtu
|
65
|
+
attr_accessor :management_network_keep
|
72
66
|
|
73
67
|
# System connection information
|
74
68
|
attr_accessor :system_uri
|
@@ -119,8 +113,10 @@ module VagrantPlugins
|
|
119
113
|
attr_accessor :graphics_port
|
120
114
|
attr_accessor :graphics_passwd
|
121
115
|
attr_accessor :graphics_ip
|
116
|
+
attr_accessor :graphics_gl
|
122
117
|
attr_accessor :video_type
|
123
118
|
attr_accessor :video_vram
|
119
|
+
attr_accessor :video_accel3d
|
124
120
|
attr_accessor :keymap
|
125
121
|
attr_accessor :kvm_hidden
|
126
122
|
attr_accessor :sound_type
|
@@ -196,6 +192,9 @@ module VagrantPlugins
|
|
196
192
|
# Use QEMU Agent to get ip address
|
197
193
|
attr_accessor :qemu_use_agent
|
198
194
|
|
195
|
+
# serial consoles
|
196
|
+
attr_accessor :serials
|
197
|
+
|
199
198
|
def initialize
|
200
199
|
@uri = UNSET_VALUE
|
201
200
|
@driver = UNSET_VALUE
|
@@ -222,6 +221,7 @@ module VagrantPlugins
|
|
222
221
|
@management_network_pci_bus = UNSET_VALUE
|
223
222
|
@management_network_domain = UNSET_VALUE
|
224
223
|
@management_network_mtu = UNSET_VALUE
|
224
|
+
@management_network_keep = UNSET_VALUE
|
225
225
|
|
226
226
|
# System connection information
|
227
227
|
@system_uri = UNSET_VALUE
|
@@ -267,8 +267,10 @@ module VagrantPlugins
|
|
267
267
|
@graphics_port = UNSET_VALUE
|
268
268
|
@graphics_ip = UNSET_VALUE
|
269
269
|
@graphics_passwd = UNSET_VALUE
|
270
|
+
@graphics_gl = UNSET_VALUE
|
270
271
|
@video_type = UNSET_VALUE
|
271
272
|
@video_vram = UNSET_VALUE
|
273
|
+
@video_accel3d = UNSET_VALUE
|
272
274
|
@sound_type = UNSET_VALUE
|
273
275
|
@keymap = UNSET_VALUE
|
274
276
|
@kvm_hidden = UNSET_VALUE
|
@@ -338,23 +340,14 @@ module VagrantPlugins
|
|
338
340
|
|
339
341
|
# Use Qemu agent to get ip address
|
340
342
|
@qemu_use_agent = UNSET_VALUE
|
343
|
+
|
344
|
+
@serials = UNSET_VALUE
|
341
345
|
end
|
342
346
|
|
343
347
|
def boot(device)
|
344
348
|
@boot_order << device # append
|
345
349
|
end
|
346
350
|
|
347
|
-
def _get_device(disks)
|
348
|
-
# skip existing devices and also the first one (vda)
|
349
|
-
exist = disks.collect { |x| x[:device] } + [1.vdev.to_s]
|
350
|
-
skip = 1 # we're 1 based, not 0 based...
|
351
|
-
loop do
|
352
|
-
dev = skip.vdev # get lettered device
|
353
|
-
return dev unless exist.include?(dev)
|
354
|
-
skip += 1
|
355
|
-
end
|
356
|
-
end
|
357
|
-
|
358
351
|
def _get_cdrom_dev(cdroms)
|
359
352
|
exist = Hash[cdroms.collect { |x| [x[:dev], true] }]
|
360
353
|
# hda - hdc
|
@@ -507,7 +500,9 @@ module VagrantPlugins
|
|
507
500
|
target_address: options[:target_address],
|
508
501
|
target_name: options[:target_name],
|
509
502
|
target_port: options[:target_port],
|
510
|
-
target_type: options[:target_type]
|
503
|
+
target_type: options[:target_type],
|
504
|
+
disabled: options[:disabled],
|
505
|
+
)
|
511
506
|
end
|
512
507
|
|
513
508
|
def random(options = {})
|
@@ -705,6 +700,22 @@ module VagrantPlugins
|
|
705
700
|
@qemu_env.merge!(options)
|
706
701
|
end
|
707
702
|
|
703
|
+
def serial(options={})
|
704
|
+
@serials = [] if @serials == UNSET_VALUE
|
705
|
+
|
706
|
+
options = {
|
707
|
+
:type => "pty",
|
708
|
+
:source => nil,
|
709
|
+
}.merge(options)
|
710
|
+
|
711
|
+
serial = {
|
712
|
+
:type => options[:type],
|
713
|
+
:source => options[:source],
|
714
|
+
}
|
715
|
+
|
716
|
+
@serials << serial
|
717
|
+
end
|
718
|
+
|
708
719
|
def _default_uri
|
709
720
|
# Determine if any settings except driver provided explicitly, if not
|
710
721
|
# and the LIBVIRT_DEFAULT_URI var is set, use that.
|
@@ -817,7 +828,7 @@ module VagrantPlugins
|
|
817
828
|
@management_network_pci_slot = nil if @management_network_pci_slot == UNSET_VALUE
|
818
829
|
@management_network_domain = nil if @management_network_domain == UNSET_VALUE
|
819
830
|
@management_network_mtu = nil if @management_network_mtu == UNSET_VALUE
|
820
|
-
@
|
831
|
+
@management_network_keep = false if @management_network_keep == UNSET_VALUE
|
821
832
|
|
822
833
|
# Domain specific settings.
|
823
834
|
@title = '' if @title == UNSET_VALUE
|
@@ -870,7 +881,9 @@ module VagrantPlugins
|
|
870
881
|
@graphics_port = -1 if @graphics_port == UNSET_VALUE
|
871
882
|
@graphics_ip = '127.0.0.1' if @graphics_ip == UNSET_VALUE
|
872
883
|
@video_type = 'cirrus' if @video_type == UNSET_VALUE
|
873
|
-
@video_vram =
|
884
|
+
@video_vram = 16384 if @video_vram == UNSET_VALUE
|
885
|
+
@video_accel3d = false if @video_accel3d == UNSET_VALUE
|
886
|
+
@graphics_gl = @video_accel3d if @graphics_gl == UNSET_VALUE
|
874
887
|
@sound_type = nil if @sound_type == UNSET_VALUE
|
875
888
|
@keymap = 'en-us' if @keymap == UNSET_VALUE
|
876
889
|
@kvm_hidden = false if @kvm_hidden == UNSET_VALUE
|
@@ -890,10 +903,6 @@ module VagrantPlugins
|
|
890
903
|
|
891
904
|
# Storage
|
892
905
|
@disks = [] if @disks == UNSET_VALUE
|
893
|
-
@disks.map! do |disk|
|
894
|
-
disk[:device] = _get_device(@disks) if disk[:device].nil?
|
895
|
-
disk
|
896
|
-
end
|
897
906
|
@cdroms = [] if @cdroms == UNSET_VALUE
|
898
907
|
@cdroms.map! do |cdrom|
|
899
908
|
cdrom[:dev] = _get_cdrom_dev(@cdroms) if cdrom[:dev].nil?
|
@@ -904,7 +913,18 @@ module VagrantPlugins
|
|
904
913
|
@inputs = [{ type: 'mouse', bus: 'ps2' }] if @inputs == UNSET_VALUE
|
905
914
|
|
906
915
|
# Channels
|
907
|
-
|
916
|
+
if @channels == UNSET_VALUE
|
917
|
+
@channels = []
|
918
|
+
if @qemu_use_agent == true
|
919
|
+
if @channels.all? { |channel| !channel.fetch(:target_name, '').start_with?('org.qemu.guest_agent.') }
|
920
|
+
channel(:type => 'unix', :target_name => 'org.qemu.guest_agent.0', :target_type => 'virtio')
|
921
|
+
end
|
922
|
+
end
|
923
|
+
end
|
924
|
+
|
925
|
+
# filter channels of anything explicitly disabled so it's possible to inject an entry to
|
926
|
+
# avoid the automatic addition of the guest_agent above, and disable it from subsequent use.
|
927
|
+
@channels = @channels.reject { |channel| channel[:disabled] }.tap {|channel| channel.delete(:disabled) }
|
908
928
|
|
909
929
|
# PCI device passthrough
|
910
930
|
@pcis = [] if @pcis == UNSET_VALUE
|
@@ -945,12 +965,19 @@ module VagrantPlugins
|
|
945
965
|
# Additional QEMU commandline environment variables
|
946
966
|
@qemu_env = {} if @qemu_env == UNSET_VALUE
|
947
967
|
|
948
|
-
@qemu_use_agent =
|
968
|
+
@qemu_use_agent = false if @qemu_use_agent == UNSET_VALUE
|
969
|
+
|
970
|
+
@serials = [{:type => 'pty', :source => nil}] if @serials == UNSET_VALUE
|
949
971
|
end
|
950
972
|
|
951
973
|
def validate(machine)
|
952
974
|
errors = _detected_errors
|
953
975
|
|
976
|
+
# technically this shouldn't occur, but ensure that if somehow it does, it gets rejected.
|
977
|
+
if @cpu_mode == 'host-passthrough' && @cpu_model != ''
|
978
|
+
errors << "cannot set cpu_model with cpu_mode of 'host-passthrough'. leave model unset or switch mode."
|
979
|
+
end
|
980
|
+
|
954
981
|
# The @uri and @qemu_use_session should not conflict
|
955
982
|
uri = _parse_uri(@uri)
|
956
983
|
if (uri.scheme.start_with? "qemu") && (uri.path.include? "session")
|
@@ -959,6 +986,9 @@ module VagrantPlugins
|
|
959
986
|
end
|
960
987
|
end
|
961
988
|
|
989
|
+
unless @qemu_use_agent == true || @qemu_use_agent == false
|
990
|
+
errors << "libvirt.qemu_use_agent must be a boolean."
|
991
|
+
end
|
962
992
|
|
963
993
|
if @qemu_use_agent == true
|
964
994
|
# if qemu agent is used to optain domain ip configuration, at least
|
@@ -969,13 +999,28 @@ module VagrantPlugins
|
|
969
999
|
end
|
970
1000
|
end
|
971
1001
|
|
972
|
-
|
973
1002
|
machine.provider_config.disks.each do |disk|
|
974
1003
|
if disk[:path] && (disk[:path][0] == '/')
|
975
1004
|
errors << "absolute volume paths like '#{disk[:path]}' not yet supported"
|
976
1005
|
end
|
977
1006
|
end
|
978
1007
|
|
1008
|
+
machine.provider_config.serials.each do |serial|
|
1009
|
+
if serial[:source] and serial[:source][:path].nil?
|
1010
|
+
errors << "serial :source requires :path to be defined"
|
1011
|
+
end
|
1012
|
+
end
|
1013
|
+
|
1014
|
+
# this won't be able to fully resolve the disks until the box has
|
1015
|
+
# been downloaded and any devices that need to be assigned to the
|
1016
|
+
# disks contained have been allocated
|
1017
|
+
disk_resolver = ::VagrantPlugins::ProviderLibvirt::Util::DiskDeviceResolver.new
|
1018
|
+
begin
|
1019
|
+
disk_resolver.resolve(machine.provider_config.disks)
|
1020
|
+
rescue Errors::VagrantLibvirtError => e
|
1021
|
+
errors << "#{e}"
|
1022
|
+
end
|
1023
|
+
|
979
1024
|
machine.config.vm.networks.each do |_type, opts|
|
980
1025
|
if opts[:mac]
|
981
1026
|
if opts[:mac] =~ /\A([0-9a-fA-F]{12})\z/
|
@@ -1017,6 +1062,12 @@ module VagrantPlugins
|
|
1017
1062
|
c = qemu_env != UNSET_VALUE ? qemu_env.dup : {}
|
1018
1063
|
c.merge!(other.qemu_env) if other.qemu_env != UNSET_VALUE
|
1019
1064
|
result.qemu_env = c
|
1065
|
+
|
1066
|
+
if serials != UNSET_VALUE
|
1067
|
+
s = serials.dup
|
1068
|
+
s += other.serials
|
1069
|
+
result.serials = s
|
1070
|
+
end
|
1020
1071
|
end
|
1021
1072
|
end
|
1022
1073
|
|
@@ -1026,6 +1077,10 @@ module VagrantPlugins
|
|
1026
1077
|
# Parse uri to extract individual components
|
1027
1078
|
uri = _parse_uri(@uri)
|
1028
1079
|
|
1080
|
+
system_uri = uri.dup
|
1081
|
+
system_uri.path = '/system'
|
1082
|
+
@system_uri = system_uri.to_s if @system_uri == UNSET_VALUE
|
1083
|
+
|
1029
1084
|
# only set @connect_via_ssh if not explicitly to avoid overriding
|
1030
1085
|
# and allow an error to occur if the @uri and @connect_via_ssh disagree
|
1031
1086
|
@connect_via_ssh = uri.scheme.include? "ssh" if @connect_via_ssh == UNSET_VALUE
|
@@ -61,7 +61,7 @@ module VagrantPlugins
|
|
61
61
|
|
62
62
|
config = @machine.provider_config
|
63
63
|
|
64
|
-
@system_connection = Libvirt::
|
64
|
+
@system_connection = Libvirt::open_read_only(config.system_uri)
|
65
65
|
@system_connection
|
66
66
|
end
|
67
67
|
|
@@ -98,16 +98,16 @@ module VagrantPlugins
|
|
98
98
|
end
|
99
99
|
|
100
100
|
def get_domain_ipaddress(machine, domain)
|
101
|
-
if @machine.provider_config.qemu_use_session
|
102
|
-
return get_ipaddress_from_system domain.mac
|
103
|
-
end
|
104
|
-
|
105
101
|
# attempt to get ip address from qemu agent
|
106
102
|
if @machine.provider_config.qemu_use_agent == true
|
107
103
|
@logger.info('Get IP via qemu agent')
|
108
104
|
return get_ipaddress_from_qemu_agent(domain, machine.id)
|
109
105
|
end
|
110
106
|
|
107
|
+
if @machine.provider_config.qemu_use_session
|
108
|
+
return get_ipaddress_from_system domain.mac
|
109
|
+
end
|
110
|
+
|
111
111
|
# Get IP address from dhcp leases table
|
112
112
|
begin
|
113
113
|
ip_address = get_ipaddress_from_domain(domain)
|
@@ -135,7 +135,9 @@ module VagrantPlugins
|
|
135
135
|
end
|
136
136
|
|
137
137
|
# TODO: terminated no longer appears to be a valid fog state, remove?
|
138
|
-
return :not_created if domain.nil?
|
138
|
+
return :not_created if domain.nil?
|
139
|
+
return :unknown if domain.state.nil?
|
140
|
+
return :not_created if domain.state.to_sym == :terminated
|
139
141
|
|
140
142
|
state = domain.state.tr('-', '_').to_sym
|
141
143
|
if state == :running
|
@@ -168,9 +170,9 @@ module VagrantPlugins
|
|
168
170
|
def get_ipaddress_from_qemu_agent(domain, machine_id)
|
169
171
|
ip_address = nil
|
170
172
|
addresses = nil
|
171
|
-
|
173
|
+
libvirt_domain = connection.client.lookup_domain_by_uuid(machine_id)
|
172
174
|
begin
|
173
|
-
response =
|
175
|
+
response = libvirt_domain.qemu_agent_command('{"execute":"guest-network-get-interfaces"}', timeout=10)
|
174
176
|
@logger.debug("Got Response from qemu agent")
|
175
177
|
@logger.debug(response)
|
176
178
|
addresses = JSON.parse(response)
|
@@ -180,7 +182,7 @@ module VagrantPlugins
|
|
180
182
|
|
181
183
|
unless addresses.nil?
|
182
184
|
addresses["return"].each{ |interface|
|
183
|
-
if domain.mac == interface["hardware-address"]
|
185
|
+
if domain.mac.downcase == interface["hardware-address"].downcase
|
184
186
|
@logger.debug("Found mathing interface: [%s]" % interface["name"])
|
185
187
|
if interface.has_key?("ip-addresses")
|
186
188
|
interface["ip-addresses"].each{ |ip|
|
@@ -18,6 +18,14 @@ module VagrantPlugins
|
|
18
18
|
error_key(:package_not_supported)
|
19
19
|
end
|
20
20
|
|
21
|
+
class DuplicateDiskDevice < VagrantLibvirtError
|
22
|
+
error_key(:duplicate_disk_device)
|
23
|
+
end
|
24
|
+
|
25
|
+
class NoDiskDeviceAvailable < VagrantLibvirtError
|
26
|
+
error_key(:no_disk_device_available)
|
27
|
+
end
|
28
|
+
|
21
29
|
# Storage pools and volumes exceptions
|
22
30
|
class NoStoragePool < VagrantLibvirtError
|
23
31
|
error_key(:no_storage_pool)
|
@@ -181,6 +189,10 @@ module VagrantPlugins
|
|
181
189
|
class DeleteSnapshotError < VagrantLibvirtError
|
182
190
|
error_key(:delete_snapshot_error)
|
183
191
|
end
|
192
|
+
|
193
|
+
class SerialCannotCreatePathError < VagrantLibvirtError
|
194
|
+
error_key(:serial_cannot_create_path_error)
|
195
|
+
end
|
184
196
|
end
|
185
197
|
end
|
186
198
|
end
|