mirror of
https://github.com/fog/fog.git
synced 2022-11-09 13:51:43 -05:00
Merge pull request #703 from ohadlevy/master
first cleanup of libvirt fog code
This commit is contained in:
commit
50960a5f46
3 changed files with 87 additions and 103 deletions
|
@ -52,6 +52,7 @@ Gem::Specification.new do |s|
|
||||||
s.add_development_dependency('rake')
|
s.add_development_dependency('rake')
|
||||||
s.add_development_dependency('rbvmomi')
|
s.add_development_dependency('rbvmomi')
|
||||||
s.add_development_dependency('rdoc')
|
s.add_development_dependency('rdoc')
|
||||||
|
s.add_development_dependency('thor')
|
||||||
s.add_development_dependency('rspec', '~>1.3.1')
|
s.add_development_dependency('rspec', '~>1.3.1')
|
||||||
s.add_development_dependency('shindo', '~>0.3.4')
|
s.add_development_dependency('shindo', '~>0.3.4')
|
||||||
s.add_development_dependency('virtualbox', '~>0.9.1')
|
s.add_development_dependency('virtualbox', '~>0.9.1')
|
||||||
|
|
|
@ -48,31 +48,10 @@ module Fog
|
||||||
# @returns server/domain created
|
# @returns server/domain created
|
||||||
def initialize(attributes={} )
|
def initialize(attributes={} )
|
||||||
|
|
||||||
self.xml ||= nil unless attributes[:xml]
|
# setup all attributes.
|
||||||
self.persistent ||=true unless attributes[:persistent]
|
defaults.merge(attributes).each do |k,v|
|
||||||
self.cpus ||=1 unless attributes[:cpus]
|
eval("self.#{k}= v") if self.respond_to?("#{k}=")
|
||||||
self.memory_size ||=256 *1024 unless attributes[:memory_size]
|
end
|
||||||
self.name ||="fog-#{SecureRandom.random_number*10E14.to_i.round}" unless attributes[:name]
|
|
||||||
|
|
||||||
self.os_type ||="hvm" unless attributes[:os_type]
|
|
||||||
self.arch ||="x86_64" unless attributes[:arch]
|
|
||||||
|
|
||||||
self.domain_type ||="kvm" unless attributes[:domain_type]
|
|
||||||
|
|
||||||
self.iso_file ||=nil unless attributes[:iso_file]
|
|
||||||
self.iso_dir ||="/var/lib/libvirt/images" unless attributes[:iso_dir]
|
|
||||||
|
|
||||||
self.volume_format_type ||=nil unless attributes[:volume_format_type]
|
|
||||||
self.volume_capacity ||=nil unless attributes[:volume_capacity]
|
|
||||||
self.volume_allocation ||=nil unless attributes[:volume_allocation]
|
|
||||||
|
|
||||||
self.volume_name ||=nil unless attributes[:volume_name]
|
|
||||||
self.volume_pool_name ||=nil unless attributes[:volume_pool_name]
|
|
||||||
self.volume_template_name ||=nil unless attributes[:volume_template_name]
|
|
||||||
|
|
||||||
self.network_interface_type ||="nat" unless attributes[:network_interface_type]
|
|
||||||
self.network_nat_network ||="default" unless attributes[:network_nat_network]
|
|
||||||
self.network_bridge_name ||="br0" unless attributes[:network_bridge_name]
|
|
||||||
|
|
||||||
super
|
super
|
||||||
end
|
end
|
||||||
|
@ -83,65 +62,55 @@ module Fog
|
||||||
|
|
||||||
validate_template_options
|
validate_template_options
|
||||||
|
|
||||||
xml=xml_from_template if xml.nil?
|
xml ||= xml_from_template
|
||||||
|
|
||||||
create_or_clone_volume
|
create_or_clone_volume
|
||||||
|
|
||||||
xml=xml_from_template
|
xml = xml_from_template
|
||||||
|
|
||||||
# We either now have xml provided by the user or generated by the template
|
# We either now have xml provided by the user or generated by the template
|
||||||
begin
|
begin
|
||||||
if !xml.nil?
|
if xml
|
||||||
domain=nil
|
self.raw = self.persistent ? connection.raw.define_domain_xml(xml) : connection.raw.create_domain_xml(xml)
|
||||||
if self.persistent
|
|
||||||
domain=connection.raw.define_domain_xml(xml)
|
|
||||||
else
|
|
||||||
domain=connection.raw.create_domain_xml(xml)
|
|
||||||
end
|
|
||||||
self.raw=domain
|
|
||||||
end
|
end
|
||||||
rescue
|
rescue
|
||||||
raise Fog::Errors::Error.new("Error saving the server: #{$!}")
|
raise Fog::Errors::Error.new("Error saving the server: #{$!}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
#TODO move all of this to the volume class
|
||||||
def create_or_clone_volume
|
def create_or_clone_volume
|
||||||
|
|
||||||
volume_options=Hash.new
|
volume_options = Hash.new
|
||||||
|
|
||||||
unless self.volume_name.nil?
|
volume_options[:name] = volume_name || default_volume_name
|
||||||
volume_options[:name]=self.volume_name
|
|
||||||
else
|
|
||||||
extension = self.volume_format_type.nil? ? "img" : self.volume_format_type
|
|
||||||
volume_name = "#{self.name}.#{extension}"
|
|
||||||
volume_options[:name]=volume_name
|
|
||||||
end
|
|
||||||
|
|
||||||
# Check if a disk template was specified
|
# Check if a disk template was specified
|
||||||
unless self.volume_template_name.nil?
|
unless self.volume_template_name.nil?
|
||||||
|
|
||||||
template_volumes=connection.volumes.all(:name => self.volume_template_name)
|
template_volumes = connection.volumes.all(:name => self.volume_template_name)
|
||||||
|
|
||||||
raise Fog::Errors::Error.new("Template #{self.volume_template_name} not found") unless template_volumes.length==1
|
raise Fog::Errors::Error.new("Template #{self.volume_template_name} not found") unless template_volumes.empty?
|
||||||
|
|
||||||
orig_volume=template_volumes.first
|
orig_volume = template_volumes.first
|
||||||
self.volume_format_type=orig_volume.format_type unless self.volume_format_type
|
volume = orig_volume.clone("#{volume_options[:name]}")
|
||||||
volume=orig_volume.clone("#{volume_options[:name]}")
|
|
||||||
|
|
||||||
|
# if we cloned it, it has the original volume type.
|
||||||
|
self.volume_format_type = orig_volume.format_type
|
||||||
# This gets passed to the domain to know the path of the disk
|
# This gets passed to the domain to know the path of the disk
|
||||||
self.volume_path=volume.path
|
self.volume_path = volume.path
|
||||||
|
|
||||||
else
|
else
|
||||||
# If no template volume was given, let's create our own volume
|
# If no template volume was given, let's create our own volume
|
||||||
|
|
||||||
volume_options[:format_type]=self.volume_format_type unless self.volume_format_type.nil?
|
volume_options[:format_type] = self.volume_format_type if volume_format_type
|
||||||
volume_options[:capacity]=self.volume_capacity unless self.volume_capacity.nil?
|
volume_options[:capacity] = self.volume_capacity if volume_capacity
|
||||||
volume_options[:allocation]=self.volume_allocation unless self.volume_allocation.nil?
|
volume_options[:allocation] = self.volume_allocation if volume_allocation
|
||||||
|
|
||||||
begin
|
begin
|
||||||
volume=connection.volumes.create(volume_options)
|
volume = connection.volumes.create(volume_options)
|
||||||
self.volume_path=volume.path
|
self.volume_path = volume.path
|
||||||
self.volume_format_type=volume.format_type unless self.volume_format_type
|
self.volume_format_type ||= volume.format_type
|
||||||
rescue
|
rescue
|
||||||
raise Fog::Errors::Error.new("Error creating the volume : #{$!}")
|
raise Fog::Errors::Error.new("Error creating the volume : #{$!}")
|
||||||
end
|
end
|
||||||
|
@ -158,27 +127,27 @@ module Fog
|
||||||
def xml_from_template
|
def xml_from_template
|
||||||
|
|
||||||
template_options={
|
template_options={
|
||||||
:cpus => self.cpus,
|
:cpus => cpus,
|
||||||
:memory_size => self.memory_size,
|
:memory_size => memory_size,
|
||||||
:domain_type => self.domain_type,
|
:domain_type => domain_type,
|
||||||
:name => self.name,
|
:name => name,
|
||||||
:iso_file => self.iso_file,
|
:iso_file => iso_file,
|
||||||
:iso_dir => self.iso_dir,
|
:iso_dir => iso_dir,
|
||||||
:os_type => self.os_type,
|
:os_type => os_type,
|
||||||
:arch => self.arch,
|
:arch => arch,
|
||||||
:volume_path => self.volume_path,
|
:volume_path => volume_path,
|
||||||
:volume_format_type => self.volume_format_type,
|
:volume_format_type => volume_format_type,
|
||||||
:network_interface_type => self.network_interface_type,
|
:network_interface_type => network_interface_type,
|
||||||
:network_nat_network => self.network_nat_network,
|
:network_nat_network => network_nat_network,
|
||||||
:network_bridge_name => self.network_bridge_name
|
:network_bridge_name => network_bridge_name
|
||||||
}
|
}
|
||||||
vars = ErbBinding.new(template_options)
|
vars = ErbBinding.new(template_options)
|
||||||
template_path=File.join(File.dirname(__FILE__),"templates","server.xml.erb")
|
template_path = File.join(File.dirname(__FILE__),"templates","server.xml.erb")
|
||||||
template=File.open(template_path).readlines.join
|
template = File.open(template_path).readlines.join
|
||||||
erb = ERB.new(template)
|
erb = ERB.new(template)
|
||||||
vars_binding = vars.send(:get_binding)
|
vars_binding = vars.send(:get_binding)
|
||||||
result=erb.result(vars_binding)
|
|
||||||
return result
|
erb.result(vars_binding)
|
||||||
end
|
end
|
||||||
|
|
||||||
def username
|
def username
|
||||||
|
@ -202,16 +171,13 @@ module Fog
|
||||||
# In fog a destroy means the remove of a machine
|
# In fog a destroy means the remove of a machine
|
||||||
def destroy(options={ :destroy_volumes => false})
|
def destroy(options={ :destroy_volumes => false})
|
||||||
requires :raw
|
requires :raw
|
||||||
if @raw.active?
|
poweroff unless stopped?
|
||||||
@raw.destroy
|
#TODO: add handling of failure
|
||||||
end
|
|
||||||
@raw.undefine
|
@raw.undefine
|
||||||
|
|
||||||
if options[:destroy_volumes]
|
if options[:destroy_volumes]
|
||||||
disk_path = document("domain/devices/disk/source", "file")
|
|
||||||
# volumes.all filters do not handle nil keys well
|
# volumes.all filters do not handle nil keys well
|
||||||
(connection.volumes.all(:path => disk_path) rescue []).each do |vol|
|
connection.volumes.all(:path => disk_path).each { |vol| vol.destroy}
|
||||||
vol.destroy
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -222,7 +188,7 @@ module Fog
|
||||||
|
|
||||||
# Alias for poweroff
|
# Alias for poweroff
|
||||||
def halt
|
def halt
|
||||||
poweroff
|
poweroff
|
||||||
end
|
end
|
||||||
|
|
||||||
# In libvirt a destroy means a hard power-off of the domain
|
# In libvirt a destroy means a hard power-off of the domain
|
||||||
|
@ -257,7 +223,10 @@ module Fog
|
||||||
when 5 then "shutoff"
|
when 5 then "shutoff"
|
||||||
when 6 then "crashed"
|
when 6 then "crashed"
|
||||||
end
|
end
|
||||||
return state
|
end
|
||||||
|
|
||||||
|
def stopped?
|
||||||
|
state == "shutdown"
|
||||||
end
|
end
|
||||||
|
|
||||||
def ready?
|
def ready?
|
||||||
|
@ -266,20 +235,15 @@ module Fog
|
||||||
|
|
||||||
def stop
|
def stop
|
||||||
requires :raw
|
requires :raw
|
||||||
|
|
||||||
@raw.shutdown
|
@raw.shutdown
|
||||||
end
|
end
|
||||||
|
|
||||||
#def xml_desc
|
|
||||||
#requires :raw
|
|
||||||
#raw.xml_desc
|
|
||||||
#end
|
|
||||||
|
|
||||||
# This retrieves the ip address of the mac address
|
# This retrieves the ip address of the mac address
|
||||||
# It returns an array of public and private ip addresses
|
# It returns an array of public and private ip addresses
|
||||||
# Currently only one ip address is returned, but in the future this could be multiple
|
# Currently only one ip address is returned, but in the future this could be multiple
|
||||||
# if the server has multiple network interface
|
# if the server has multiple network interface
|
||||||
#
|
#
|
||||||
|
#TODO: move this into the util class
|
||||||
def addresses(options={})
|
def addresses(options={})
|
||||||
mac=self.mac
|
mac=self.mac
|
||||||
|
|
||||||
|
@ -487,21 +451,20 @@ module Fog
|
||||||
# Retrieves the mac address from parsing the XML of the domain
|
# Retrieves the mac address from parsing the XML of the domain
|
||||||
def mac
|
def mac
|
||||||
mac = document("domain/devices/interface/mac", "address")
|
mac = document("domain/devices/interface/mac", "address")
|
||||||
return mac
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def vnc_port
|
def vnc_port
|
||||||
|
|
||||||
port = document("domain/devices/graphics[@type='vnc']", "port")
|
port = document("domain/devices/graphics[@type='vnc']", "port")
|
||||||
return port
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def disk_path
|
||||||
|
document("domain/devices/disk/source", "file")
|
||||||
|
rescue
|
||||||
|
[]
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
attr_reader :raw
|
||||||
def raw
|
|
||||||
@raw
|
|
||||||
end
|
|
||||||
|
|
||||||
def raw=(new_raw)
|
def raw=(new_raw)
|
||||||
@raw = new_raw
|
@raw = new_raw
|
||||||
|
@ -523,13 +486,33 @@ module Fog
|
||||||
merge_attributes(raw_attributes)
|
merge_attributes(raw_attributes)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def randomized_name
|
||||||
# finds a value from xml
|
"fog-#{SecureRandom.random_number*10E14.to_i.round}"
|
||||||
def document path, attribute=nil
|
|
||||||
xml = REXML::Document.new(self.xml)
|
|
||||||
attribute.nil? ? xml.elements[path].text : xml.elements[path].attributes[attribute]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def default_iso_dir
|
||||||
|
"/var/lib/libvirt/images"
|
||||||
|
end
|
||||||
|
|
||||||
|
def default_volume_name
|
||||||
|
"#{name}.#{volume_format_type || 'img'}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def defaults
|
||||||
|
{
|
||||||
|
:persistent => true,
|
||||||
|
:cpus => 1,
|
||||||
|
:memory_size => 256 *1024,
|
||||||
|
:name => randomized_name,
|
||||||
|
:os_type => "hvm",
|
||||||
|
:arch => "x86_64",
|
||||||
|
:domain_type => "kvm",
|
||||||
|
:iso_dir => default_iso_dir ,
|
||||||
|
:network_interface_type => "nat",
|
||||||
|
:network_nat_network => "default",
|
||||||
|
:network_bridge_name => "br0"
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ module Fog
|
||||||
# finds a value from xml
|
# finds a value from xml
|
||||||
def document path, attribute=nil
|
def document path, attribute=nil
|
||||||
return nil if new?
|
return nil if new?
|
||||||
xml = REXML::Document.new(@xml_desc)
|
xml = REXML::Document.new(self.xml)
|
||||||
attribute.nil? ? xml.elements[path].text : xml.elements[path].attributes[attribute]
|
attribute.nil? ? xml.elements[path].text : xml.elements[path].attributes[attribute]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue