libvirt_ffi 0.2.1 → 0.3.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.
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