|
| 1 | +require "nokogiri" |
| 2 | + |
| 3 | +module Fog |
| 4 | + module Libvirt |
| 5 | + class Compute |
| 6 | + module Shared |
| 7 | + def detach_iso(uuid, options = {}) |
| 8 | + raise ArgumentError, "uuid is a required parameter" if uuid.nil? |
| 9 | + |
| 10 | + options ||= {} |
| 11 | + raise ArgumentError, "options must be a hash" unless options.is_a?(Hash) |
| 12 | + |
| 13 | + target_dev = options.fetch(:target_dev, "sdc") |
| 14 | + bus = options.fetch(:bus, "sata") |
| 15 | + flags = options.fetch(:flags, ::Libvirt::Domain::AFFECT_CONFIG) |
| 16 | + domain = client.lookup_domain_by_uuid(uuid) |
| 17 | + domain_active = domain.active? |
| 18 | + flags = effective_detach_iso_flags(flags, domain_active) |
| 19 | + |
| 20 | + if domain_active |
| 21 | + domain.update_device(eject_cdrom_xml(target_dev, bus), flags) |
| 22 | + begin |
| 23 | + domain.detach_device(detach_cdrom_xml(target_dev, bus), flags) |
| 24 | + rescue ::Libvirt::Error |
| 25 | + # Some backends don't allow to detach the cdrom if the host is running. |
| 26 | + # In this case, we just eject the cdrom and leave it attached to the VM. |
| 27 | + # Return true that maybe the ISO file can be removed in further steps. |
| 28 | + true |
| 29 | + end |
| 30 | + else |
| 31 | + begin |
| 32 | + domain.detach_device(detach_cdrom_xml(target_dev, bus), flags) |
| 33 | + true |
| 34 | + rescue ::Libvirt::Error |
| 35 | + false |
| 36 | + end |
| 37 | + end |
| 38 | + end |
| 39 | + |
| 40 | + private |
| 41 | + |
| 42 | + def detach_cdrom_xml(target_dev, bus) |
| 43 | + Nokogiri::XML::Builder.new do |x| |
| 44 | + x.disk(:type => "file", :device => "cdrom") do |
| 45 | + x.target(:dev => target_dev, :bus => bus) |
| 46 | + end |
| 47 | + end.to_xml |
| 48 | + end |
| 49 | + |
| 50 | + def eject_cdrom_xml(target_dev, bus) |
| 51 | + Nokogiri::XML::Builder.new do |x| |
| 52 | + x.disk(:type => "file", :device => "cdrom", :tray => "open") do |
| 53 | + x.driver(:name => "qemu", :type => "raw") |
| 54 | + x.target(:dev => target_dev, :bus => bus) |
| 55 | + x.readonly |
| 56 | + end |
| 57 | + end.to_xml |
| 58 | + end |
| 59 | + |
| 60 | + def effective_detach_iso_flags(flags, domain_active) |
| 61 | + return flags unless flags == ::Libvirt::Domain::AFFECT_CONFIG |
| 62 | + return flags unless domain_active |
| 63 | + |
| 64 | + flags | ::Libvirt::Domain::AFFECT_LIVE |
| 65 | + rescue ::Libvirt::Error |
| 66 | + flags |
| 67 | + end |
| 68 | + end |
| 69 | + |
| 70 | + class Real |
| 71 | + include Shared |
| 72 | + end |
| 73 | + |
| 74 | + class Mock |
| 75 | + include Shared |
| 76 | + end |
| 77 | + end |
| 78 | + end |
| 79 | +end |
0 commit comments