From 827f84e391ff2407eec65a7af711218a77885bab Mon Sep 17 00:00:00 2001 From: Florian Feldhaus Date: Sun, 6 Jan 2013 21:15:27 +0100 Subject: [PATCH] KVM provider: Fixed Windows support * fixed adding of floppy drive to KVM machines * support for adding virtio drivers to KVM machines --- lib/veewee/provider/kvm/box/create.rb | 117 ++++++++++++++++++++++---- 1 file changed, 101 insertions(+), 16 deletions(-) diff --git a/lib/veewee/provider/kvm/box/create.rb b/lib/veewee/provider/kvm/box/create.rb index 5b7183ef..484a7d63 100644 --- a/lib/veewee/provider/kvm/box/create.rb +++ b/lib/veewee/provider/kvm/box/create.rb @@ -1,4 +1,5 @@ require 'nokogiri' +require 'fileutils' module Veewee module Provider @@ -7,11 +8,12 @@ module BoxCommand # Create a new vm def create(options={}) # Assemble the Virtualmachine and set all the memory and other stuff" - - create_server(options) create_volume(options) + add_virtio_drivers if File.exists?(File.join(definition.path, 'Autounattend.xml')) self.create_floppy("virtualfloppy.img") + FileUtils.move(File.join(definition.path, 'Autounattend.xml.virtio'), File.join(definition.path, 'Autounattend.xml')) if File.exists?(File.join(definition.path, 'Autounattend.xml.virtio')) + add_floppy unless definition.floppy_files.nil? end def create_server(options) @@ -20,14 +22,14 @@ def create_server(options) kvm_options = definition.kvm[:vm_options][0] # Create the "server" attributes = { - :name => name, - :memory_size => definition.memory_size.to_i*1024, - :cpus => definition.cpu_count.to_i, - :volume_capacity => "#{definition.disk_size}M", - :domain_type => options['use_emulation'] ? 'qemu': 'kvm', - :iso_file => definition.iso_file, - :arch => definition.os_type_id.end_with?("_64") ? "x86_64" : "i686", - :iso_dir => env.config.veewee.iso_dir + :name => name, + :memory_size => definition.memory_size.to_i*1024, + :cpus => definition.cpu_count.to_i, + :volume_capacity => "#{definition.disk_size}M", + :domain_type => options['use_emulation'] ? 'qemu' : 'kvm', + :iso_file => definition.iso_file, + :arch => definition.os_type_id.end_with?("_64") ? "x86_64" : "i686", + :iso_dir => env.config.veewee.iso_dir } # Check for network stuff (default, bridge) check_network(kvm_options, attributes) @@ -91,11 +93,12 @@ def create_volume(options) end def add_floppy + env.logger.info 'Adding floppy disk' # Get a raw libvirt connection - c=@connection.raw + conn = ::Libvirt::open("qemu:///system") # Retrieve the domain - domain=c.lookup_domain_by_name(name) + domain=conn.lookup_domain_by_name(name) # Retrieve the existing XML from the domain domain_xml=domain.xml_desc @@ -107,8 +110,8 @@ def add_floppy devices=domain_doc.xpath('/domain/devices').first # The floppy xml representation floppy_xml="
+ File.join(definition.path, "virtualfloppy.img") + + "'/>
" # Convert the floppy xml to nokogiri @@ -121,10 +124,92 @@ def add_floppy new_xml=domain_doc.to_xml # Undefine the existing domain - s.undefine + domain.undefine # Re-define the domain - c.define_domain_xml(new_xml) + conn.define_domain_xml(new_xml) + end + + def add_virtio_drivers + env.logger.info 'Adding virtio drivers for windows system to the virtual machine' + # Get a raw libvirt connection + conn = ::Libvirt::open("qemu:///system") + + # Retrieve the domain + domain=conn.lookup_domain_by_name(name) + + # Retrieve the existing XML from the domain + domain_xml=domain.xml_desc + + # Convert the xml nokogiri doc + domain_doc=Nokogiri::XML(domain_xml) + + # Find the device section + devices=domain_doc.xpath('/domain/devices').first + + # get latest version of virtio drivers + url ='http://alt.fedoraproject.org/pub/alt/virtio-win/latest/images/bin/' + filename = open(url).read.scan(/\"(virtio-win-.*.iso)\"/).first.first + download_iso(url + filename, filename) + path = File.join(env.config.veewee.iso_dir, filename) + + # The disk xml representation + disk_xml="" + + # Convert the disk xml to nokogiri + disk_doc=Nokogiri::XML(disk_xml) + + # Add the floppy to the devices section + devices.add_child(disk_doc.root) + + # Get the raw xml of the changed document + new_xml=domain_doc.to_xml + + # Undefine the existing domain + domain.undefine + + # Re-define the domain + conn.define_domain_xml(new_xml) + + env.logger.info 'Add search path for virtio drivers to Autounattend.xml' + # parse Autoattend.xml to document + FileUtils.copy(File.join(definition.path, 'Autounattend.xml'), File.join(definition.path, 'Autounattend.xml.virtio')) + doc = Nokogiri::XML.parse(File.read(File.join(definition.path, 'Autounattend.xml'))) + # determine platform and windows version + platform = definition.os_type_id.end_with?("_64") ? "amd64" : "x86" + version = case definition.os_type_id.downcase + when /windows-?7/ + 'win7' + when /windows-?2008/ + 'win7' + when /windows-?8/ + 'win8' + when /xp/ + 'xp' + when /vista/ + 'vista' + else + raise 'could not determine windows version' + end + # create new element + component=Nokogiri::XML(%Q| + + +e:\\#{version}\\#{platform} + + +|) + doc.xpath('//unattend:settings[@pass="windowsPE"]', 'unattend' => 'urn:schemas-microsoft-com:unattend').first.add_child component.root + + file = File.open(File.join(definition.path, 'Autounattend.xml'), 'w') + file.write(doc) + file.close + end end #End Module