Permalink
Browse files

added basic VMWare support, WIP

This patch provides a structure in which it would be easier to
add new hypervisors and guests types that are supported by libvirt.

each hypervisor can now have its own set of templates, and classes.
  • Loading branch information...
1 parent 5128477 commit 065ef56378021494d91d91082348a24d48bf8a5c @ohadlevy committed Oct 27, 2011
View
@@ -29,7 +29,6 @@ Rake::TestTask.new(:test) do |test|
test.libs << 'lib' << 'test'
test.pattern = 'test/*test*.rb'
test.verbose = true
- test.warning = true
end
require 'rcov/rcovtask'
View
@@ -7,10 +7,12 @@
require 'virt/interface'
module Virt
+ autoload :KVM, "virt/kvm"
+ autoload :VMWare, "virt/vmware"
class << self
- def connect uri
- @connection = Virt::Connection.new uri
+ def connect uri, options = {}
+ @connection = Virt::Connection.new uri, options
end
def connection
View
@@ -1,11 +1,26 @@
require 'libvirt'
module Virt
class Connection
- attr_reader :connection
+ attr_reader :connection, :type
- def initialize uri
- raise("Must provide a guest to connect to") unless uri
- @connection = Libvirt::open uri
+ def initialize uri, options = {}
+ raise("Must provide a host to connect to") unless uri
+ if uri =~ /^(esx|vpx)/
+ raise("Must provide a username and password") unless options[:username] or options[:password]
+ @connection = Libvirt::open_auth(uri, [Libvirt::CRED_AUTHNAME, Libvirt::CRED_PASSPHRASE]) do |cred|
+ # This may only be required for ESXi connections, not sure.
+ @type = "VMWare"
+ case cred['type']
+ when ::Libvirt::CRED_AUTHNAME
+ options[:username]
+ when ::Libvirt::CRED_PASSPHRASE
+ options[:password]
+ end
+ end
+ else
+ @type = "KVM"
+ @connection = Libvirt::open uri
+ end
end
def closed?
@@ -25,7 +40,14 @@ def disconnect
end
def host
- Host.new
+ case type
+ when "KVM"
+ KVM::Host.new
+ when "VMWare"
+ VMWare::Host.new
+ else
+ raise "Non supported hypervisor"
+ end
end
end
View
@@ -15,8 +15,6 @@ def initialize options = {}
@arch ||= options[:arch] || default_arch
@template_path = options[:template_path] || default_template_path
- @volume = Volume.new options
- @interface ||= Interface.new options
end
def new?
@@ -79,10 +77,6 @@ def uuid
@domain.uuid unless new?
end
- def arch= value
- @arch = value == "i386" ? "i686" : value
- end
-
def to_s
name.to_s
end
@@ -91,7 +85,7 @@ def <=> other
self.name <=> other.name
end
- private
+ protected
def fetch_guest
@domain = @connection.connection.lookup_domain_by_name(name)
@@ -108,7 +102,7 @@ def fetch_info
@vcpu = document("domain/vcpu")
@arch = document("domain/os/type", "arch")
@machine = document("domain/os/type", "machine")
- @boot_device = document("domain/os/boot", "dev")
+ @boot_device = document("domain/os/boot", "dev") rescue nil
# do we have a NIC?
network_type = document("domain/devices/interface", "type") rescue nil
@@ -134,8 +128,6 @@ def default_arch
"x86_64"
end
- def default_template_path
- "guest.xml.erb"
- end
+ def default_template_path; end
end
end
View
@@ -26,32 +26,13 @@ def defined_guests
find_guest_by_name domain
end
end
-
- # Available libvirt interfaces, excluding lo
- def interfaces
- connection.list_interfaces.delete_if{|i| i == "lo"}.sort
- rescue => e
- raise "This function is not supported by the hypervisor: #{e}"
- end
-
- def interface iface
- connection.lookup_interface_by_name(iface)
- end
-
- # libvirt internal networks
- def networks
- connection.list_networks.map do |network|
- connection.lookup_network_by_name(network).bridge_name
- end
- end
-
def storage_pools
- connection.list_storage_pools.map {|p| Pool.new({:name => p})}
+ connection.list_storage_pools.map {|p| create_pool({:name => p})}
end
# Returns a Virt::Pool object based on the pool name
def storage_pool pool
- Pool.new({:name => pool.is_a?(Libvirt::StoragePool) ? pool.name : pool })
+ create_pool({:name => pool.is_a?(Libvirt::StoragePool) ? pool.name : pool })
rescue Libvirt::RetrieveError
end
@@ -66,15 +47,25 @@ def volumes
def find_guest_by_name name
if connection.lookup_domain_by_name name
- return Guest.new({:name => name})
+ return create_guest({:name => name})
end
end
def find_guest_by_id id
- id.to_a.map do |did|
- return Guest.new({:name => connection.lookup_domain_by_id(did).name})
+ Array(id).map do |did|
+ return create_guest({:name => connection.lookup_domain_by_id(did).name})
end
end
+ protected
+
+ def create_guest opts
+ Virt::Guest.new opts
+ end
+
+ def create_pool opts
+ Virt::Pool.new opts
+ end
+
end
end
View
@@ -15,21 +15,14 @@ def new?
mac.nil?
end
- private
+ protected
- def default_device
- @connection.host.interfaces.first
- rescue
- "br0"
- end
+ # Abstracted methods
+ def default_device; end
- def default_type
- "bridge"
- end
+ def default_type; end
- def default_model
- "virtio"
- end
+ def default_model; end
end
end
View
@@ -0,0 +1,6 @@
+module Virt::KVM
+ autoload :Host, 'virt/kvm/host.rb'
+ autoload :Guest, 'virt/kvm/guest.rb'
+ autoload :Interface, 'virt/kvm/interface.rb'
+ autoload :Volume, 'virt/kvm/volume.rb'
+end
View
@@ -0,0 +1,22 @@
+module Virt::KVM
+ class Guest < Virt::Guest
+
+ def initialize options = {}
+ super(options)
+ @volume = Volume.new options
+ @interface ||= Interface.new options
+ end
+
+ def arch= value
+ @arch = value == "i386" ? "i686" : value
+ end
+
+
+ protected
+
+ def default_template_path
+ "kvm/guest.xml.erb"
+ end
+
+ end
+end
View
@@ -0,0 +1,28 @@
+module Virt::KVM
+ class Host < Virt::Host
+
+ # Available libvirt interfaces, excluding lo
+ def interfaces
+ connection.list_interfaces.delete_if{|i| i == "lo"}.sort
+ rescue => e
+ raise "This function is not supported by the hypervisor: #{e}"
+ end
+
+ def interface iface
+ connection.lookup_interface_by_name(iface)
+ end
+
+ # libvirt internal networks
+ def networks
+ connection.list_networks.map do |network|
+ connection.lookup_network_by_name(network).bridge_name
+ end
+ end
+
+ def create_guest opts
+ Virt::KVM::Guest.new opts
+ end
+
+ end
+
+end
View
@@ -0,0 +1,25 @@
+module Virt::KVM
+ class Interface < Virt::Interface
+
+ protected
+
+ def default_template_path
+ "kvm/guest.xml.erb"
+ end
+
+ def default_device
+ @connection.host.interfaces.first
+ rescue
+ "br0"
+ end
+
+ def default_type
+ "bridge"
+ end
+
+ def default_model
+ "virtio"
+ end
+
+ end
+end
View
@@ -0,0 +1,23 @@
+module Virt::KVM
+ class Volume < Virt::Volume
+
+ def default_type
+ "raw"
+ end
+
+ def default_template_path
+ "kvm/volume.xml.erb"
+ end
+
+ def path
+ "#{pool.path}/#{name}"
+ end
+
+ def name= name
+ super name
+ @name += ".img" unless name.match(/.*\.img$/)
+ end
+
+
+ end
+end
View
@@ -0,0 +1,6 @@
+module Virt::VMWare
+ autoload :Host, 'virt/vmware/host.rb'
+ autoload :Guest, 'virt/vmware/guest.rb'
+ autoload :Interface, 'virt/vmware/interface.rb'
+ autoload :Volume, 'virt/vmware/volume.rb'
+end
View
@@ -0,0 +1,17 @@
+module Virt::VMWare
+ class Guest < Virt::Guest
+
+ def initialize options = {}
+ super(options)
+ @volume = Volume.new options
+ @interface ||= Interface.new options
+ end
+
+ protected
+
+ def default_template_path
+ "vmware/guest.xml.erb"
+ end
+
+ end
+end
View
@@ -0,0 +1,28 @@
+module Virt::VMWare
+ class Host < Virt::Host
+
+ # Available libvirt interfaces, excluding lo
+ def interfaces
+ connection.list_interfaces.delete_if{|i| i == "lo"}.sort
+ rescue => e
+ raise "This function is not supported by the hypervisor: #{e}"
+ end
+
+ def interface iface
+ connection.lookup_interface_by_name(iface)
+ end
+
+ # libvirt internal networks
+ def networks
+ connection.list_networks.map do |network|
+ connection.lookup_network_by_name(network).bridge_name
+ end
+ end
+
+ def create_guest opts
+ Virt::VMWare::Guest.new opts
+ end
+
+ end
+
+end
@@ -0,0 +1,25 @@
+module Virt::VMWare
+ class Interface < Virt::Interface
+
+ protected
+
+ def default_template_path
+ "vmware/guest.xml.erb"
+ end
+
+ def default_device
+ @connection.host.interfaces.first
+ rescue
+ "VM Network"
+ end
+
+ def default_type
+ "bridge"
+ end
+
+ def default_model
+ "e1000"
+ end
+
+ end
+end
Oops, something went wrong.

0 comments on commit 065ef56

Please sign in to comment.