libvirt_ffi 0.4.0 → 0.5.3

Sign up to get free protection for your applications and to get access to all the features.
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