libvirt 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. data/.gitignore +10 -0
  2. data/.yardopts +3 -0
  3. data/CHANGELOG.md +3 -0
  4. data/Gemfile +12 -0
  5. data/Gemfile.lock +36 -0
  6. data/README.md +83 -0
  7. data/Rakefile +20 -0
  8. data/docs/user_guide.md +259 -0
  9. data/examples/README.md +10 -0
  10. data/examples/create_domain.rb +46 -0
  11. data/examples/print_domain_info.rb +46 -0
  12. data/examples/print_hypervisor_info.rb +40 -0
  13. data/lib/ffi/libvirt/domain_info.rb +12 -0
  14. data/lib/ffi/libvirt/error.rb +25 -0
  15. data/lib/ffi/libvirt/error_functions.rb +21 -0
  16. data/lib/ffi/libvirt/error_types.rb +125 -0
  17. data/lib/ffi/libvirt/functions.rb +363 -0
  18. data/lib/ffi/libvirt/node_info.rb +27 -0
  19. data/lib/ffi/libvirt/storage_pool_info.rb +11 -0
  20. data/lib/ffi/libvirt/storage_volume_info.rb +14 -0
  21. data/lib/ffi/libvirt/types.rb +61 -0
  22. data/lib/ffi/libvirt/util.rb +19 -0
  23. data/lib/ffi/libvirt/version.rb +46 -0
  24. data/lib/ffi/libvirt.rb +29 -0
  25. data/lib/libvirt/collection/abstract_collection.rb +49 -0
  26. data/lib/libvirt/collection/domain_collection.rb +98 -0
  27. data/lib/libvirt/collection/interface_collection.rb +16 -0
  28. data/lib/libvirt/collection/network_collection.rb +58 -0
  29. data/lib/libvirt/collection/node_device_collection.rb +29 -0
  30. data/lib/libvirt/collection/nwfilter_collection.rb +15 -0
  31. data/lib/libvirt/collection/storage_pool_collection.rb +58 -0
  32. data/lib/libvirt/collection/storage_volume_collection.rb +57 -0
  33. data/lib/libvirt/collection.rb +12 -0
  34. data/lib/libvirt/connection.rb +225 -0
  35. data/lib/libvirt/domain.rb +241 -0
  36. data/lib/libvirt/error.rb +91 -0
  37. data/lib/libvirt/exception.rb +19 -0
  38. data/lib/libvirt/network.rb +118 -0
  39. data/lib/libvirt/node.rb +118 -0
  40. data/lib/libvirt/node_device.rb +75 -0
  41. data/lib/libvirt/spec/device/disk.rb +58 -0
  42. data/lib/libvirt/spec/device/emulator.rb +23 -0
  43. data/lib/libvirt/spec/device.rb +8 -0
  44. data/lib/libvirt/spec/domain/os_booting.rb +69 -0
  45. data/lib/libvirt/spec/domain.rb +71 -0
  46. data/lib/libvirt/spec.rb +12 -0
  47. data/lib/libvirt/storage_pool.rb +164 -0
  48. data/lib/libvirt/storage_volume.rb +109 -0
  49. data/lib/libvirt/version.rb +3 -0
  50. data/lib/libvirt.rb +53 -0
  51. data/libvirt.gemspec +27 -0
  52. data/test/libvirt/collection/abstract_collection_test.rb +14 -0
  53. data/test/libvirt/collection/domain_collection_test.rb +122 -0
  54. data/test/libvirt/collection/interface_collection_test.rb +9 -0
  55. data/test/libvirt/collection/network_collection_test.rb +41 -0
  56. data/test/libvirt/collection/node_device_collection_test.rb +24 -0
  57. data/test/libvirt/collection/nwfilter_collection_test.rb +7 -0
  58. data/test/libvirt/collection/storage_pool_collection_test.rb +41 -0
  59. data/test/libvirt/collection/storage_volume_collection_test.rb +86 -0
  60. data/test/libvirt/connection_test.rb +133 -0
  61. data/test/libvirt/domain_test.rb +221 -0
  62. data/test/libvirt/error_test.rb +93 -0
  63. data/test/libvirt/libvirt_test.rb +16 -0
  64. data/test/libvirt/network_test.rb +76 -0
  65. data/test/libvirt/node_device_test.rb +16 -0
  66. data/test/libvirt/node_test.rb +24 -0
  67. data/test/libvirt/spec/devices/disk_test.rb +107 -0
  68. data/test/libvirt/spec/devices/emulator_test.rb +20 -0
  69. data/test/libvirt/spec/domain_test.rb +17 -0
  70. data/test/libvirt/storage_pool_test.rb +133 -0
  71. data/test/libvirt/storage_volume_test.rb +63 -0
  72. data/test/support/xml_assertions.rb +29 -0
  73. data/test/test_helper.rb +23 -0
  74. metadata +219 -0
@@ -0,0 +1,29 @@
1
+ require 'ffi'
2
+
3
+ module FFI
4
+ # The FFI Libvirt module contains the raw access to the Libvirt C
5
+ # API. This module contains no fluff or nice abstractions above the API,
6
+ # and is actually a way to access the C API directly. This also means
7
+ # that it is up to you to manage all the pointers and so on that come
8
+ # with this power.
9
+ module Libvirt
10
+ extend FFI::Library
11
+ ffi_lib "libvirt"
12
+
13
+ autoload :Util, 'ffi/libvirt/util'
14
+ end
15
+ end
16
+
17
+ # The order matters here, sadly. If you muck with the ordering and
18
+ # no exceptions are raised while running tests, you're probably okay.
19
+ # But, still, be careful.
20
+ require 'ffi/libvirt/types'
21
+ require 'ffi/libvirt/version'
22
+ require 'ffi/libvirt/functions'
23
+ require 'ffi/libvirt/error_types'
24
+ require 'ffi/libvirt/error_functions'
25
+ require 'ffi/libvirt/domain_info'
26
+ require 'ffi/libvirt/error'
27
+ require 'ffi/libvirt/node_info'
28
+ require 'ffi/libvirt/storage_pool_info'
29
+ require 'ffi/libvirt/storage_volume_info'
@@ -0,0 +1,49 @@
1
+ require 'forwardable'
2
+
3
+ module Libvirt
4
+ module Collection
5
+ # Abstract parent class for all collections within libvirt.
6
+ #
7
+ # Subclasses of any collection are expected to implement the function
8
+ # `all` which returns all results of a collection. This will automatically
9
+ # make the enumerability work as well as some methods such as
10
+ # `first` and `length`.
11
+ class AbstractCollection
12
+ include Enumerable
13
+ extend Forwardable
14
+ def_delegators :all, :first, :last, :each, :length, :[], :inspect, :to_s
15
+
16
+ attr_reader :interface
17
+
18
+ # Initializes a new collection. All collections belong to a parent
19
+ # structure in some way, which is expected to be passed in here.
20
+ #
21
+ # @param [Object] Parent object
22
+ def initialize(interface)
23
+ @interface = interface
24
+ end
25
+
26
+ protected
27
+
28
+ # A helper method to follow libvirt's API conventions to get the
29
+ # values of an array.
30
+ #
31
+ # @param [Symbol] getter Getter for the array
32
+ # @param [Symbol] count Method for getting the size of the array
33
+ # @param [Symbol] type Type of value returned
34
+ # @return [Array]
35
+ def read_array(getter, counter, type)
36
+ count_max = FFI::Libvirt.send(counter, interface)
37
+ output_ptr = FFI::MemoryPointer.new(:pointer, count_max)
38
+ count_returned = FFI::Libvirt.send(getter, interface, output_ptr, count_max)
39
+ output_ptr.send("get_array_of_#{type}", 0, count_returned)
40
+ end
41
+
42
+ # A helper method to wrap the resulting method call in an object
43
+ # if the pointer result is not null, or return nil otherwise.
44
+ def nil_or_object(result, klass)
45
+ result.null? ? nil : klass.new(result)
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,98 @@
1
+ module Libvirt
2
+ module Collection
3
+ # Represents a collection of domains. This is an enumerable (in the Ruby sense)
4
+ # object, but it is not directly an `Array`. This collection is a special enumerable
5
+ # which allows you to do things such as get only the active domains, create a new
6
+ # domain from a specification, etc.
7
+ #
8
+ # If you enumerate the entire collection, then this is equivalent to enumerating
9
+ # over {#all} domains. e.g. `collection.length` is equivalent to calling
10
+ # `collection.all.length` (where `collection` is a `DomainCollection` object).
11
+ class DomainCollection < AbstractCollection
12
+ # Searches for a domain. This will search first by name, then by ID,
13
+ # then by UUID, returning a result as soon as one is found.
14
+ #
15
+ # @return [Domain]
16
+ def find(value)
17
+ result = find_by_name(value) rescue nil
18
+ result ||= find_by_id(value) rescue nil
19
+ result ||= find_by_uuid(value) rescue nil
20
+ end
21
+
22
+ # Searches for a domain by name.
23
+ #
24
+ # @return [Domain]
25
+ def find_by_name(name)
26
+ nil_or_object(FFI::Libvirt.virDomainLookupByName(interface, name), Domain)
27
+ end
28
+
29
+ # Searches for a domain by ID.
30
+ #
31
+ # @return [Domain]
32
+ def find_by_id(id)
33
+ nil_or_object(FFI::Libvirt.virDomainLookupByID(interface, id), Domain)
34
+ end
35
+
36
+ # Searches for a domain by UUID.
37
+ #
38
+ # @return [Domain]
39
+ def find_by_uuid(uuid)
40
+ nil_or_object(FFI::Libvirt.virDomainLookupByUUIDString(interface, uuid), Domain)
41
+ end
42
+
43
+ # Defines a new domain with the given valid specification. This method
44
+ # doesn't start the domain.
45
+ #
46
+ # @param [Object] spec
47
+ # @return [Domain]
48
+ def define(spec)
49
+ spec = spec.is_a?(String) ? spec : spec.to_xml
50
+ nil_or_object(FFI::Libvirt.virDomainDefineXML(interface, spec), Domain)
51
+ end
52
+
53
+ # Creates a new domain and starts it. This domain configuration is not
54
+ # persisted, so it may disappear after the next reboot or shutdown.
55
+ #
56
+ # @param [Object] spec
57
+ # @return [Domain]
58
+ def create(spec)
59
+ spec = spec.is_a?(String) ? spec : spec.to_xml
60
+ nil_or_object(FFI::Libvirt.virDomainCreateXML(interface, spec, 0), Domain)
61
+ end
62
+
63
+ # Returns all the active (running) domains for the connection which this
64
+ # collection belongs to.
65
+ #
66
+ # @return [Array<Domain>]
67
+ def active
68
+ # Do some pointer and array fiddling to extract the ids of the active
69
+ # domains from the libvirt API
70
+ ids = read_array(:virConnectListDomains, :virConnectNumOfDomains, :int)
71
+
72
+ # Lookup all the IDs and make them proper Domain objects
73
+ ids.collect { |id| find_by_id(id) }
74
+ end
75
+
76
+ # Returns all the inactive (not running) domains for the connection
77
+ # which this collection belongs to.
78
+ #
79
+ # @return [Array<Domain>]
80
+ def inactive
81
+ # Do some pointer and array fiddling to extract the names of the active
82
+ # domains from the libvirt API
83
+ ids = read_array(:virConnectListDefinedDomains, :virConnectNumOfDefinedDomains, :string)
84
+
85
+ # Lookup all the names and make them proper Domain objects
86
+ ids.collect { |id| find_by_name(id) }
87
+ end
88
+
89
+ # Returns all domains (active and inactive) for the connection this collection
90
+ # belongs to.
91
+ #
92
+ # @return [Array<Domain>]
93
+ def all
94
+ active + inactive
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,16 @@
1
+ module Libvirt
2
+ module Collection
3
+ # Represents a collection of interfaces. This is an enumerable (in the
4
+ # Ruby sense) object, but it is not directly an `Array`.
5
+ class InterfaceCollection < AbstractCollection
6
+ # Returns all the active interfaces for the connection which this
7
+ # collection belongs to.
8
+ #
9
+ # @return [Array<Interface>]
10
+ def active
11
+ # TODO: Doesn't work on mac :) must dev on linux
12
+ # read_array(:virConnectListInterfaces, :virConnectNumOfInterfaces, :string)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,58 @@
1
+ module Libvirt
2
+ module Collection
3
+ # Represents a collection of networks. This is an enumerable (in the
4
+ # Ruby sense) object, but it is not directly an `Array`.
5
+ class NetworkCollection < AbstractCollection
6
+ # Searches for a network. This will first search by name, then
7
+ # by UUID.
8
+ #
9
+ # @return [Network]
10
+ def find(value)
11
+ result = find_by_name(value) rescue nil
12
+ result ||= find_by_uuid(value) rescue nil
13
+ end
14
+
15
+ # Searches for a network by name.
16
+ #
17
+ # @return [Network]
18
+ def find_by_name(name)
19
+ nil_or_object(FFI::Libvirt.virNetworkLookupByName(interface, name), Network)
20
+ end
21
+
22
+ # Searches for a network by UUID.
23
+ #
24
+ # @return [Network]
25
+ def find_by_uuid(uuid)
26
+ nil_or_object(FFI::Libvirt.virNetworkLookupByUUIDString(interface, uuid), Network)
27
+ end
28
+
29
+ # Returns all the active networks for the connection which this
30
+ # collection belongs to.
31
+ #
32
+ # @return [Array<Network>]
33
+ def active
34
+ read_array(:virConnectListNetworks, :virConnectNumOfNetworks, :string).collect do |name|
35
+ find_by_name(name)
36
+ end
37
+ end
38
+
39
+ # Returns all the inactive networks for the connection which this
40
+ # collection belongs to.
41
+ #
42
+ # @return [Array<Network>]
43
+ def inactive
44
+ read_array(:virConnectListDefinedNetworks, :virConnectNumOfDefinedNetworks, :string).collect do |name|
45
+ find_by_name(name)
46
+ end
47
+ end
48
+
49
+ # Returns all networks (active and inactive) for the connection this
50
+ # collection belongs to.
51
+ #
52
+ # @return [Array<Netowrk>]
53
+ def all
54
+ active + inactive
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,29 @@
1
+ module Libvirt
2
+ module Collection
3
+ # Represents a collection of devices on a given node. Retrieve
4
+ # this collection using {Node#devices}.
5
+ class NodeDeviceCollection < AbstractCollection
6
+ # Create a node device on the host system.
7
+ #
8
+ # @return [NodeDevice]
9
+ def create(spec)
10
+ nil_or_object(FFI::Libvirt.virNodeDeviceCreateXML(interface, spec, 0), NodeDevice)
11
+ end
12
+
13
+ # Returns all of the node devices for the given connection.
14
+ #
15
+ # @return [Array<NodeDevice>]
16
+ def all
17
+ # We can't use the `read_array` helper here due to the methods being
18
+ # a bit different.
19
+ count_max = FFI::Libvirt.virNodeNumOfDevices(interface, nil, 0)
20
+ output_ptr = FFI::MemoryPointer.new(:pointer, count_max)
21
+ count_returned = FFI::Libvirt.virNodeListDevices(interface, nil, output_ptr, count_max, 0)
22
+
23
+ output_ptr.get_array_of_string(0, count_returned).collect do |name|
24
+ nil_or_object(FFI::Libvirt.virNodeDeviceLookupByName(interface, name), NodeDevice)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,15 @@
1
+ module Libvirt
2
+ module Collection
3
+ # Represents a collection of network filters.
4
+ class NWFilterCollection < AbstractCollection
5
+ # Returns all network filters.
6
+ #
7
+ # @return [Array<NWFilter>]
8
+ def all
9
+ read_array(:virConnectListNWFilters, :virConnectNumOfNWFilters, :string).each do |name|
10
+ # TODO
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,58 @@
1
+ module Libvirt
2
+ module Collection
3
+ # Represents a collection of storage pools.
4
+ class StoragePoolCollection < AbstractCollection
5
+ # Search for a storage pool. This will first search by name and
6
+ # then by UUID, returning the first result returned.
7
+ #
8
+ # @return [StoragePool]
9
+ def find(value)
10
+ result = find_by_name(value) rescue nil
11
+ result ||= find_by_uuid(value) rescue nil
12
+ end
13
+
14
+ # Search for a storage pool by name.
15
+ #
16
+ # @return [StoragePool]
17
+ def find_by_name(name)
18
+ nil_or_object(FFI::Libvirt.virStoragePoolLookupByName(interface, name), StoragePool)
19
+ end
20
+
21
+ # Search for a storage pool by UUID.
22
+ #
23
+ # @return [StoragePool]
24
+ def find_by_uuid(uuid)
25
+ nil_or_object(FFI::Libvirt.virStoragePoolLookupByUUIDString(interface, uuid), StoragePool)
26
+ end
27
+
28
+ # Returns the inactive storage pools.
29
+ #
30
+ # @return [Array<StoragePool>]
31
+ def inactive
32
+ read_array(:virConnectListDefinedStoragePools, :virConnectNumOfDefinedStoragePools, :string).collect do |name|
33
+ find_by_name(name)
34
+ end
35
+ end
36
+
37
+ # Returns the active storage pools.
38
+ #
39
+ # @return [Array<StoragePool>]
40
+ def active
41
+ read_array(:virConnectListStoragePools, :virConnectNumOfStoragePools, :string).collect do |name|
42
+ find_by_name(name)
43
+ end
44
+ end
45
+
46
+ # Returns all storage pools.
47
+ #
48
+ # @return [Array<StoragePool>]
49
+ def all
50
+ inactive + active
51
+ rescue Exception::LibvirtError
52
+ # If inactive isn't supported, then we just return the active
53
+ # storage pools.
54
+ active
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,57 @@
1
+ module Libvirt
2
+ module Collection
3
+ # Represents a collection of storage volumes, which belongs to a
4
+ # storage pool.
5
+ class StorageVolumeCollection < AbstractCollection
6
+ # Searches for a storage volume. This will search by name, then by
7
+ # key, then finally by path. If no storage volume is found, nil will
8
+ # be returned.
9
+ #
10
+ # @return [StorageVolume]
11
+ def find(value)
12
+ result = find_by_name(value) rescue nil
13
+ result ||= find_by_key(value) rescue nil
14
+ result ||= find_by_path(value) rescue nil
15
+ end
16
+
17
+ # Searches for a storage volume by name.
18
+ #
19
+ # @return [StorageVolume]
20
+ def find_by_name(name)
21
+ nil_or_object(FFI::Libvirt.virStorageVolLookupByName(interface, name), StorageVolume)
22
+ end
23
+
24
+ # Searches for a storage volume by key.
25
+ #
26
+ # @return [StorageVolume]
27
+ def find_by_key(key)
28
+ nil_or_object(FFI::Libvirt.virStorageVolLookupByKey(interface.connection, key), StorageVolume)
29
+ end
30
+
31
+ # Searches for a storage volume by path.
32
+ #
33
+ # @return [StorageVolume]
34
+ def find_by_path(path)
35
+ nil_or_object(FFI::Libvirt.virStorageVolLookupByPath(interface.connection, path), StorageVolume)
36
+ end
37
+
38
+ # Creates a new storage volume from an XML specification.
39
+ #
40
+ # @return [StorageVolume]
41
+ def create(spec)
42
+ nil_or_object(FFI::Libvirt.virStorageVolCreateXML(interface, spec, 0), StorageVolume)
43
+ end
44
+
45
+ # Returns all storage volumes. Its unnecessary to call this directly
46
+ # since the {#all} array is delegated for the various `Array`-like
47
+ # methods.
48
+ #
49
+ # @return [Array]
50
+ def all
51
+ read_array(:virStoragePoolListVolumes, :virStoragePoolNumOfVolumes, :string).collect do |name|
52
+ find_by_name(name)
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,12 @@
1
+ module Libvirt
2
+ module Collection
3
+ autoload :AbstractCollection, 'libvirt/collection/abstract_collection'
4
+ autoload :DomainCollection, 'libvirt/collection/domain_collection'
5
+ autoload :InterfaceCollection, 'libvirt/collection/interface_collection'
6
+ autoload :NetworkCollection, 'libvirt/collection/network_collection'
7
+ autoload :NodeDeviceCollection, 'libvirt/collection/node_device_collection'
8
+ autoload :NWFilterCollection, 'libvirt/collection/nwfilter_collection'
9
+ autoload :StoragePoolCollection, 'libvirt/collection/storage_pool_collection'
10
+ autoload :StorageVolumeCollection, 'libvirt/collection/storage_volume_collection'
11
+ end
12
+ end
@@ -0,0 +1,225 @@
1
+ module Libvirt
2
+ # Describes a connection to an instance of libvirt. This instance may be local
3
+ # or remote.
4
+ #
5
+ # # Initiating a Connection
6
+ #
7
+ # ## Basic
8
+ #
9
+ # A basic example of initiating a connection is to just allow the libvirt client
10
+ # library to choose the best (first available) hypervisor for you. If you're only
11
+ # running one hypervisor or you're not sure what is available on your machine,
12
+ # then this is the easiest option to get started:
13
+ #
14
+ # conn = Libvirt::Connection.new
15
+ #
16
+ # A shortcut is also provided for your convenience:
17
+ #
18
+ # conn = Libvirt.connect
19
+ #
20
+ # ## Specifying a URI
21
+ #
22
+ # Libvirt connections are made by giving a URI to libvirt, which can describe
23
+ # a local or remote libvirt instance (remote being that `libvirtd` is running).
24
+ # The following is an example of a local VirtualBox connection:
25
+ #
26
+ # conn = Libvirt::Connection.new("vbox:///session")
27
+ #
28
+ # And perhaps a remote qemu connection:
29
+ #
30
+ # conn = Libvirt::Connection.new("qemu+tcp://10.0.0.1/system")
31
+ #
32
+ # # Readonly Connections
33
+ #
34
+ # A readonly connection can be made by specifying the `readonly` option to be
35
+ # truthy. A couple examples follow:
36
+ #
37
+ # conn = Libvirt::Connection.new("vbox:///session", :readonly => true)
38
+ # conn = Libvirt::Connection.new(:readonly => true)
39
+ #
40
+ # # Basic Information of a Connection
41
+ #
42
+ # Once you have a connection object, you can gather basic information about it
43
+ # by using methods such as {#name}, {#capabilities}, etc.:
44
+ #
45
+ # puts "Hypervisor type: #{conn.hypervisor}"
46
+ # puts "Hypervisor version: #{conn.hypervisor_verison}"
47
+ # puts "Library version: #{conn.lib_version}"
48
+ #
49
+ class Connection
50
+ # Opens a new connection to libvirt. This connection may be local or remote.
51
+ # If a `uri` is given, an attempt to connect to the given URI is made. The URI
52
+ # can be used to specify the location of libvirt along with the hypervisor
53
+ # to connect to.
54
+ #
55
+ # @param [String] uri
56
+ def initialize(*args)
57
+ opts = args.last.is_a?(Hash) ? args.pop : {}
58
+ uri = args.first
59
+
60
+ if args.first.is_a?(FFI::Pointer)
61
+ # Store away the pointer and increase the reference count, since
62
+ # we're taking ownership of this pointer directly.
63
+ @pointer = args.first
64
+ FFI::Libvirt.virConnectRef(self)
65
+ end
66
+
67
+ # If the pointer is not yet set, attempt to open a connection with
68
+ # the specified URI.
69
+ @pointer ||= if opts[:readonly]
70
+ FFI::Libvirt.virConnectOpenReadOnly(uri)
71
+ else
72
+ FFI::Libvirt.virConnectOpen(uri)
73
+ end
74
+
75
+ ObjectSpace.define_finalizer(self, method(:finalize))
76
+ end
77
+
78
+ # Returns the domains (both active and inactive) related to this
79
+ # connection. The various states of the domains returned can be
80
+ # queried using {Domain#state}.
81
+ #
82
+ # @return [Collection::DomainCollection]
83
+ def domains
84
+ Collection::DomainCollection.new(self)
85
+ end
86
+
87
+ # Returns the interfaces (both active and inactive) related to this
88
+ # connection.
89
+ #
90
+ # @return [Collection::InterfaceCollection]
91
+ def interfaces
92
+ Collection::InterfaceCollection.new(self)
93
+ end
94
+
95
+ # Returns the networks related to this connection.
96
+ #
97
+ # @return [Collection::NetworkCollection]
98
+ def networks
99
+ Collection::NetworkCollection.new(self)
100
+ end
101
+
102
+ # Returns the network filters related to this connection.
103
+ #
104
+ # @return [Collection::NWFilterCollection]
105
+ def nwfilters
106
+ Collection::NWFilterCollection.new(self)
107
+ end
108
+
109
+ # Returns the storage pools related to this connection
110
+ #
111
+ # @return [Collection::StoragePoolCollection]
112
+ def storage_pools
113
+ Collection::StoragePoolCollection.new(self)
114
+ end
115
+
116
+ # Returns a node object to retrieve information about the node which
117
+ # this connection is established to.
118
+ #
119
+ # @return [Node]
120
+ def node
121
+ Node.new(self)
122
+ end
123
+
124
+ # Returns the capabilities of the connected hypervisor/driver. Returns them
125
+ # as an XML string. This method calls `virConnectGetCapabilities`. This will
126
+ # probably be parsed into a more useful format in the future.
127
+ #
128
+ # @return [String]
129
+ def capabilities
130
+ FFI::Libvirt.virConnectGetCapabilities(self)
131
+ end
132
+
133
+ # Returns the system hostname on which the hypervisor is running. Therefore,
134
+ # if connected to a remote `libvirtd` daemon, then it will return the hostname
135
+ # of that machine.
136
+ #
137
+ # @return [String]
138
+ def hostname
139
+ FFI::Libvirt.virConnectGetHostname(self)
140
+ end
141
+
142
+ # Returns the URI of the connection.
143
+ #
144
+ # @return [String]
145
+ def uri
146
+ FFI::Libvirt.virConnectGetURI(self)
147
+ end
148
+
149
+ # Returns the name of the hypervisor. This is named "type" since that is the
150
+ # terminology which libvirt itself uses. This is also aliased as `hypervisor`
151
+ # since that is more friendly.
152
+ #
153
+ # @return [String]
154
+ def type
155
+ FFI::Libvirt.virConnectGetType(self)
156
+ end
157
+ alias :hypervisor :type
158
+
159
+ # Returns the maximum number of virtual CPUs for a given domain type.
160
+ #
161
+ # @return [Integer]
162
+ def max_virtual_cpus(type)
163
+ FFI::Libvirt.virConnectGetMaxVcpus(self, type)
164
+ end
165
+
166
+ # Returns a boolean of whether the connection is encrypted or not.
167
+ #
168
+ # @return [Boolean]
169
+ def encrypted?
170
+ result = FFI::Libvirt.virConnectIsEncrypted(self)
171
+ return nil if result == -1
172
+ result == 1
173
+ end
174
+
175
+ # Returns a boolean of whether the connection is secure or not.
176
+ #
177
+ # @return [Boolean]
178
+ def secure?
179
+ result = FFI::Libvirt.virConnectIsSecure(self)
180
+ return nil if result == -1
181
+ result == 1
182
+ end
183
+
184
+ # Returns the version of the hypervisor. This version is returned as an array
185
+ # representation as `[major, minor, patch]`.
186
+ #
187
+ # @return [Array]
188
+ def hypervisor_version
189
+ output_ptr = FFI::MemoryPointer.new(:ulong)
190
+ FFI::Libvirt.virConnectGetVersion(self, output_ptr)
191
+ FFI::Libvirt::Util.parse_version_number(output_ptr.get_ulong(0))
192
+ end
193
+
194
+ # Returns the version of `libvirt` which the daemon on the other side is
195
+ # running. If not connected to a remote daemon, it will return the version
196
+ # of libvirt on this machine. The result is an array representatin of the
197
+ # version, as `[major, minor, patch]`.
198
+ #
199
+ # @return [Array]
200
+ def lib_version
201
+ output_ptr = FFI::MemoryPointer.new(:ulong)
202
+ FFI::Libvirt.virConnectGetLibVersion(self, output_ptr)
203
+ FFI::Libvirt::Util.parse_version_number(output_ptr.get_ulong(0))
204
+ end
205
+
206
+ # Provides the pointer of the connection. This allows this object to be
207
+ # used directly with the FFI layer, as if this object were actually
208
+ # a `virConnectPtr`.
209
+ #
210
+ # @return [FFI::Pointer]
211
+ def to_ptr
212
+ @pointer
213
+ end
214
+
215
+ protected
216
+
217
+ # Cleans up the connection by releasing the connection object. This
218
+ # never needs to be called directly since there is a finalizer on
219
+ # this object to clean the connection. Therefore, to close the connection,
220
+ # simply release the reference to the connection.
221
+ def finalize(*args)
222
+ FFI::Libvirt.virConnectClose(self) rescue nil
223
+ end
224
+ end
225
+ end