Permalink
Browse files

KVM provider: Fixed Windows support

* fixed adding of floppy drive to KVM machines
* support for adding virtio drivers to KVM machines
  • Loading branch information...
1 parent 9976627 commit 827f84e391ff2407eec65a7af711218a77885bab @ffeldhaus committed Jan 6, 2013
Showing with 101 additions and 16 deletions.
  1. +101 −16 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="<disk type='file' device='floppy'><driver name='qemu' type='raw'/><source file='"+
- File.join(definitition.path,"virtualfloppy.img") +
- "'/><target dev='fda' bus='fdc'/><address type='drive' controller='0' bus='0' unit='0'/></disk>
+ File.join(definition.path, "virtualfloppy.img") +
+ "'/><target dev='fda' bus='fdc'/><address type='drive' controller='0' bus='0' unit='0'/></disk>
<controller type='fdc' index='0'>"
# 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="<disk type='file' device='cdrom'><driver name='qemu' type='raw'/><source file='" +
+ path + "'/><target dev='hdd' bus='ide'/></disk>"
+
+ # 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|<component name="Microsoft-Windows-PnpCustomizationsWinPE"
+processorArchitecture="#{platform}" publicKeyToken="31bf3856ad364e35"
+language="neutral" versionScope="nonSxS"
+xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+<DriverPaths>
+<PathAndCredentials wcm:keyValue="1" wcm:action="add">
+<Path>e:\\#{version}\\#{platform}</Path>
+</PathAndCredentials>
+</DriverPaths>
+</component>|)
+ 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

1 comment on commit 827f84e

@jedi4ever

@ffeldhaus thanks! interesting work for the virtio drivers.

I'm wondering why you switched from the @raw object to the qemu:///system system?
I personally use kvm over ssh and therefore have another connections string. this is going through $HOME/.fog to specify things

Please sign in to comment.