libvirt_ffi 0.5.6 → 0.8.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.
- checksums.yaml +4 -4
- data/lib/libvirt.rb +3 -1
- data/lib/libvirt/base_info.rb +8 -0
- data/lib/libvirt/connection.rb +267 -22
- data/lib/libvirt/domain.rb +23 -2
- data/lib/libvirt/ffi.rb +2 -0
- data/lib/libvirt/ffi/domain.rb +57 -43
- data/lib/libvirt/ffi/host.rb +9 -1
- data/lib/libvirt/ffi/interface.rb +175 -0
- data/lib/libvirt/ffi/network.rb +392 -0
- data/lib/libvirt/ffi/storage.rb +85 -0
- data/lib/libvirt/{domain_callback_storage.rb → host_callback_storage.rb} +19 -8
- data/lib/libvirt/interface.rb +92 -0
- data/lib/libvirt/network.rb +176 -0
- data/lib/libvirt/network_dhcp_lease.rb +20 -0
- data/lib/libvirt/storage_pool.rb +17 -2
- data/lib/libvirt/util.rb +2 -0
- data/lib/libvirt/version.rb +1 -1
- data/lib/libvirt/xml.rb +3 -0
- data/lib/libvirt/xml/generic.rb +6 -3
- data/lib/libvirt/xml/interface.rb +79 -0
- data/lib/libvirt/xml/ip_address.rb +51 -0
- data/lib/libvirt/xml/network.rb +204 -0
- data/test_usage/test_interface.rb +47 -0
- data/test_usage/test_network.rb +73 -0
- metadata +13 -3
@@ -1,18 +1,21 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Libvirt
|
4
|
-
class
|
4
|
+
class HostCallbackStorage
|
5
5
|
class CallbackDataStruct < ::FFI::Struct
|
6
6
|
layout :connection_pointer, :pointer,
|
7
7
|
:callback_id, :int
|
8
8
|
end
|
9
9
|
|
10
|
-
|
10
|
+
attr_reader :name
|
11
|
+
|
12
|
+
def initialize(name)
|
13
|
+
@name = name
|
11
14
|
@inner_storage = Hash.new { |h, key| h[key] = {} }
|
12
15
|
end
|
13
16
|
|
14
17
|
# @return [Array<2>]
|
15
|
-
# cb_data [Libvirt::
|
18
|
+
# cb_data [Libvirt::HostCallbackStorage::CallbackDataStruct],
|
16
19
|
# cb_data_free_func [FFI::Function]
|
17
20
|
def allocate_struct
|
18
21
|
dbg { '#allocate_struct' }
|
@@ -20,22 +23,30 @@ module Libvirt
|
|
20
23
|
cb_data_ptr = ::FFI::MemoryPointer.new(:char, CallbackDataStruct.size, false)
|
21
24
|
cb_data = CallbackDataStruct.new(cb_data_ptr)
|
22
25
|
cb_data_free_func = FFI::Common.free_function do |pointer|
|
23
|
-
dbg {
|
26
|
+
dbg { "cb_data_free_func triggered pointer=#{pointer}" }
|
24
27
|
remove_struct(pointer)
|
25
28
|
end
|
26
29
|
[cb_data, cb_data_free_func]
|
27
30
|
end
|
28
31
|
|
29
|
-
def store_struct(cb_data,
|
32
|
+
def store_struct(cb_data, options)
|
30
33
|
dbg { '#store_struct' }
|
31
34
|
|
35
|
+
options.assert_valid_keys(:connection_pointer, :callback_id, :cb, :opaque, :free_func)
|
36
|
+
connection_pointer = options.fetch(:connection_pointer)
|
37
|
+
callback_id = options.fetch(:callback_id)
|
38
|
+
cb = options.fetch(:cb)
|
39
|
+
opaque = options.fetch(:opaque)
|
40
|
+
free_func = options.fetch(:free_func)
|
32
41
|
cb_data[:connection_pointer] = connection_pointer
|
33
42
|
cb_data[:callback_id] = callback_id
|
34
|
-
@inner_storage[connection_pointer.address][callback_id] = {
|
43
|
+
@inner_storage[connection_pointer.address][callback_id] = {
|
44
|
+
cb: cb, opaque: opaque, pointer: cb_data.pointer, free_func: free_func
|
45
|
+
}
|
35
46
|
end
|
36
47
|
|
37
48
|
def remove_struct(pointer)
|
38
|
-
dbg { "#remove_struct pointer=#{pointer}" }
|
49
|
+
dbg { "#remove_struct pointer=#{pointer}," }
|
39
50
|
|
40
51
|
cb_data_struct = CallbackDataStruct.new(pointer)
|
41
52
|
connection_pointer = cb_data_struct[:connection_pointer]
|
@@ -63,7 +74,7 @@ module Libvirt
|
|
63
74
|
private
|
64
75
|
|
65
76
|
def dbg(&block)
|
66
|
-
Util.log(:debug,
|
77
|
+
Util.log(:debug, "Libvirt::HostCallbackStorage(#{name})", &block)
|
67
78
|
end
|
68
79
|
end
|
69
80
|
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Libvirt
|
4
|
+
class Interface
|
5
|
+
# @param pointer [FFI::Pointer]
|
6
|
+
def self.load_ref(pointer)
|
7
|
+
result = FFI::Interface.virInterfaceRef(pointer)
|
8
|
+
raise Errors::LibError, "Couldn't retrieve interface reference" if result.negative?
|
9
|
+
|
10
|
+
new(pointer)
|
11
|
+
end
|
12
|
+
|
13
|
+
# @param pointer [FFI::Pointer]
|
14
|
+
def initialize(pointer)
|
15
|
+
@ptr = pointer
|
16
|
+
|
17
|
+
free = ->(obj_id) do
|
18
|
+
dbg { "Finalize Libvirt::Interface object_id=0x#{obj_id.to_s(16)}, pointer=0x#{@ptr.address.to_s(16)}" }
|
19
|
+
return unless @ptr
|
20
|
+
|
21
|
+
warn "Couldn't free Libvirt::Interface object_id=0x#{obj_id.to_s(16)}, pointer=0x#{@ptr.address.to_s(16)}" if FFI::Interface.virInterfaceFree(@ptr).negative?
|
22
|
+
end
|
23
|
+
ObjectSpace.define_finalizer(self, free)
|
24
|
+
end
|
25
|
+
|
26
|
+
# @return [FFI::Pointer]
|
27
|
+
def to_ptr
|
28
|
+
@ptr
|
29
|
+
end
|
30
|
+
|
31
|
+
# @return [String]
|
32
|
+
# @raise [Libvirt::Errors::LibError]
|
33
|
+
def name
|
34
|
+
result = FFI::Interface.virInterfaceGetName(@ptr)
|
35
|
+
raise Errors::LibError, "Couldn't get interface name" if result.nil?
|
36
|
+
|
37
|
+
result
|
38
|
+
end
|
39
|
+
|
40
|
+
# @return [String]
|
41
|
+
# @raise [Libvirt::Errors::LibError]
|
42
|
+
def mac
|
43
|
+
result = FFI::Interface.virInterfaceGetMACString(@ptr)
|
44
|
+
raise Errors::LibError, "Couldn't get interface mac" if result.nil?
|
45
|
+
|
46
|
+
result
|
47
|
+
end
|
48
|
+
|
49
|
+
# @param options_or_flags [Array<Symbol>,Hash{Symbol=>Boolean},Integer,Symbol,nil]
|
50
|
+
# @raise [Libvirt::Errors::LibError]
|
51
|
+
def xml_desc(options_or_flags = nil)
|
52
|
+
flags = Util.parse_flags options_or_flags, FFI::Interface.enum_type(:xml_flags)
|
53
|
+
result = FFI::Interface.virInterfaceGetXMLDesc(@ptr, flags)
|
54
|
+
raise Errors::LibError, "Couldn't get interface xml desc" if result.nil?
|
55
|
+
|
56
|
+
result
|
57
|
+
end
|
58
|
+
|
59
|
+
# @return [Boolean]
|
60
|
+
# @raise [Libvirt::Errors::LibError]
|
61
|
+
def active?
|
62
|
+
result = FFI::Interface.virInterfaceIsActive(@ptr)
|
63
|
+
raise Errors::LibError, "Couldn't get interface is active" if result.nil?
|
64
|
+
|
65
|
+
result == 1
|
66
|
+
end
|
67
|
+
|
68
|
+
# @raise [Libvirt::Errors::LibError]
|
69
|
+
def start
|
70
|
+
result = FFI::Interface.virInterfaceCreate(@ptr, 0)
|
71
|
+
raise Errors::LibError, "Couldn't start interface" if result.negative?
|
72
|
+
end
|
73
|
+
|
74
|
+
# @raise [Libvirt::Errors::LibError]
|
75
|
+
def destroy
|
76
|
+
result = FFI::Interface.virInterfaceDestroy(@ptr, 0)
|
77
|
+
raise Errors::LibError, "Couldn't destroy interface" if result.negative?
|
78
|
+
end
|
79
|
+
|
80
|
+
# @raise [Libvirt::Errors::LibError]
|
81
|
+
def undefine
|
82
|
+
result = FFI::Interface.virInterfaceUndefine(@ptr)
|
83
|
+
raise Errors::LibError, "Couldn't undefine interface" if result.negative?
|
84
|
+
end
|
85
|
+
|
86
|
+
private
|
87
|
+
|
88
|
+
def dbg(&block)
|
89
|
+
Util.log(:debug, 'Libvirt::Network', &block)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,176 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Libvirt
|
4
|
+
class Network
|
5
|
+
# @param pointer [FFI::Pointer]
|
6
|
+
def self.load_ref(pointer)
|
7
|
+
result = FFI::Network.virNetworkRef(pointer)
|
8
|
+
raise Errors::LibError, "Couldn't retrieve network reference" if result.negative?
|
9
|
+
|
10
|
+
new(pointer)
|
11
|
+
end
|
12
|
+
|
13
|
+
# @param pointer [FFI::Pointer]
|
14
|
+
def initialize(pointer)
|
15
|
+
@ptr = pointer
|
16
|
+
|
17
|
+
free = ->(obj_id) do
|
18
|
+
dbg { "Finalize Libvirt::Network object_id=0x#{obj_id.to_s(16)}, pointer=0x#{@ptr.address.to_s(16)}" }
|
19
|
+
return unless @ptr
|
20
|
+
|
21
|
+
warn "Couldn't free Libvirt::Network object_id=0x#{obj_id.to_s(16)}, pointer=0x#{@ptr.address.to_s(16)}" if FFI::Network.virNetworkFree(@ptr).negative?
|
22
|
+
end
|
23
|
+
ObjectSpace.define_finalizer(self, free)
|
24
|
+
end
|
25
|
+
|
26
|
+
# @return [FFI::Pointer]
|
27
|
+
def to_ptr
|
28
|
+
@ptr
|
29
|
+
end
|
30
|
+
|
31
|
+
# @return [String]
|
32
|
+
# @raise [Libvirt::Errors::LibError]
|
33
|
+
def uuid
|
34
|
+
buff = ::FFI::MemoryPointer.new(:char, Util::UUID_STRING_BUFLEN)
|
35
|
+
result = FFI::Network.virNetworkGetUUIDString(@ptr, buff)
|
36
|
+
raise Errors::LibError, "Couldn't get network uuid" if result.negative?
|
37
|
+
|
38
|
+
buff.read_string
|
39
|
+
end
|
40
|
+
|
41
|
+
# @return [String]
|
42
|
+
# @raise [Libvirt::Errors::LibError]
|
43
|
+
def name
|
44
|
+
result = FFI::Network.virNetworkGetName(@ptr)
|
45
|
+
raise Errors::LibError, "Couldn't get network name" if result.nil?
|
46
|
+
|
47
|
+
result
|
48
|
+
end
|
49
|
+
|
50
|
+
# @param options_or_flags [Array<Symbol>,Hash{Symbol=>Boolean},Integer,Symbol,nil]
|
51
|
+
# @raise [Libvirt::Errors::LibError]
|
52
|
+
def xml_desc(options_or_flags = nil)
|
53
|
+
flags = Util.parse_flags options_or_flags, FFI::Network.enum_type(:xml_flags)
|
54
|
+
result = FFI::Network.virNetworkGetXMLDesc(@ptr, flags)
|
55
|
+
raise Errors::LibError, "Couldn't get network xml_desc" if result.nil?
|
56
|
+
|
57
|
+
result
|
58
|
+
end
|
59
|
+
|
60
|
+
# @return [Boolean]
|
61
|
+
# @raise [Libvirt::Errors::LibError]
|
62
|
+
def active?
|
63
|
+
result = FFI::Network.virNetworkIsActive(@ptr)
|
64
|
+
raise Errors::LibError, "Couldn't get network is active" if result.nil?
|
65
|
+
|
66
|
+
result == 1
|
67
|
+
end
|
68
|
+
|
69
|
+
# @return [Boolean]
|
70
|
+
# @raise [Libvirt::Errors::LibError]
|
71
|
+
def persistent?
|
72
|
+
result = FFI::Network.virNetworkIsPersistent(@ptr)
|
73
|
+
raise Errors::LibError, "Couldn't get network is persistent" if result.nil?
|
74
|
+
|
75
|
+
result == 1
|
76
|
+
end
|
77
|
+
|
78
|
+
# @return [String]
|
79
|
+
# @raise [Libvirt::Errors::LibError]
|
80
|
+
def bridge_name
|
81
|
+
result = FFI::Network.virNetworkGetBridgeName(@ptr)
|
82
|
+
raise Errors::LibError, "Couldn't get network bridge_name" if result.nil?
|
83
|
+
|
84
|
+
result
|
85
|
+
end
|
86
|
+
|
87
|
+
# @return [Boolean]
|
88
|
+
# @raise [Libvirt::Errors::LibError]
|
89
|
+
def auto_start?
|
90
|
+
value = ::FFI::MemoryPointer.new(:int)
|
91
|
+
result = FFI::Network.virNetworkGetAutostart(@ptr, value)
|
92
|
+
raise Errors::LibError, "Couldn't get network auto_start" if result.negative?
|
93
|
+
|
94
|
+
value.read_int == 1
|
95
|
+
end
|
96
|
+
|
97
|
+
# @param value [Boolean]
|
98
|
+
# @raise [Libvirt::Errors::LibError]
|
99
|
+
def set_auto_start(value)
|
100
|
+
value = value ? 1 : 0
|
101
|
+
result = FFI::Network.virNetworkSetAutostart(@ptr, value)
|
102
|
+
raise Errors::LibError, "Couldn't set network auto_start" if result.negative?
|
103
|
+
end
|
104
|
+
|
105
|
+
# @param mac [String]
|
106
|
+
# @return [Integer]
|
107
|
+
# @raise [Libvirt::Errors::LibError]
|
108
|
+
def dhcp_leases_qty(mac = nil)
|
109
|
+
result = FFI::Network.virNetworkGetDHCPLeases(@ptr, mac, nil, 0)
|
110
|
+
raise Errors::LibError, "Couldn't get network dhcp leases qty" if result.nil?
|
111
|
+
|
112
|
+
result
|
113
|
+
end
|
114
|
+
|
115
|
+
# @param mac [String]
|
116
|
+
# @return [Array<Libvirt::NetworkDhcpLease>, Array]
|
117
|
+
# @raise [Libvirt::Errors::LibError]
|
118
|
+
def dhcp_leases(mac = nil)
|
119
|
+
size = dhcp_leases_qty(mac)
|
120
|
+
return [] if size.zero?
|
121
|
+
|
122
|
+
dhcp_leases_ptr = ::FFI::MemoryPointer.new(:pointer, size)
|
123
|
+
result = FFI::Network.virNetworkGetDHCPLeases(@ptr, mac, dhcp_leases_ptr, 0)
|
124
|
+
raise Errors::LibError, "Couldn't retrieve network dhcp leases" if result.negative?
|
125
|
+
|
126
|
+
ptr = dhcp_leases_ptr.read_pointer
|
127
|
+
ptr.get_array_of_pointer(0, size).map { |dhcpl_ptr| NetworkDhcpLease.new(dhcpl_ptr) }
|
128
|
+
end
|
129
|
+
|
130
|
+
# @raise [Libvirt::Errors::LibError]
|
131
|
+
def start
|
132
|
+
result = FFI::Network.virNetworkCreate(@ptr)
|
133
|
+
raise Errors::LibError, "Couldn't start network" if result.negative?
|
134
|
+
end
|
135
|
+
|
136
|
+
# @raise [Libvirt::Errors::LibError]
|
137
|
+
def destroy
|
138
|
+
result = FFI::Network.virNetworkDestroy(@ptr)
|
139
|
+
raise Errors::LibError, "Couldn't destroy network" if result.negative?
|
140
|
+
end
|
141
|
+
|
142
|
+
# @raise [Libvirt::Errors::LibError]
|
143
|
+
def undefine
|
144
|
+
result = FFI::Network.virNetworkUndefine(@ptr)
|
145
|
+
raise Errors::LibError, "Couldn't undefine network" if result.negative?
|
146
|
+
end
|
147
|
+
|
148
|
+
# @param xml [String]
|
149
|
+
# @param command [Integer, Symbol]
|
150
|
+
# @param section [Integer, Symbol]
|
151
|
+
# @param flags [Integer, Symbol]
|
152
|
+
# @param parent_index [Integer] default -1 (means don't care)
|
153
|
+
# @raise [Libvirt::Errors::LibError]
|
154
|
+
def update(xml, command, section, flags, parent_index = -1)
|
155
|
+
command = Util.parse_flags command, FFI::Network.enum_type(:update_command)
|
156
|
+
section = Util.parse_flags section, FFI::Network.enum_type(:update_section)
|
157
|
+
flags = Util.parse_flags flags, FFI::Network.enum_type(:update_flags)
|
158
|
+
|
159
|
+
result = FFI::Network.virNetworkUpdate(
|
160
|
+
@ptr,
|
161
|
+
command,
|
162
|
+
section,
|
163
|
+
parent_index,
|
164
|
+
xml,
|
165
|
+
flags
|
166
|
+
)
|
167
|
+
raise Errors::LibError, "Couldn't update network" if result.negative?
|
168
|
+
end
|
169
|
+
|
170
|
+
private
|
171
|
+
|
172
|
+
def dbg(&block)
|
173
|
+
Util.log(:debug, 'Libvirt::Network', &block)
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Libvirt
|
4
|
+
class NetworkDhcpLease < BaseInfo
|
5
|
+
struct_class FFI::Network::DhcpLeaseStruct
|
6
|
+
|
7
|
+
# @param pointer [FFI::Pointer]
|
8
|
+
def initialize(pointer)
|
9
|
+
super
|
10
|
+
|
11
|
+
free = ->(obj_id) do
|
12
|
+
dbg { "Finalize Libvirt::NetworkDhcpLease object_id=0x#{obj_id.to_s(16)}, pointer=0x#{@ptr.address.to_s(16)}" }
|
13
|
+
return unless @ptr
|
14
|
+
|
15
|
+
warn "Couldn't free Libvirt::NetworkDhcpLease object_id=0x#{obj_id.to_s(16)}, pointer=0x#{@ptr.address.to_s(16)}" if FFI::Storage.virNetworkDHCPLeaseFree(@ptr).negative?
|
16
|
+
end
|
17
|
+
ObjectSpace.define_finalizer(self, free)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/lib/libvirt/storage_pool.rb
CHANGED
@@ -13,7 +13,7 @@ module Libvirt
|
|
13
13
|
@ptr = pointer
|
14
14
|
|
15
15
|
free = ->(obj_id) do
|
16
|
-
|
16
|
+
dbg { "Finalize Libvirt::StoragePool 0x#{obj_id.to_s(16)} @ptr=#{@ptr}," }
|
17
17
|
return unless @ptr
|
18
18
|
|
19
19
|
fr_result = FFI::Storage.virStoragePoolFree(@ptr)
|
@@ -61,10 +61,25 @@ module Libvirt
|
|
61
61
|
ptr.get_array_of_pointer(0, size).map { |stv_ptr| StorageVolume.new(stv_ptr) }
|
62
62
|
end
|
63
63
|
|
64
|
+
def uuid
|
65
|
+
buff = ::FFI::MemoryPointer.new(:char, Util::UUID_STRING_BUFLEN)
|
66
|
+
result = FFI::Storage.virStoragePoolGetUUIDString(@ptr, buff)
|
67
|
+
raise Errors::LibError, "Couldn't get storage pool uuid" if result.negative?
|
68
|
+
|
69
|
+
buff.read_string
|
70
|
+
end
|
71
|
+
|
72
|
+
def name
|
73
|
+
result = FFI::Storage.virStoragePoolGetName(@ptr)
|
74
|
+
raise Errors::LibError, "Couldn't retrieve storage pool name" if result.nil?
|
75
|
+
|
76
|
+
result
|
77
|
+
end
|
78
|
+
|
64
79
|
private
|
65
80
|
|
66
81
|
def dbg(&block)
|
67
|
-
Util.log(:debug, 'Libvirt::
|
82
|
+
Util.log(:debug, 'Libvirt::StoragePool', &block)
|
68
83
|
end
|
69
84
|
end
|
70
85
|
end
|
data/lib/libvirt/util.rb
CHANGED
data/lib/libvirt/version.rb
CHANGED
data/lib/libvirt/xml.rb
CHANGED
@@ -13,6 +13,9 @@ module Libvirt
|
|
13
13
|
require 'libvirt/xml/generic'
|
14
14
|
require 'libvirt/xml/storage_pool'
|
15
15
|
require 'libvirt/xml/storage_volume'
|
16
|
+
require 'libvirt/xml/interface'
|
17
|
+
require 'libvirt/xml/ip_address'
|
18
|
+
require 'libvirt/xml/network'
|
16
19
|
require 'libvirt/xml/memory'
|
17
20
|
require 'libvirt/xml/graphics'
|
18
21
|
require 'libvirt/xml/disk'
|
data/lib/libvirt/xml/generic.rb
CHANGED
@@ -3,6 +3,9 @@
|
|
3
3
|
module Libvirt
|
4
4
|
module Xml
|
5
5
|
class Generic
|
6
|
+
TRUE_VALUES = %w[yes on].freeze
|
7
|
+
FALSE_VALUES = %w[no off].freeze
|
8
|
+
|
6
9
|
class_attribute :_root_path, instance_writer: false, default: '.'
|
7
10
|
class_attribute :_attributes_opts, instance_writer: false, default: {}
|
8
11
|
|
@@ -111,7 +114,7 @@ module Libvirt
|
|
111
114
|
# @param opts [Hash{Symbol=>Object}]
|
112
115
|
# @return [Object, nil]
|
113
116
|
def decode(value, opts)
|
114
|
-
return if value.nil?
|
117
|
+
return opts[:default] if value.nil?
|
115
118
|
|
116
119
|
cast = opts[:cast]
|
117
120
|
return value if cast.nil?
|
@@ -144,9 +147,9 @@ module Libvirt
|
|
144
147
|
def decode_bool(value, _opts)
|
145
148
|
return value if value.is_a?(TrueClass) || value.is_a?(FalseClass)
|
146
149
|
|
147
|
-
return true if value
|
150
|
+
return true if TRUE_VALUES.include?(value)
|
148
151
|
|
149
|
-
return false if value
|
152
|
+
return false if FALSE_VALUES.include?(value)
|
150
153
|
|
151
154
|
nil
|
152
155
|
end
|