libvirt_ffi 0.5.6 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|