Class: VagrantPlugins::ProviderLibvirt::Action::DestroyDomain
- Inherits:
-
Object
- Object
- VagrantPlugins::ProviderLibvirt::Action::DestroyDomain
- Defined in:
- lib/vagrant-libvirt/action/destroy_domain.rb
Instance Method Summary collapse
- #call(env) ⇒ Object
-
#initialize(app, _env) ⇒ DestroyDomain
constructor
A new instance of DestroyDomain.
Constructor Details
#initialize(app, _env) ⇒ DestroyDomain
Returns a new instance of DestroyDomain.
14 15 16 17 |
# File 'lib/vagrant-libvirt/action/destroy_domain.rb', line 14 def initialize(app, _env) @logger = Log4r::Logger.new('vagrant_libvirt::action::destroy_domain') @app = app end |
Instance Method Details
#call(env) ⇒ Object
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
# File 'lib/vagrant-libvirt/action/destroy_domain.rb', line 19 def call(env) # Destroy the server, remove the tracking ID env[:ui].info(I18n.t('vagrant_libvirt.destroy_domain')) # Must delete any snapshots before domain can be destroyed # Fog Libvirt currently doesn't support snapshots. Use # ruby-libvirt client directly. Note this is racy, see # http://www.libvirt.org/html/libvirt-libvirt.html#virDomainSnapshotListNames 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. end end rescue # Some drivers (xen) don't support getting list of snapshots, # not much can be done here about it @logger.warn("Failed to get list of snapshots") end # must remove managed saves 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? # if using default configuration of disks and cdroms # cdroms are consider volumes, but cannot be destroyed 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 # Remove root storage. If no aliases available, perform the removal by name and keep track # of how many matches there are in the volumes. This will provide a fallback offset to where # the additional storage devices are. 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 # fallback to try and infer which boxes are box images, as they are listed first # as soon as there is no match, can exit 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 # work out if there are any custom disks attached that wasn't done by vagrant-libvirt, # and warn there might be unexpected behaviour 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 no aliases found, see if it's possible to check the number of box disks # otherwise the destroy could remove the wrong disk by accident. if env[:machine].box != nil box_disks = env[:machine].box..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 only used when no aliases available offset = detected_box_volumes end env[:machine].provider_config.disks.each_with_index.each do |disk, index| # shared disks remove only manually or ??? next if disk[:allow_existing] # look for exact match using aliases which will be used # for subsequent domain creations 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 # otherwise fallback to find the disk by device if specified by user # and finally index counting with offset and hope the match is correct 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 |