def call(env)
env[:ui].info(I18n.t('vagrant_libvirt.destroy_domain'))
libvirt_domain = env[:machine].provider.driver.connection.client.lookup_domain_by_uuid(
env[:machine].id
)
begin
libvirt_domain.list_snapshots.each do |name|
@logger.info("Deleting snapshot '#{name}'")
begin
libvirt_domain.lookup_snapshot_by_name(name).delete
rescue => e
raise Errors::SnapshotDeletionError, error_message: e.message
end
end
rescue
@logger.warn("Failed to get list of snapshots")
end
libvirt_domain.managed_save_remove if libvirt_domain.has_managed_save?
domain = env[:machine].provider.driver.connection.servers.get(env[:machine].id.to_s)
undefine_flags = 0
undefine_flags |= ProviderLibvirt::Util::DomainFlags::VIR_DOMAIN_UNDEFINE_KEEP_NVRAM if env[:machine].provider_config.nvram
if env[:machine].provider_config.disks.empty? &&
env[:machine].provider_config.cdroms.empty?
domain.destroy(destroy_volumes: true, flags: undefine_flags)
else
domain_xml = libvirt_domain.xml_desc(1)
xml_descr = REXML::Document.new(domain_xml)
disks_xml = REXML::XPath.match(xml_descr, '/domain/devices/disk[@device="disk"]')
have_aliases = !(REXML::XPath.match(disks_xml, './alias[@name="ua-box-volume-0"]').first).nil?
if !have_aliases
env[:ui].warn(I18n.t('vagrant_libvirt.domain_xml.obsolete_method'))
end
domain.destroy(destroy_volumes: false, flags: undefine_flags)
volumes = domain.volumes
detected_box_volumes = 0
if have_aliases
REXML::XPath.match(disks_xml, './alias[contains(@name, "ua-box-volume-")]').each do |box_disk|
diskname = box_disk.parent.elements['source'].attributes['file'].rpartition('/').last
detected_box_volumes += 1
destroy_volume(volumes, diskname, env)
end
else
disks_xml.each_with_index do |box_disk, idx|
name = libvirt_domain.name + (idx == 0 ? '.img' : "_#{idx}.img")
diskname = box_disk.elements['source'].attributes['file'].rpartition('/').last
break if name != diskname
detected_box_volumes += 1
root_disk = volumes.select do |x|
x.name == name if x
end.first
if root_disk
root_disk.destroy
end
end
end
total_disks = disks_xml.length
offset = total_disks - env[:machine].provider_config.disks.length
if offset != detected_box_volumes
env[:ui].warn(I18n.t('vagrant_libvirt.destroy.unexpected_volumes'))
end
if !have_aliases
if env[:machine].box != nil
box_disks = env[:machine].box.metadata.fetch('disks', [1])
offset = box_disks.length
if offset != detected_box_volumes
env[:ui].warn(I18n.t('vagrant_libvirt.destroy.expected_removal_mismatch'))
end
else
env[:ui].warn(I18n.t('vagrant_libvirt.destroy.box_metadata_unavailable'))
end
offset = detected_box_volumes
end
env[:machine].provider_config.disks.each_with_index.each do |disk, index|
next if disk[:allow_existing]
if have_aliases
domain_disk = REXML::XPath.match(disks_xml, './alias[@name="ua-disk-volume-' + index.to_s + '"]').first
domain_disk = domain_disk.parent if !domain_disk.nil?
else
if !disk[:device].nil?
domain_disk = REXML::XPath.match(disks_xml, './target[@dev="' + disk[:device] + '"]').first
domain_disk = domain_disk.parent if !domain_disk.nil?
else
domain_disk = disks_xml[offset + index]
end
end
next if domain_disk.nil?
diskname = domain_disk.elements['source'].attributes['file'].rpartition('/').last
destroy_volume(volumes, diskname, env)
end
end
@app.call(env)
end