Class: Fog::Libvirt::Compute::Real

Inherits:
Object
  • Object
show all
Includes:
Shared
Defined in:
lib/fog/libvirt/compute.rb,
lib/fog/libvirt/requests/compute/vm_action.rb,
lib/fog/libvirt/requests/compute/libversion.rb,
lib/fog/libvirt/requests/compute/list_pools.rb,
lib/fog/libvirt/requests/compute/define_pool.rb,
lib/fog/libvirt/requests/compute/dhcp_leases.rb,
lib/fog/libvirt/requests/compute/pool_action.rb,
lib/fog/libvirt/requests/compute/clone_volume.rb,
lib/fog/libvirt/requests/compute/list_domains.rb,
lib/fog/libvirt/requests/compute/list_volumes.rb,
lib/fog/libvirt/requests/compute/create_domain.rb,
lib/fog/libvirt/requests/compute/create_volume.rb,
lib/fog/libvirt/requests/compute/define_domain.rb,
lib/fog/libvirt/requests/compute/get_node_info.rb,
lib/fog/libvirt/requests/compute/list_networks.rb,
lib/fog/libvirt/requests/compute/upload_volume.rb,
lib/fog/libvirt/requests/compute/volume_action.rb,
lib/fog/libvirt/requests/compute/update_display.rb,
lib/fog/libvirt/requests/compute/destroy_network.rb,
lib/fog/libvirt/requests/compute/list_interfaces.rb,
lib/fog/libvirt/requests/compute/update_autostart.rb,
lib/fog/libvirt/requests/compute/destroy_interface.rb,
lib/fog/libvirt/requests/compute/list_pool_volumes.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Util

#randomized_name, #to_xml, #xml_element, #xml_elements

Constructor Details

#initialize(options = {}) ⇒ Real

Returns a new instance of Real.



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/fog/libvirt/compute.rb', line 81

def initialize(options={})
  @uri = ::Fog::Libvirt::Util::URI.new(enhance_uri(options[:libvirt_uri]))
  @ip_command = options[:libvirt_ip_command]

  # libvirt is part of the gem => ruby-libvirt
  begin
    require 'libvirt'
  rescue LoadError => e
    retry if require('rubygems')
    raise e.message
  end

  begin
    if options[:libvirt_username] and options[:libvirt_password]
      @client = ::Libvirt::open_auth(uri.uri, [::Libvirt::CRED_AUTHNAME, ::Libvirt::CRED_PASSPHRASE]) do |cred|
        case cred['type']
          when ::Libvirt::CRED_AUTHNAME
            options[:libvirt_username]
          when ::Libvirt::CRED_PASSPHRASE
            options[:libvirt_password]
        end
      end
    else
      @client = ::Libvirt::open(uri.uri)
    end

  rescue ::Libvirt::ConnectionError
    raise Fog::Errors::Error.new("Error making a connection to libvirt URI #{uri.uri}:\n#{$!}")
  end
end

Instance Attribute Details

#clientObject (readonly)

Returns the value of attribute client.



77
78
79
# File 'lib/fog/libvirt/compute.rb', line 77

def client
  @client
end

#ip_commandObject (readonly)

Returns the value of attribute ip_command.



79
80
81
# File 'lib/fog/libvirt/compute.rb', line 79

def ip_command
  @ip_command
end

#uriObject (readonly)

Returns the value of attribute uri.



78
79
80
# File 'lib/fog/libvirt/compute.rb', line 78

def uri
  @uri
end

Instance Method Details

#catchLibvirtExceptionsObject

Catch Libvirt exceptions to avoid race conditions involving concurrent libvirt operations from other processes. For example, domains being undefined while fog-libvirt is trying to work with domain lists.



23
24
25
26
27
# File 'lib/fog/libvirt/requests/compute/list_domains.rb', line 23

def catchLibvirtExceptions
  yield
rescue ::Libvirt::RetrieveError, ::Libvirt::Error
  nil
end

#clone_volume(pool_name, xml, name) ⇒ Object



5
6
7
8
# File 'lib/fog/libvirt/requests/compute/clone_volume.rb', line 5

def clone_volume (pool_name, xml, name)
  vol = client.lookup_storage_pool_by_name(pool_name).lookup_volume_by_name(name)
  client.lookup_storage_pool_by_name(pool_name).create_vol_xml_from(xml, vol)
end

#create_domain(xml) ⇒ Object



5
6
7
# File 'lib/fog/libvirt/requests/compute/create_domain.rb', line 5

def create_domain(xml)
  client.create_domain_xml(xml)
end

#create_volume(pool_name, xml) ⇒ Object



5
6
7
# File 'lib/fog/libvirt/requests/compute/create_volume.rb', line 5

def create_volume(pool_name, xml)
  client.lookup_storage_pool_by_name(pool_name).create_vol_xml(xml)
end

#define_domain(xml) ⇒ Object



5
6
7
# File 'lib/fog/libvirt/requests/compute/define_domain.rb', line 5

def define_domain(xml)
  client.define_domain_xml(xml)
end

#define_pool(xml) ⇒ Object



5
6
7
# File 'lib/fog/libvirt/requests/compute/define_pool.rb', line 5

def define_pool(xml)
  client.define_storage_pool_xml(xml)
end

#destroy_interface(uuid) ⇒ Object

shutdown the interface



6
7
8
# File 'lib/fog/libvirt/requests/compute/destroy_interface.rb', line 6

def destroy_interface(uuid)
  client.lookup_interface_by_uuid(uuid).destroy
end

#destroy_network(uuid) ⇒ Object



5
6
7
# File 'lib/fog/libvirt/requests/compute/destroy_network.rb', line 5

def destroy_network(uuid)
  client.lookup_network_by_uuid(uuid).destroy
end

#dhcp_leases(uuid, mac, flags = 0) ⇒ Object



7
8
9
# File 'lib/fog/libvirt/requests/compute/dhcp_leases.rb', line 7

def dhcp_leases(uuid, mac, flags = 0)
  client.lookup_network_by_uuid(uuid).dhcp_leases(mac, flags)
end

#enhance_uri(uri) ⇒ Object



116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/fog/libvirt/compute.rb', line 116

def enhance_uri(uri)
  require 'cgi'
  append=""

  # on macosx, chances are we are using libvirt through homebrew
  # the client will default to a socket location based on it's own location (/opt)
  # we conveniently point it to /var/run/libvirt/libvirt-sock
  # if no socket option has been specified explicitly

  if RUBY_PLATFORM =~ /darwin/
    querystring=::URI.parse(uri).query
    if querystring.nil?
      append="?socket=/var/run/libvirt/libvirt-sock"
    else
      if !::CGI.parse(querystring).key?("socket")
        append="&socket=/var/run/libvirt/libvirt-sock"
      end
    end
  end
  uri+append
end

#get_node_infoObject



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# File 'lib/fog/libvirt/requests/compute/get_node_info.rb', line 5

def get_node_info
  node_hash = Hash.new
  node_info = client.node_get_info
  [:model, :memory, :cpus, :mhz, :nodes, :sockets, :cores, :threads].each do |param|
    node_hash[param] = node_info.send(param) rescue nil
  end
  [:type, :version, :node_free_memory, :max_vcpus].each do |param|
    node_hash[param] = client.send(param) rescue nil
  end
  node_hash[:uri] = client.uri
  xml = client.sys_info rescue nil
  [:uuid, :manufacturer, :product, :serial].each do |attr|
    node_hash[attr] = node_attr(attr, xml) rescue nil
  end if xml

  node_hash[:hostname] = client.hostname
  [node_hash]
end

#libversionObject



6
7
8
# File 'lib/fog/libvirt/requests/compute/libversion.rb', line 6

def libversion()
  client.libversion
end

#list_domains(filter = { }) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
# File 'lib/fog/libvirt/requests/compute/list_domains.rb', line 5

def list_domains(filter = { })
  data=[]

  if filter.key?(:uuid)
    data << client.lookup_domain_by_uuid(filter[:uuid])
  elsif filter.key?(:name)
    data << client.lookup_domain_by_name(filter[:name])
  else
    client.list_defined_domains.each { |name| data << catchLibvirtExceptions { client.lookup_domain_by_name(name) } } unless filter[:defined] == false
    client.list_domains.each { |id| data << catchLibvirtExceptions { client.lookup_domain_by_id(id) } } unless filter[:active] == false
  end
  data.compact.map { |d| domain_to_attributes d }.compact
end

#list_interfaces(filter = { }) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
# File 'lib/fog/libvirt/requests/compute/list_interfaces.rb', line 5

def list_interfaces(filter = { })
  data=[]
  if filter.keys.empty?
    active_networks = client.list_interfaces rescue []
    defined_networks = client.list_defined_interfaces rescue []
    (active_networks + defined_networks).each do |ifname|
      data << interface_to_attributes(client.lookup_interface_by_name(ifname))
    end
  else
    data = [interface_to_attributes(get_interface_by_filter(filter))]
  end
  data.compact
end

#list_networks(filter = { }) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
# File 'lib/fog/libvirt/requests/compute/list_networks.rb', line 5

def list_networks(filter = { })
  data=[]
  if filter.keys.empty?
    (client.list_networks + client.list_defined_networks).each do |network_name|
      data << network_to_attributes(client.lookup_network_by_name(network_name))
    end
  else
    data = [network_to_attributes(get_network_by_filter(filter))]
  end
  data
end

#list_pool_volumes(uuid) ⇒ Object



5
6
7
8
9
10
# File 'lib/fog/libvirt/requests/compute/list_pool_volumes.rb', line 5

def list_pool_volumes(uuid)
  pool = client.lookup_storage_pool_by_uuid uuid
  pool.list_volumes.map do |volume_name|
    volume_to_attributes(pool.lookup_volume_by_name(volume_name))
  end
end

#list_pools(filter = { }) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
# File 'lib/fog/libvirt/requests/compute/list_pools.rb', line 5

def list_pools(filter = { })
  data=[]
  if filter.key?(:name)
    data << find_pool_by_name(filter[:name])
  elsif filter.key?(:uuid)
    data << find_pool_by_uuid(filter[:uuid])
  else
    (client.list_storage_pools + client.list_defined_storage_pools).each do |name|
      data << find_pool_by_name(name)
    end
  end
  data.compact
end

#list_volumes(filter = { }) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# File 'lib/fog/libvirt/requests/compute/list_volumes.rb', line 5

def list_volumes(filter = { })
  data = []
  if filter.keys.empty?
    raw_volumes do |pool|
      pool.list_volumes.each do |volume_name|
        begin
          data << volume_to_attributes(pool.lookup_volume_by_name(volume_name))
        rescue ::Libvirt::RetrieveError
          # Catch libvirt exceptions to avoid race conditions involving
          # concurrent libvirt operations (like from another process)
          next
        end
      end
    end
  else
    data << get_volume(filter)
  end
  data.compact
end

#pool_action(uuid, action) ⇒ Object



5
6
7
8
9
# File 'lib/fog/libvirt/requests/compute/pool_action.rb', line 5

def pool_action(uuid, action)
  pool = client.lookup_storage_pool_by_uuid uuid
  pool.send(action)
  true
end

#terminateObject



112
113
114
# File 'lib/fog/libvirt/compute.rb', line 112

def terminate
  @client.close if @client and !@client.closed?
end

#update_autostart(uuid, value) ⇒ Object



5
6
7
8
# File 'lib/fog/libvirt/requests/compute/update_autostart.rb', line 5

def update_autostart(uuid, value)
  domain = client.lookup_domain_by_uuid(uuid)
  domain.autostart = value
end

#update_display(options = { }) ⇒ Object

Raises:

  • (ArgumentError)


5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/fog/libvirt/requests/compute/update_display.rb', line 5

def update_display(options = { })
  raise ArgumentError, "uuid is a required parameter" unless options.key? :uuid

  domain = client.lookup_domain_by_uuid(options[:uuid])

  display          = { }
  display[:type]   = options[:type] || 'vnc'
  display[:port]   = (options[:port] || -1).to_s
  display[:listen] = options[:listen].to_s   if options[:listen]
  display[:passwd] = options[:password].to_s if options[:password]
  display[:autoport] = 'yes' if display[:port] == '-1'
  new_keymap       = options[:keymap] || xml_elements(domain.xml_desc, "graphics", "keymap")[0]
  display[:keymap] = new_keymap unless new_keymap.nil?

  builder = Nokogiri::XML::Builder.new { graphics_ (display) }
  xml     = Nokogiri::XML(builder.to_xml).root.to_s

  domain.update_device(xml, 0)
  # if we got no exceptions, then we're good'
  true
end

#upload_volume(pool_name, volume_name, file_path) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# File 'lib/fog/libvirt/requests/compute/upload_volume.rb', line 5

def upload_volume(pool_name, volume_name, file_path)
  volume = client.lookup_storage_pool_by_name(pool_name).lookup_volume_by_name(volume_name)
  stream = client.stream

  image_file = File.open(file_path, "rb")
  volume.upload(stream, 0, image_file.size)
  stream.sendall do |_opaque, n|
    begin
      r = image_file.read(n)
      r ? [r.length, r] : [0, ""]
    rescue Exception => e
      [-1, ""]
    end
  end
  stream.finish
ensure
  image_file.close if image_file
end

#vm_action(uuid, action) ⇒ Object



5
6
7
8
9
# File 'lib/fog/libvirt/requests/compute/vm_action.rb', line 5

def vm_action(uuid, action)
  domain = client.lookup_domain_by_uuid(uuid)
  domain.send(action)
  true
end

#volume_action(key, action, options = {}) ⇒ Object



5
6
7
8
# File 'lib/fog/libvirt/requests/compute/volume_action.rb', line 5

def volume_action(key, action, options={})
  get_volume({:key => key}, true).send(action)
  true
end