libvirt_ffi 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 556422a513288d81aa723c2751129033da2118eb1d8a6a03c01e60efa57017fd
4
- data.tar.gz: 309fd55853169a8b25669736be80d1b0eebc7f66bb4e082f00714d4e751c9ff7
3
+ metadata.gz: 32cd6d96cd065507a105cffe398c5d6bfa2afd2cd472888f831dd2ad382a48de
4
+ data.tar.gz: 06ae43ce6d0d65c8d6a5daa0914df5cfa01a3102f467bc7bef3bafaa19e2208a
5
5
  SHA512:
6
- metadata.gz: '039e73eb32c5354f99e3c31ca9fab1e81e23b0249bfd20f7ed78c10a9b21da5f2f5b73e124df4c2765b18c8e965e55ee5422135d73f56b84b1465506281c3d0b'
7
- data.tar.gz: f9d398150d78a71ed3682a6556cbcbd5e61e9d9304bc38fbaa0935f85798a571fcb9885feed73c50f64e20f7fde06bb79aa120ae7928b183531ac08bc656e4f4
6
+ metadata.gz: 205e7bc1253381af45bcf354b784476acf35f862ba212f6a9b7cdeba3673ed2ae5b73b54ec0a894632e753dd8f1e7ba90cec6a40187c1a0c33df6900f4208c71
7
+ data.tar.gz: d5754a19f39a9c508722b1cb8d29227d38c62eb1c9f0a7503d94aba33f815180217d4b346c32a1e4638a8b1e2526910ebf6dc6ccffe6ab8e3c415870b629b430
@@ -6,9 +6,11 @@ module Libvirt
6
6
  @uri = uri
7
7
  @conn_ptr = ::FFI::Pointer.new(0)
8
8
  @cb_data = {}
9
- ObjectSpace.define_finalizer(self, proc { |obj_id|
10
- STDOUT.puts("finalized Libvirt::Connection #{obj_id.to_s(16)}")
11
- })
9
+
10
+ free = ->(obj_id) do
11
+ STDOUT.puts("finalized Libvirt::Connection obj_id=0x#{obj_id.to_s(16)}, @conn_ptr=#{@conn_ptr}, @uri=#{@uri}, @cb_data=#{@cb_data}")
12
+ end
13
+ ObjectSpace.define_finalizer(self, free)
12
14
  end
13
15
 
14
16
  def open
@@ -61,7 +63,7 @@ module Libvirt
61
63
  result = FFI::Domain.virConnectListAllDomains(@conn_ptr, domains_ptr, flags)
62
64
  raise Error, "Couldn't retrieve domains list with flags #{flags.to_s(16)}" if result < 0
63
65
  ptr = domains_ptr.read_pointer
64
- ptr.get_array_of_pointer(0, size).map { |dom_ptr| Libvirt::Domain.new(dom_ptr, self) }
66
+ ptr.get_array_of_pointer(0, size).map { |dom_ptr| Libvirt::Domain.new(dom_ptr) }
65
67
  end
66
68
 
67
69
  # @yield conn, dom
@@ -131,6 +133,12 @@ module Libvirt
131
133
  NodeInfo.new(node_info_ptr)
132
134
  end
133
135
 
136
+ def stream(flags = 0)
137
+ pointer = FFI::Stream.virStreamNew(@conn_ptr, flags)
138
+ raise Error, "Couldn't create stream" if pointer.null?
139
+ Stream.new(pointer)
140
+ end
141
+
134
142
  private
135
143
 
136
144
  def check_open!
@@ -2,12 +2,13 @@
2
2
 
3
3
  module Libvirt
4
4
  class Domain
5
- def initialize(dom_ptr, conn)
5
+ def initialize(dom_ptr)
6
6
  @dom_ptr = dom_ptr
7
- @conn = conn
8
- ObjectSpace.define_finalizer(self, proc { |obj_id|
9
- STDOUT.puts("finalized Libvirt::Domain #{obj_id.to_s(16)}")
10
- })
7
+
8
+ free = ->(obj_id) do
9
+ STDOUT.puts("finalized Libvirt::Domain obj_id=0x#{obj_id.to_s(16)}, @dom_ptr=#{@dom_ptr},")
10
+ end
11
+ ObjectSpace.define_finalizer(self, free)
11
12
  end
12
13
 
13
14
  def get_state
@@ -56,5 +57,12 @@ module Libvirt
56
57
  def xml_desc(flags = 0)
57
58
  FFI::Domain.virDomainGetXMLDesc(@dom_ptr, flags)
58
59
  end
60
+
61
+ def screenshot(stream, display = 0)
62
+ mime_type, pointer = FFI::Domain.virDomainScreenshot(@dom_ptr, stream.to_ptr, display, 0)
63
+ raise Error, "Couldn't attach domain screenshot" if pointer.null?
64
+ # free pointer required
65
+ mime_type
66
+ end
59
67
  end
60
68
  end
data/lib/libvirt/event.rb CHANGED
@@ -9,24 +9,32 @@ module Libvirt
9
9
  extend Forwardable
10
10
  extend SingleForwardable
11
11
 
12
- single_delegate [:register, :unregister, :registered?] => :instance
12
+ single_delegate [
13
+ :register,
14
+ :unregister,
15
+ :registered?,
16
+ :debug,
17
+ :debug=,
18
+ :invoke_handle_callback,
19
+ :invoke_timeout_callback
20
+ ] => :instance
21
+
22
+ attr_accessor :debug
13
23
 
14
24
  Opaque = Struct.new(:cb, :opaque, :ff)
15
25
 
16
- class << self
17
- def invoke_handle_callback(watch, fd, events, opaque)
18
- cb = opaque.cb
19
- op = opaque.opaque
20
- Util.log(:debug) { "Libvirt::Event INVOKE_HANDLE_CALLBACK watch=#{watch} fd=#{fd} events=#{events} op=#{op}" }
21
- cb.call(watch, fd, events, op)
22
- end
23
-
24
- def invoke_timeout_callback(timer, opaque)
25
- cb = opaque.cb
26
- op = opaque.opaque
27
- Util.log(:debug) { "Libvirt::Event INVOKE_TIMEOUT_CALLBACK timer=#{timer} op=#{op}" }
28
- cb.call(timer, op)
29
- end
26
+ def invoke_handle_callback(watch, fd, events, opaque)
27
+ cb = opaque.cb
28
+ op = opaque.opaque
29
+ dbg { "Libvirt::Event INVOKE_HANDLE_CALLBACK watch=#{watch} fd=#{fd} events=#{events} op=#{op}" }
30
+ cb.call(watch, fd, events, op)
31
+ end
32
+
33
+ def invoke_timeout_callback(timer, opaque)
34
+ cb = opaque.cb
35
+ op = opaque.opaque
36
+ dbg { "Libvirt::Event INVOKE_TIMEOUT_CALLBACK timer=#{timer} op=#{op}" }
37
+ cb.call(timer, op)
30
38
  end
31
39
 
32
40
  def registered?
@@ -80,18 +88,18 @@ module Libvirt
80
88
  private
81
89
 
82
90
  def _add_handle(fd, event, cb, opaque, ff)
83
- Util.log(:debug) { "Libvirt::Event ADD_HANDLE fd=#{fd}, #{event}=event, cb=#{cb}, opaque=#{opaque}, ff=#{ff}" }
91
+ dbg { "Libvirt::Event ADD_HANDLE fd=#{fd}, #{event}=event, cb=#{cb}, opaque=#{opaque}, ff=#{ff}" }
84
92
  op = Opaque.new(cb, opaque, ff)
85
93
  @add_handle.call(fd, event, op)
86
94
  end
87
95
 
88
96
  def _update_handle(watch, event)
89
- Util.log(:debug) { "Libvirt::Event UPDATE_HANDLE watch=#{watch}, event=#{event}" }
97
+ dbg { "Libvirt::Event UPDATE_HANDLE watch=#{watch}, event=#{event}" }
90
98
  @update_handle.call(watch, event)
91
99
  end
92
100
 
93
101
  def _remove_handle(watch)
94
- Util.log(:debug) { "Libvirt::Event REMOVE_HANDLE watch=#{watch}" }
102
+ dbg { "Libvirt::Event REMOVE_HANDLE watch=#{watch}" }
95
103
  op = @remove_handle.call(watch)
96
104
  free_func = op.ff
97
105
  opaque = op.opaque
@@ -100,18 +108,18 @@ module Libvirt
100
108
  end
101
109
 
102
110
  def _add_timer(timeout, cb, opaque, ff)
103
- Util.log(:debug) { "Libvirt::Event ADD_TIMER timeout=#{timeout}, cb=#{cb}, opaque=#{opaque}, ff=#{ff}" }
111
+ dbg { "Libvirt::Event ADD_TIMER timeout=#{timeout}, cb=#{cb}, opaque=#{opaque}, ff=#{ff}" }
104
112
  op = Opaque.new(cb, opaque, ff)
105
113
  @add_timer.call(timeout, op)
106
114
  end
107
115
 
108
116
  def _update_timer(timer, timeout)
109
- Util.log(:debug) { "Libvirt::Event UPDATE_TIMER timer=#{timer}, timeout=#{timeout}" }
117
+ dbg { "Libvirt::Event UPDATE_TIMER timer=#{timer}, timeout=#{timeout}" }
110
118
  @update_timer.call(timer, timeout)
111
119
  end
112
120
 
113
121
  def _remove_timer(timer)
114
- Util.log(:debug) { "Libvirt::Event REMOVE_TIMER timer=#{timer}" }
122
+ dbg { "Libvirt::Event REMOVE_TIMER timer=#{timer}" }
115
123
  op = @remove_timer.call(timer)
116
124
  free_func = op.ff
117
125
  opaque = op.opaque
@@ -119,5 +127,11 @@ module Libvirt
119
127
  0
120
128
  end
121
129
 
130
+ def dbg(&block)
131
+ return unless debug
132
+
133
+ Util.log(:debug, &block)
134
+ end
135
+
122
136
  end
123
137
  end
@@ -109,6 +109,14 @@ module Libvirt
109
109
  # )
110
110
  attach_function :virDomainGetXMLDesc, [:pointer, :uint], :string # strptr?
111
111
 
112
+ # char *virDomainScreenshot (
113
+ # virDomainPtr domain,
114
+ # virStreamPtr stream,
115
+ # unsigned int screen,
116
+ # unsigned int flags
117
+ # )
118
+ attach_function :virDomainScreenshot, [:pointer, :pointer, :uint, :uint], :strptr
119
+
112
120
  # typedef int (*virConnectDomainEventCallback) (
113
121
  # virConnectPtr conn,
114
122
  # virDomainPtr dom,
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Libvirt
4
+ module FFI
5
+ module Stream
6
+ extend ::FFI::Library
7
+ ffi_lib Util.library_path
8
+
9
+ # virStreamPtr virStreamNew (
10
+ # virConnectPtr conn,
11
+ # unsigned int flags
12
+ # )
13
+ attach_function :virStreamNew, [:pointer, :uint], :pointer
14
+
15
+ # typedef void (*virStreamEventCallback) (
16
+ # virStreamPtr stream,
17
+ # int events,
18
+ # void * opaque
19
+ # )
20
+ callback :virStreamEventCallback, [:pointer, :int, :pointer], :void
21
+
22
+ # int virStreamEventAddCallback (
23
+ # virStreamPtr stream,
24
+ # int events,
25
+ # virStreamEventCallback cb,
26
+ # void * opaque,
27
+ # virFreeCallback ff
28
+ # )
29
+ attach_function :virStreamEventAddCallback, [
30
+ :pointer,
31
+ :int,
32
+ :virStreamEventCallback,
33
+ :pointer,
34
+ FFI::Common::FREE_CALLBACK
35
+ ], :int
36
+
37
+ # int virStreamEventRemoveCallback (
38
+ # virStreamPtr stream
39
+ # )
40
+ attach_function :virStreamEventRemoveCallback, [:pointer], :int
41
+
42
+ # int virStreamEventUpdateCallback (
43
+ # virStreamPtr stream,
44
+ # int events
45
+ # )
46
+ attach_function :virStreamEventUpdateCallback, [:pointer, :int], :int
47
+
48
+ # int virStreamFinish (
49
+ # virStreamPtr stream
50
+ # )
51
+ attach_function :virStreamFinish, [:pointer], :int
52
+
53
+ # int virStreamFree (
54
+ # virStreamPtr stream
55
+ # )
56
+ attach_function :virStreamFree, [:pointer], :int
57
+
58
+ # int virStreamAbort (
59
+ # virStreamPtr stream
60
+ # )
61
+ attach_function :virStreamAbort, [:pointer], :int
62
+
63
+ # int virStreamRecv (
64
+ # virStreamPtr stream,
65
+ # char *data,
66
+ # size_t nbytes
67
+ # )
68
+ attach_function :virStreamRecv, [:pointer, :pointer, :size_t], :int
69
+
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,97 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Libvirt
4
+ class Stream
5
+ NONBLOCK = 0x1
6
+ EVENT_READABLE = 0x1
7
+ EVENT_WRITABLE = 0x2
8
+
9
+ def initialize(stream_ptr)
10
+ @stream_ptr = stream_ptr
11
+ @cb = nil
12
+ @opaque = nil
13
+
14
+ free = ->(obj_id) do
15
+ STDOUT.puts("finalized Libvirt::Stream obj_id=0x#{obj_id.to_s(16)}, @stream_ptr=#{@stream_ptr}, @cb=#{@cb},")
16
+ if @stream_ptr && @cb
17
+ rm = FFI::Stream.virStreamEventRemoveCallback(@stream_ptr)
18
+ STDOUT.puts("finalized Libvirt::Stream obj_id=0x#{obj_id.to_s(16)} rm=#{rm}")
19
+ ab = FFI::Stream.virStreamAbort(@stream_ptr)
20
+ STDOUT.puts("finalized Libvirt::Stream obj_id=0x#{obj_id.to_s(16)} ab=#{ab}")
21
+ end
22
+ fr = FFI::Stream.virStreamFree(@stream_ptr) if @stream_ptr
23
+ STDOUT.puts("finalized Libvirt::Stream obj_id=0x#{obj_id.to_s(16)} fr=#{fr}")
24
+ end
25
+ ObjectSpace.define_finalizer(self, free)
26
+ end
27
+
28
+ def to_ptr
29
+ @stream_ptr
30
+ end
31
+
32
+ # @param events [Integer] bit OR of EVENT_READABLE, EVENT_READABLE
33
+ # @param opaque [Object]
34
+ # @yield [Stream]
35
+ def event_add_callback(events, opaque, &block)
36
+ raise Error, 'callback already added' unless @cb.nil?
37
+
38
+ @opaque = opaque
39
+ @cb = ::FFI::Function.new(:void, [:pointer, :int, :pointer]) do |_stream_ptr, evs, _op|
40
+ # stream = Stream.new(stream_ptr)
41
+ block.call(self, evs, @opaque)
42
+ end
43
+
44
+ result = FFI::Stream.virStreamEventAddCallback(@stream_ptr, events, @cb, nil, nil)
45
+ raise Error, "Couldn't add stream event callback" if result < 0
46
+
47
+ true
48
+ end
49
+
50
+ # @param events [Integer] bit OR of EVENT_READABLE, EVENT_READABLE
51
+ def event_update_callback(events)
52
+ result = FFI::Stream.virStreamEventUpdateCallback(@stream_ptr, events)
53
+ raise Error, "Couldn't remove stream event callback" if result < 0
54
+ true
55
+ end
56
+
57
+ def event_remove_callback
58
+ result = FFI::Stream.virStreamEventRemoveCallback(@stream_ptr)
59
+ raise Error, "Couldn't remove stream event callback" if result < 0
60
+ opaque = @opaque
61
+ @cb = nil
62
+ @opaque = nil
63
+ opaque
64
+ end
65
+
66
+ def finish
67
+ result = FFI::Stream.virStreamFinish(@stream_ptr)
68
+ raise Error, "Couldn't remove stream event callback" if result < 0
69
+ @cb = nil
70
+ @opaque = nil
71
+ end
72
+
73
+ def abort_stream
74
+ result = FFI::Stream.virStreamAbort(@stream_ptr)
75
+ raise Error, "Couldn't remove stream event callback" if result < 0
76
+ @cb = nil
77
+ @opaque = nil
78
+ end
79
+
80
+ def recv(bytes)
81
+ buffer = ::FFI::MemoryPointer.new(:char, bytes)
82
+ result = FFI::Stream.virStreamRecv(@stream_ptr, buffer, bytes)
83
+ if result == -1
84
+ abort_stream
85
+ [-1, nil]
86
+ elsif result == 0
87
+ [0, nil]
88
+ elsif result == -2
89
+ [-2, nil]
90
+ elsif result > 0
91
+ [result, buffer.read_bytes(result)]
92
+ else
93
+ raise Error, "Invalid response from virStreamRecv #{result.inspect}"
94
+ end
95
+ end
96
+ end
97
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Libvirt
4
- VERSION = '0.2.1'
4
+ VERSION = '0.3.0'
5
5
  end
data/lib/libvirt.rb CHANGED
@@ -10,10 +10,12 @@ require 'libvirt/ffi/connection'
10
10
  require 'libvirt/ffi/domain'
11
11
  require 'libvirt/ffi/event'
12
12
  require 'libvirt/ffi/node_info'
13
+ require 'libvirt/ffi/stream'
13
14
  require 'libvirt/event'
14
15
  require 'libvirt/connection'
15
16
  require 'libvirt/domain'
16
17
  require 'libvirt/node_info'
18
+ require 'libvirt/stream'
17
19
  require 'libvirt/version'
18
20
 
19
21
  module Libvirt
@@ -1,17 +1,27 @@
1
1
  module LibvirtAsync
2
+ class << self
3
+ def logger=(logger)
4
+ @logger = logger
5
+ end
6
+
7
+ def logger
8
+ @logger
9
+ end
10
+ end
11
+
2
12
  module WithDbg
3
13
  extend ActiveSupport::Concern
4
14
 
5
15
  class_methods do
6
16
  def dbg(progname = nil, &block)
7
- Libvirt.logger.debug(progname || "#{name}.:0x#{object_id.to_s(16)}", &block)
17
+ LibvirtAsync.logger&.debug(progname || "#{name}.:0x#{object_id.to_s(16)}", &block)
8
18
  end
9
19
  end
10
20
 
11
21
  private
12
22
 
13
23
  def dbg(progname = nil, &block)
14
- Libvirt.logger.debug(progname || "#{self.class}#:0x#{object_id.to_s(16)}", &block)
24
+ LibvirtAsync.logger&.debug(progname || "#{self.class}#:0x#{object_id.to_s(16)}", &block)
15
25
  end
16
26
  end
17
27
 
@@ -0,0 +1,196 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'libvirt'
5
+ require 'logger'
6
+ require 'active_support/all'
7
+ require 'async'
8
+ require 'get_process_mem'
9
+
10
+ require_relative 'support/libvirt_async'
11
+ require_relative 'support/log_formatter'
12
+
13
+ Libvirt.logger = Logger.new(STDOUT, formatter: LogFormatter.new)
14
+ Libvirt.logger.level = ENV['DEBUG'] ? :debug : :info
15
+
16
+ LibvirtAsync.logger = Logger.new(STDOUT, formatter: LogFormatter.new)
17
+ LibvirtAsync.logger.level = ENV['LIBVIRT_DEBUG'] ? :debug : :info
18
+
19
+ def print_usage(msg)
20
+ mem = GetProcessMem.new
21
+ STDOUT.puts "#{msg} [#{mem.mb}MB]"
22
+ end
23
+
24
+ def run_gc(msg)
25
+ print_usage "#{msg} before GC.start"
26
+ GC.start
27
+ print_usage "#{msg} after GC.start"
28
+ end
29
+
30
+ IMPL = LibvirtAsync::Implementations.new
31
+ CONNS = []
32
+ DOMS = []
33
+ STREAMS = { stream: nil }
34
+
35
+ class ScreenshotOpaque
36
+ CALLBACK = proc do |s, ev, op|
37
+ #run_gc('ScreenshotOpaque CALLBACK start')
38
+ next unless (Libvirt::Stream::EVENT_READABLE & ev) != 0
39
+ begin
40
+ code, data = s.recv(1024)
41
+ rescue Libvirt::Error => e
42
+ op.on_libvirt_error(s, e)
43
+ next
44
+ end
45
+ #run_gc('ScreenshotOpaque CALLBACK after recv')
46
+
47
+ case code
48
+ when 0
49
+ op.on_complete(s)
50
+ when -1
51
+ op.on_recv_error(s)
52
+ when -2
53
+ print_usage "Opaque::CALLBACK #{op.filepath} wait for data"
54
+ else
55
+ op.on_receive(data)
56
+ end
57
+ end
58
+
59
+ attr_reader :filepath
60
+
61
+ def initialize(filepath, finish_cb)
62
+ @filepath = filepath
63
+ @f = File.open(@filepath, 'wb')
64
+ @finish_cb = finish_cb
65
+ end
66
+
67
+ def on_complete(stream)
68
+ print_usage "Opaque#on_complete #{@filepath}"
69
+ success, reason = finish_stream(stream)
70
+ finish(success, reason)
71
+ end
72
+
73
+ def on_receive(data)
74
+ print_usage "Opaque#on_receive #{@filepath} #{data&.size}"
75
+ @f.write(data)
76
+ end
77
+
78
+ def on_recv_error(stream)
79
+ print_usage "Opaque#on_recv_error #{@filepath}"
80
+ success, reason = finish_stream(stream)
81
+ finish(success, reason)
82
+ end
83
+
84
+ def on_libvirt_error(stream, e)
85
+ print_usage "Opaque#on_libvirt_error #{@filepath} #{e}"
86
+ success, reason = finish_stream(stream)
87
+ finish(success, reason)
88
+ end
89
+
90
+ private
91
+
92
+ def finish_stream(stream)
93
+ print_usage "Opaque#finish_stream stream.event_remove_callback #{@filepath}"
94
+ stream.event_remove_callback
95
+ result = begin
96
+ print_usage "Opaque#finish_stream stream.finish #{@filepath}"
97
+ stream.finish
98
+ [true, nil]
99
+ rescue Libvirt::Error => e
100
+ STDERR.puts "Opaque#finish_stream stream.finish exception rescued #{e.class} #{e.message}"
101
+ [false, e.message]
102
+ end
103
+ print_usage "Opaque#finish_stream ends #{@filepath}"
104
+ result
105
+ end
106
+
107
+ def finish(success, reason)
108
+ print_usage "Opaque#finish success=#{success} #{@filepath}"
109
+
110
+ @f.close
111
+ @f = nil
112
+ @finish_cb.call(success, reason)
113
+ @finish_cb = nil
114
+ end
115
+ end
116
+
117
+ def save_screenshot(c, domain, i)
118
+ stream = c.stream(Libvirt::Stream::NONBLOCK)
119
+
120
+ opaque_cb = proc do |success|
121
+ puts "Stream #{i} complete success=#{success}"
122
+ print_usage "after stream #{i} complete stream=#{STREAMS["stream#{i}"]}"
123
+ run_gc("Stream #{i} complete before remove stream")
124
+ print_usage "after stream #{i} complete and GC.start"
125
+ STREAMS["stream#{i}"] = nil
126
+ run_gc("Stream #{i} complete before remove stream")
127
+ print_usage "after stream #{i} delete and GC.start"
128
+ end
129
+
130
+ opaque = ScreenshotOpaque.new("tmp/screenshots_test#{i}.pnm", opaque_cb)
131
+
132
+ STREAMS["stream#{i}"] = stream
133
+
134
+ print_usage "test_screenshot_mem #{i} before stream start"
135
+ domain.screenshot(stream, 0)
136
+ stream.event_add_callback(
137
+ Libvirt::Stream::EVENT_READABLE,
138
+ opaque,
139
+ &ScreenshotOpaque::CALLBACK
140
+ )
141
+ run_gc("Stream #{i} after add event")
142
+ end
143
+
144
+ Async do
145
+ ASYNC_REACTOR = Async::Task.current.reactor
146
+
147
+ puts "Lib version #{Libvirt.lib_version}"
148
+ puts "Gem version #{Libvirt::VERSION}"
149
+
150
+ IMPL.start
151
+
152
+ c = Libvirt::Connection.new('qemu+tcp://localhost:16510/system')
153
+ c.open
154
+ res = c.set_keep_alive(2, 1)
155
+ Libvirt.logger.info { "set_keep_alive #{res}" }
156
+ CONNS.push(c)
157
+
158
+ domain = c.list_all_domains.first
159
+ DOMS.push(domain)
160
+
161
+ print_usage "First generation"
162
+ 5.times do |i|
163
+ save_screenshot(c, domain, 100 + i)
164
+ end
165
+
166
+ ASYNC_REACTOR.after(15) do
167
+ Async::Task.new(ASYNC_REACTOR, nil) do
168
+ print_usage "Second generation"
169
+
170
+ con = CONNS.first
171
+ dom = DOMS.first
172
+ 5.times do |i|
173
+ save_screenshot(con, dom, 200 + i)
174
+ end
175
+ end.run
176
+ end
177
+
178
+ ASYNC_REACTOR.after(30) do
179
+ Async::Task.new(ASYNC_REACTOR, nil) do
180
+ print_usage "Third generation"
181
+
182
+ con = CONNS.first
183
+ dom = DOMS.first
184
+ 5.times do |i|
185
+ save_screenshot(con, dom, 300 + i)
186
+ end
187
+ end.run
188
+ end
189
+
190
+ ASYNC_REACTOR.every(5) do
191
+ Async::Task.new(ASYNC_REACTOR, nil) do
192
+ run_gc 'PERIODIC'
193
+ end.run
194
+ end
195
+
196
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: libvirt_ffi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Denis Talakevich
@@ -53,7 +53,9 @@ files:
53
53
  - lib/libvirt/ffi/event.rb
54
54
  - lib/libvirt/ffi/libvirt.rb
55
55
  - lib/libvirt/ffi/node_info.rb
56
+ - lib/libvirt/ffi/stream.rb
56
57
  - lib/libvirt/node_info.rb
58
+ - lib/libvirt/stream.rb
57
59
  - lib/libvirt/util.rb
58
60
  - lib/libvirt/version.rb
59
61
  - lib/libvirt_ffi.rb
@@ -61,6 +63,7 @@ files:
61
63
  - test_usage/support/libvirt_async.rb
62
64
  - test_usage/support/log_formatter.rb
63
65
  - test_usage/test_event_loop.rb
66
+ - test_usage/test_screenshot.rb
64
67
  homepage: https://github.com/senid231/libvirt_ffi
65
68
  licenses:
66
69
  - MIT