libvirt 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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,241 @@
|
|
1
|
+
module Libvirt
|
2
|
+
# Represents a domain within libvirt, which is a single virtual
|
3
|
+
# machine or environment, typically.
|
4
|
+
class Domain
|
5
|
+
# Initializes a new {Domain} object. If you're calling this directly,
|
6
|
+
# omit the `pointer` argument, since that is meant for internal use.
|
7
|
+
def initialize(pointer=nil)
|
8
|
+
@pointer = pointer if pointer.is_a?(FFI::Pointer)
|
9
|
+
ObjectSpace.define_finalizer(self, method(:finalize))
|
10
|
+
end
|
11
|
+
|
12
|
+
# Returns the name of the domain as a string.
|
13
|
+
#
|
14
|
+
# @return [String]
|
15
|
+
def name
|
16
|
+
FFI::Libvirt.virDomainGetName(self)
|
17
|
+
end
|
18
|
+
|
19
|
+
# Returns the UUID of the domain as a string.
|
20
|
+
#
|
21
|
+
# @return [String]
|
22
|
+
def uuid
|
23
|
+
output_ptr = FFI::MemoryPointer.new(:char, 36)
|
24
|
+
FFI::Libvirt.virDomainGetUUIDString(self, output_ptr)
|
25
|
+
output_ptr.read_string
|
26
|
+
end
|
27
|
+
|
28
|
+
# Returns the hypervisor ID number for this domain.
|
29
|
+
#
|
30
|
+
# @return [Integer]
|
31
|
+
def id
|
32
|
+
FFI::Libvirt.virDomainGetID(self)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Returns the OS type of the domain.
|
36
|
+
#
|
37
|
+
# @return [String]
|
38
|
+
def os_type
|
39
|
+
FFI::Libvirt.virDomainGetOSType(self)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Returns the current state this domain is in.
|
43
|
+
#
|
44
|
+
# @return [Symbol]
|
45
|
+
def state
|
46
|
+
domain_info[:state]
|
47
|
+
end
|
48
|
+
|
49
|
+
# Returns the maximum memory (in KB) allowed on this domain.
|
50
|
+
#
|
51
|
+
# @return [Integer]
|
52
|
+
def max_memory
|
53
|
+
domain_info[:maxMem]
|
54
|
+
end
|
55
|
+
|
56
|
+
# Sets the maximum memory (in KB) allowed on this domain.
|
57
|
+
#
|
58
|
+
# @return [Boolean] Success of the command.
|
59
|
+
def max_memory=(value)
|
60
|
+
FFI::Libvirt.virDomainSetMaxMemory(self, value) == 0
|
61
|
+
end
|
62
|
+
|
63
|
+
# Returns the memory (in KB) currently allocated to this domain.
|
64
|
+
#
|
65
|
+
# @return [Integer]
|
66
|
+
def memory
|
67
|
+
domain_info[:memory]
|
68
|
+
end
|
69
|
+
|
70
|
+
# Sets the memory (in KB) on an active domain.
|
71
|
+
#
|
72
|
+
# @return [Boolean] Success of the command.
|
73
|
+
def memory=(value)
|
74
|
+
FFI::Libvirt.virDomainSetMemory(self, value) == 0
|
75
|
+
end
|
76
|
+
|
77
|
+
# Returns the number of virtual CPUs for this domain.
|
78
|
+
#
|
79
|
+
# @return [Integer]
|
80
|
+
def virtual_cpus
|
81
|
+
domain_info[:nrVirtCpu]
|
82
|
+
end
|
83
|
+
|
84
|
+
# Sets the number of virtual CPUs for this domain.
|
85
|
+
#
|
86
|
+
# @return [Boolean] Success of the command.
|
87
|
+
def virtual_cpus=(value)
|
88
|
+
FFI::Libvirt.virDomainSetVcpus(self, value) == 0
|
89
|
+
end
|
90
|
+
|
91
|
+
# Returns the maximum number of virtual CPUs supported for this guest
|
92
|
+
# VM.
|
93
|
+
#
|
94
|
+
# @return [Integer]
|
95
|
+
def max_virtual_cpus
|
96
|
+
FFI::Libvirt.virDomainGetMaxVcpus(self)
|
97
|
+
end
|
98
|
+
|
99
|
+
# Returns the CPU time used in nanoseconds.
|
100
|
+
#
|
101
|
+
# @return [Integer]
|
102
|
+
def cpu_time_used
|
103
|
+
domain_info[:cpuTime]
|
104
|
+
end
|
105
|
+
|
106
|
+
# Returns the XML description of this domain.
|
107
|
+
#
|
108
|
+
# @return [String]
|
109
|
+
def xml
|
110
|
+
# TODO: The flags in the 2nd parameter
|
111
|
+
FFI::Libvirt.virDomainGetXMLDesc(self, 0)
|
112
|
+
end
|
113
|
+
|
114
|
+
# Returns boolean of whether the domain is active (running) or not.
|
115
|
+
#
|
116
|
+
# @return [Boolean]
|
117
|
+
def active?
|
118
|
+
result = FFI::Libvirt.virDomainIsActive(self)
|
119
|
+
return nil if result == -1
|
120
|
+
result == 1
|
121
|
+
end
|
122
|
+
|
123
|
+
# Returns boolean of whether the domain is persistent, or whether it
|
124
|
+
# will still exist after it is shut down.
|
125
|
+
#
|
126
|
+
# @return [Boolean]
|
127
|
+
def persistent?
|
128
|
+
result = FFI::Libvirt.virDomainIsPersistent(self)
|
129
|
+
return nil if result == -1
|
130
|
+
result == 1
|
131
|
+
end
|
132
|
+
|
133
|
+
# Returns boolean of whether the domain autostarts on boot.
|
134
|
+
#
|
135
|
+
# @return [Boolean]
|
136
|
+
def autostart?
|
137
|
+
output_ptr = FFI::MemoryPointer.new(:int)
|
138
|
+
return nil if FFI::Libvirt.virDomainGetAutostart(self, output_ptr) < 0
|
139
|
+
output_ptr.read_int == 1
|
140
|
+
end
|
141
|
+
|
142
|
+
# Sets the autostart status. This assignment sets the value immediately
|
143
|
+
# on the domain.
|
144
|
+
#
|
145
|
+
# @param [Boolean] value
|
146
|
+
# @return [Boolean] The set value
|
147
|
+
def autostart=(value)
|
148
|
+
FFI::Libvirt.virDomainSetAutostart(self, value ? 1 : 0)
|
149
|
+
value
|
150
|
+
end
|
151
|
+
|
152
|
+
# Starts the domain (moves it from the inactive to running state), and
|
153
|
+
# returns a boolean of whether the call succeeded or not.
|
154
|
+
#
|
155
|
+
# @return [Boolean]
|
156
|
+
def create
|
157
|
+
return true if active?
|
158
|
+
FFI::Libvirt.virDomainCreate(self) == 0
|
159
|
+
end
|
160
|
+
alias :start :create
|
161
|
+
|
162
|
+
# Stops a running domain and returns a boolean of whether the call succeeded
|
163
|
+
# or not.
|
164
|
+
#
|
165
|
+
# @return [Boolean]
|
166
|
+
def destroy
|
167
|
+
FFI::Libvirt.virDomainDestroy(self) == 0
|
168
|
+
end
|
169
|
+
alias :stop :destroy
|
170
|
+
|
171
|
+
# Suspends an active domain, the process is frozen but the memory is still
|
172
|
+
# allocated. Returns a boolean of whether the call succeeded or not.
|
173
|
+
#
|
174
|
+
# @return [Boolean]
|
175
|
+
def suspend
|
176
|
+
FFI::Libvirt.virDomainSuspend(self) == 0
|
177
|
+
end
|
178
|
+
|
179
|
+
# Resumes a suspended domain, returns a boolean of whether the call
|
180
|
+
# succeeded or not.
|
181
|
+
#
|
182
|
+
# @return [Boolean]
|
183
|
+
def resume
|
184
|
+
return true if active?
|
185
|
+
FFI::Libvirt.virDomainResume(self) == 0
|
186
|
+
end
|
187
|
+
|
188
|
+
# Reboots the domain.
|
189
|
+
#
|
190
|
+
# @return [Boolean]
|
191
|
+
def reboot
|
192
|
+
FFI::Libvirt.virDomainReboot(self, 0) == 0
|
193
|
+
end
|
194
|
+
|
195
|
+
# Shutdown a domain, stopping the domain OS.
|
196
|
+
#
|
197
|
+
# @return [Boolean]
|
198
|
+
def shutdown
|
199
|
+
FFI::Libvirt.virDomainShutdown(self) == 0
|
200
|
+
end
|
201
|
+
|
202
|
+
# Undefine a domain. This will not stop it if it is running.
|
203
|
+
#
|
204
|
+
# @return [Boolean]
|
205
|
+
def undefine
|
206
|
+
FFI::Libvirt.virDomainUndefine(self) == 0
|
207
|
+
end
|
208
|
+
|
209
|
+
# Provides the pointer to the domain. This allows this object to be used
|
210
|
+
# directly with the FFI layer which expects a `virDomainPtr`.
|
211
|
+
#
|
212
|
+
# @return [FFI::Pointer]
|
213
|
+
def to_ptr
|
214
|
+
@pointer
|
215
|
+
end
|
216
|
+
|
217
|
+
# Provide a meaningful equality check so that two domains can easily
|
218
|
+
# be checked for equality. This works by comparing UUIDs.
|
219
|
+
#
|
220
|
+
# @return [Boolean]
|
221
|
+
def ==(other)
|
222
|
+
other.is_a?(Domain) && other.uuid == uuid
|
223
|
+
end
|
224
|
+
|
225
|
+
protected
|
226
|
+
|
227
|
+
# Queries the domain info from libvirt to get standard information
|
228
|
+
# about this domain.
|
229
|
+
def domain_info
|
230
|
+
result = FFI::Libvirt::DomainInfo.new
|
231
|
+
FFI::Libvirt.virDomainGetInfo(self, result.to_ptr)
|
232
|
+
result
|
233
|
+
end
|
234
|
+
|
235
|
+
# Cleans the `virDomainPtr` underlying the class when the class is
|
236
|
+
# released.
|
237
|
+
def finalize(*args)
|
238
|
+
FFI::Libvirt.virDomainFree(self)
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
module Libvirt
|
2
|
+
# Represents the actual `libvirt` error object which most erroneous
|
3
|
+
# events set. This contains important information such as the message,
|
4
|
+
# domain, etc.
|
5
|
+
class Error
|
6
|
+
@@error_block = nil
|
7
|
+
@@raise_errors = true
|
8
|
+
|
9
|
+
attr_reader :interface
|
10
|
+
|
11
|
+
class << self
|
12
|
+
# Gets the last error (if there is one) and returns the {Error}
|
13
|
+
# representing it.
|
14
|
+
#
|
15
|
+
# @return [Error]
|
16
|
+
def last_error
|
17
|
+
pointer = FFI::Libvirt.virGetLastError
|
18
|
+
return nil if pointer.null?
|
19
|
+
new(pointer)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Sets an error handling function. This will call the given block
|
23
|
+
# whenever an error occurs within libvirt.
|
24
|
+
def on_error(&block)
|
25
|
+
@@error_block = block
|
26
|
+
end
|
27
|
+
|
28
|
+
# Returns whether or not Libvirt is currently configured to raise
|
29
|
+
# errors automatically when it is reported.
|
30
|
+
#
|
31
|
+
# @return [Boolean]
|
32
|
+
def raise_errors; @@raise_errors; end
|
33
|
+
|
34
|
+
# Set this to a boolean true/false to control whether the library
|
35
|
+
# automatically raises {Exception::LibvirtError} whenever an error
|
36
|
+
# occurs.
|
37
|
+
#
|
38
|
+
# @param [Boolean] value
|
39
|
+
def raise_errors=(value)
|
40
|
+
@@raise_errors = !!value
|
41
|
+
end
|
42
|
+
|
43
|
+
protected
|
44
|
+
|
45
|
+
def error_handler(userdata, error_ptr)
|
46
|
+
error_object = new(error_ptr)
|
47
|
+
@@error_block.call(error_object) if @@error_block
|
48
|
+
|
49
|
+
# Raise the exception
|
50
|
+
raise Exception::LibvirtError, error_object if @@raise_errors
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# This proc needs to be assigned to a constant so that it is never GC'd
|
55
|
+
# and can be assigned as a callback to the API.
|
56
|
+
ERROR_HANDLER_PROC = method(:error_handler)
|
57
|
+
FFI::Libvirt.virSetErrorFunc(nil, ERROR_HANDLER_PROC)
|
58
|
+
|
59
|
+
# Initializes a new error object. This shouldn't be called publicly.
|
60
|
+
# Instead use {last_error} or obtain the error from any of the exceptions
|
61
|
+
# which the library raises.
|
62
|
+
def initialize(pointer)
|
63
|
+
@interface = FFI::Libvirt::Error.new(pointer)
|
64
|
+
end
|
65
|
+
|
66
|
+
# Returns the error code of the error. Internally, this is represented
|
67
|
+
# by a C `enum`, so this will actually return a Ruby `Symbol` representation
|
68
|
+
# of the error.
|
69
|
+
#
|
70
|
+
# @return [Symbol]
|
71
|
+
def code
|
72
|
+
interface[:code]
|
73
|
+
end
|
74
|
+
|
75
|
+
# Returns the domain or "category" in which this error occured. This
|
76
|
+
# is represented internally as a C `enum`, so this will actually return
|
77
|
+
# a Ruby `symbol`.
|
78
|
+
#
|
79
|
+
# @return [Symbol]
|
80
|
+
def domain
|
81
|
+
interface[:domain]
|
82
|
+
end
|
83
|
+
|
84
|
+
# Returns a human-friendly message related to the error.
|
85
|
+
#
|
86
|
+
# @return [String]
|
87
|
+
def message
|
88
|
+
interface[:message]
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Libvirt
|
2
|
+
# Contains all the potential exceptions which the library can
|
3
|
+
# throw. This is different from a {Libvirt::Error}, which represents
|
4
|
+
# an actual `libvirt` error object.
|
5
|
+
module Exception
|
6
|
+
# Represents an exceptional event within the Libvirt library.
|
7
|
+
# This contains an `error` readable attribute which, if available,
|
8
|
+
# is a {Libvirt::Error} object, which contains more details
|
9
|
+
# about the error which occurred.
|
10
|
+
class LibvirtError < StandardError
|
11
|
+
attr_reader :error
|
12
|
+
|
13
|
+
def initialize(error)
|
14
|
+
@error = error
|
15
|
+
super(error.message)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
module Libvirt
|
2
|
+
# Represents a network within libvirt, which is a network interface
|
3
|
+
# such as a host-only network for VirtualBox, for example.
|
4
|
+
class Network
|
5
|
+
# Initializes a new {Network} object given a `virNetworkPtr`. Please
|
6
|
+
# do not call this directly. Instead, use the {Connection#networks}
|
7
|
+
# object.
|
8
|
+
def initialize(pointer)
|
9
|
+
@pointer = pointer
|
10
|
+
ObjectSpace.define_finalizer(self, method(:finalize))
|
11
|
+
end
|
12
|
+
|
13
|
+
# Returns the name of the network as a string.
|
14
|
+
#
|
15
|
+
# @return [String]
|
16
|
+
def name
|
17
|
+
FFI::Libvirt.virNetworkGetName(self)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Returns the XML descriptions of this network.
|
21
|
+
#
|
22
|
+
# @return [String]
|
23
|
+
def xml
|
24
|
+
FFI::Libvirt.virNetworkGetXMLDesc(self, 0)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Returns the UUID of the network as a string.
|
28
|
+
#
|
29
|
+
# @return [String]
|
30
|
+
def uuid
|
31
|
+
output_ptr = FFI::MemoryPointer.new(:char, 36)
|
32
|
+
FFI::Libvirt.virNetworkGetUUIDString(self, output_ptr)
|
33
|
+
output_ptr.read_string
|
34
|
+
end
|
35
|
+
|
36
|
+
# Returns the bridge that this network is attached to.
|
37
|
+
#
|
38
|
+
# @return [String]
|
39
|
+
def bridge
|
40
|
+
FFI::Libvirt.virNetworkGetBridgeName(self)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Determine if the network is set to autostart on boot or not.
|
44
|
+
#
|
45
|
+
# @return [Boolean]
|
46
|
+
def autostart?
|
47
|
+
output_ptr = FFI::MemoryPointer.new(:int)
|
48
|
+
return nil if FFI::Libvirt.virNetworkGetAutostart(self, output_ptr) < 0
|
49
|
+
output_ptr.read_int == 1
|
50
|
+
end
|
51
|
+
|
52
|
+
# Set the autostart value on the network.
|
53
|
+
#
|
54
|
+
# @return [Boolean]
|
55
|
+
def autostart=(value)
|
56
|
+
FFI::Libvirt.virNetworkSetAutostart(self, value ? 1 : 0)
|
57
|
+
value
|
58
|
+
end
|
59
|
+
|
60
|
+
# Determine if the network is active or not.
|
61
|
+
#
|
62
|
+
# @return [Boolean]
|
63
|
+
def active?
|
64
|
+
FFI::Libvirt.virNetworkIsActive(self) == 1
|
65
|
+
end
|
66
|
+
|
67
|
+
# Determine if the network is persistent or not.
|
68
|
+
#
|
69
|
+
# @return [Boolean]
|
70
|
+
def persistent?
|
71
|
+
FFI::Libvirt.virNetworkIsPersistent(self) == 1
|
72
|
+
end
|
73
|
+
|
74
|
+
# Starts a network.
|
75
|
+
def create
|
76
|
+
FFI::Libvirt.virNetworkCreate(self)
|
77
|
+
end
|
78
|
+
alias :start :create
|
79
|
+
|
80
|
+
# Stops a network.
|
81
|
+
def destroy
|
82
|
+
FFI::Libvirt.virNetworkDestroy(self)
|
83
|
+
end
|
84
|
+
alias :stop :destroy
|
85
|
+
|
86
|
+
# Undefines the network, but will not stop it if it is
|
87
|
+
# running.
|
88
|
+
def undefine
|
89
|
+
FFI::Libvirt.virNetworkUndefine(self)
|
90
|
+
end
|
91
|
+
|
92
|
+
# Converts to the actual `virNetworkPtr` of this structure. This allows
|
93
|
+
# this object to be used directly with the FFI layer which expects a
|
94
|
+
# `virNetworkPtr`.
|
95
|
+
#
|
96
|
+
# @return [FFI::Pointer]
|
97
|
+
def to_ptr
|
98
|
+
@pointer
|
99
|
+
end
|
100
|
+
|
101
|
+
# Provide a meaningful equality check for two networks by comparing
|
102
|
+
# UUID.
|
103
|
+
#
|
104
|
+
# @return [Boolean]
|
105
|
+
def ==(other)
|
106
|
+
other.is_a?(Network) && other.uuid == uuid
|
107
|
+
end
|
108
|
+
|
109
|
+
protected
|
110
|
+
|
111
|
+
# Cleans up the `virNetworkPtr` and releases the resources associated
|
112
|
+
# with it. This is automatically called when this object is garbage
|
113
|
+
# collected.
|
114
|
+
def finalize(*args)
|
115
|
+
FFI::Libvirt.virNetworkFree(self)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
data/lib/libvirt/node.rb
ADDED
@@ -0,0 +1,118 @@
|
|
1
|
+
module Libvirt
|
2
|
+
# Represents a node which libvirt resides on.
|
3
|
+
class Node
|
4
|
+
# Initializes a node object with the given {Connection} pointer. This
|
5
|
+
# shouldn't be called directly. Instead, retrieve the node using
|
6
|
+
# {Connection#node}.
|
7
|
+
def initialize(pointer)
|
8
|
+
# This pointer can either be a `virConnectPtr` directly or a
|
9
|
+
# {Connection} since it implements `to_ptr`.
|
10
|
+
@pointer = pointer
|
11
|
+
|
12
|
+
# We increase the reference count on the connection while this
|
13
|
+
# node object is in use.
|
14
|
+
FFI::Libvirt.virConnectRef(connection)
|
15
|
+
|
16
|
+
# Register finalizer for reference cleanup
|
17
|
+
ObjectSpace.define_finalizer(self, method(:finalize))
|
18
|
+
end
|
19
|
+
|
20
|
+
# Returns the connection this node belongs to as a {Connection}
|
21
|
+
# object.
|
22
|
+
#
|
23
|
+
# @return [Connection]
|
24
|
+
def connection
|
25
|
+
@connection ||= @pointer.is_a?(Connection) ? @pointer : Connection.new(@pointer)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Returns the devices connected to this node.
|
29
|
+
#
|
30
|
+
# @return [Collection::NodeDeviceCollection]
|
31
|
+
def devices
|
32
|
+
Collection::NodeDeviceCollection.new(connection)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Returns the free memory available on the node. This is returned
|
36
|
+
# in bytes.
|
37
|
+
#
|
38
|
+
# @return [Integer]
|
39
|
+
def free_memory
|
40
|
+
FFI::Libvirt.virNodeGetFreeMemory(connection)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Returns the CPU model of the node.
|
44
|
+
#
|
45
|
+
# @return [String]
|
46
|
+
def cpu_model
|
47
|
+
info[:model]
|
48
|
+
end
|
49
|
+
|
50
|
+
# Returns the memory size in kilobytes.
|
51
|
+
#
|
52
|
+
# @return [Integer]
|
53
|
+
def memory
|
54
|
+
info[:memory]
|
55
|
+
end
|
56
|
+
|
57
|
+
# Returns the number of active CPUs.
|
58
|
+
#
|
59
|
+
# @return [Integer]
|
60
|
+
def cpus
|
61
|
+
info[:cpus]
|
62
|
+
end
|
63
|
+
|
64
|
+
# Returns the expected CPU frequency in MHz.
|
65
|
+
#
|
66
|
+
# @return [Integer]
|
67
|
+
def mhz
|
68
|
+
info[:mhz]
|
69
|
+
end
|
70
|
+
|
71
|
+
# Returns the number of NUMA cell, 1 for uniform memory access.
|
72
|
+
#
|
73
|
+
# @return [Integer]
|
74
|
+
def nodes
|
75
|
+
info[:nodes]
|
76
|
+
end
|
77
|
+
|
78
|
+
# Returns the number of CPU sockets per node.
|
79
|
+
#
|
80
|
+
# @return [Integer]
|
81
|
+
def sockets
|
82
|
+
info[:sockets]
|
83
|
+
end
|
84
|
+
|
85
|
+
# Returns the number of cores per socket.
|
86
|
+
#
|
87
|
+
# @return [Integer]
|
88
|
+
def cores
|
89
|
+
info[:cores]
|
90
|
+
end
|
91
|
+
|
92
|
+
# Returns the number of threads per core.
|
93
|
+
#
|
94
|
+
# @return [Integer]
|
95
|
+
def threads
|
96
|
+
info[:threads]
|
97
|
+
end
|
98
|
+
|
99
|
+
protected
|
100
|
+
|
101
|
+
# Returns the {FFI::Libvirt::NodeInfo} structure associated with this
|
102
|
+
# node. The various fields of this structure are accessed using the
|
103
|
+
# other methods in this class.
|
104
|
+
#
|
105
|
+
# @return [FFI::Libvirt::NodeInfo]
|
106
|
+
def info
|
107
|
+
result = FFI::Libvirt::NodeInfo.new
|
108
|
+
FFI::Libvirt.virNodeGetInfo(connection, result.to_ptr)
|
109
|
+
result
|
110
|
+
end
|
111
|
+
|
112
|
+
# Releases the reference to the underlying connection structure.
|
113
|
+
# This is automatically called when the object is garbage collected.
|
114
|
+
def finalize(*args)
|
115
|
+
FFI::Libvirt.virConnectClose(connection)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module Libvirt
|
2
|
+
# Represents a device on a node.
|
3
|
+
class NodeDevice
|
4
|
+
# Initializes a node device with the given `virNodeDevicePtr`. This
|
5
|
+
# should not be called directly. Instead, call {Node#devices} to get
|
6
|
+
# a list of the devices.
|
7
|
+
#
|
8
|
+
# @param [FFI::Pointer] pointer
|
9
|
+
def initialize(pointer)
|
10
|
+
@pointer = pointer
|
11
|
+
ObjectSpace.define_finalizer(self, method(:finalize))
|
12
|
+
end
|
13
|
+
|
14
|
+
# Returns the name of this device.
|
15
|
+
#
|
16
|
+
# @return [String]
|
17
|
+
def name
|
18
|
+
FFI::Libvirt.virNodeDeviceGetName(self)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Returns the XML specification for this device.
|
22
|
+
#
|
23
|
+
# @return [String]
|
24
|
+
def xml
|
25
|
+
FFI::Libvirt.virNodeDeviceGetXMLDesc(self, 0)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Detaches the device from the node itself so that it may be bound to
|
29
|
+
# a guest domain.
|
30
|
+
#
|
31
|
+
# @return [Boolean]
|
32
|
+
def dettach
|
33
|
+
FFI::Libvirt.virNodeDeviceDettach(self) == 0
|
34
|
+
end
|
35
|
+
|
36
|
+
# Reattach the device onto the node.
|
37
|
+
#
|
38
|
+
# @return [Boolena]
|
39
|
+
def reattach
|
40
|
+
FFI::Libvirt.virNodeDeviceReAttach(self) == 0
|
41
|
+
end
|
42
|
+
|
43
|
+
# Reset the device. The exact semantics of this method are hypervisor
|
44
|
+
# specific.
|
45
|
+
#
|
46
|
+
# @return [Boolena]
|
47
|
+
def reset
|
48
|
+
FFI::Libvirt.virNodeDeviceReset(self) == 0
|
49
|
+
end
|
50
|
+
|
51
|
+
# Destroy the device, removing the virtual device from the host operating
|
52
|
+
# system.
|
53
|
+
#
|
54
|
+
# @return [Boolean]
|
55
|
+
def destroy
|
56
|
+
FFI::Libvirt.virNodeDeviceDestroy(self) == 0
|
57
|
+
end
|
58
|
+
|
59
|
+
# Returns the underlying `virNodeDevicePtr`. This allows this object to
|
60
|
+
# be used directly with FFI methods.
|
61
|
+
#
|
62
|
+
# @return [FFI::Pointer]
|
63
|
+
def to_ptr
|
64
|
+
@pointer
|
65
|
+
end
|
66
|
+
|
67
|
+
protected
|
68
|
+
|
69
|
+
# Frees the underlying resources of the node device. This is called
|
70
|
+
# automatically when this object is garbage collected.
|
71
|
+
def finalize(*args)
|
72
|
+
FFI::Libvirt.virNodeDeviceFree(self)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|