class Libvirt::Connection

Constants

CLOSE_CALLBACK
CLOSE_STORAGE
DOMAIN_EVENT_CALLBACKS
DOMAIN_EVENT_IDS
DOMAIN_STORAGE
NETWORK_EVENT_CALLBACKS
NETWORK_EVENT_IDS
NETWORK_STORAGE
POOL_EVENT_CALLBACKS
POOL_EVENT_IDS
POOL_STORAGE

Public Class Methods

load_ref(conn_ptr) click to toggle source
# File lib/libvirt/connection.rb, line 60
def self.load_ref(conn_ptr)
  ref_result = FFI::Host.virConnectRef(conn_ptr)
  raise Errors::LibError, "Couldn't retrieve connection reference" if ref_result.negative?

  new(nil).tap { |r| r.send(:set_connection, conn_ptr) }
end
new(uri) click to toggle source
# File lib/libvirt/connection.rb, line 67
def initialize(uri)
  @uri = uri
  @conn_ptr = ::FFI::Pointer.new(0)
  @close_data = nil

  free = ->(obj_id) do
    Util.log(:debug) { "Finalize Libvirt::Connection 0x#{obj_id.to_s(16)} @conn_ptr=#{@conn_ptr}," }
    return if @conn_ptr.null?

    cl_result = FFI::Host.virConnectClose(@conn_ptr)
    warn "Couldn't close Libvirt::Connection (0x#{obj_id.to_s(16)}) pointer #{@conn_ptr.address}" if cl_result.negative?
  end
  ObjectSpace.define_finalizer(self, free)
end

Public Instance Methods

begin_interface_change() click to toggle source

@raise [Libvirt::Errors::LibError]

# File lib/libvirt/connection.rb, line 475
def begin_interface_change
  result = FFI::Interface.virInterfaceChangeBegin(@conn_ptr, 0)
  raise Errors::LibError, "Couldn't begin interface change" if result.negative?
end
capabilities() click to toggle source
# File lib/libvirt/connection.rb, line 420
def capabilities
  FFI::Host.virConnectGetCapabilities(@conn_ptr)
end
close() click to toggle source
# File lib/libvirt/connection.rb, line 89
def close
  result = FFI::Host.virConnectClose(@conn_ptr)
  raise Errors::LibError, "Couldn't close connection to #{@uri.inspect}" if result.negative?

  @conn_ptr = ::FFI::Pointer.new(0)
  true
end
commit_interface_change() click to toggle source

@raise [Libvirt::Errors::LibError]

# File lib/libvirt/connection.rb, line 481
def commit_interface_change
  result = FFI::Interface.virInterfaceChangeCommit(@conn_ptr, 0)
  raise Errors::LibError, "Couldn't commit interface change" if result.negative?
end
create_network(xml) click to toggle source

@param xml [String] @raise [Libvirt::Errors::LibError]

# File lib/libvirt/connection.rb, line 449
def create_network(xml)
  pointer = FFI::Network.virNetworkCreateXML(@ptr, xml)
  raise Errors::LibError, "Couldn't create network with xml" if pointer.null?

  Network.new(pointer)
end
define_domain(xml, options_or_flags = nil) click to toggle source
# File lib/libvirt/connection.rb, line 439
def define_domain(xml, options_or_flags = nil)
  flags = Util.parse_flags options_or_flags, FFI::Domain.enum_type(:define_flags)
  pointer = FFI::Domain.virDomainDefineXMLFlags(@conn_ptr, xml, flags)
  raise Errors::LibError, "Couldn't define domain" if pointer.null?

  Domain.new(pointer)
end
define_interface(xml) click to toggle source

@param xml [String] @raise [Libvirt::Errors::LibError]

# File lib/libvirt/connection.rb, line 467
def define_interface(xml)
  pointer = FFI::Interface.virInterfaceDefineXML(@conn_ptr, xml, 0)
  raise Errors::LibError, "Couldn't define interface with xml" if pointer.null?

  Interface.new(pointer)
end
define_network(xml) click to toggle source

@param xml [String] @raise [Libvirt::Errors::LibError]

# File lib/libvirt/connection.rb, line 458
def define_network(xml)
  pointer = FFI::Network.virNetworkDefineXML(@ptr, xml)
  raise Errors::LibError, "Couldn't define network with xml" if pointer.null?

  Network.new(pointer)
end
deregister_close_callback() click to toggle source
# File lib/libvirt/connection.rb, line 258
def deregister_close_callback
  dbg { '#deregister_close_callback' }

  result = FFI::Host.virConnectUnregisterCloseCallback(@conn_ptr, CLOSE_CALLBACK)
  raise Errors::LibError, "Couldn't deregister close callback" if result.negative?

  # virConnectUnregisterCloseCallback will call free func
  # So we don't need to remove object from CLOSE_STORAGE here.
  true
end
deregister_domain_event_callback(callback_id) click to toggle source
# File lib/libvirt/connection.rb, line 303
def deregister_domain_event_callback(callback_id)
  dbg { "#deregister_domain_event_callback callback_id=#{callback_id}" }

  result = FFI::Domain.virConnectDomainEventDeregisterAny(@conn_ptr, callback_id)
  raise Errors::LibError, "Couldn't deregister domain event callback" if result.negative?

  # virConnectDomainEventDeregisterAny will call free func
  # So we don't need to remove object from DOMAIN_STORAGE here.
  true
end
deregister_network_event_callback(callback_id) click to toggle source
# File lib/libvirt/connection.rb, line 391
def deregister_network_event_callback(callback_id)
  dbg { "#deregister_network_event_callback callback_id=#{callback_id}" }

  result = FFI::Network.virConnectNetworkEventDeregisterAny(@conn_ptr, callback_id)
  raise Errors::LibError, "Couldn't deregister network event callback" if result.negative?

  # virConnectNetworkEventDeregisterAny will call free func
  # So we don't need to remove object from NETWORK_STORAGE here.
  true
end
deregister_storage_pool_event_callback(callback_id) click to toggle source
# File lib/libvirt/connection.rb, line 347
def deregister_storage_pool_event_callback(callback_id)
  dbg { "#deregister_storage_pool_event_callback callback_id=#{callback_id}" }

  result = FFI::Storage.virConnectStoragePoolEventDeregisterAny(@conn_ptr, callback_id)
  raise Errors::LibError, "Couldn't deregister storage pool event callback" if result.negative?

  # virConnectStoragePoolEventDeregisterAny will call free func
  # So we don't need to remove object from POOL_STORAGE here.
  true
end
free_memory() click to toggle source
# File lib/libvirt/connection.rb, line 123
def free_memory
  result = FFI::Host.virNodeGetFreeMemory(@conn_ptr)
  raise Errors::LibError, "Couldn't set connection keep_alive" if result.negative?

  result
end
hostname() click to toggle source
# File lib/libvirt/connection.rb, line 411
def hostname
  FFI::Host.virConnectGetHostname(@conn_ptr)
end
inspect() click to toggle source
# File lib/libvirt/connection.rb, line 134
def inspect
  to_s
end
lib_version() click to toggle source
# File lib/libvirt/connection.rb, line 402
def lib_version
  version_ptr = ::FFI::MemoryPointer.new(:ulong)
  result = FFI::Host.virConnectGetLibVersion(@conn_ptr, version_ptr)
  raise Errors::LibError, "Couldn't get connection lib version" if result.negative?

  version_number = version_ptr.get_ulong(0)
  Util.parse_version(version_number)
end
list_all_domains(flags = 0) click to toggle source
# File lib/libvirt/connection.rb, line 145
def list_all_domains(flags = 0)
  size = list_all_domains_qty(flags)
  return [] if size.zero?

  domains_ptr = ::FFI::MemoryPointer.new(:pointer, size)
  result = FFI::Domain.virConnectListAllDomains(@conn_ptr, domains_ptr, flags)
  raise Errors::LibError, "Couldn't retrieve domains list with flags #{flags.to_s(16)}" if result.negative?

  ptr = domains_ptr.read_pointer
  ptr.get_array_of_pointer(0, size).map { |dom_ptr| Libvirt::Domain.new(dom_ptr) }
end
list_all_domains_qty(flags = 0) click to toggle source
# File lib/libvirt/connection.rb, line 138
def list_all_domains_qty(flags = 0)
  result = FFI::Domain.virConnectListAllDomains(@conn_ptr, nil, flags)
  raise Errors::LibError, "Couldn't retrieve domains qty with flags #{flags.to_s(16)}" if result.negative?

  result
end
list_all_interfaces(options_or_flags = nil) click to toggle source

@param options_or_flags [Array<Symbol>,Hash{Symbol=>Boolean},Integer,Symbol,nil] @return [Array<Libvirt::Interface>, Array] @raise [Libvirt::Errors::LibError]

# File lib/libvirt/connection.rb, line 219
def list_all_interfaces(options_or_flags = nil)
  flags = Util.parse_flags options_or_flags, FFI::Interface.enum_type(:list_all_flags)
  size = list_all_interfaces_qty(flags)
  return [] if size.zero?

  interfaces_ptr = ::FFI::MemoryPointer.new(:pointer, size)
  result = FFI::Interface.virConnectListAllInterfaces(@conn_ptr, interfaces_ptr, 0)
  raise Errors::LibError, "Couldn't retrieve interfaces list" if result.negative?

  ptr = interfaces_ptr.read_pointer
  ptr.get_array_of_pointer(0, size).map { |i_ptr| Interface.new(i_ptr) }
end
list_all_interfaces_qty(options_or_flags = nil) click to toggle source

@param options_or_flags [Array<Symbol>,Hash{Symbol=>Boolean},Integer,Symbol,nil] @return [Integer] @raise [Libvirt::Errors::LibError]

# File lib/libvirt/connection.rb, line 208
def list_all_interfaces_qty(options_or_flags = nil)
  flags = Util.parse_flags options_or_flags, FFI::Interface.enum_type(:list_all_flags)
  result = FFI::Interface.virConnectListAllInterfaces(@conn_ptr, nil, flags)
  raise Errors::LibError, "Couldn't retrieve interfaces qty with flags #{flags.to_s(16)}" if result.negative?

  result
end
list_all_networks(options_or_flags = nil) click to toggle source

@param options_or_flags [Array<Symbol>,Hash{Symbol=>Boolean},Integer,Symbol,nil] @return [Array<Libvirt::Network>, Array] @raise [Libvirt::Errors::LibError]

# File lib/libvirt/connection.rb, line 192
def list_all_networks(options_or_flags = nil)
  flags = Util.parse_flags options_or_flags, FFI::Network.enum_type(:list_all_flags)
  size = list_all_networks_qty(flags)
  return [] if size.zero?

  networks_ptr = ::FFI::MemoryPointer.new(:pointer, size)
  result = FFI::Network.virConnectListAllNetworks(@conn_ptr, networks_ptr, 0)
  raise Errors::LibError, "Couldn't retrieve networks list" if result.negative?

  ptr = networks_ptr.read_pointer
  ptr.get_array_of_pointer(0, size).map { |n_ptr| Network.new(n_ptr) }
end
list_all_networks_qty(options_or_flags = nil) click to toggle source

@param options_or_flags [Array<Symbol>,Hash{Symbol=>Boolean},Integer,Symbol,nil] @return [Integer] @raise [Libvirt::Errors::LibError]

# File lib/libvirt/connection.rb, line 181
def list_all_networks_qty(options_or_flags = nil)
  flags = Util.parse_flags options_or_flags, FFI::Network.enum_type(:list_all_flags)
  result = FFI::Network.virConnectListAllNetworks(@conn_ptr, nil, flags)
  raise Errors::LibError, "Couldn't retrieve networks qty with flags #{flags.to_s(16)}" if result.negative?

  result
end
list_all_storage_pools(options_or_flags = nil) click to toggle source
# File lib/libvirt/connection.rb, line 165
def list_all_storage_pools(options_or_flags = nil)
  flags = Util.parse_flags options_or_flags, FFI::Storage.enum_type(:list_all_pools_flags)
  size = list_all_storage_pools_qty(flags)
  return [] if size.zero?

  storage_pools_ptr = ::FFI::MemoryPointer.new(:pointer, size)
  result = FFI::Storage.virConnectListAllStoragePools(@conn_ptr, storage_pools_ptr, flags)
  raise Errors::LibError, "Couldn't retrieve storage pools list with flags #{flags.to_s(16)}" if result.negative?

  ptr = storage_pools_ptr.read_pointer
  ptr.get_array_of_pointer(0, size).map { |stp_ptr| StoragePool.new(stp_ptr) }
end
list_all_storage_pools_qty(options_or_flags = nil) click to toggle source
# File lib/libvirt/connection.rb, line 157
def list_all_storage_pools_qty(options_or_flags = nil)
  flags = Util.parse_flags options_or_flags, FFI::Storage.enum_type(:list_all_pools_flags)
  result = FFI::Storage.virConnectListAllStoragePools(@conn_ptr, nil, flags)
  raise Errors::LibError, "Couldn't retrieve storage pools qty with flags #{flags.to_s(16)}" if result.negative?

  result
end
max_vcpus(type = nil) click to toggle source

@param type [String,NilClass]

# File lib/libvirt/connection.rb, line 416
def max_vcpus(type = nil)
  FFI::Host.virConnectGetMaxVcpus(@conn_ptr, type)
end
node_info() click to toggle source
# File lib/libvirt/connection.rb, line 424
def node_info
  node_info_ptr = ::FFI::MemoryPointer.new(FFI::Host::NodeInfoStruct.by_value)
  result = FFI::Host.virNodeGetInfo(@conn_ptr, node_info_ptr)
  raise Errors::LibError, "Couldn't get connection node info" if result.negative?

  NodeInfo.new(node_info_ptr)
end
open() click to toggle source
# File lib/libvirt/connection.rb, line 82
def open
  @conn_ptr = FFI::Host.virConnectOpen(@uri)
  raise Errors::LibError, "Couldn't open connection to #{@uri.inspect}" if @conn_ptr.null?

  true
end
opened?() click to toggle source
# File lib/libvirt/connection.rb, line 97
def opened?
  !@conn_ptr.null?
end
register_close_callback(opaque = nil, &block) click to toggle source
# File lib/libvirt/connection.rb, line 232
def register_close_callback(opaque = nil, &block)
  dbg { "#register_close_callback opaque=#{opaque}" }

  cb_data, cb_data_free_func = CLOSE_STORAGE.allocate_struct
  result = FFI::Host.virConnectRegisterCloseCallback(
      @conn_ptr,
      CLOSE_CALLBACK,
      cb_data.pointer,
      cb_data_free_func
  )
  if result.negative?
    cb_data.pointer.free
    raise Errors::LibError, "Couldn't register connection close callback"
  end

  CLOSE_STORAGE.store_struct(
      cb_data,
      connection_pointer: @conn_ptr,
      callback_id: result,
      cb: block,
      opaque: opaque,
      free_func: cb_data_free_func
  )
  result
end
register_domain_event_callback(event_id, domain = nil, opaque = nil, &block) click to toggle source

@yield conn, dom, *args

# File lib/libvirt/connection.rb, line 270
def register_domain_event_callback(event_id, domain = nil, opaque = nil, &block)
  dbg { "#register_domain_event_callback event_id=#{event_id}" }

  enum = FFI::Domain.enum_type(:event_id)
  event_id, event_id_sym = Util.parse_enum(enum, event_id)
  cb = DOMAIN_EVENT_CALLBACKS.fetch(event_id_sym)

  cb_data, cb_data_free_func = DOMAIN_STORAGE.allocate_struct

  result = FFI::Domain.virConnectDomainEventRegisterAny(
      @conn_ptr,
      domain&.to_ptr,
      event_id,
      cb,
      cb_data.pointer,
      cb_data_free_func
  )
  if result.negative?
    cb_data.pointer.free
    raise Errors::LibError, "Couldn't register domain event callback"
  end

  DOMAIN_STORAGE.store_struct(
      cb_data,
      connection_pointer: @conn_ptr,
      callback_id: result,
      cb: block,
      opaque: opaque,
      free_func: cb_data_free_func
  )
  result
end
register_network_event_callback(event_id, network = nil, opaque = nil, &block) click to toggle source
# File lib/libvirt/connection.rb, line 358
def register_network_event_callback(event_id, network = nil, opaque = nil, &block)
  dbg { "#register_network_event_callback event_id=#{event_id}" }

  enum = FFI::Network.enum_type(:event_id)
  event_id, event_id_sym = Util.parse_enum(enum, event_id)
  cb = NETWORK_EVENT_CALLBACKS.fetch(event_id_sym)

  cb_data, cb_data_free_func = NETWORK_STORAGE.allocate_struct

  result = FFI::Network.virConnectNetworkEventRegisterAny(
      @conn_ptr,
      network&.to_ptr,
      event_id,
      cb,
      cb_data.pointer,
      cb_data_free_func
  )
  if result.negative?
    cb_data.pointer.free
    raise Errors::LibError, "Couldn't register network event callback"
  end

  NETWORK_STORAGE.store_struct(
      cb_data,
      connection_pointer: @conn_ptr,
      callback_id: result,
      cb: block,
      opaque: opaque,
      free_func: cb_data_free_func
  )
  result
end
register_storage_pool_event_callback(event_id, storage_pool = nil, opaque = nil, &block) click to toggle source
# File lib/libvirt/connection.rb, line 314
def register_storage_pool_event_callback(event_id, storage_pool = nil, opaque = nil, &block)
  dbg { "#register_storage_pool_event_callback event_id=#{event_id}" }

  enum = FFI::Storage.enum_type(:event_id)
  event_id, event_id_sym = Util.parse_enum(enum, event_id)
  cb = POOL_EVENT_CALLBACKS.fetch(event_id_sym)

  cb_data, cb_data_free_func = POOL_STORAGE.allocate_struct

  result = FFI::Storage.virConnectStoragePoolEventRegisterAny(
      @conn_ptr,
      storage_pool&.to_ptr,
      event_id,
      cb,
      cb_data.pointer,
      cb_data_free_func
  )
  if result.negative?
    cb_data.pointer.free
    raise Errors::LibError, "Couldn't register storage pool event callback"
  end

  POOL_STORAGE.store_struct(
      cb_data,
      connection_pointer: @conn_ptr,
      callback_id: result,
      cb: block,
      opaque: opaque,
      free_func: cb_data_free_func
  )
  result
end
rollback_interface_change() click to toggle source

@raise [Libvirt::Errors::LibError]

# File lib/libvirt/connection.rb, line 487
def rollback_interface_change
  result = FFI::Interface.virInterfaceChangeRollback(@conn_ptr, 0)
  raise Errors::LibError, "Couldn't rollback interface change" if result.negative?
end
set_keep_alive(interval, count) click to toggle source
# File lib/libvirt/connection.rb, line 116
def set_keep_alive(interval, count)
  result = FFI::Host.virConnectSetKeepAlive(@conn_ptr, interval, count)
  raise Errors::LibError, "Couldn't set connection keep_alive" if result.negative?

  result.zero?
end
stream(flags = 0) click to toggle source
# File lib/libvirt/connection.rb, line 432
def stream(flags = 0)
  pointer = FFI::Stream.virStreamNew(@conn_ptr, flags)
  raise Errors::LibError, "Couldn't create stream" if pointer.null?

  Stream.new(pointer)
end
to_ptr() click to toggle source
# File lib/libvirt/connection.rb, line 101
def to_ptr
  @conn_ptr
end
to_s() click to toggle source
# File lib/libvirt/connection.rb, line 130
def to_s
  "#<#{self.class}:0x#{object_id.to_s(16)} @uri=#{@uri.inspect} @conn_ptr=0x#{@conn_ptr.address.to_s(16)}>"
end
version() click to toggle source
# File lib/libvirt/connection.rb, line 105
def version
  check_open!

  version_ptr = ::FFI::MemoryPointer.new(:ulong)
  result = FFI::Host.virConnectGetVersion(@conn_ptr, version_ptr)
  raise Errors::LibError, "Couldn't retrieve connection version" if result.negative?

  version_number = version_ptr.get_ulong(0)
  Util.parse_version(version_number)
end

Private Instance Methods

check_open!() click to toggle source
# File lib/libvirt/connection.rb, line 498
def check_open!
  raise Errors::LibError, "Connection to #{@uri.inspect} is not open" if @conn_ptr.null?
end
dbg(&block) click to toggle source
# File lib/libvirt/connection.rb, line 502
def dbg(&block)
  Util.log(:debug, 'Libvirt::Connection', &block)
end
set_connection(conn_ptr) click to toggle source
# File lib/libvirt/connection.rb, line 494
def set_connection(conn_ptr)
  @conn_ptr = conn_ptr
end