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.
@@ -1,18 +1,21 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Libvirt
4
- class DomainCallbackStorage
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
- def initialize
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::DomainCallbackStorage::CallbackDataStruct],
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 { 'Libvirt::DomainCallbackStorage cb_data_free_func triggered' }
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, connection_pointer:, callback_id:, cb:, opaque:)
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] = { cb: cb, opaque: opaque, pointer: cb_data.pointer }
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, 'Libvirt::DomainCallbackStorage', &block)
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
@@ -13,7 +13,7 @@ module Libvirt
13
13
  @ptr = pointer
14
14
 
15
15
  free = ->(obj_id) do
16
- Util.log(:debug) { "Finalize Libvirt::StoragePool 0x#{obj_id.to_s(16)} @ptr=#{@ptr}," }
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::Domain', &block)
82
+ Util.log(:debug, 'Libvirt::StoragePool', &block)
68
83
  end
69
84
  end
70
85
  end
@@ -19,6 +19,8 @@ module Libvirt
19
19
  TiB: 1_099_511_627_776
20
20
  }.freeze
21
21
 
22
+ UUID_STRING_BUFLEN = 0x80 # RFC4122
23
+
22
24
  class << self
23
25
  attr_writer :logger
24
26
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Libvirt
4
- VERSION = '0.5.6'
4
+ VERSION = '0.8.0'
5
5
  end
@@ -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'
@@ -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 == 'yes'
150
+ return true if TRUE_VALUES.include?(value)
148
151
 
149
- return false if value == 'no'
152
+ return false if FALSE_VALUES.include?(value)
150
153
 
151
154
  nil
152
155
  end