libvirt 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +10 -0
- data/.yardopts +3 -0
- data/CHANGELOG.md +3 -0
- data/Gemfile +12 -0
- data/Gemfile.lock +36 -0
- data/README.md +83 -0
- data/Rakefile +20 -0
- data/docs/user_guide.md +259 -0
- data/examples/README.md +10 -0
- data/examples/create_domain.rb +46 -0
- data/examples/print_domain_info.rb +46 -0
- data/examples/print_hypervisor_info.rb +40 -0
- data/lib/ffi/libvirt/domain_info.rb +12 -0
- data/lib/ffi/libvirt/error.rb +25 -0
- data/lib/ffi/libvirt/error_functions.rb +21 -0
- data/lib/ffi/libvirt/error_types.rb +125 -0
- data/lib/ffi/libvirt/functions.rb +363 -0
- data/lib/ffi/libvirt/node_info.rb +27 -0
- data/lib/ffi/libvirt/storage_pool_info.rb +11 -0
- data/lib/ffi/libvirt/storage_volume_info.rb +14 -0
- data/lib/ffi/libvirt/types.rb +61 -0
- data/lib/ffi/libvirt/util.rb +19 -0
- data/lib/ffi/libvirt/version.rb +46 -0
- data/lib/ffi/libvirt.rb +29 -0
- data/lib/libvirt/collection/abstract_collection.rb +49 -0
- data/lib/libvirt/collection/domain_collection.rb +98 -0
- data/lib/libvirt/collection/interface_collection.rb +16 -0
- data/lib/libvirt/collection/network_collection.rb +58 -0
- data/lib/libvirt/collection/node_device_collection.rb +29 -0
- data/lib/libvirt/collection/nwfilter_collection.rb +15 -0
- data/lib/libvirt/collection/storage_pool_collection.rb +58 -0
- data/lib/libvirt/collection/storage_volume_collection.rb +57 -0
- data/lib/libvirt/collection.rb +12 -0
- data/lib/libvirt/connection.rb +225 -0
- data/lib/libvirt/domain.rb +241 -0
- data/lib/libvirt/error.rb +91 -0
- data/lib/libvirt/exception.rb +19 -0
- data/lib/libvirt/network.rb +118 -0
- data/lib/libvirt/node.rb +118 -0
- data/lib/libvirt/node_device.rb +75 -0
- data/lib/libvirt/spec/device/disk.rb +58 -0
- data/lib/libvirt/spec/device/emulator.rb +23 -0
- data/lib/libvirt/spec/device.rb +8 -0
- data/lib/libvirt/spec/domain/os_booting.rb +69 -0
- data/lib/libvirt/spec/domain.rb +71 -0
- data/lib/libvirt/spec.rb +12 -0
- data/lib/libvirt/storage_pool.rb +164 -0
- data/lib/libvirt/storage_volume.rb +109 -0
- data/lib/libvirt/version.rb +3 -0
- data/lib/libvirt.rb +53 -0
- data/libvirt.gemspec +27 -0
- data/test/libvirt/collection/abstract_collection_test.rb +14 -0
- data/test/libvirt/collection/domain_collection_test.rb +122 -0
- data/test/libvirt/collection/interface_collection_test.rb +9 -0
- data/test/libvirt/collection/network_collection_test.rb +41 -0
- data/test/libvirt/collection/node_device_collection_test.rb +24 -0
- data/test/libvirt/collection/nwfilter_collection_test.rb +7 -0
- data/test/libvirt/collection/storage_pool_collection_test.rb +41 -0
- data/test/libvirt/collection/storage_volume_collection_test.rb +86 -0
- data/test/libvirt/connection_test.rb +133 -0
- data/test/libvirt/domain_test.rb +221 -0
- data/test/libvirt/error_test.rb +93 -0
- data/test/libvirt/libvirt_test.rb +16 -0
- data/test/libvirt/network_test.rb +76 -0
- data/test/libvirt/node_device_test.rb +16 -0
- data/test/libvirt/node_test.rb +24 -0
- data/test/libvirt/spec/devices/disk_test.rb +107 -0
- data/test/libvirt/spec/devices/emulator_test.rb +20 -0
- data/test/libvirt/spec/domain_test.rb +17 -0
- data/test/libvirt/storage_pool_test.rb +133 -0
- data/test/libvirt/storage_volume_test.rb +63 -0
- data/test/support/xml_assertions.rb +29 -0
- data/test/test_helper.rb +23 -0
- metadata +219 -0
@@ -0,0 +1,58 @@
|
|
1
|
+
module Libvirt
|
2
|
+
module Spec
|
3
|
+
module Device
|
4
|
+
# Any device that looks like a disk, be it a floppy, harddisk,
|
5
|
+
# cdrom, or paravirtualized driver is specified via the disk
|
6
|
+
# element.
|
7
|
+
class Disk
|
8
|
+
attr_accessor :type
|
9
|
+
attr_accessor :source
|
10
|
+
attr_accessor :target_dev
|
11
|
+
attr_accessor :target_bus
|
12
|
+
attr_accessor :driver
|
13
|
+
attr_accessor :driver_type
|
14
|
+
attr_accessor :driver_cache
|
15
|
+
attr_accessor :shareable
|
16
|
+
attr_accessor :serial
|
17
|
+
|
18
|
+
# Initialize a new disk element with the given type. Examples
|
19
|
+
# of valid `type`s are "disk," "floppy," and "cdrom."
|
20
|
+
def initialize(type)
|
21
|
+
@type = type
|
22
|
+
@shareable = false
|
23
|
+
end
|
24
|
+
|
25
|
+
# Returns the XML representation of this device.
|
26
|
+
def to_xml(xml=Nokogiri::XML::Builder.new)
|
27
|
+
xml.disk(:type => type) do |d|
|
28
|
+
if source
|
29
|
+
# Source tag, the attribute depends on the type.
|
30
|
+
attribute = type == :block ? :dev : :file
|
31
|
+
d.source(attribute => source)
|
32
|
+
end
|
33
|
+
|
34
|
+
if target_dev
|
35
|
+
# Target tag has optional "bus" parameter
|
36
|
+
options = { :dev => target_dev }
|
37
|
+
options[:bus] = target_bus if target_bus
|
38
|
+
d.target(options)
|
39
|
+
end
|
40
|
+
|
41
|
+
if driver
|
42
|
+
# Driver tag has a couple optional parameters
|
43
|
+
options = { :name => driver }
|
44
|
+
options[:type] = driver_type if driver_type
|
45
|
+
options[:cache] = driver_cache if driver_cache
|
46
|
+
d.driver(options)
|
47
|
+
end
|
48
|
+
|
49
|
+
d.shareable if shareable
|
50
|
+
d.serial serial if serial
|
51
|
+
end
|
52
|
+
|
53
|
+
xml.to_xml
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Libvirt
|
2
|
+
module Spec
|
3
|
+
module Device
|
4
|
+
class Emulator
|
5
|
+
attr_accessor :path
|
6
|
+
|
7
|
+
# Initialize an emulator device with the given path. The capabilities
|
8
|
+
# XML from {Connection} describes what emulators are available.
|
9
|
+
def initialize(path)
|
10
|
+
@path = path
|
11
|
+
end
|
12
|
+
|
13
|
+
# Returns the XML for this device.
|
14
|
+
#
|
15
|
+
# @return [String]
|
16
|
+
def to_xml(xml=Nokogiri::XML::Builder.new)
|
17
|
+
xml.emulator path
|
18
|
+
xml.to_xml
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module Libvirt
|
2
|
+
module Spec
|
3
|
+
class Domain
|
4
|
+
# The OS booting section of a domain specification indicates to libvirt
|
5
|
+
# how to configure the virtual machine to boot. There are three main ways
|
6
|
+
# to configure booting. Each hypervisor supports one or more of the following:
|
7
|
+
#
|
8
|
+
# 1. BIOS bootloader
|
9
|
+
# 2. Host bootloader
|
10
|
+
# 3. Direct kernel boot
|
11
|
+
#
|
12
|
+
# TODO: Host bootloader and direct kernel bootloader options.
|
13
|
+
class OSBooting
|
14
|
+
attr_accessor :type
|
15
|
+
attr_accessor :arch
|
16
|
+
attr_accessor :loader # Part of the BIOS bootloader
|
17
|
+
attr_accessor :boot
|
18
|
+
attr_accessor :bootmenu_enabled
|
19
|
+
|
20
|
+
# Host bootloader configuration options
|
21
|
+
attr_accessor :bootloader
|
22
|
+
attr_accessor :bootloader_args
|
23
|
+
|
24
|
+
# Direct kernel boot
|
25
|
+
attr_accessor :kernel
|
26
|
+
attr_accessor :initrd
|
27
|
+
attr_accessor :cmdline
|
28
|
+
|
29
|
+
def initialize
|
30
|
+
@boot = []
|
31
|
+
end
|
32
|
+
|
33
|
+
# Enables or disables the interactive boot menu prompt on guest startup.
|
34
|
+
def bootmenu_enabled=(value)
|
35
|
+
# Force a boolean value
|
36
|
+
@bootmenu_enabled = !!value
|
37
|
+
end
|
38
|
+
|
39
|
+
# Convert just the OS booting section to its XML representation.
|
40
|
+
def to_xml(parent=Nokogiri::XML::Builder.new)
|
41
|
+
parent.os do |os|
|
42
|
+
# Build the arguments for the OS booting type
|
43
|
+
type_args = [type]
|
44
|
+
type_args << { :arch => arch } if arch
|
45
|
+
|
46
|
+
# Setup the specification
|
47
|
+
os.type_ *type_args
|
48
|
+
os.loader loader if loader
|
49
|
+
os.bootmenu(:enable => bootmenu_enabled ? 'yes' : 'no') if !bootmenu_enabled.nil?
|
50
|
+
|
51
|
+
# Boot order for BIOS booting
|
52
|
+
boot.each { |dev| os.boot :dev => dev } if boot.is_a?(Array)
|
53
|
+
|
54
|
+
# Host bootloader configuration options
|
55
|
+
os.bootloader bootloader if bootloader
|
56
|
+
os.bootloader_args bootloader_args if bootloader_args
|
57
|
+
|
58
|
+
# Direct kernel boot options
|
59
|
+
os.kernel kernel if kernel
|
60
|
+
os.initrd initrd if initrd
|
61
|
+
os.cmdline cmdline if cmdline
|
62
|
+
end
|
63
|
+
|
64
|
+
parent.to_xml
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'libvirt/spec/domain/os_booting'
|
2
|
+
|
3
|
+
module Libvirt
|
4
|
+
module Spec
|
5
|
+
# A specification of a domain. This translates directly down to XML
|
6
|
+
# which can be used to define and launch domains on a node by libvirt.
|
7
|
+
#
|
8
|
+
# **Note:** This class may only be temporary, and the functionality
|
9
|
+
# may be merged back into {Domain}. Also, the interface will likely
|
10
|
+
# change.
|
11
|
+
class Domain
|
12
|
+
attr_accessor :hypervisor
|
13
|
+
attr_accessor :name
|
14
|
+
attr_accessor :uuid
|
15
|
+
attr_accessor :description
|
16
|
+
attr_accessor :os
|
17
|
+
attr_accessor :memory
|
18
|
+
attr_accessor :current_memory
|
19
|
+
attr_accessor :vcpu
|
20
|
+
|
21
|
+
attr_accessor :on_poweroff
|
22
|
+
attr_accessor :on_reboot
|
23
|
+
attr_accessor :on_crash
|
24
|
+
|
25
|
+
attr_accessor :devices
|
26
|
+
|
27
|
+
def initialize
|
28
|
+
@os = OSBooting.new
|
29
|
+
@devices = []
|
30
|
+
end
|
31
|
+
|
32
|
+
# Returns the XML for this specification. This XML may be passed
|
33
|
+
# into libvirt to create a domain. This is actually the method which
|
34
|
+
# should be used for validation of this XML, since libvirt has
|
35
|
+
# great validation built in. If you define a domain and an error occurs,
|
36
|
+
# then it will notify you what is missing or wrong with the specification.
|
37
|
+
#
|
38
|
+
# @return [String]
|
39
|
+
def to_xml
|
40
|
+
Nokogiri::XML::Builder.new do |xml|
|
41
|
+
xml.domain(:type => hypervisor) do
|
42
|
+
# Name and description
|
43
|
+
xml.name name if name
|
44
|
+
xml.uuid uuid if uuid
|
45
|
+
xml.description description if description
|
46
|
+
|
47
|
+
# Operating system boot information
|
48
|
+
os.to_xml(xml)
|
49
|
+
|
50
|
+
# Basic resources
|
51
|
+
xml.memory memory if memory
|
52
|
+
xml.currentMemory current_memory if current_memory
|
53
|
+
xml.vcpu vcpu if vcpu
|
54
|
+
|
55
|
+
# Lifecycle control
|
56
|
+
xml.on_poweroff on_poweroff if on_poweroff
|
57
|
+
xml.on_reboot on_reboot if on_reboot
|
58
|
+
xml.on_crash on_crash if on_crash
|
59
|
+
|
60
|
+
# Devices
|
61
|
+
if !devices.empty?
|
62
|
+
xml.devices do
|
63
|
+
devices.map { |d| d.to_xml(xml) }
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end.to_xml
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
data/lib/libvirt/spec.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
module Libvirt
|
2
|
+
# This is the namespace which contains all the classes which define
|
3
|
+
# specifications for domains, networks, storage pools, etc. These
|
4
|
+
# specifications are used to define and launch them via libvirt.
|
5
|
+
# The specifications are converted down to XML for consumption by
|
6
|
+
# libvirt. Please view the example files for examples on how to use
|
7
|
+
# the specs.
|
8
|
+
module Spec
|
9
|
+
autoload :Device, 'libvirt/spec/device'
|
10
|
+
autoload :Domain, 'libvirt/spec/domain'
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,164 @@
|
|
1
|
+
module Libvirt
|
2
|
+
# Represents a single storage pool.
|
3
|
+
class StoragePool
|
4
|
+
# Initializes a new {StoragePool} object given a `virStoragePoolPtr`.
|
5
|
+
# Do not call this directly. Instead, use the {Connection#storage_pools}
|
6
|
+
# object to retrieve a specific {StoragePool}.
|
7
|
+
def initialize(pointer)
|
8
|
+
@pointer = pointer
|
9
|
+
ObjectSpace.define_finalizer(self, method(:finalize))
|
10
|
+
end
|
11
|
+
|
12
|
+
# Returns the connection of this storage pool.
|
13
|
+
#
|
14
|
+
# @return [Connection]
|
15
|
+
def connection
|
16
|
+
Connection.new(FFI::Libvirt.virStoragePoolGetConnect(self))
|
17
|
+
end
|
18
|
+
|
19
|
+
# Returns the name of the network as a string.
|
20
|
+
#
|
21
|
+
# @return [String]
|
22
|
+
def name
|
23
|
+
FFI::Libvirt.virStoragePoolGetName(self)
|
24
|
+
end
|
25
|
+
|
26
|
+
# Returns the UUID of the storage pool as a string.
|
27
|
+
#
|
28
|
+
# @return [String]
|
29
|
+
def uuid
|
30
|
+
output_ptr = FFI::MemoryPointer.new(:char, 36)
|
31
|
+
FFI::Libvirt.virStoragePoolGetUUIDString(self, output_ptr)
|
32
|
+
output_ptr.read_string
|
33
|
+
end
|
34
|
+
|
35
|
+
# Returns the XML description of this storage pool.
|
36
|
+
#
|
37
|
+
# @return [String]
|
38
|
+
def xml
|
39
|
+
FFI::Libvirt.virStoragePoolGetXMLDesc(self, 0)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Deterine if the storage pool is active or not.
|
43
|
+
#
|
44
|
+
# @return [Boolean]
|
45
|
+
def active?
|
46
|
+
FFI::Libvirt.virStoragePoolIsActive(self) == 1
|
47
|
+
end
|
48
|
+
|
49
|
+
# Determine if the storage pool is persistent or not.
|
50
|
+
#
|
51
|
+
# @return [Boolean]
|
52
|
+
def persistent?
|
53
|
+
FFI::Libvirt.virStoragePoolIsPersistent(self) == 1
|
54
|
+
end
|
55
|
+
|
56
|
+
# Build the underlying storage pool.
|
57
|
+
#
|
58
|
+
# @return [Boolean]
|
59
|
+
def build
|
60
|
+
FFI::Libvirt.virStoragePoolBuild(self, 0) == 0
|
61
|
+
end
|
62
|
+
|
63
|
+
# Starts an inactive storage pool.
|
64
|
+
#
|
65
|
+
# @return [Boolean]
|
66
|
+
def create
|
67
|
+
return true if active?
|
68
|
+
FFI::Libvirt.virStoragePoolCreate(self, 0) == 0
|
69
|
+
end
|
70
|
+
alias :start :create
|
71
|
+
|
72
|
+
# Delete the underlying pool resources. This is a non-recoverable
|
73
|
+
# operation. This won't undefine the pool.
|
74
|
+
#
|
75
|
+
# @return [Boolean]
|
76
|
+
def delete(type=nil)
|
77
|
+
type ||= :normal
|
78
|
+
FFI::Libvirt.virStoragePoolDelete(self, type) == 0
|
79
|
+
end
|
80
|
+
|
81
|
+
# Stops an active storage pool.
|
82
|
+
#
|
83
|
+
# @return [Boolean]
|
84
|
+
def destroy
|
85
|
+
FFI::Libvirt.virStoragePoolDestroy(self) == 0
|
86
|
+
end
|
87
|
+
alias :stop :destroy
|
88
|
+
|
89
|
+
# Undefines the storage pool. This requires that the storage pool be
|
90
|
+
# inactive. This won't delete the underlying resources of the storage pool,
|
91
|
+
# however. Run {#delete} for that.
|
92
|
+
#
|
93
|
+
# @return [Boolean]
|
94
|
+
def undefine
|
95
|
+
FFI::Libvirt.virStoragePoolUndefine(self) == 0
|
96
|
+
end
|
97
|
+
|
98
|
+
# Returns the state of the storage pool as a symbol.
|
99
|
+
#
|
100
|
+
# @return [Symbol]
|
101
|
+
def state
|
102
|
+
info[:state]
|
103
|
+
end
|
104
|
+
|
105
|
+
# Returns the capacity in bytes.
|
106
|
+
#
|
107
|
+
# @return [Fixnum]
|
108
|
+
def capacity
|
109
|
+
info[:capacity]
|
110
|
+
end
|
111
|
+
|
112
|
+
# Returns the current allocation in bytes.
|
113
|
+
#
|
114
|
+
# @return [Fixnum]
|
115
|
+
def allocation
|
116
|
+
info[:allocation]
|
117
|
+
end
|
118
|
+
|
119
|
+
# Returns the available free space in bytes.
|
120
|
+
#
|
121
|
+
# @return [Fixnum]
|
122
|
+
def available
|
123
|
+
info[:available]
|
124
|
+
end
|
125
|
+
|
126
|
+
# Returns the volumes associated with this storage pool.
|
127
|
+
#
|
128
|
+
# @return [Collection::StorageVolumeCollection]
|
129
|
+
def volumes
|
130
|
+
Collection::StorageVolumeCollection.new(self)
|
131
|
+
end
|
132
|
+
|
133
|
+
# Provide a meaningful equality check for two storage pools by comparing
|
134
|
+
# UUID.
|
135
|
+
#
|
136
|
+
# @return [Boolean]
|
137
|
+
def ==(other)
|
138
|
+
other.is_a?(StoragePool) && other.uuid == uuid
|
139
|
+
end
|
140
|
+
|
141
|
+
# Returns the actual `virStoragePoolPtr` underlying this structure.
|
142
|
+
#
|
143
|
+
# @return [FFI::Pointer]
|
144
|
+
def to_ptr
|
145
|
+
@pointer
|
146
|
+
end
|
147
|
+
|
148
|
+
protected
|
149
|
+
|
150
|
+
# Gets the virStoragePoolInfo structure for this storage pool.
|
151
|
+
#
|
152
|
+
# @return [Hash]
|
153
|
+
def info
|
154
|
+
result = FFI::Libvirt::StoragePoolInfo.new
|
155
|
+
FFI::Libvirt.virStoragePoolGetInfo(self, result.to_ptr)
|
156
|
+
result
|
157
|
+
end
|
158
|
+
|
159
|
+
# Frees the underlying memory associated with this object.
|
160
|
+
def finalize(*args)
|
161
|
+
FFI::Libvirt.virStoragePoolFree(self)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
module Libvirt
|
2
|
+
# Represents a single storage volume.
|
3
|
+
class StorageVolume
|
4
|
+
# Initializes a new {StorageVolume} object given a `virStorageVolPtr`.
|
5
|
+
# Do not call this directly. Instead, use the {StoragePool#volumes} collection
|
6
|
+
# object to retrieve a specific {StorageVolume}.
|
7
|
+
def initialize(pointer)
|
8
|
+
@pointer = pointer
|
9
|
+
ObjectSpace.define_finalizer(self, method(:finalize))
|
10
|
+
end
|
11
|
+
|
12
|
+
# Returns a key for this storage volume. The key is a unique identifier.
|
13
|
+
#
|
14
|
+
# @return [String]
|
15
|
+
def key
|
16
|
+
FFI::Libvirt.virStorageVolGetKey(self)
|
17
|
+
end
|
18
|
+
alias :uuid :key
|
19
|
+
|
20
|
+
# Returns the name of this storage volume.
|
21
|
+
#
|
22
|
+
# @return [String]
|
23
|
+
def name
|
24
|
+
FFI::Libvirt.virStorageVolGetName(self)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Returns the path of this storage volume.
|
28
|
+
#
|
29
|
+
# @return [String]
|
30
|
+
def path
|
31
|
+
FFI::Libvirt.virStorageVolGetPath(self)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Returns the type of this storage volume.
|
35
|
+
#
|
36
|
+
# @return [Symbol]
|
37
|
+
def type
|
38
|
+
info[:type]
|
39
|
+
end
|
40
|
+
|
41
|
+
# Returns the capacity of this volume in bytes.
|
42
|
+
#
|
43
|
+
# @return [Integer]
|
44
|
+
def capacity
|
45
|
+
info[:capacity]
|
46
|
+
end
|
47
|
+
|
48
|
+
# Returns the currently allocated number of bytes.
|
49
|
+
#
|
50
|
+
# @return [Integer]
|
51
|
+
def allocation
|
52
|
+
info[:allocation]
|
53
|
+
end
|
54
|
+
|
55
|
+
# Wipe the contents of a volume so it is not readable in the future.
|
56
|
+
#
|
57
|
+
# @return [Boolean]
|
58
|
+
def wipe
|
59
|
+
FFI::Libvirt.virStorageVolWipe(self, 0) == 0
|
60
|
+
end
|
61
|
+
|
62
|
+
# Delete the storage volume rom the pool.
|
63
|
+
#
|
64
|
+
# @return [Boolean]
|
65
|
+
def delete
|
66
|
+
FFI::Libvirt.virStorageVolDelete(self, 0) == 0
|
67
|
+
end
|
68
|
+
|
69
|
+
# Returns the XML description of this storage volume.
|
70
|
+
#
|
71
|
+
# @return [String]
|
72
|
+
def xml
|
73
|
+
FFI::Libvirt.virStorageVolGetXMLDesc(self, 0)
|
74
|
+
end
|
75
|
+
|
76
|
+
# Returns the actual `virStorageVolPtr` underlying this structure.
|
77
|
+
#
|
78
|
+
# @return [FFI::Pointer]
|
79
|
+
def to_ptr
|
80
|
+
@pointer
|
81
|
+
end
|
82
|
+
|
83
|
+
# Provide a meaningful equality check so that two storage volumes
|
84
|
+
# can eaisly be checked for equality.
|
85
|
+
#
|
86
|
+
# @return [Boolean]
|
87
|
+
def ==(other)
|
88
|
+
other.is_a?(StorageVolume) && other.uuid == uuid
|
89
|
+
end
|
90
|
+
|
91
|
+
protected
|
92
|
+
|
93
|
+
# Returns the {FFI::Libvirt::StorageVolumeInfo} object for this volume.
|
94
|
+
# The various fields of the info struct are accessible via other getters.
|
95
|
+
#
|
96
|
+
# @return [FFI::Libvirt::StorageVolumeInfo]
|
97
|
+
def info
|
98
|
+
result = FFI::Libvirt::StorageVolumeInfo.new
|
99
|
+
FFI::Libvirt.virStorageVolGetInfo(self, result.to_ptr)
|
100
|
+
result
|
101
|
+
end
|
102
|
+
|
103
|
+
# Release the resources underlying this storage volume. This is called
|
104
|
+
# automatically when this volume is garbage collected.
|
105
|
+
def finalize(*args)
|
106
|
+
FFI::Libvirt.virStorageVolFree(self)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
data/lib/libvirt.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
require 'ffi/libvirt'
|
3
|
+
|
4
|
+
# This module is the namespace for the higher level library on top of
|
5
|
+
# libvirt, in typicaly Ruby library style. In contrast with {FFI::Libvirt}
|
6
|
+
# which is a direct layer on top of FFI, this namespace abstracts much of
|
7
|
+
# the manual work away (especially pointer handling) and exposes aspects
|
8
|
+
# of the API through nice Ruby objects.
|
9
|
+
#
|
10
|
+
# Due to the nature of this side of the project, there may be certain features
|
11
|
+
# not readily available which are supported by the API. If this is the case,
|
12
|
+
# you can use the {FFI::Libvirt} library alongside this side.
|
13
|
+
module Libvirt
|
14
|
+
autoload :Collection, 'libvirt/collection'
|
15
|
+
autoload :Connection, 'libvirt/connection'
|
16
|
+
autoload :Domain, 'libvirt/domain'
|
17
|
+
autoload :Error, 'libvirt/error'
|
18
|
+
autoload :Exception, 'libvirt/exception'
|
19
|
+
autoload :Network, 'libvirt/network'
|
20
|
+
autoload :Node, 'libvirt/node'
|
21
|
+
autoload :NodeDevice, 'libvirt/node_device'
|
22
|
+
autoload :Spec, 'libvirt/spec'
|
23
|
+
autoload :StoragePool, 'libvirt/storage_pool'
|
24
|
+
autoload :StorageVolume, 'libvirt/storage_volume'
|
25
|
+
|
26
|
+
# Initializes the library by calling `virInitialize`. Most methods
|
27
|
+
# in libvirt actually call this themselves, so its not strictly
|
28
|
+
# necessary. However, it is good practice and is **highly** recommended
|
29
|
+
# that this is called at a same place in a multi-threaded environment.
|
30
|
+
def self.initialize!
|
31
|
+
FFI::Libvirt.virInitialize == 0
|
32
|
+
end
|
33
|
+
|
34
|
+
# Returns the version of `libvirt` on the client machine. **This is
|
35
|
+
# not the version of the `libvirt` ruby library.** The result is
|
36
|
+
# return as an array of `[major, minor, patch]`.
|
37
|
+
#
|
38
|
+
# @return [Array]
|
39
|
+
def self.version
|
40
|
+
FFI::Libvirt.version
|
41
|
+
end
|
42
|
+
|
43
|
+
# Connect to a hypervisor using libvirt. This is a shortcut to
|
44
|
+
# instantiating a {Connection} object, therefore for documentation on
|
45
|
+
# the arguments and return value for this method, please consult
|
46
|
+
# {Connection#initialize}.
|
47
|
+
def self.connect(*args)
|
48
|
+
Connection.new(*args)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# Disable the stderr output which libvirt defaults to.
|
53
|
+
Libvirt::Error.on_error
|
data/libvirt.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "libvirt/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "libvirt"
|
7
|
+
s.version = Libvirt::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Mitchell Hashimoto"]
|
10
|
+
s.email = ["mitchell.hashimoto@gmail.com"]
|
11
|
+
s.homepage = "http://rubygems.org/gems/libvirt"
|
12
|
+
s.summary = "A ruby client library providing the raw interface to libvirt via FFI."
|
13
|
+
s.description = "A ruby client library providing the raw interface to libvirt via FFI."
|
14
|
+
|
15
|
+
s.rubyforge_project = "libvirt"
|
16
|
+
|
17
|
+
s.add_dependency "ffi", "~> 0.6.3"
|
18
|
+
s.add_dependency "nokogiri", "~> 1.4.3"
|
19
|
+
|
20
|
+
s.add_development_dependency "protest", "~> 0.4.0"
|
21
|
+
s.add_development_dependency "mocha", "~> 0.9.8"
|
22
|
+
|
23
|
+
s.files = `git ls-files`.split("\n")
|
24
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
25
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
26
|
+
s.require_paths = ["lib"]
|
27
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
Protest.describe("abstract collection") do
|
4
|
+
setup do
|
5
|
+
@klass = Libvirt::Collection::AbstractCollection
|
6
|
+
|
7
|
+
@connection = mock("connection")
|
8
|
+
@instance = @klass.new(@connection)
|
9
|
+
end
|
10
|
+
|
11
|
+
should "have interface be available as an attribute" do
|
12
|
+
assert_equal @connection, @instance.interface
|
13
|
+
end
|
14
|
+
end
|