libvirt_ffi 0.6.1 → 0.8.1
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/.github/workflows/tests.yml +26 -0
- data/.gitignore +2 -1
- data/.rspec +1 -0
- data/.rubocop.yml +1 -1
- data/Gemfile +7 -10
- data/README.md +2 -2
- data/Rakefile +3 -8
- data/lib/libvirt/base_info.rb +8 -0
- data/lib/libvirt/connection.rb +228 -69
- data/lib/libvirt/domain.rb +18 -0
- data/lib/libvirt/ffi/domain.rb +53 -41
- data/lib/libvirt/ffi/host.rb +78 -39
- data/lib/libvirt/ffi/interface.rb +175 -0
- data/lib/libvirt/ffi/network.rb +392 -0
- data/lib/libvirt/ffi/storage.rb +1 -1
- data/lib/libvirt/ffi.rb +2 -0
- data/lib/libvirt/host_callback_storage.rb +10 -2
- data/lib/libvirt/interface.rb +92 -0
- data/lib/libvirt/loggable.rb +58 -0
- data/lib/libvirt/network.rb +176 -0
- data/lib/libvirt/network_dhcp_lease.rb +20 -0
- data/lib/libvirt/storage_pool.rb +2 -2
- data/lib/libvirt/util.rb +87 -64
- data/lib/libvirt/version.rb +1 -1
- data/lib/libvirt/xml/generic.rb +8 -5
- 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/lib/libvirt/xml.rb +6 -2
- data/lib/libvirt.rb +18 -16
- data/libvirt.gemspec +11 -13
- metadata +14 -26
- data/.travis.yml +0 -6
- data/test_usage/support/libvirt_async.rb +0 -536
- data/test_usage/support/log_formatter.rb +0 -33
- data/test_usage/test_domain.rb +0 -43
- data/test_usage/test_event_loop.rb +0 -185
- data/test_usage/test_libvirtd_restart.rb +0 -63
- data/test_usage/test_metadata.rb +0 -104
- data/test_usage/test_screenshot.rb +0 -197
- data/test_usage/test_storage.rb +0 -52
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d81d03c71f0077138bdc7369c7468138333eb45ae1de85c857089b263975e8c4
|
4
|
+
data.tar.gz: cdae17b6ecb8174ee12247d31d4419a9bf367ba17a460c6f9e3e5cc347d313ca
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4f2a8d886ed935f536bd5e04fd9e710d953d0f7f78a8e408220018784291ac3ba71f2e342dcaedbe44b3b57c2e1c77cd36784a05f9d6a0b486ddc6b1dfeb1bd3
|
7
|
+
data.tar.gz: 3df70b41610251d35c2986ba77fd617ee15cb956dc690f850b4650ac34ef4fee80072987d83b1cefcf806501fd87e6401def2c2d2d120e5d8db1b09136d21742
|
@@ -0,0 +1,26 @@
|
|
1
|
+
name: Tests
|
2
|
+
on:
|
3
|
+
pull_request:
|
4
|
+
push:
|
5
|
+
branches:
|
6
|
+
- master
|
7
|
+
|
8
|
+
jobs:
|
9
|
+
test:
|
10
|
+
runs-on: ubuntu-latest
|
11
|
+
strategy:
|
12
|
+
matrix:
|
13
|
+
ruby: [ '2.6', '2.7', '3.0' ]
|
14
|
+
name: Tests with Ruby ${{ matrix.ruby }}
|
15
|
+
steps:
|
16
|
+
- name: Install libvirt
|
17
|
+
run: sudo apt-get install -y libvirt-dev libvirt0
|
18
|
+
- uses: actions/checkout@v2
|
19
|
+
- uses: actions/setup-ruby@v1
|
20
|
+
with:
|
21
|
+
ruby-version: ${{ matrix.ruby }}
|
22
|
+
- name: Run tests
|
23
|
+
run: |
|
24
|
+
gem install bundler
|
25
|
+
bundle install
|
26
|
+
bundle exec rake
|
data/.gitignore
CHANGED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--require spec_helper
|
data/.rubocop.yml
CHANGED
data/Gemfile
CHANGED
@@ -5,14 +5,11 @@ source 'https://rubygems.org'
|
|
5
5
|
# Specify your gem's dependencies in libvirt.gemspec
|
6
6
|
gemspec
|
7
7
|
|
8
|
-
gem '
|
9
|
-
gem '
|
10
|
-
|
8
|
+
gem 'activesupport'
|
9
|
+
gem 'async', '~> 1.24'
|
10
|
+
gem 'gc_tracer'
|
11
|
+
gem 'get_process_mem'
|
11
12
|
gem 'nokogiri'
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
gem 'async', '~> 1.24'
|
16
|
-
gem 'gc_tracer'
|
17
|
-
gem 'get_process_mem'
|
18
|
-
end
|
13
|
+
gem 'rake', '~> 12.0'
|
14
|
+
gem 'rspec', '~> 3.9'
|
15
|
+
gem 'rubocop', '~> 0.80.1'
|
data/README.md
CHANGED
@@ -32,7 +32,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
32
32
|
|
33
33
|
## Contributing
|
34
34
|
|
35
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/
|
35
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/senid231/libvirt. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/senid231/libvirt/blob/master/CODE_OF_CONDUCT.md).
|
36
36
|
|
37
37
|
|
38
38
|
## License
|
@@ -41,4 +41,4 @@ The gem is available as open source under the terms of the [MIT License](https:/
|
|
41
41
|
|
42
42
|
## Code of Conduct
|
43
43
|
|
44
|
-
Everyone interacting in the Libvirt project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/
|
44
|
+
Everyone interacting in the Libvirt project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/senid231/libvirt/blob/master/CODE_OF_CONDUCT.md).
|
data/Rakefile
CHANGED
@@ -1,15 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'bundler/gem_tasks'
|
4
|
-
require '
|
4
|
+
require 'rspec/core/rake_task'
|
5
5
|
require 'rubocop/rake_task'
|
6
6
|
|
7
|
-
|
8
|
-
t.libs << 'test'
|
9
|
-
t.libs << 'lib'
|
10
|
-
t.test_files = FileList['test/**/*_test.rb']
|
11
|
-
end
|
12
|
-
|
7
|
+
RSpec::Core::RakeTask.new(:spec)
|
13
8
|
RuboCop::RakeTask.new(:rubocop)
|
14
9
|
|
15
|
-
task default: [:rubocop, :
|
10
|
+
task default: [:rubocop, :spec]
|
data/lib/libvirt/base_info.rb
CHANGED
@@ -16,6 +16,7 @@ module Libvirt
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
+
# @param pointer [FFI::Pointer]
|
19
20
|
def initialize(pointer)
|
20
21
|
raise ArgumentError, "Can't initialize base class #{self.class}" if self.class == BaseInfo
|
21
22
|
|
@@ -23,12 +24,19 @@ module Libvirt
|
|
23
24
|
@struct = self.class._struct_class.new(pointer)
|
24
25
|
end
|
25
26
|
|
27
|
+
# @param attr [Symbol]
|
28
|
+
# @return [Object, nil]
|
26
29
|
def [](attr)
|
27
30
|
@struct[attr]
|
28
31
|
end
|
29
32
|
|
33
|
+
# @return [Hash]
|
30
34
|
def to_h
|
31
35
|
@struct.members.map { |attr| [attr, @struct[attr]] }.to_h
|
32
36
|
end
|
37
|
+
|
38
|
+
def to_ptr
|
39
|
+
@struct.to_ptr
|
40
|
+
end
|
33
41
|
end
|
34
42
|
end
|
data/lib/libvirt/connection.rb
CHANGED
@@ -2,11 +2,15 @@
|
|
2
2
|
|
3
3
|
module Libvirt
|
4
4
|
class Connection
|
5
|
+
include Loggable
|
6
|
+
|
5
7
|
DOMAIN_EVENT_IDS = FFI::Domain.enum_type(:event_id).symbols.dup.freeze
|
6
8
|
POOL_EVENT_IDS = FFI::Storage.enum_type(:event_id).symbols.dup.freeze
|
9
|
+
NETWORK_EVENT_IDS = FFI::Network.enum_type(:event_id).symbols.dup.freeze
|
7
10
|
|
8
11
|
DOMAIN_STORAGE = HostCallbackStorage.new(:domain_event)
|
9
12
|
POOL_STORAGE = HostCallbackStorage.new(:storage_pool_event)
|
13
|
+
NETWORK_STORAGE = HostCallbackStorage.new(:network_event)
|
10
14
|
CLOSE_STORAGE = HostCallbackStorage.new(:close)
|
11
15
|
|
12
16
|
DOMAIN_EVENT_CALLBACKS = DOMAIN_EVENT_IDS.map do |event_id_sym|
|
@@ -35,6 +39,19 @@ module Libvirt
|
|
35
39
|
[event_id_sym, func]
|
36
40
|
end.to_h.freeze
|
37
41
|
|
42
|
+
NETWORK_EVENT_CALLBACKS = NETWORK_EVENT_IDS.map do |event_id_sym|
|
43
|
+
func = FFI::Network.event_callback_for(event_id_sym) do |conn_ptr, pool_ptr, *args, op_ptr|
|
44
|
+
Util.log(:debug, "NETWORK_EVENT_CALLBACKS[#{event_id_sym}]") do
|
45
|
+
"inside callback conn_ptr=#{conn_ptr}, pool_ptr=#{pool_ptr}, args=#{args}, op_ptr=#{op_ptr}"
|
46
|
+
end
|
47
|
+
connection = Connection.load_ref(conn_ptr)
|
48
|
+
pool = Network.load_ref(pool_ptr)
|
49
|
+
block, opaque = NETWORK_STORAGE.retrieve_from_pointer(op_ptr)
|
50
|
+
block.call(connection, pool, *args, opaque)
|
51
|
+
end
|
52
|
+
[event_id_sym, func]
|
53
|
+
end.to_h.freeze
|
54
|
+
|
38
55
|
CLOSE_CALLBACK = FFI::Host.callback_function(:virConnectCloseFunc) do |conn_ptr, reason, op_ptr|
|
39
56
|
Util.log(:debug, 'CLOSE_CALLBACK') { "inside callback conn_ptr=#{conn_ptr}, reason=#{reason}, op_ptr=#{op_ptr}" }
|
40
57
|
connection = Connection.load_ref(conn_ptr)
|
@@ -42,56 +59,68 @@ module Libvirt
|
|
42
59
|
block.call(connection, reason, opaque)
|
43
60
|
end
|
44
61
|
|
45
|
-
def self.load_ref(
|
46
|
-
|
47
|
-
raise Errors::LibError, "Couldn't retrieve connection reference" if
|
62
|
+
def self.load_ref(ptr)
|
63
|
+
result = FFI::Host.virConnectRef(ptr)
|
64
|
+
raise Errors::LibError, "Couldn't retrieve connection reference" if result.negative?
|
48
65
|
|
49
|
-
|
66
|
+
uri = FFI::Host.virConnectGetURI(ptr)
|
67
|
+
new(uri).tap { |c| c.instance_variable_set(:@ptr, ptr) }
|
50
68
|
end
|
51
69
|
|
70
|
+
attr_reader :uri
|
71
|
+
|
52
72
|
def initialize(uri)
|
53
73
|
@uri = uri
|
54
|
-
@
|
74
|
+
@ptr = ::FFI::Pointer.new(0)
|
55
75
|
@close_data = nil
|
56
76
|
|
57
|
-
|
58
|
-
|
59
|
-
return if @conn_ptr.null?
|
77
|
+
Util.define_finalizer(self) { |pointer| FFI::Host.virConnectClose(pointer) }
|
78
|
+
end
|
60
79
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
80
|
+
def to_s
|
81
|
+
"#<#{self.class}:0x#{object_id.to_s(16)} @uri=#{@uri.inspect} @ptr=0x#{@ptr.address.to_s(16)}>"
|
82
|
+
end
|
83
|
+
|
84
|
+
def inspect
|
85
|
+
to_s
|
86
|
+
end
|
87
|
+
|
88
|
+
def to_ptr
|
89
|
+
@ptr
|
65
90
|
end
|
66
91
|
|
67
92
|
def open
|
68
|
-
@
|
69
|
-
raise Errors::LibError, "Couldn't open connection to #{@uri.inspect}" if @
|
93
|
+
@ptr = FFI::Host.virConnectOpen(@uri)
|
94
|
+
raise Errors::LibError, "Couldn't open connection to #{@uri.inspect}" if @ptr.null?
|
95
|
+
|
96
|
+
dbg { 'opened' }
|
70
97
|
|
71
98
|
true
|
72
99
|
end
|
73
100
|
|
74
101
|
def close
|
75
|
-
result = FFI::Host.virConnectClose(@
|
102
|
+
result = FFI::Host.virConnectClose(@ptr)
|
76
103
|
raise Errors::LibError, "Couldn't close connection to #{@uri.inspect}" if result.negative?
|
77
104
|
|
78
|
-
|
105
|
+
dbg { 'closed' }
|
106
|
+
|
107
|
+
@ptr = ::FFI::Pointer.new(0)
|
79
108
|
true
|
80
109
|
end
|
81
110
|
|
82
111
|
def opened?
|
83
|
-
!@
|
112
|
+
!@ptr.null?
|
84
113
|
end
|
85
114
|
|
86
|
-
def
|
87
|
-
|
115
|
+
def closed?
|
116
|
+
!opened?
|
88
117
|
end
|
89
118
|
|
90
119
|
def version
|
91
120
|
check_open!
|
92
121
|
|
93
122
|
version_ptr = ::FFI::MemoryPointer.new(:ulong)
|
94
|
-
result = FFI::Host.virConnectGetVersion(@
|
123
|
+
result = FFI::Host.virConnectGetVersion(@ptr, version_ptr)
|
95
124
|
raise Errors::LibError, "Couldn't retrieve connection version" if result.negative?
|
96
125
|
|
97
126
|
version_number = version_ptr.get_ulong(0)
|
@@ -99,29 +128,21 @@ module Libvirt
|
|
99
128
|
end
|
100
129
|
|
101
130
|
def set_keep_alive(interval, count)
|
102
|
-
result = FFI::Host.virConnectSetKeepAlive(@
|
131
|
+
result = FFI::Host.virConnectSetKeepAlive(@ptr, interval, count)
|
103
132
|
raise Errors::LibError, "Couldn't set connection keep_alive" if result.negative?
|
104
133
|
|
105
134
|
result.zero?
|
106
135
|
end
|
107
136
|
|
108
137
|
def free_memory
|
109
|
-
result = FFI::Host.virNodeGetFreeMemory(@
|
138
|
+
result = FFI::Host.virNodeGetFreeMemory(@ptr)
|
110
139
|
raise Errors::LibError, "Couldn't set connection keep_alive" if result.negative?
|
111
140
|
|
112
141
|
result
|
113
142
|
end
|
114
143
|
|
115
|
-
def to_s
|
116
|
-
"#<#{self.class}:0x#{object_id.to_s(16)} @uri=#{@uri.inspect} @conn_ptr=0x#{@conn_ptr.address.to_s(16)}>"
|
117
|
-
end
|
118
|
-
|
119
|
-
def inspect
|
120
|
-
to_s
|
121
|
-
end
|
122
|
-
|
123
144
|
def list_all_domains_qty(flags = 0)
|
124
|
-
result = FFI::Domain.virConnectListAllDomains(@
|
145
|
+
result = FFI::Domain.virConnectListAllDomains(@ptr, nil, flags)
|
125
146
|
raise Errors::LibError, "Couldn't retrieve domains qty with flags #{flags.to_s(16)}" if result.negative?
|
126
147
|
|
127
148
|
result
|
@@ -132,7 +153,7 @@ module Libvirt
|
|
132
153
|
return [] if size.zero?
|
133
154
|
|
134
155
|
domains_ptr = ::FFI::MemoryPointer.new(:pointer, size)
|
135
|
-
result = FFI::Domain.virConnectListAllDomains(@
|
156
|
+
result = FFI::Domain.virConnectListAllDomains(@ptr, domains_ptr, flags)
|
136
157
|
raise Errors::LibError, "Couldn't retrieve domains list with flags #{flags.to_s(16)}" if result.negative?
|
137
158
|
|
138
159
|
ptr = domains_ptr.read_pointer
|
@@ -141,7 +162,7 @@ module Libvirt
|
|
141
162
|
|
142
163
|
def list_all_storage_pools_qty(options_or_flags = nil)
|
143
164
|
flags = Util.parse_flags options_or_flags, FFI::Storage.enum_type(:list_all_pools_flags)
|
144
|
-
result = FFI::Storage.virConnectListAllStoragePools(@
|
165
|
+
result = FFI::Storage.virConnectListAllStoragePools(@ptr, nil, flags)
|
145
166
|
raise Errors::LibError, "Couldn't retrieve storage pools qty with flags #{flags.to_s(16)}" if result.negative?
|
146
167
|
|
147
168
|
result
|
@@ -153,19 +174,73 @@ module Libvirt
|
|
153
174
|
return [] if size.zero?
|
154
175
|
|
155
176
|
storage_pools_ptr = ::FFI::MemoryPointer.new(:pointer, size)
|
156
|
-
result = FFI::Storage.virConnectListAllStoragePools(@
|
177
|
+
result = FFI::Storage.virConnectListAllStoragePools(@ptr, storage_pools_ptr, flags)
|
157
178
|
raise Errors::LibError, "Couldn't retrieve storage pools list with flags #{flags.to_s(16)}" if result.negative?
|
158
179
|
|
159
180
|
ptr = storage_pools_ptr.read_pointer
|
160
181
|
ptr.get_array_of_pointer(0, size).map { |stp_ptr| StoragePool.new(stp_ptr) }
|
161
182
|
end
|
162
183
|
|
184
|
+
# @param options_or_flags [Array<Symbol>,Hash{Symbol=>Boolean},Integer,Symbol,nil]
|
185
|
+
# @return [Integer]
|
186
|
+
# @raise [Libvirt::Errors::LibError]
|
187
|
+
def list_all_networks_qty(options_or_flags = nil)
|
188
|
+
flags = Util.parse_flags options_or_flags, FFI::Network.enum_type(:list_all_flags)
|
189
|
+
result = FFI::Network.virConnectListAllNetworks(@ptr, nil, flags)
|
190
|
+
raise Errors::LibError, "Couldn't retrieve networks qty with flags #{flags.to_s(16)}" if result.negative?
|
191
|
+
|
192
|
+
result
|
193
|
+
end
|
194
|
+
|
195
|
+
# @param options_or_flags [Array<Symbol>,Hash{Symbol=>Boolean},Integer,Symbol,nil]
|
196
|
+
# @return [Array<Libvirt::Network>, Array]
|
197
|
+
# @raise [Libvirt::Errors::LibError]
|
198
|
+
def list_all_networks(options_or_flags = nil)
|
199
|
+
flags = Util.parse_flags options_or_flags, FFI::Network.enum_type(:list_all_flags)
|
200
|
+
size = list_all_networks_qty(flags)
|
201
|
+
return [] if size.zero?
|
202
|
+
|
203
|
+
networks_ptr = ::FFI::MemoryPointer.new(:pointer, size)
|
204
|
+
result = FFI::Network.virConnectListAllNetworks(@ptr, networks_ptr, 0)
|
205
|
+
raise Errors::LibError, "Couldn't retrieve networks list" if result.negative?
|
206
|
+
|
207
|
+
ptr = networks_ptr.read_pointer
|
208
|
+
ptr.get_array_of_pointer(0, size).map { |n_ptr| Network.new(n_ptr) }
|
209
|
+
end
|
210
|
+
|
211
|
+
# @param options_or_flags [Array<Symbol>,Hash{Symbol=>Boolean},Integer,Symbol,nil]
|
212
|
+
# @return [Integer]
|
213
|
+
# @raise [Libvirt::Errors::LibError]
|
214
|
+
def list_all_interfaces_qty(options_or_flags = nil)
|
215
|
+
flags = Util.parse_flags options_or_flags, FFI::Interface.enum_type(:list_all_flags)
|
216
|
+
result = FFI::Interface.virConnectListAllInterfaces(@ptr, nil, flags)
|
217
|
+
raise Errors::LibError, "Couldn't retrieve interfaces qty with flags #{flags.to_s(16)}" if result.negative?
|
218
|
+
|
219
|
+
result
|
220
|
+
end
|
221
|
+
|
222
|
+
# @param options_or_flags [Array<Symbol>,Hash{Symbol=>Boolean},Integer,Symbol,nil]
|
223
|
+
# @return [Array<Libvirt::Interface>, Array]
|
224
|
+
# @raise [Libvirt::Errors::LibError]
|
225
|
+
def list_all_interfaces(options_or_flags = nil)
|
226
|
+
flags = Util.parse_flags options_or_flags, FFI::Interface.enum_type(:list_all_flags)
|
227
|
+
size = list_all_interfaces_qty(flags)
|
228
|
+
return [] if size.zero?
|
229
|
+
|
230
|
+
interfaces_ptr = ::FFI::MemoryPointer.new(:pointer, size)
|
231
|
+
result = FFI::Interface.virConnectListAllInterfaces(@ptr, interfaces_ptr, 0)
|
232
|
+
raise Errors::LibError, "Couldn't retrieve interfaces list" if result.negative?
|
233
|
+
|
234
|
+
ptr = interfaces_ptr.read_pointer
|
235
|
+
ptr.get_array_of_pointer(0, size).map { |i_ptr| Interface.new(i_ptr) }
|
236
|
+
end
|
237
|
+
|
163
238
|
def register_close_callback(opaque = nil, &block)
|
164
|
-
dbg { "
|
239
|
+
dbg { "opaque=#{opaque}" }
|
165
240
|
|
166
241
|
cb_data, cb_data_free_func = CLOSE_STORAGE.allocate_struct
|
167
242
|
result = FFI::Host.virConnectRegisterCloseCallback(
|
168
|
-
@
|
243
|
+
@ptr,
|
169
244
|
CLOSE_CALLBACK,
|
170
245
|
cb_data.pointer,
|
171
246
|
cb_data_free_func
|
@@ -177,17 +252,29 @@ module Libvirt
|
|
177
252
|
|
178
253
|
CLOSE_STORAGE.store_struct(
|
179
254
|
cb_data,
|
180
|
-
connection_pointer: @
|
255
|
+
connection_pointer: @ptr,
|
181
256
|
callback_id: result,
|
182
257
|
cb: block,
|
183
|
-
opaque: opaque
|
258
|
+
opaque: opaque,
|
259
|
+
free_func: cb_data_free_func
|
184
260
|
)
|
185
261
|
result
|
186
262
|
end
|
187
263
|
|
264
|
+
def deregister_close_callback
|
265
|
+
dbg { 'deregister' }
|
266
|
+
|
267
|
+
result = FFI::Host.virConnectUnregisterCloseCallback(@ptr, CLOSE_CALLBACK)
|
268
|
+
raise Errors::LibError, "Couldn't deregister close callback" if result.negative?
|
269
|
+
|
270
|
+
# virConnectUnregisterCloseCallback will call free func
|
271
|
+
# So we don't need to remove object from CLOSE_STORAGE here.
|
272
|
+
true
|
273
|
+
end
|
274
|
+
|
188
275
|
# @yield conn, dom, *args
|
189
276
|
def register_domain_event_callback(event_id, domain = nil, opaque = nil, &block)
|
190
|
-
dbg { "
|
277
|
+
dbg { "event_id=#{event_id}" }
|
191
278
|
|
192
279
|
enum = FFI::Domain.enum_type(:event_id)
|
193
280
|
event_id, event_id_sym = Util.parse_enum(enum, event_id)
|
@@ -196,7 +283,7 @@ module Libvirt
|
|
196
283
|
cb_data, cb_data_free_func = DOMAIN_STORAGE.allocate_struct
|
197
284
|
|
198
285
|
result = FFI::Domain.virConnectDomainEventRegisterAny(
|
199
|
-
@
|
286
|
+
@ptr,
|
200
287
|
domain&.to_ptr,
|
201
288
|
event_id,
|
202
289
|
cb,
|
@@ -213,15 +300,16 @@ module Libvirt
|
|
213
300
|
connection_pointer: @conn_ptr,
|
214
301
|
callback_id: result,
|
215
302
|
cb: block,
|
216
|
-
opaque: opaque
|
303
|
+
opaque: opaque,
|
304
|
+
free_func: cb_data_free_func
|
217
305
|
)
|
218
306
|
result
|
219
307
|
end
|
220
308
|
|
221
309
|
def deregister_domain_event_callback(callback_id)
|
222
|
-
dbg { "
|
310
|
+
dbg { "callback_id=#{callback_id}" }
|
223
311
|
|
224
|
-
result = FFI::Domain.virConnectDomainEventDeregisterAny(@
|
312
|
+
result = FFI::Domain.virConnectDomainEventDeregisterAny(@ptr, callback_id)
|
225
313
|
raise Errors::LibError, "Couldn't deregister domain event callback" if result.negative?
|
226
314
|
|
227
315
|
# virConnectDomainEventDeregisterAny will call free func
|
@@ -230,7 +318,7 @@ module Libvirt
|
|
230
318
|
end
|
231
319
|
|
232
320
|
def register_storage_pool_event_callback(event_id, storage_pool = nil, opaque = nil, &block)
|
233
|
-
dbg { "
|
321
|
+
dbg { "event_id=#{event_id}" }
|
234
322
|
|
235
323
|
enum = FFI::Storage.enum_type(:event_id)
|
236
324
|
event_id, event_id_sym = Util.parse_enum(enum, event_id)
|
@@ -239,7 +327,7 @@ module Libvirt
|
|
239
327
|
cb_data, cb_data_free_func = POOL_STORAGE.allocate_struct
|
240
328
|
|
241
329
|
result = FFI::Storage.virConnectStoragePoolEventRegisterAny(
|
242
|
-
@
|
330
|
+
@ptr,
|
243
331
|
storage_pool&.to_ptr,
|
244
332
|
event_id,
|
245
333
|
cb,
|
@@ -253,18 +341,19 @@ module Libvirt
|
|
253
341
|
|
254
342
|
POOL_STORAGE.store_struct(
|
255
343
|
cb_data,
|
256
|
-
connection_pointer: @
|
344
|
+
connection_pointer: @ptr,
|
257
345
|
callback_id: result,
|
258
346
|
cb: block,
|
259
|
-
opaque: opaque
|
347
|
+
opaque: opaque,
|
348
|
+
free_func: cb_data_free_func
|
260
349
|
)
|
261
350
|
result
|
262
351
|
end
|
263
352
|
|
264
353
|
def deregister_storage_pool_event_callback(callback_id)
|
265
|
-
dbg { "
|
354
|
+
dbg { "callback_id=#{callback_id}" }
|
266
355
|
|
267
|
-
result = FFI::Storage.virConnectStoragePoolEventDeregisterAny(@
|
356
|
+
result = FFI::Storage.virConnectStoragePoolEventDeregisterAny(@ptr, callback_id)
|
268
357
|
raise Errors::LibError, "Couldn't deregister storage pool event callback" if result.negative?
|
269
358
|
|
270
359
|
# virConnectStoragePoolEventDeregisterAny will call free func
|
@@ -272,20 +361,53 @@ module Libvirt
|
|
272
361
|
true
|
273
362
|
end
|
274
363
|
|
275
|
-
def
|
276
|
-
dbg {
|
364
|
+
def register_network_event_callback(event_id, network = nil, opaque = nil, &block)
|
365
|
+
dbg { "event_id=#{event_id}" }
|
277
366
|
|
278
|
-
|
279
|
-
|
367
|
+
enum = FFI::Network.enum_type(:event_id)
|
368
|
+
event_id, event_id_sym = Util.parse_enum(enum, event_id)
|
369
|
+
cb = NETWORK_EVENT_CALLBACKS.fetch(event_id_sym)
|
280
370
|
|
281
|
-
|
282
|
-
|
371
|
+
cb_data, cb_data_free_func = NETWORK_STORAGE.allocate_struct
|
372
|
+
|
373
|
+
result = FFI::Network.virConnectNetworkEventRegisterAny(
|
374
|
+
@ptr,
|
375
|
+
network&.to_ptr,
|
376
|
+
event_id,
|
377
|
+
cb,
|
378
|
+
cb_data.pointer,
|
379
|
+
cb_data_free_func
|
380
|
+
)
|
381
|
+
if result.negative?
|
382
|
+
cb_data.pointer.free
|
383
|
+
raise Errors::LibError, "Couldn't register network event callback"
|
384
|
+
end
|
385
|
+
|
386
|
+
NETWORK_STORAGE.store_struct(
|
387
|
+
cb_data,
|
388
|
+
connection_pointer: @ptr,
|
389
|
+
callback_id: result,
|
390
|
+
cb: block,
|
391
|
+
opaque: opaque,
|
392
|
+
free_func: cb_data_free_func
|
393
|
+
)
|
394
|
+
result
|
395
|
+
end
|
396
|
+
|
397
|
+
def deregister_network_event_callback(callback_id)
|
398
|
+
dbg { "callback_id=#{callback_id}" }
|
399
|
+
|
400
|
+
result = FFI::Network.virConnectNetworkEventDeregisterAny(@ptr, callback_id)
|
401
|
+
raise Errors::LibError, "Couldn't deregister network event callback" if result.negative?
|
402
|
+
|
403
|
+
# virConnectNetworkEventDeregisterAny will call free func
|
404
|
+
# So we don't need to remove object from NETWORK_STORAGE here.
|
283
405
|
true
|
284
406
|
end
|
285
407
|
|
286
408
|
def lib_version
|
287
409
|
version_ptr = ::FFI::MemoryPointer.new(:ulong)
|
288
|
-
result = FFI::Host.virConnectGetLibVersion(@
|
410
|
+
result = FFI::Host.virConnectGetLibVersion(@ptr, version_ptr)
|
289
411
|
raise Errors::LibError, "Couldn't get connection lib version" if result.negative?
|
290
412
|
|
291
413
|
version_number = version_ptr.get_ulong(0)
|
@@ -293,28 +415,28 @@ module Libvirt
|
|
293
415
|
end
|
294
416
|
|
295
417
|
def hostname
|
296
|
-
FFI::Host.virConnectGetHostname(@
|
418
|
+
FFI::Host.virConnectGetHostname(@ptr)
|
297
419
|
end
|
298
420
|
|
299
421
|
# @param type [String,NilClass]
|
300
422
|
def max_vcpus(type = nil)
|
301
|
-
FFI::Host.virConnectGetMaxVcpus(@
|
423
|
+
FFI::Host.virConnectGetMaxVcpus(@ptr, type)
|
302
424
|
end
|
303
425
|
|
304
426
|
def capabilities
|
305
|
-
FFI::Host.virConnectGetCapabilities(@
|
427
|
+
FFI::Host.virConnectGetCapabilities(@ptr)
|
306
428
|
end
|
307
429
|
|
308
430
|
def node_info
|
309
431
|
node_info_ptr = ::FFI::MemoryPointer.new(FFI::Host::NodeInfoStruct.by_value)
|
310
|
-
result = FFI::Host.virNodeGetInfo(@
|
432
|
+
result = FFI::Host.virNodeGetInfo(@ptr, node_info_ptr)
|
311
433
|
raise Errors::LibError, "Couldn't get connection node info" if result.negative?
|
312
434
|
|
313
435
|
NodeInfo.new(node_info_ptr)
|
314
436
|
end
|
315
437
|
|
316
438
|
def stream(flags = 0)
|
317
|
-
pointer = FFI::Stream.virStreamNew(@
|
439
|
+
pointer = FFI::Stream.virStreamNew(@ptr, flags)
|
318
440
|
raise Errors::LibError, "Couldn't create stream" if pointer.null?
|
319
441
|
|
320
442
|
Stream.new(pointer)
|
@@ -322,24 +444,61 @@ module Libvirt
|
|
322
444
|
|
323
445
|
def define_domain(xml, options_or_flags = nil)
|
324
446
|
flags = Util.parse_flags options_or_flags, FFI::Domain.enum_type(:define_flags)
|
325
|
-
pointer = FFI::Domain.virDomainDefineXMLFlags(@
|
447
|
+
pointer = FFI::Domain.virDomainDefineXMLFlags(@ptr, xml, flags)
|
326
448
|
raise Errors::LibError, "Couldn't define domain" if pointer.null?
|
327
449
|
|
328
450
|
Domain.new(pointer)
|
329
451
|
end
|
330
452
|
|
331
|
-
|
453
|
+
# @param xml [String]
|
454
|
+
# @raise [Libvirt::Errors::LibError]
|
455
|
+
def create_network(xml)
|
456
|
+
pointer = FFI::Network.virNetworkCreateXML(@ptr, xml)
|
457
|
+
raise Errors::LibError, "Couldn't create network with xml" if pointer.null?
|
332
458
|
|
333
|
-
|
334
|
-
@conn_ptr = conn_ptr
|
459
|
+
Network.new(pointer)
|
335
460
|
end
|
336
461
|
|
337
|
-
|
338
|
-
|
462
|
+
# @param xml [String]
|
463
|
+
# @raise [Libvirt::Errors::LibError]
|
464
|
+
def define_network(xml)
|
465
|
+
pointer = FFI::Network.virNetworkDefineXML(@ptr, xml)
|
466
|
+
raise Errors::LibError, "Couldn't define network with xml" if pointer.null?
|
467
|
+
|
468
|
+
Network.new(pointer)
|
339
469
|
end
|
340
470
|
|
341
|
-
|
342
|
-
|
471
|
+
# @param xml [String]
|
472
|
+
# @raise [Libvirt::Errors::LibError]
|
473
|
+
def define_interface(xml)
|
474
|
+
pointer = FFI::Interface.virInterfaceDefineXML(@ptr, xml, 0)
|
475
|
+
raise Errors::LibError, "Couldn't define interface with xml" if pointer.null?
|
476
|
+
|
477
|
+
Interface.new(pointer)
|
478
|
+
end
|
479
|
+
|
480
|
+
# @raise [Libvirt::Errors::LibError]
|
481
|
+
def begin_interface_change
|
482
|
+
result = FFI::Interface.virInterfaceChangeBegin(@ptr, 0)
|
483
|
+
raise Errors::LibError, "Couldn't begin interface change" if result.negative?
|
484
|
+
end
|
485
|
+
|
486
|
+
# @raise [Libvirt::Errors::LibError]
|
487
|
+
def commit_interface_change
|
488
|
+
result = FFI::Interface.virInterfaceChangeCommit(@ptr, 0)
|
489
|
+
raise Errors::LibError, "Couldn't commit interface change" if result.negative?
|
490
|
+
end
|
491
|
+
|
492
|
+
# @raise [Libvirt::Errors::LibError]
|
493
|
+
def rollback_interface_change
|
494
|
+
result = FFI::Interface.virInterfaceChangeRollback(@ptr, 0)
|
495
|
+
raise Errors::LibError, "Couldn't rollback interface change" if result.negative?
|
496
|
+
end
|
497
|
+
|
498
|
+
private
|
499
|
+
|
500
|
+
def check_open!
|
501
|
+
raise Errors::LibError, "Connection to #{@uri.inspect} is not open" if @ptr.null?
|
343
502
|
end
|
344
503
|
end
|
345
504
|
end
|