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.
@@ -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