libvirt_ffi 0.4.0 → 0.5.3

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.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +78 -0
  3. data/Gemfile +7 -3
  4. data/Rakefile +6 -1
  5. data/bin/console +1 -0
  6. data/exe/libvirt +1 -0
  7. data/lib/libvirt.rb +12 -12
  8. data/lib/libvirt/base_info.rb +34 -0
  9. data/lib/libvirt/connection.rb +111 -38
  10. data/lib/libvirt/domain.rb +113 -8
  11. data/lib/libvirt/domain_callback_storage.rb +20 -16
  12. data/lib/libvirt/errors.rb +65 -0
  13. data/lib/libvirt/event.rb +36 -28
  14. data/lib/libvirt/ffi.rb +17 -0
  15. data/lib/libvirt/ffi/common.rb +8 -1
  16. data/lib/libvirt/ffi/domain.rb +530 -196
  17. data/lib/libvirt/ffi/error.rb +243 -0
  18. data/lib/libvirt/ffi/event.rb +30 -36
  19. data/lib/libvirt/ffi/helpers.rb +17 -0
  20. data/lib/libvirt/ffi/host.rb +127 -0
  21. data/lib/libvirt/ffi/storage.rb +149 -0
  22. data/lib/libvirt/ffi/stream.rb +19 -17
  23. data/lib/libvirt/node_info.rb +2 -41
  24. data/lib/libvirt/storage_pool.rb +70 -0
  25. data/lib/libvirt/storage_pool_info.rb +7 -0
  26. data/lib/libvirt/storage_volume.rb +51 -0
  27. data/lib/libvirt/storage_volume_info.rb +7 -0
  28. data/lib/libvirt/stream.rb +33 -14
  29. data/lib/libvirt/util.rb +61 -8
  30. data/lib/libvirt/version.rb +1 -1
  31. data/lib/libvirt/xml.rb +23 -0
  32. data/lib/libvirt/xml/disk.rb +59 -0
  33. data/lib/libvirt/xml/domain.rb +76 -0
  34. data/lib/libvirt/xml/generic.rb +252 -0
  35. data/lib/libvirt/xml/graphics.rb +14 -0
  36. data/lib/libvirt/xml/max_vcpu.rb +12 -0
  37. data/lib/libvirt/xml/memory.rb +14 -0
  38. data/lib/libvirt/xml/storage_pool.rb +24 -0
  39. data/lib/libvirt/xml/storage_volume.rb +32 -0
  40. data/lib/libvirt/xml/vcpu.rb +12 -0
  41. data/lib/libvirt_ffi.rb +2 -0
  42. data/libvirt.gemspec +5 -1
  43. data/test_usage/support/libvirt_async.rb +27 -35
  44. data/test_usage/support/log_formatter.rb +5 -10
  45. data/test_usage/test_domain.rb +43 -0
  46. data/test_usage/test_event_loop.rb +115 -39
  47. data/test_usage/test_libvirtd_restart.rb +63 -0
  48. data/test_usage/test_metadata.rb +104 -0
  49. data/test_usage/test_screenshot.rb +14 -13
  50. data/test_usage/test_storage.rb +52 -0
  51. metadata +42 -6
  52. data/lib/libvirt/error.rb +0 -6
  53. data/lib/libvirt/ffi/connection.rb +0 -94
  54. data/lib/libvirt/ffi/libvirt.rb +0 -17
  55. data/lib/libvirt/ffi/node_info.rb +0 -37
@@ -0,0 +1,63 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'bundler/setup'
5
+ require 'libvirt'
6
+ require 'logger'
7
+ require 'active_support/all'
8
+ require 'async'
9
+ require 'get_process_mem'
10
+ require 'gc_tracer'
11
+
12
+ require_relative 'support/libvirt_async'
13
+ require_relative 'support/log_formatter'
14
+
15
+ GC::Tracer.start_logging(
16
+ nil,
17
+ gc_stat: false,
18
+ gc_latest_gc_info: false,
19
+ rusage: false,
20
+ events: [:end_mark, :end_sweep]
21
+ )
22
+
23
+ Libvirt.logger = Logger.new(STDOUT, formatter: LogFormatter.new)
24
+ Libvirt.logger.level = ENV['DEBUG'] ? :debug : :info
25
+
26
+ IMPL = LibvirtAsync::Implementations.new
27
+ OBJECTS = {
28
+ hv: nil
29
+ }.freeze
30
+
31
+ def async_task(run, parent = nil, &block)
32
+ task = LibvirtAsync::Util.create_task(parent, ASYNC_REACTOR, &block)
33
+ case run
34
+ when :now
35
+ task.run
36
+ when :later
37
+ task.reactor << task.fiber
38
+ else
39
+ raise ArgumentError, "invalid run #{run}"
40
+ end
41
+ end
42
+
43
+ Async do
44
+ ASYNC_REACTOR = Async::Task.current.reactor
45
+
46
+ puts "Lib version #{Libvirt.lib_version}"
47
+ puts "Gem version #{Libvirt::VERSION}"
48
+
49
+ IMPL.start
50
+
51
+ OBJECTS[:hv] = Libvirt::Connection.new('qemu+tcp://localhost:16510/system')
52
+ OBJECTS[:hv].open
53
+ OBJECTS[:hv].register_close_callback do |conn, reason, _op|
54
+ puts "Im closing conn=#{conn}, reason=#{reason}"
55
+ end
56
+ # OBJECTS[:hv].set_keep_alive(2, 1)
57
+
58
+ ASYNC_REACTOR.every(5) do
59
+ async_task(:now) do
60
+ puts "list_all_domains_qty #{OBJECTS[:hv].list_all_domains_qty}"
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,104 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'bundler/setup'
5
+ require 'libvirt'
6
+ require 'logger'
7
+ require 'active_support/all'
8
+ require 'async'
9
+
10
+ require_relative 'support/libvirt_async'
11
+ require_relative 'support/log_formatter'
12
+
13
+ require 'libvirt/xml'
14
+
15
+ Libvirt.logger = Logger.new(STDOUT, formatter: LogFormatter.new)
16
+ Libvirt.logger.level = ENV['DEBUG'] ? :debug : :info
17
+
18
+ IMPL = LibvirtAsync::Implementations.new
19
+
20
+ STDOUT.sync = true
21
+ STDERR.sync = true
22
+
23
+ def log_error(error, skip_backtrace: false, causes: [])
24
+ STDERR.puts "<#{error.class}>: #{error.message}", error.backtrace
25
+ if error.cause && error.cause != error && !causes.include?(error.cause)
26
+ causes.push(error)
27
+ log_error(error.cause, skip_backtrace: skip_backtrace, causes: causes)
28
+ end
29
+ end
30
+
31
+ def libvirt_safe(rescue_value = nil)
32
+ yield
33
+ rescue Libvirt::Errors::LibError => e
34
+ STDERR.puts "<#{e.class}>: #{e.message}"
35
+ rescue_value
36
+ end
37
+
38
+ Async do
39
+ ASYNC_REACTOR = Async::Task.current.reactor
40
+
41
+ puts "Lib version #{Libvirt.lib_version}"
42
+ puts "Gem version #{Libvirt::VERSION}"
43
+
44
+ IMPL.start
45
+
46
+ conn = Libvirt::Connection.new('qemu+tcp://localhost:16510/system')
47
+ conn.open
48
+
49
+ puts "Connection version #{conn.version.inspect}"
50
+ puts "Connection lib_version #{conn.lib_version.inspect}"
51
+ puts "Connection hostname #{conn.hostname.inspect}"
52
+
53
+ dom = conn.list_all_domains.first
54
+ puts "Domain #{dom.uuid} #{dom.name} #{dom.get_state}"
55
+
56
+ libvirt_safe do
57
+ dom.start
58
+ end
59
+
60
+ dom.set_metadata("test title #{Process.pid}", type: :TITLE, flags: :AFFECT_CONFIG)
61
+ dom.set_metadata("test desc #{Process.pid}", type: :DESCRIPTION, flags: :AFFECT_CONFIG)
62
+
63
+ puts "domain title", libvirt_safe{ dom.get_metadata(type: :TITLE, flags: :AFFECT_CONFIG) }
64
+ puts "domain description", libvirt_safe { dom.get_metadata(type: :DESCRIPTION, flags: :AFFECT_CONFIG) }
65
+
66
+ puts "full XML title", Libvirt::Xml::Domain.load(dom.xml_desc).title
67
+ puts "full XML description", Libvirt::Xml::Domain.load(dom.xml_desc).description
68
+
69
+ namespace = 'https://example.com'
70
+ old_metadata = dom.get_metadata(
71
+ uri: namespace, flags: :AFFECT_CONFIG
72
+ )
73
+
74
+ puts "Old Metadata", old_metadata
75
+
76
+ new_metadata = "<pid>#{Process.pid}</pid>"
77
+ key = 'example'
78
+ dom.set_metadata new_metadata,
79
+ key: key,
80
+ uri: namespace,
81
+ flags: :AFFECT_CONFIG
82
+
83
+ puts "new metadata", dom.get_metadata(
84
+ uri: namespace, flags: :AFFECT_CONFIG
85
+ )
86
+
87
+ puts "full XML metadata", Libvirt::Xml::Domain.load(dom.xml_desc).metadata
88
+
89
+ puts "domain shutdown", libvirt_safe { dom.shutdown }
90
+ ASYNC_REACTOR.sleep 5
91
+ puts dom.get_state
92
+
93
+ puts "domain start", libvirt_safe { dom.start }
94
+ ASYNC_REACTOR.sleep 2
95
+ puts dom.get_state
96
+
97
+ puts "full XML metadata", Libvirt::Xml::Domain.load(dom.xml_desc).metadata
98
+ puts "full XML title", Libvirt::Xml::Domain.load(dom.xml_desc).title
99
+ puts "full XML description", Libvirt::Xml::Domain.load(dom.xml_desc).description
100
+
101
+ rescue StandardError => e
102
+ log_error(e)
103
+ exit 1
104
+ end
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'bundler/setup'
4
5
  require 'libvirt'
@@ -28,21 +29,22 @@ def run_gc(msg)
28
29
  end
29
30
 
30
31
  IMPL = LibvirtAsync::Implementations.new
31
- CONNS = []
32
- DOMS = []
33
- STREAMS = { stream: nil }
32
+ CONNS = [].freeze
33
+ DOMS = [].freeze
34
+ STREAMS = { stream: nil }.freeze
34
35
 
35
36
  class ScreenshotOpaque
36
37
  CALLBACK = proc do |s, ev, op|
37
- #run_gc('ScreenshotOpaque CALLBACK start')
38
+ # run_gc('ScreenshotOpaque CALLBACK start')
38
39
  next unless (Libvirt::Stream::EVENT_READABLE & ev) != 0
40
+
39
41
  begin
40
42
  code, data = s.recv(1024)
41
- rescue Libvirt::Error => e
43
+ rescue Libvirt::Errors::LibError => e
42
44
  op.on_libvirt_error(s, e)
43
45
  next
44
46
  end
45
- #run_gc('ScreenshotOpaque CALLBACK after recv')
47
+ # run_gc('ScreenshotOpaque CALLBACK after recv')
46
48
 
47
49
  case code
48
50
  when 0
@@ -96,9 +98,9 @@ class ScreenshotOpaque
96
98
  print_usage "Opaque#finish_stream stream.finish #{@filepath}"
97
99
  stream.finish
98
100
  [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]
101
+ rescue Libvirt::Errors::LibError => e
102
+ warn "Opaque#finish_stream stream.finish exception rescued #{e.class} #{e.message}"
103
+ [false, e.message]
102
104
  end
103
105
  print_usage "Opaque#finish_stream ends #{@filepath}"
104
106
  result
@@ -158,14 +160,14 @@ Async do
158
160
  domain = c.list_all_domains.first
159
161
  DOMS.push(domain)
160
162
 
161
- print_usage "First generation"
163
+ print_usage 'First generation'
162
164
  5.times do |i|
163
165
  save_screenshot(c, domain, 100 + i)
164
166
  end
165
167
 
166
168
  ASYNC_REACTOR.after(15) do
167
169
  Async::Task.new(ASYNC_REACTOR, nil) do
168
- print_usage "Second generation"
170
+ print_usage 'Second generation'
169
171
 
170
172
  con = CONNS.first
171
173
  dom = DOMS.first
@@ -177,7 +179,7 @@ Async do
177
179
 
178
180
  ASYNC_REACTOR.after(30) do
179
181
  Async::Task.new(ASYNC_REACTOR, nil) do
180
- print_usage "Third generation"
182
+ print_usage 'Third generation'
181
183
 
182
184
  con = CONNS.first
183
185
  dom = DOMS.first
@@ -192,5 +194,4 @@ Async do
192
194
  run_gc 'PERIODIC'
193
195
  end.run
194
196
  end
195
-
196
197
  end
@@ -0,0 +1,52 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'bundler/setup'
5
+ require 'libvirt'
6
+ require 'logger'
7
+ require 'active_support/all'
8
+ require 'async'
9
+
10
+ require_relative 'support/libvirt_async'
11
+ require_relative 'support/log_formatter'
12
+
13
+ require 'libvirt/xml'
14
+
15
+ Libvirt.logger = Logger.new(STDOUT, formatter: LogFormatter.new)
16
+ Libvirt.logger.level = ENV['DEBUG'] ? :debug : :info
17
+
18
+ IMPL = LibvirtAsync::Implementations.new
19
+
20
+ Async do
21
+ ASYNC_REACTOR = Async::Task.current.reactor
22
+
23
+ puts "Lib version #{Libvirt.lib_version}"
24
+ puts "Gem version #{Libvirt::VERSION}"
25
+
26
+ IMPL.start
27
+
28
+ conn = Libvirt::Connection.new('qemu+tcp://localhost:16510/system')
29
+ conn.open
30
+
31
+ puts "Connection version #{conn.version.inspect}"
32
+ puts "Connection lib_version #{conn.lib_version.inspect}"
33
+ puts "Connection hostname #{conn.hostname.inspect}"
34
+
35
+ pools = conn.list_all_storage_pools
36
+ puts "Connection storage pools qty #{pools.size}"
37
+
38
+ pools.each.with_index do |pool, i|
39
+ puts "Storage pool #{i} info", pool.info.to_h
40
+ puts "Storage pool #{i} xml", Libvirt::Xml::StoragePool.load(pool.xml_desc).to_h
41
+ end
42
+
43
+ pools.each.with_index do |pool, i|
44
+ volumes = pool.list_all_volumes
45
+ puts "Storage pool #{i} volumes qty #{volumes.size}"
46
+
47
+ volumes.each.with_index do |vol, j|
48
+ puts "Storage pool #{i} volume #{j} info", vol.info.to_h
49
+ puts "Storage pool #{i} volume #{j} xml", Libvirt::Xml::StorageVolume.load(vol.xml_desc).to_h
50
+ end
51
+ end
52
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: libvirt_ffi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Denis Talakevich
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-01-31 00:00:00.000000000 Z
11
+ date: 2020-03-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rubocop
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.80.1
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.80.1
27
41
  description: Libvirt FFI
28
42
  email:
29
43
  - senid231@gmail.com
@@ -33,6 +47,7 @@ extensions: []
33
47
  extra_rdoc_files: []
34
48
  files:
35
49
  - ".gitignore"
50
+ - ".rubocop.yml"
36
51
  - ".travis.yml"
37
52
  - CODE_OF_CONDUCT.md
38
53
  - Gemfile
@@ -43,28 +58,49 @@ files:
43
58
  - bin/setup
44
59
  - exe/libvirt
45
60
  - lib/libvirt.rb
61
+ - lib/libvirt/base_info.rb
46
62
  - lib/libvirt/connection.rb
47
63
  - lib/libvirt/domain.rb
48
64
  - lib/libvirt/domain_callback_storage.rb
49
- - lib/libvirt/error.rb
65
+ - lib/libvirt/errors.rb
50
66
  - lib/libvirt/event.rb
67
+ - lib/libvirt/ffi.rb
51
68
  - lib/libvirt/ffi/common.rb
52
- - lib/libvirt/ffi/connection.rb
53
69
  - lib/libvirt/ffi/domain.rb
70
+ - lib/libvirt/ffi/error.rb
54
71
  - lib/libvirt/ffi/event.rb
55
- - lib/libvirt/ffi/libvirt.rb
56
- - lib/libvirt/ffi/node_info.rb
72
+ - lib/libvirt/ffi/helpers.rb
73
+ - lib/libvirt/ffi/host.rb
74
+ - lib/libvirt/ffi/storage.rb
57
75
  - lib/libvirt/ffi/stream.rb
58
76
  - lib/libvirt/node_info.rb
77
+ - lib/libvirt/storage_pool.rb
78
+ - lib/libvirt/storage_pool_info.rb
79
+ - lib/libvirt/storage_volume.rb
80
+ - lib/libvirt/storage_volume_info.rb
59
81
  - lib/libvirt/stream.rb
60
82
  - lib/libvirt/util.rb
61
83
  - lib/libvirt/version.rb
84
+ - lib/libvirt/xml.rb
85
+ - lib/libvirt/xml/disk.rb
86
+ - lib/libvirt/xml/domain.rb
87
+ - lib/libvirt/xml/generic.rb
88
+ - lib/libvirt/xml/graphics.rb
89
+ - lib/libvirt/xml/max_vcpu.rb
90
+ - lib/libvirt/xml/memory.rb
91
+ - lib/libvirt/xml/storage_pool.rb
92
+ - lib/libvirt/xml/storage_volume.rb
93
+ - lib/libvirt/xml/vcpu.rb
62
94
  - lib/libvirt_ffi.rb
63
95
  - libvirt.gemspec
64
96
  - test_usage/support/libvirt_async.rb
65
97
  - test_usage/support/log_formatter.rb
98
+ - test_usage/test_domain.rb
66
99
  - test_usage/test_event_loop.rb
100
+ - test_usage/test_libvirtd_restart.rb
101
+ - test_usage/test_metadata.rb
67
102
  - test_usage/test_screenshot.rb
103
+ - test_usage/test_storage.rb
68
104
  homepage: https://github.com/senid231/libvirt_ffi
69
105
  licenses:
70
106
  - MIT
@@ -1,6 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Libvirt
4
- class Error < StandardError
5
- end
6
- end
@@ -1,94 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Libvirt
4
- module FFI
5
- module Connection
6
- extend ::FFI::Library
7
- ffi_lib Util.library_path
8
-
9
- # struct virNodeInfo {
10
- #
11
- # char model[32] model - string indicating the CPU model
12
- # unsigned long memory - memory size in kilobytes
13
- # unsigned int cpus - the number of active CPUs
14
- # unsigned int mhz - expected CPU frequency, 0 if not known or on unusual architectures
15
- # unsigned int nodes - the number of NUMA cell, 1 for unusual NUMA topologies or uniform memory access; check capabilities XML for the actual NUMA topology
16
- # unsigned int sockets - number of CPU sockets per node if nodes > 1, 1 in case of unusual NUMA topology
17
- # unsigned int cores - number of cores per socket, total number of processors in case of unusual NUMA topolog
18
- # unsigned int threads - number of threads per core, 1 in case of unusual numa topology
19
- # }
20
- class NodeInfoStruct < ::FFI::Struct
21
- layout :model, [:char, 32],
22
- :memory, :ulong,
23
- :cpus, :ulong,
24
- :mhz, :ulong,
25
- :nodes, :ulong,
26
- :sockets, :ulong,
27
- :cores, :ulong,
28
- :threads, :ulong
29
- end
30
-
31
- class NodeInfo
32
- def initialize(node_info_ptr, node_info_struct)
33
- @node_info_ptr = node_info_ptr
34
- @node_info_struct = node_info_struct
35
- end
36
-
37
- def [](attr)
38
- @node_info_struct[attr]
39
- end
40
- end
41
-
42
- # virConnectPtr virConnectOpen (const char * name)
43
- attach_function :virConnectOpen, [:string], :pointer
44
-
45
- # int virConnectGetVersion (virConnectPtr conn, unsigned long *hvVer)
46
- attach_function :virConnectGetVersion, [:pointer, :pointer], :int
47
-
48
- # int virConnectSetKeepAlive (
49
- # virConnectPtr conn,
50
- # int interval,
51
- # unsigned int count
52
- # )
53
- attach_function :virConnectSetKeepAlive, [:pointer, :int, :uint], :int
54
-
55
- # int virConnectGetVersion (
56
- # virConnectPtr conn,
57
- # unsigned long * hvVer
58
- # )
59
- attach_function :virConnectGetVersion, [:pointer, :pointer], :int
60
-
61
- # int virConnectGetLibVersion (
62
- # virConnectPtr conn,
63
- # unsigned long * libVer
64
- # )
65
- attach_function :virConnectGetLibVersion, [:pointer, :pointer], :int
66
-
67
- # char * virConnectGetHostname (
68
- # virConnectPtr conn
69
- # )
70
- attach_function :virConnectGetHostname, [:pointer], :string # strptr ?
71
-
72
- # int virConnectGetMaxVcpus (
73
- # virConnectPtr conn,
74
- # const char * type
75
- # )
76
- attach_function :virConnectGetMaxVcpus, [:pointer, :string], :int
77
-
78
- # char * virConnectGetCapabilities (
79
- # virConnectPtr conn
80
- # )
81
- attach_function :virConnectGetCapabilities, [:pointer], :string # strptr ?
82
-
83
- # int virConnectClose (
84
- # virConnectPtr conn
85
- # )
86
- attach_function :virConnectClose, [:pointer], :int
87
-
88
- # int virConnectRef (
89
- # virConnectPtr conn
90
- # )
91
- attach_function :virConnectRef, [:pointer], :int
92
- end
93
- end
94
- end