vagrant-libvirt 0.8.2 → 0.9.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 (40) hide show
  1. checksums.yaml +4 -4
  2. data/lib/vagrant-libvirt/action/create_domain.rb +19 -91
  3. data/lib/vagrant-libvirt/action/destroy_domain.rb +20 -4
  4. data/lib/vagrant-libvirt/action/destroy_networks.rb +1 -1
  5. data/lib/vagrant-libvirt/action/handle_box_image.rb +2 -0
  6. data/lib/vagrant-libvirt/action/resolve_disk_settings.rb +174 -0
  7. data/lib/vagrant-libvirt/action/start_domain.rb +41 -1
  8. data/lib/vagrant-libvirt/action.rb +4 -0
  9. data/lib/vagrant-libvirt/config.rb +4 -0
  10. data/lib/vagrant-libvirt/templates/domain.xml.erb +2 -2
  11. data/lib/vagrant-libvirt/util/domain_flags.rb +15 -0
  12. data/lib/vagrant-libvirt/util.rb +1 -0
  13. data/lib/vagrant-libvirt/version +1 -1
  14. data/locales/en.yml +4 -2
  15. data/spec/support/libvirt_context.rb +4 -0
  16. data/spec/unit/action/cleanup_on_failure_spec.rb +0 -2
  17. data/spec/unit/action/create_domain_spec.rb +113 -147
  18. data/spec/unit/action/create_domain_volume_spec.rb +0 -3
  19. data/spec/unit/action/destroy_domain_spec.rb +43 -10
  20. data/spec/unit/action/handle_box_image_spec.rb +13 -13
  21. data/spec/unit/action/package_domain_spec.rb +0 -5
  22. data/spec/unit/action/resolve_disk_settings_spec/default_domain.xml +43 -0
  23. data/spec/unit/action/resolve_disk_settings_spec/default_no_aliases.xml +42 -0
  24. data/spec/unit/action/{create_domain_spec → resolve_disk_settings_spec}/default_system_storage_pool.xml +0 -0
  25. data/spec/unit/action/resolve_disk_settings_spec/multi_volume_box.xml +55 -0
  26. data/spec/unit/action/resolve_disk_settings_spec/multi_volume_box_additional_and_custom_no_aliases.xml +67 -0
  27. data/spec/unit/action/resolve_disk_settings_spec/multi_volume_box_additional_storage.xml +67 -0
  28. data/spec/unit/action/resolve_disk_settings_spec.rb +361 -0
  29. data/spec/unit/action/start_domain_spec/existing_added_nvram.xml +62 -0
  30. data/spec/unit/action/start_domain_spec/nvram_domain.xml +64 -0
  31. data/spec/unit/action/start_domain_spec/nvram_domain_other_setting.xml +64 -0
  32. data/spec/unit/action/start_domain_spec/nvram_domain_removed.xml +64 -0
  33. data/spec/unit/action/start_domain_spec.rb +64 -6
  34. data/spec/unit/action/wait_till_up_spec.rb +0 -2
  35. data/spec/unit/action_spec.rb +0 -3
  36. data/spec/unit/config_spec.rb +18 -0
  37. data/spec/unit/driver_spec.rb +2 -0
  38. data/spec/unit/templates/domain_all_settings.xml +2 -2
  39. data/spec/unit/templates/domain_spec.rb +2 -2
  40. metadata +37 -15
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c7f252cbd53f8459e02a21e94449e6fef1ce762f1d053433970015fad9d00fef
4
- data.tar.gz: 54af8a7a564e8ffdd0f18d3d3eca44367ac7613fb4892af995c5d202d8e429ea
3
+ metadata.gz: 79027c1097a7e8136b8d56f74fd0b27932bf17c48387de84c57626c2bd348714
4
+ data.tar.gz: cd6acea3cf183191ea6bbee6e60d7a1fc76a5f0b556f273f60657238283841ce
5
5
  SHA512:
6
- metadata.gz: 00c708fba6fb82cec02b0b68730da87975964584b8b189bfcd77857b3b386ff81609bd135423872dcd04cd7e071f10f1cf7806d97b28565ed27464d2b2021857
7
- data.tar.gz: abbbe10ad322fec1a49b9f3463fa7a50c9e46bce93c8c6aa505ca3c4fbd5e6a3b4bfa248e912d0608e5aefdd3427ce819e6bff9f0807da187a187c2e9085d13e
6
+ metadata.gz: 6d6483a73ce398e6fd057b2fc0503392c628ad1fc228d9d954b9a5e31d9a65ab883c25f30cb9360ce5eff46554492dd010b68d741f3c8935e64228207bf2f210
7
+ data.tar.gz: 1a083a93899bb48d4d750aa8967bdcb8e6b1b0b9a8fb0d88c912097444cd202c52fe0330f81a1e4803dde184b06e035c8bd8d32397035c186653b978db790e12
@@ -16,20 +16,6 @@ module VagrantPlugins
16
16
  @app = app
17
17
  end
18
18
 
19
- def _disk_name(name, disk)
20
- "#{name}-#{disk[:device]}.#{disk[:type]}" # disk name
21
- end
22
-
23
- def _disks_print(disks)
24
- disks.collect do |x|
25
- "#{x[:device]}(#{x[:type]}, #{x[:bus]}, #{x[:size]})"
26
- end.join(', ')
27
- end
28
-
29
- def _cdroms_print(cdroms)
30
- cdroms.collect { |x| x[:dev] }.join(', ')
31
- end
32
-
33
19
  def call(env)
34
20
  # Get config.
35
21
  config = env[:machine].provider_config
@@ -58,8 +44,6 @@ module VagrantPlugins
58
44
  @nvram = config.nvram
59
45
  @machine_type = config.machine_type
60
46
  @machine_arch = config.machine_arch
61
- @disk_bus = config.disk_bus
62
- @disk_device = config.disk_device
63
47
  @disk_driver_opts = config.disk_driver_opts
64
48
  @nested = config.nested
65
49
  @memory_size = config.memory.to_i * 1024
@@ -94,9 +78,8 @@ module VagrantPlugins
94
78
 
95
79
  # Storage
96
80
  @storage_pool_name = config.storage_pool_name
97
- @snapshot_pool_name = config.snapshot_pool_name
98
- @domain_volumes = []
99
- @disks = config.disks
81
+ @domain_volumes = env[:domain_volumes] || []
82
+ @disks = env[:disks] || []
100
83
  @cdroms = config.cdroms
101
84
 
102
85
  # Input
@@ -139,77 +122,19 @@ module VagrantPlugins
139
122
  @memballoon_pci_bus = config.memballoon_pci_bus
140
123
  @memballoon_pci_slot = config.memballoon_pci_slot
141
124
 
142
- config = env[:machine].provider_config
143
125
  @domain_type = config.driver
144
126
 
145
127
  @os_type = 'hvm'
146
128
 
147
- resolver = ::VagrantPlugins::ProviderLibvirt::Util::DiskDeviceResolver.new(prefix=@disk_device[0..1])
148
-
149
- # Get path to domain image from the storage pool selected if we have a box.
150
- if env[:machine].config.vm.box
151
- if @snapshot_pool_name != @storage_pool_name
152
- pool_name = @snapshot_pool_name
153
- else
154
- pool_name = @storage_pool_name
155
- end
156
-
157
- # special handling for domain volume
158
- env[:box_volumes][0][:device] = env[:box_volumes][0].fetch(:device, @disk_device)
159
-
160
- resolver.resolve!(env[:box_volumes])
161
-
162
- @logger.debug "Search for volumes in pool: #{pool_name}"
163
- env[:box_volumes].each_index do |index|
164
- suffix_index = index > 0 ? "_#{index}" : ''
165
- domain_volume = env[:machine].provider.driver.connection.volumes.all(
166
- name: "#{@name}#{suffix_index}.img"
167
- ).find { |x| x.pool_name == pool_name }
168
- raise Errors::DomainVolumeExists if domain_volume.nil?
169
-
170
- @domain_volumes.push({
171
- :dev => env[:box_volumes][index][:device],
172
- :cache => @domain_volume_cache,
173
- :bus => @disk_bus,
174
- :path => domain_volume.path,
175
- :virtual_size => env[:box_volumes][index][:virtual_size]
176
- })
177
- end
178
-
129
+ env[:domain_volumes].each_with_index do |vol, index|
130
+ suffix_index = index > 0 ? "_#{index}" : ''
131
+ domain_volume = env[:machine].provider.driver.connection.volumes.all(
132
+ name: "#{@name}#{suffix_index}.img"
133
+ ).find { |x| x.pool_name == vol[:pool] }
134
+ raise Errors::NoDomainVolume if domain_volume.nil?
179
135
  end
180
136
 
181
- # If we have a box, take the path from the domain volume and set our storage_prefix.
182
- # If not, we dump the storage pool xml to get its defined path.
183
- # the default storage prefix is typically: /var/lib/libvirt/images/
184
- if env[:machine].config.vm.box
185
- storage_prefix = File.dirname(@domain_volumes[0][:path]) + '/' # steal
186
- else
187
- storage_prefix = get_disk_storage_prefix(env, @storage_pool_name)
188
- end
189
-
190
- resolver.resolve!(@disks)
191
-
192
137
  @disks.each do |disk|
193
- disk[:path] ||= _disk_name(@name, disk)
194
-
195
- # On volume creation, the <path> element inside <target>
196
- # is oddly ignored; instead the path is taken from the
197
- # <name> element:
198
- # http://www.redhat.com/archives/libvir-list/2008-August/msg00329.html
199
- disk[:name] = disk[:path]
200
-
201
- disk[:absolute_path] = storage_prefix + disk[:path]
202
-
203
- if not disk[:pool].nil?
204
- disk_pool_name = disk[:pool]
205
- @logger.debug "Overriding pool name with: #{disk_pool_name}"
206
- disk_storage_prefix = get_disk_storage_prefix(env, disk_pool_name)
207
- disk[:absolute_path] = disk_storage_prefix + disk[:path]
208
- @logger.debug "Overriding disk path with: #{disk[:absolute_path]}"
209
- else
210
- disk_pool_name = @storage_pool_name
211
- end
212
-
213
138
  # make the disk. equivalent to:
214
139
  # qemu-img create -f qcow2 <path> 5g
215
140
  begin
@@ -221,13 +146,13 @@ module VagrantPlugins
221
146
  owner: storage_uid(env),
222
147
  group: storage_gid(env),
223
148
  #:allocation => ?,
224
- pool_name: disk_pool_name
149
+ pool_name: disk[:pool],
225
150
  )
226
151
  rescue Libvirt::Error => e
227
152
  # It is hard to believe that e contains just a string
228
153
  # and no useful error code!
229
154
  msg = "Call to virStorageVolCreateXML failed: " +
230
- "storage volume '#{disk[:path]}' exists already"
155
+ "storage volume '#{disk[:absolute_path]}' exists already"
231
156
  if e.message == msg and disk[:allow_existing]
232
157
  disk[:preexisting] = true
233
158
  else
@@ -300,7 +225,7 @@ module VagrantPlugins
300
225
  end
301
226
  env[:ui].info(" -- Storage pool: #{@storage_pool_name}")
302
227
  @domain_volumes.each do |volume|
303
- env[:ui].info(" -- Image(#{volume[:dev]}): #{volume[:path]}, #{volume[:bus]}, #{volume[:virtual_size].to_GB}G")
228
+ env[:ui].info(" -- Image(#{volume[:device]}): #{volume[:absolute_path]}, #{volume[:bus]}, #{volume[:virtual_size].to_GB}G")
304
229
  end
305
230
 
306
231
  if not @disk_driver_opts.empty?
@@ -466,11 +391,14 @@ module VagrantPlugins
466
391
  end
467
392
 
468
393
  private
469
- def get_disk_storage_prefix(env, disk_pool_name)
470
- disk_storage_pool = env[:machine].provider.driver.connection.client.lookup_storage_pool_by_name(disk_pool_name)
471
- raise Errors::NoStoragePool if disk_storage_pool.nil?
472
- xml = Nokogiri::XML(disk_storage_pool.xml_desc)
473
- disk_storage_prefix = xml.xpath('/pool/target/path').inner_text.to_s + '/'
394
+ def _disks_print(disks)
395
+ disks.collect do |x|
396
+ "#{x[:device]}(#{x[:type]}, #{x[:bus]}, #{x[:size]})"
397
+ end.join(', ')
398
+ end
399
+
400
+ def _cdroms_print(cdroms)
401
+ cdroms.collect { |x| x[:dev] }.join(', ')
474
402
  end
475
403
  end
476
404
  end
@@ -1,7 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'log4r'
4
- require 'rexml'
4
+
5
+ begin
6
+ require 'rexml'
7
+ rescue LoadError
8
+ require 'rexml/rexml'
9
+ end
5
10
 
6
11
  module VagrantPlugins
7
12
  module ProviderLibvirt
@@ -43,21 +48,24 @@ module VagrantPlugins
43
48
 
44
49
  domain = env[:machine].provider.driver.connection.servers.get(env[:machine].id.to_s)
45
50
 
51
+ undefine_flags = 0
52
+ undefine_flags |= ProviderLibvirt::Util::DomainFlags::VIR_DOMAIN_UNDEFINE_KEEP_NVRAM if env[:machine].provider_config.nvram
53
+
46
54
  if env[:machine].provider_config.disks.empty? &&
47
55
  env[:machine].provider_config.cdroms.empty?
48
56
  # if using default configuration of disks and cdroms
49
57
  # cdroms are consider volumes, but cannot be destroyed
50
- domain.destroy(destroy_volumes: true)
58
+ destroy_domain(domain, destroy_volumes: true, flags: undefine_flags)
51
59
  else
52
60
  domain_xml = libvirt_domain.xml_desc(1)
53
61
  xml_descr = REXML::Document.new(domain_xml)
54
62
  disks_xml = REXML::XPath.match(xml_descr, '/domain/devices/disk[@device="disk"]')
55
63
  have_aliases = !(REXML::XPath.match(disks_xml, './alias[@name="ua-box-volume-0"]').first).nil?
56
64
  if !have_aliases
57
- env[:ui].warn(I18n.t('vagrant_libvirt.destroy.obsolete_method'))
65
+ env[:ui].warn(I18n.t('vagrant_libvirt.domain_xml.obsolete_method'))
58
66
  end
59
67
 
60
- domain.destroy(destroy_volumes: false)
68
+ destroy_domain(domain, destroy_volumes: false, flags: undefine_flags)
61
69
 
62
70
  volumes = domain.volumes
63
71
 
@@ -164,6 +172,14 @@ module VagrantPlugins
164
172
  libvirt_disk.destroy if libvirt_disk
165
173
  end
166
174
  end
175
+
176
+ def destroy_domain(domain, destroy_volumes:, flags:)
177
+ if domain.method(:destroy).parameters.first.include?(:flags)
178
+ domain.destroy(destroy_volumes: destroy_volumes, flags: flags)
179
+ else
180
+ domain.destroy(destroy_volumes: destroy_volumes)
181
+ end
182
+ end
167
183
  end
168
184
  end
169
185
  end
@@ -68,7 +68,7 @@ module VagrantPlugins
68
68
  # Shutdown network first.
69
69
  # Undefine network.
70
70
  begin
71
- libvirt_network.destroy
71
+ libvirt_network.destroy if libvirt_network.active?
72
72
  libvirt_network.undefine
73
73
  @logger.info 'Undefined it'
74
74
  rescue => e
@@ -104,6 +104,8 @@ module VagrantPlugins
104
104
  end
105
105
  # save for use by later actions
106
106
  env[:box_volumes][0][:virtual_size] = box_virtual_size
107
+ # special handling for domain volume
108
+ env[:box_volumes][0][:device] ||= config.disk_device
107
109
 
108
110
  # while inside the synchronize block take care not to call the next
109
111
  # action in the chain, as must exit this block first to prevent
@@ -0,0 +1,174 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'log4r'
4
+ require 'rexml'
5
+
6
+ require 'vagrant-libvirt/util/resolvers'
7
+
8
+ module VagrantPlugins
9
+ module ProviderLibvirt
10
+ module Action
11
+ class ResolveDiskSettings
12
+ def initialize(app, _env)
13
+ @logger = Log4r::Logger.new('vagrant_libvirt::action::resolve_disk_devices')
14
+ @app = app
15
+ end
16
+
17
+ def call(env)
18
+ # Get config.
19
+ config = env[:machine].provider_config
20
+
21
+ domain_name = env[:domain_name] # only set on create
22
+ disk_bus = config.disk_bus
23
+ disk_device = config.disk_device
24
+ domain_volume_cache = config.volume_cache || 'default'
25
+
26
+ # Storage
27
+ storage_pool_name = config.storage_pool_name
28
+ snapshot_pool_name = config.snapshot_pool_name
29
+ domain_volumes = []
30
+ disks = config.disks.dup
31
+
32
+ resolver = ::VagrantPlugins::ProviderLibvirt::Util::DiskDeviceResolver.new(disk_device[0..1])
33
+
34
+ # Get path to domain image from the storage pool selected if we have a box.
35
+ if env[:machine].config.vm.box
36
+ pool_name = if snapshot_pool_name == storage_pool_name
37
+ storage_pool_name
38
+ else
39
+ snapshot_pool_name
40
+ end
41
+
42
+ if env[:box_volumes].nil?
43
+ # domain must be already created, need to read domain volumes from domain XML
44
+ libvirt_domain = env[:machine].provider.driver.connection.client.lookup_domain_by_uuid(
45
+ env[:machine].id
46
+ )
47
+ domain_xml = libvirt_domain.xml_desc(1)
48
+ xml_descr = REXML::Document.new(domain_xml)
49
+ domain_name = xml_descr.elements['domain'].elements['name'].text
50
+ disks_xml = REXML::XPath.match(xml_descr, '/domain/devices/disk[@device="disk"]')
51
+ have_aliases = !REXML::XPath.match(disks_xml, './alias[@name="ua-box-volume-0"]').first.nil?
52
+ env[:ui].warn(I18n.t('vagrant_libvirt.domain_xml.obsolete_method')) unless have_aliases
53
+
54
+ if have_aliases
55
+ REXML::XPath.match(disks_xml,
56
+ './alias[contains(@name, "ua-box-volume-")]').each_with_index do |alias_xml, idx|
57
+ domain_volumes.push(volume_from_xml(alias_xml.parent, domain_name, idx))
58
+ end
59
+ else
60
+ # fallback to try and infer which boxes are box images, as they are listed first
61
+ # as soon as there is no match, can exit
62
+ disks_xml.each_with_index do |box_disk_xml, idx|
63
+ diskname = box_disk_xml.elements['source'].attributes['file'].rpartition('/').last
64
+
65
+ break if volume_name(domain_name, idx) != diskname
66
+
67
+ domain_volumes.push(volume_from_xml(box_disk_xml, domain_name, idx))
68
+ end
69
+ end
70
+ else
71
+
72
+ @logger.debug "Search for volumes in pool: #{pool_name}"
73
+ env[:box_volumes].each_index do |index|
74
+ domain_volume = env[:machine].provider.driver.connection.volumes.all(
75
+ name: volume_name(domain_name, index)
76
+ ).find { |x| x.pool_name == pool_name }
77
+ raise Errors::NoDomainVolume if domain_volume.nil?
78
+
79
+ domain_volumes.push(
80
+ {
81
+ name: volume_name(domain_name, index),
82
+ device: env[:box_volumes][index][:device],
83
+ cache: domain_volume_cache,
84
+ bus: disk_bus,
85
+ absolute_path: domain_volume.path,
86
+ virtual_size: env[:box_volumes][index][:virtual_size],
87
+ pool: pool_name,
88
+ }
89
+ )
90
+ end
91
+ end
92
+
93
+ resolver.resolve!(domain_volumes)
94
+
95
+ # If we have a box, take the path from the domain volume and set our storage_prefix.
96
+ # If not, we dump the storage pool xml to get its defined path.
97
+ # the default storage prefix is typically: /var/lib/libvirt/images/
98
+ storage_prefix = "#{File.dirname(domain_volumes[0][:absolute_path])}/" # steal
99
+ else
100
+ # Ensure domain name is set for subsequent steps if restarting a machine without a box
101
+ libvirt_domain = env[:machine].provider.driver.connection.client.lookup_domain_by_uuid(
102
+ env[:machine].id
103
+ )
104
+ domain_xml = libvirt_domain.xml_desc(1)
105
+ xml_descr = REXML::Document.new(domain_xml)
106
+ domain_name = xml_descr.elements['domain'].elements['name'].text
107
+
108
+ storage_prefix = get_disk_storage_prefix(env[:machine], storage_pool_name)
109
+ end
110
+
111
+ resolver.resolve!(disks)
112
+
113
+ disks.each do |disk|
114
+ disk[:path] ||= disk_name(domain_name, disk)
115
+
116
+ # On volume creation, the <path> element inside <target>
117
+ # is oddly ignored; instead the path is taken from the
118
+ # <name> element:
119
+ # http://www.redhat.com/archives/libvir-list/2008-August/msg00329.html
120
+ disk[:name] = disk[:path]
121
+
122
+ disk[:absolute_path] = storage_prefix + disk[:path]
123
+
124
+ if disk[:pool].nil?
125
+ disk[:pool] = storage_pool_name
126
+ else
127
+ @logger.debug "Overriding pool name with: #{disk[:pool]}"
128
+ disk_storage_prefix = get_disk_storage_prefix(env[:machine], disk[:pool])
129
+ disk[:absolute_path] = disk_storage_prefix + disk[:path]
130
+ @logger.debug "Overriding disk path with: #{disk[:absolute_path]}"
131
+ end
132
+ end
133
+
134
+ env[:domain_volumes] = domain_volumes
135
+ env[:disks] = disks
136
+
137
+ @app.call(env)
138
+ end
139
+
140
+ private
141
+
142
+ def disk_name(name, disk)
143
+ "#{name}-#{disk[:device]}.#{disk[:type]}" # disk name
144
+ end
145
+
146
+ def get_disk_storage_prefix(machine, disk_pool_name)
147
+ disk_storage_pool = machine.provider.driver.connection.client.lookup_storage_pool_by_name(disk_pool_name)
148
+ raise Errors::NoStoragePool if disk_storage_pool.nil?
149
+
150
+ xml = Nokogiri::XML(disk_storage_pool.xml_desc)
151
+ "#{xml.xpath('/pool/target/path').inner_text}/"
152
+ end
153
+
154
+ def volume_name(domain_name, index)
155
+ domain_name + (index.zero? ? '.img' : "_#{index}.img")
156
+ end
157
+
158
+ def volume_from_xml(device_xml, domain_name, index)
159
+ driver = device_xml.elements['driver']
160
+ source = device_xml.elements['source']
161
+ target = device_xml.elements['target']
162
+
163
+ {
164
+ name: volume_name(domain_name, index),
165
+ device: target.attributes['dev'],
166
+ cache: driver.attributes['cache'],
167
+ bus: target.attributes['bus'],
168
+ absolute_path: source.attributes['file'],
169
+ }
170
+ end
171
+ end
172
+ end
173
+ end
174
+ end
@@ -375,10 +375,50 @@ module VagrantPlugins
375
375
  end
376
376
  end
377
377
 
378
+ loader = REXML::XPath.first(xml_descr, '/domain/os/loader')
379
+ if config.loader
380
+ if loader.nil?
381
+ descr_changed = true
382
+ loader = REXML::Element.new('loader')
383
+ REXML::XPath.first(xml_descr, '/domain/os').insert_after('//type', loader)
384
+ loader.text = config.loader
385
+ else
386
+ if (loader.text or '').strip != config.loader
387
+ descr_changed = true
388
+ loader.text = config.loader
389
+ end
390
+ end
391
+ loader.attributes['type'] = config.nvram ? 'pflash' : 'rom'
392
+ elsif !loader.nil?
393
+ descr_changed = true
394
+ loader.parent.delete_element(loader)
395
+ end
396
+
397
+ undefine_flags = 0
398
+ nvram = REXML::XPath.first(xml_descr, '/domain/os/nvram')
399
+ if config.nvram
400
+ if nvram.nil?
401
+ descr_changed = true
402
+ nvram = REXML::Element.new('nvram')
403
+ REXML::XPath.first(xml_descr, '/domain/os').insert_after(loader, nvram)
404
+ nvram.text = config.nvram
405
+ else
406
+ if (nvram.text or '').strip != config.nvram
407
+ descr_changed = true
408
+ nvram.text = config.nvram
409
+ end
410
+ undefine_flags |= ProviderLibvirt::Util::DomainFlags::VIR_DOMAIN_UNDEFINE_KEEP_NVRAM
411
+ end
412
+ elsif !nvram.nil?
413
+ descr_changed = true
414
+ undefine_flags |= ProviderLibvirt::Util::DomainFlags::VIR_DOMAIN_UNDEFINE_NVRAM
415
+ nvram.parent.delete_element(nvram)
416
+ end
417
+
378
418
  # Apply
379
419
  if descr_changed
380
420
  begin
381
- libvirt_domain.undefine
421
+ libvirt_domain.undefine(undefine_flags)
382
422
  new_descr = String.new
383
423
  xml_descr.write new_descr
384
424
  env[:machine].provider.driver.connection.servers.create(xml: new_descr)
@@ -35,6 +35,7 @@ module VagrantPlugins
35
35
  autoload :ReadMacAddresses, action_root.join('read_mac_addresses')
36
36
  autoload :RemoveLibvirtImage, action_root.join('remove_libvirt_image')
37
37
  autoload :RemoveStaleVolume, action_root.join('remove_stale_volume')
38
+ autoload :ResolveDiskSettings, action_root.join('resolve_disk_settings')
38
39
  autoload :ResumeDomain, action_root.join('resume_domain')
39
40
  autoload :SetNameOfDomain, action_root.join('set_name_of_domain')
40
41
  autoload :SetBootOrder, action_root.join('set_boot_order')
@@ -81,6 +82,7 @@ module VagrantPlugins
81
82
  b2.use SetNameOfDomain
82
83
 
83
84
  if !env[:machine].config.vm.box
85
+ b2.use ResolveDiskSettings
84
86
  b2.use CreateDomain
85
87
  b2.use CreateNetworks
86
88
  b2.use CreateNetworkInterfaces
@@ -94,6 +96,7 @@ module VagrantPlugins
94
96
  b2.use HandleBox
95
97
  b2.use HandleBoxImage
96
98
  b2.use CreateDomainVolume
99
+ b2.use ResolveDiskSettings
97
100
  b2.use CreateDomain
98
101
  b2.use CreateNetworks
99
102
  b2.use CreateNetworkInterfaces
@@ -104,6 +107,7 @@ module VagrantPlugins
104
107
  end
105
108
  else
106
109
  env[:halt_on_error] = true
110
+ b2.use ResolveDiskSettings
107
111
  b2.use CreateNetworks
108
112
  b2.use action_start
109
113
  end
@@ -994,6 +994,10 @@ module VagrantPlugins
994
994
  errors << "libvirt.qemu_use_agent must be a boolean."
995
995
  end
996
996
 
997
+ if !@nvram.nil? && @loader.nil?
998
+ errors << "use of 'nvram' requires a 'loader' to be specified, please add one to the configuration"
999
+ end
1000
+
997
1001
  if @qemu_use_agent == true
998
1002
  # if qemu agent is used to optain domain ip configuration, at least
999
1003
  # one qemu channel has to be configured. As there are various options,
@@ -117,9 +117,9 @@
117
117
  @disk_driver_opts.reject { |k,v| v.nil? }
118
118
  .map { |k,v| "#{k}='#{v}'"}
119
119
  .join(' ') -%>/>
120
- <source file='<%= volume[:path] %>'/>
120
+ <source file='<%= volume[:absolute_path] %>'/>
121
121
  <%# we need to ensure a unique target dev -%>
122
- <target dev='<%= volume[:dev] %>' bus='<%= volume[:bus] %>'/>
122
+ <target dev='<%= volume[:device] %>' bus='<%= volume[:bus] %>'/>
123
123
  </disk>
124
124
  <%- end -%>
125
125
  <%# additional disks -%>
@@ -0,0 +1,15 @@
1
+ # Ripped from https://libvirt.org/html/libvirt-libvirt-domain.html#types
2
+ module VagrantPlugins
3
+ module ProviderLibvirt
4
+ module Util
5
+ module DomainFlags
6
+ # virDomainUndefineFlagsValues
7
+ VIR_DOMAIN_UNDEFINE_MANAGED_SAVE = 1 # Also remove any managed save
8
+ VIR_DOMAIN_UNDEFINE_SNAPSHOTS_METADATA = 2 # If last use of domain, then also remove any snapshot metadata
9
+ VIR_DOMAIN_UNDEFINE_NVRAM = 4 # Also remove any nvram file
10
+ VIR_DOMAIN_UNDEFINE_KEEP_NVRAM = 8 # Keep nvram file
11
+ VIR_DOMAIN_UNDEFINE_CHECKPOINTS_METADATA = 16 # If last use of domain, then also remove any checkpoint metadata Future undefine control flags should come here.
12
+ end
13
+ end
14
+ end
15
+ end
@@ -9,6 +9,7 @@ module VagrantPlugins
9
9
  autoload :NetworkUtil, 'vagrant-libvirt/util/network_util'
10
10
  autoload :StorageUtil, 'vagrant-libvirt/util/storage_util'
11
11
  autoload :ErrorCodes, 'vagrant-libvirt/util/error_codes'
12
+ autoload :DomainFlags, 'vagrant-libvirt/util/domain_flags'
12
13
  autoload :Ui, 'vagrant-libvirt/util/ui'
13
14
  end
14
15
  end
@@ -1 +1 @@
1
- 0.8.2
1
+ 0.9.0
data/locales/en.yml CHANGED
@@ -58,9 +58,11 @@ en:
58
58
  remove_stale_volume: |-
59
59
  Remove stale volume...
60
60
 
61
- destroy:
61
+ domain_xml:
62
62
  obsolete_method: |
63
- Destroying machine that was originally created without device aliases (pre 0.6.0), using fallback approach.
63
+ Machine that was originally created without device aliases (pre 0.6.0), using fall-back approach for device identification.
64
+
65
+ destroy:
64
66
  unexpected_volumes: |
65
67
  Unexpected number of volumes detected, possibly additional volumes attached outside of vagrant-libvirt.
66
68
  Attempting to handle this correctly, however may experience unexpected behaviour in the domain destroy.
@@ -10,6 +10,7 @@ shared_context 'libvirt' do
10
10
  let(:libvirt_context) { true }
11
11
  let(:id) { 'dummy-vagrant_dummy' }
12
12
  let(:connection) { double('connection') }
13
+ let(:driver) { instance_double(VagrantPlugins::ProviderLibvirt::Driver) }
13
14
  let(:domain) { instance_double(::Fog::Libvirt::Compute::Server) }
14
15
  let(:libvirt_client) { instance_double(::Libvirt::Connect) }
15
16
  let(:libvirt_domain) { instance_double(::Libvirt::Domain) }
@@ -33,5 +34,8 @@ shared_context 'libvirt' do
33
34
 
34
35
  allow(machine).to receive(:id).and_return(id)
35
36
  allow(Log4r::Logger).to receive(:new).and_return(logger)
37
+
38
+ allow(machine.provider).to receive('driver').and_return(driver)
39
+ allow(driver).to receive(:connection).and_return(connection)
36
40
  end
37
41
  end
@@ -34,8 +34,6 @@ describe VagrantPlugins::ProviderLibvirt::Action::CleanupOnFailure do
34
34
  let(:state) { double('state') }
35
35
 
36
36
  before do
37
- allow_any_instance_of(VagrantPlugins::ProviderLibvirt::Driver)
38
- .to receive(:connection).and_return(connection)
39
37
  allow(machine).to receive(:id).and_return('test-machine-id')
40
38
  allow(machine).to receive(:state).and_return(state)
41
39