Module: Fog::Libvirt::Compute::Shared

Includes:
Util
Included in:
Mock, Real
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/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, #xml_element, #xml_elements

Instance Attribute Details

#clientObject (readonly)

Returns the value of attribute client.



53
54
55
# File 'lib/fog/libvirt/compute.rb', line 53

def client
  @client
end

#uriObject (readonly)

Returns the value of attribute uri.



54
55
56
# File 'lib/fog/libvirt/compute.rb', line 54

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

#enhance_uri(uri) ⇒ Object



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/fog/libvirt/compute.rb', line 91

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 and
  # if the socket exists

  socketpath="/var/run/libvirt/libvirt-sock"
  if RUBY_PLATFORM =~ /darwin/ && File.exist?(socketpath)
    querystring=::URI.parse(uri).query
    if querystring.nil?
      append="?socket=#{socketpath}"
    elsif !::CGI.parse(querystring).key?("socket")
      append="&socket=#{socketpath}"
    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

#initialize(options = {}) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/fog/libvirt/compute.rb', line 56

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

  # 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

#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], filter[:include_inactive])
  elsif filter.key?(:uuid)
    data << find_pool_by_uuid(filter[:uuid], filter[:include_inactive])
  else
    (client.list_storage_pools + client.list_defined_storage_pools).each do |name|
      data << find_pool_by_name(name, filter[:include_inactive])
    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



87
88
89
# File 'lib/fog/libvirt/compute.rb', line 87

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, *params) ⇒ Object



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

def vm_action(uuid, action, *params)
  domain = client.lookup_domain_by_uuid(uuid)
  domain.send(action, *params)
  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