libvirt 0.1.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.
Files changed (74) hide show
  1. data/.gitignore +10 -0
  2. data/.yardopts +3 -0
  3. data/CHANGELOG.md +3 -0
  4. data/Gemfile +12 -0
  5. data/Gemfile.lock +36 -0
  6. data/README.md +83 -0
  7. data/Rakefile +20 -0
  8. data/docs/user_guide.md +259 -0
  9. data/examples/README.md +10 -0
  10. data/examples/create_domain.rb +46 -0
  11. data/examples/print_domain_info.rb +46 -0
  12. data/examples/print_hypervisor_info.rb +40 -0
  13. data/lib/ffi/libvirt/domain_info.rb +12 -0
  14. data/lib/ffi/libvirt/error.rb +25 -0
  15. data/lib/ffi/libvirt/error_functions.rb +21 -0
  16. data/lib/ffi/libvirt/error_types.rb +125 -0
  17. data/lib/ffi/libvirt/functions.rb +363 -0
  18. data/lib/ffi/libvirt/node_info.rb +27 -0
  19. data/lib/ffi/libvirt/storage_pool_info.rb +11 -0
  20. data/lib/ffi/libvirt/storage_volume_info.rb +14 -0
  21. data/lib/ffi/libvirt/types.rb +61 -0
  22. data/lib/ffi/libvirt/util.rb +19 -0
  23. data/lib/ffi/libvirt/version.rb +46 -0
  24. data/lib/ffi/libvirt.rb +29 -0
  25. data/lib/libvirt/collection/abstract_collection.rb +49 -0
  26. data/lib/libvirt/collection/domain_collection.rb +98 -0
  27. data/lib/libvirt/collection/interface_collection.rb +16 -0
  28. data/lib/libvirt/collection/network_collection.rb +58 -0
  29. data/lib/libvirt/collection/node_device_collection.rb +29 -0
  30. data/lib/libvirt/collection/nwfilter_collection.rb +15 -0
  31. data/lib/libvirt/collection/storage_pool_collection.rb +58 -0
  32. data/lib/libvirt/collection/storage_volume_collection.rb +57 -0
  33. data/lib/libvirt/collection.rb +12 -0
  34. data/lib/libvirt/connection.rb +225 -0
  35. data/lib/libvirt/domain.rb +241 -0
  36. data/lib/libvirt/error.rb +91 -0
  37. data/lib/libvirt/exception.rb +19 -0
  38. data/lib/libvirt/network.rb +118 -0
  39. data/lib/libvirt/node.rb +118 -0
  40. data/lib/libvirt/node_device.rb +75 -0
  41. data/lib/libvirt/spec/device/disk.rb +58 -0
  42. data/lib/libvirt/spec/device/emulator.rb +23 -0
  43. data/lib/libvirt/spec/device.rb +8 -0
  44. data/lib/libvirt/spec/domain/os_booting.rb +69 -0
  45. data/lib/libvirt/spec/domain.rb +71 -0
  46. data/lib/libvirt/spec.rb +12 -0
  47. data/lib/libvirt/storage_pool.rb +164 -0
  48. data/lib/libvirt/storage_volume.rb +109 -0
  49. data/lib/libvirt/version.rb +3 -0
  50. data/lib/libvirt.rb +53 -0
  51. data/libvirt.gemspec +27 -0
  52. data/test/libvirt/collection/abstract_collection_test.rb +14 -0
  53. data/test/libvirt/collection/domain_collection_test.rb +122 -0
  54. data/test/libvirt/collection/interface_collection_test.rb +9 -0
  55. data/test/libvirt/collection/network_collection_test.rb +41 -0
  56. data/test/libvirt/collection/node_device_collection_test.rb +24 -0
  57. data/test/libvirt/collection/nwfilter_collection_test.rb +7 -0
  58. data/test/libvirt/collection/storage_pool_collection_test.rb +41 -0
  59. data/test/libvirt/collection/storage_volume_collection_test.rb +86 -0
  60. data/test/libvirt/connection_test.rb +133 -0
  61. data/test/libvirt/domain_test.rb +221 -0
  62. data/test/libvirt/error_test.rb +93 -0
  63. data/test/libvirt/libvirt_test.rb +16 -0
  64. data/test/libvirt/network_test.rb +76 -0
  65. data/test/libvirt/node_device_test.rb +16 -0
  66. data/test/libvirt/node_test.rb +24 -0
  67. data/test/libvirt/spec/devices/disk_test.rb +107 -0
  68. data/test/libvirt/spec/devices/emulator_test.rb +20 -0
  69. data/test/libvirt/spec/domain_test.rb +17 -0
  70. data/test/libvirt/storage_pool_test.rb +133 -0
  71. data/test/libvirt/storage_volume_test.rb +63 -0
  72. data/test/support/xml_assertions.rb +29 -0
  73. data/test/test_helper.rb +23 -0
  74. metadata +219 -0
data/.gitignore ADDED
@@ -0,0 +1,10 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
4
+ .yardoc
5
+ doc/
6
+ test.rb
7
+ test.c
8
+
9
+ # Rubinius
10
+ *.rbc
data/.yardopts ADDED
@@ -0,0 +1,3 @@
1
+ -m markdown
2
+ --files
3
+ docs/user_guide.md
data/CHANGELOG.md ADDED
@@ -0,0 +1,3 @@
1
+ ## 0.1.0 (November 16, 2010)
2
+
3
+ - Initial release
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in libvirt.gemspec
4
+ gemspec
5
+
6
+ group :development do
7
+ # Not JRuby, which doesn't like bluecloth
8
+ platforms :ruby, :mri do
9
+ gem "yard", "~> 0.6.1"
10
+ gem "bluecloth", "~> 2.0.9"
11
+ end
12
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,36 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ libvirt (0.1.0)
5
+ ffi (~> 0.6.3)
6
+ nokogiri (~> 1.4.3)
7
+
8
+ GEM
9
+ remote: http://rubygems.org/
10
+ specs:
11
+ bluecloth (2.0.9)
12
+ ffi (0.6.3)
13
+ rake (>= 0.8.7)
14
+ ffi (0.6.3-java)
15
+ mocha (0.9.8)
16
+ rake
17
+ nokogiri (1.4.3.1)
18
+ nokogiri (1.4.3.1-java)
19
+ weakling (>= 0.0.3)
20
+ protest (0.4.1)
21
+ rake (0.8.7)
22
+ weakling (0.0.4-java)
23
+ yard (0.6.1)
24
+
25
+ PLATFORMS
26
+ java
27
+ ruby
28
+
29
+ DEPENDENCIES
30
+ bluecloth (~> 2.0.9)
31
+ ffi (~> 0.6.3)
32
+ libvirt!
33
+ mocha (~> 0.9.8)
34
+ nokogiri (~> 1.4.3)
35
+ protest (~> 0.4.0)
36
+ yard (~> 0.6.1)
data/README.md ADDED
@@ -0,0 +1,83 @@
1
+ # Libvirt Ruby Library
2
+
3
+ * Source: [http://github.com/mitchellh/libvirt-rb](http://github.com/mitchellh/libvirt-rb)
4
+ * IRC: `#vagrant` on Freenode
5
+ * Issues: [http://github.com/mitchellh/libvirt-rb/issues](http://github.com/mitchellh/libvirt-rb/issues)
6
+
7
+ A ruby client library providing the raw interface to libvirt via
8
+ FFI. The library is backwards compatible to libvirt 0.6.0. The
9
+ library consists of two namespaces:
10
+
11
+ * `Libvirt` - All objects under this namespace provide a very Ruby-like
12
+ object oriented interface above the raw libvirt API. This is the recommended
13
+ way of using libvirt with Ruby. These objects are mostly compatible with
14
+ the FFI layer as well (you may pass in a `Connection` object in place of
15
+ a `virConnectPtr` for example).
16
+ * `FFI::Libvirt` - A direct interface to the libvirt API using FFI. This is
17
+ for the power players out there who need extremely customized functionality,
18
+ with the tradeoff being that it is more complicated to use and you must manage
19
+ your own pointers.
20
+
21
+ ## Project Status
22
+
23
+ **Functional beta.** The project has been initially released with complete
24
+ FFI coverage and extensive coverage with the nicer Ruby objects. More
25
+ functionality will constantly be developed. If you'd like to see a specific
26
+ feature come first, please open an [issue](http://github.com/mitchellh/libvirt-rb/issues).
27
+
28
+ ## Installation
29
+
30
+ This library will be a gem. First, you need to install libvirt, using
31
+ your OS's respective package manager. On OS X the recommended way is
32
+ using [homebrew](http://github.com/mxcl/homebrew):
33
+
34
+ brew install libvirt
35
+
36
+ After installing libvirt, install the gem:
37
+
38
+ gem install libvirt
39
+
40
+ If you'd like to try the bleeding edge version of libvirt-rb, we try
41
+ to keep master pretty stable and you're welcome to give it a shot. To
42
+ do this just clone out the repository and run this from the working
43
+ directory:
44
+
45
+ rake install
46
+
47
+ ## Usage
48
+
49
+ For detailed usage and examples, please view the documentation. But
50
+ a small example is shown below so you can get a feel for how the library
51
+ is meant to be used:
52
+
53
+ require 'libvirt'
54
+
55
+ conn = Libvirt.connect
56
+
57
+ # Output some basic information
58
+ puts "You are connected to: #{cxn.hypervisor}"
59
+ puts "Hypervisor version: #{cxn.hypervisor_version}"
60
+ puts "Libvirt version: #{cxn.lib_version}"
61
+
62
+ # Output the names of all the domains
63
+ conn.domains.each do |domain|
64
+ puts "Domain: #{domain.name}"
65
+ end
66
+
67
+ # Start a domain and stop another
68
+ conn.domains[0].start
69
+ conn.domains[1].stop
70
+
71
+ # Create a new domain (assuming `xml` is defined somewhere)
72
+ # to an XML string
73
+ new_domain = conn.domains.create(xml)
74
+ puts "New domain created: #{new_domain.name}"
75
+
76
+ As I said earlier, please read the full usage page in the documentation
77
+ and also check out the examples in the `examples/` directory.
78
+
79
+ ## Contributing
80
+
81
+ To contribute to the project, fork it and send me pull requests of any
82
+ changes made. For more information, see the [Hacker's Guide](http://github.com/mitchellh/libvirt-rb/wiki/Hacker's-Guide)
83
+ and the [Contributor's Guide](http://github.com/mitchellh/libvirt-rb/wiki/Contributor's-Guide).
data/Rakefile ADDED
@@ -0,0 +1,20 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ require 'bundler/setup'
4
+ Bundler::GemHelper.install_tasks
5
+
6
+ task :default => :test
7
+
8
+ desc "Run the test suite."
9
+ task :test do
10
+ $:.unshift File.expand_path("../test", __FILE__)
11
+ files = ENV["TEST"] ? [ENV["TEST"]] : Dir["test/**/*_test.rb"]
12
+ files.each { |f| load f }
13
+ end
14
+
15
+ begin
16
+ # Documentation task
17
+ require 'yard'
18
+ YARD::Rake::YardocTask.new
19
+ rescue LoadError
20
+ end
@@ -0,0 +1,259 @@
1
+ # libvirt-rb User's Guide
2
+
3
+ ## Overview
4
+
5
+ `libvirt-rb` is a Ruby library for [libvirt](http://libvirt.org), a library sponsored
6
+ by RedHat for talking to various hypervisors with a single API. `libvirt-rb` is backwards
7
+ compatible to libvirt 0.6.0 and consists of two namespaces for users to interact
8
+ with depending on their level of comfort with the libvirt API:
9
+
10
+ * `Libvirt` - All objects under this namespace provide a very Ruby-like
11
+ object oriented interface above the raw libvirt API. This is the recommended
12
+ way of using libvirt with Ruby. These objects are mostly compatible with
13
+ the FFI layer as well (you may pass in a `Connection` object in place of
14
+ a `virConnectPtr` for example).
15
+ * `FFI::Libvirt` - A direct interface to the libvirt API using FFI. This is
16
+ for the power players out there who need extremely customized functionality,
17
+ with the tradeoff being that it is more complicated to use and you must manage
18
+ your own pointers.
19
+
20
+ ## Installation
21
+
22
+ ### Prerequisites
23
+
24
+ Before the library itself is installed, [libvirt](http://libvirt.org) must be
25
+ installed on the system. How to do this for various operating systems is shown
26
+ below.
27
+
28
+ #### Mac OS X
29
+
30
+ On Mac OS X, [homebrew](http://github.com/mxcl/homebrew) is the recommended
31
+ way of installing Mac OS X. There is currently not a MacPort for it.
32
+
33
+ brew install libvirt
34
+
35
+ #### Linux
36
+
37
+ Most linux flavors have a libvirt installation in their respective package
38
+ managers. The libvirt library might be slightly out of date but if you
39
+ find you need the most up-to-date libvirt, its very easy to compile by
40
+ hand as well.
41
+
42
+ apt-get install libvirt
43
+
44
+ #### Windows
45
+
46
+ While libvirt supposedly compiles on Windows, this is still a work in
47
+ progress on my part to verify the install and test the library. Hang
48
+ in there!
49
+
50
+ ### Install libvirt-rb
51
+
52
+ `libvirt-rb` is packaged as a RubyGem, making the installation a one-step
53
+ process:
54
+
55
+ gem install libvirt
56
+
57
+
58
+ ## Basic Concepts and Usage
59
+
60
+ This section will cover the basic concepts of the higher level portion of
61
+ the libvirt ruby library (that is, it won't talk directly about the `FFI`
62
+ portion, which is mentioned in a later section). This is the portion of the
63
+ library that most people will use and is the recommended way of interacting
64
+ with libvirt from ruby.
65
+
66
+ This section _will not_ try cover how libvirt works or the various uses of
67
+ libvirt. Libvirt itself has many pages of documentation on this which you
68
+ should read to learn more about it.
69
+
70
+ ### Establishing a Connection to Libvirt
71
+
72
+ The first step before anything can be done with libvirt is to establish
73
+ a connection to either a local or remote instance of libvirt (if remote,
74
+ you would be connecting to a `libvirtd` instance). Libvirt establishes
75
+ connections using a URI. Each line below is another example on how to
76
+ establish a connection:
77
+
78
+
79
+ conn = Libvirt.connect
80
+ conn = Libvirt.connect("test:///default")
81
+ conn = Libvirt.connect("qemu+ssh://10.0.0.1/system")
82
+ conn = Libvirt.connect("vbox:///system", :readonly => true)
83
+
84
+ This connection is the base object used to do most other things. Libvirt
85
+ has been made so that when you're done with the connection and it is
86
+ garbage collected, the underlying connection data is properly freed as
87
+ well. In fact, this is true for all objects in the libvirt library. If
88
+ you find a memory leak with the libvirt objects, it is a bug.
89
+
90
+ ### Accessing Collections
91
+
92
+ Libvirt objects, especially the connection, exposes a variety of
93
+ _collection_ objects, such as domains, interfaces, networks, etc.
94
+ These collections are all exposed in a similar way, and this section
95
+ is meant to give a rough overview on how they work. Exact details
96
+ for each collection can be seen by reading their respective
97
+ documentation (such as {Libvirt::Collection::DomainCollection}).
98
+
99
+ ### Using and Accessing Objects in Collections
100
+
101
+ All collections can be treated as `Array`-like objects. They are
102
+ `Enumerable` and provide additional methods as well. All collections
103
+ implement the `all` method to retrieve all of their collection.
104
+ Some collections can be drilled down further, such as domains, with
105
+ `inactive` and just `active`.
106
+
107
+ Examples of using a collection are shown below:
108
+
109
+ # You can use a collection like an array:
110
+ conn.domains.include?(other)
111
+
112
+ # You can iterate over a collection:
113
+ conn.domains.each do |domain|
114
+ puts "Domain: #{domain.name}"
115
+ end
116
+
117
+ # You can drill down further on some collections:
118
+ puts "Inactive domains: #{conn.domains.inactive.length}"
119
+
120
+ # You can explicitly access all domains, though this is
121
+ # the same as treating the whole collection as an array:
122
+ puts "All domains: #{conn.domains.all.length}"
123
+
124
+ Understanding these collections are fundamental to using the library,
125
+ so play around with them and get comfortable.
126
+
127
+ ### Creating and Defining Objects in Collections
128
+
129
+ Most collection objects support creation and definition. The difference
130
+ in libvirt is that defining will create a persistent object that survives
131
+ node reboots, but it will not start immediately. Creating, on the other
132
+ hand, creates and starts the object but it won't persist after reboots,
133
+ typically. Refer to the actual libvirt documentation for verification
134
+ on this.
135
+
136
+ Everything in libvirt is defined using XML. In the future, the libvirt-rb
137
+ library will probably provide Ruby object wrappers around these XML
138
+ structures but in the current version, you are expected to pass in the
139
+ XML as a string. An example is shown below:
140
+
141
+ volume_xml = <<-XML
142
+ <volume>
143
+ <name>test</name>
144
+ <key>g9eba311-ea76-4e4a-ad7b-401fa81e38c8</key>
145
+ <source>
146
+ </source>
147
+ <capacity>8589934592</capacity>
148
+ <allocation>33280</allocation>
149
+ <target>
150
+ <format type='raw'/>
151
+ <permissions>
152
+ <mode>00</mode>
153
+ <owner>0</owner>
154
+ <group>0</group>
155
+ </permissions>
156
+ </target>
157
+ </volume>
158
+ XML
159
+
160
+ volume = conn.storage_pools.first.volumes.create(volume_xml)
161
+
162
+ **Note:** You can also retrieve the XML for an object using the `xml`
163
+ method which is available on most objects, such as {Libvirt::Domain#xml}.
164
+
165
+ ### Using Libvirt Objects
166
+
167
+ Once you have retrieved a single libvirt object, such as {Libvirt::Connection Connection}
168
+ or {Libvirt::Domain Domain}, there are common ways to access information
169
+ and manipulate the object.
170
+
171
+ All objects have attributes which are accessed using simple method
172
+ calls, an example using a domain object below:
173
+
174
+ puts domain.name
175
+ puts domain.uuid
176
+ puts domain.xml
177
+ puts domain.state
178
+
179
+ Additionally, there are usually methods to control the state of an
180
+ object, and transition it to new states, such as starting or stopping
181
+ a domain:
182
+
183
+ domain.start
184
+ domain.stop
185
+ domain.undefine
186
+
187
+ These methods return a boolean `true` or `false` depending on whether
188
+ they succeed or not.
189
+
190
+ ### Error Handling
191
+
192
+ Libvirt itself provides a great error handling mechanism through
193
+ callbacks. By default, libvirt-rb will raise an {Libvirt::Exception::LibvirtError}
194
+ whenever an error occurs. That error contains a human readable
195
+ message and an error code, as well as a backtrace as to where the error
196
+ could have occurred. The exception simply wraps a {Libvirt::Error}
197
+ object.
198
+
199
+ If, instead of raising an exception for every error, you'd like
200
+ custom behavior, you can set a new callback which will be called
201
+ every time:
202
+
203
+ Libvirt::Error.on_error do |error|
204
+ # Do anything you want with `error`...
205
+ end
206
+
207
+ You can also disable error callbacks alltogether by specifying no
208
+ block:
209
+
210
+ Libvirt::Error.on_error
211
+
212
+ Most methods return `nil` on error. Some methods have no reasonable
213
+ way of representing an error (for example `nil` might just mean a
214
+ find failed), so doing nothing is not recommended.
215
+
216
+ ## Advanced: Direct FFI Access
217
+
218
+ For advanced users out there, there is nearly 100% FFI coverage over
219
+ the libvirt API from the `FFI::Libvirt` namespace. This is a mostly
220
+ flat namespace for all the API methods, with classes for the various
221
+ structs. An example of using this API directly:
222
+
223
+ c = FFI::Libvirt.virConnectOpen("test:///default")
224
+ puts "Connected URI: #{FFI::Libvirt.virConnectGetURI(c)}"
225
+
226
+ ### Creating libvirt-rb Objects with FFI Pointers
227
+
228
+ Many of the pointers returned by the FFI layer can be used to initialize
229
+ higher level objects, allowing a smooth transition between FFI and
230
+ libvirt-rb. An example of this is shown below:
231
+
232
+ c = FFI::Libvirt.virConnectOpen("test:///default")
233
+
234
+ # Use the pointer to create a Connection object, this is the
235
+ # same as doing `Libvirt.connect("test:///default")`
236
+ conn = Libvirt::Connection.new(c)
237
+
238
+ # We are responsible for cleaning up the pointer. Since the Connection
239
+ # object took ownership, this free simply decreases a reference count
240
+ FFI::Libvirt.virConnectFree(c)
241
+
242
+ **Warning:** As you can see through the example above, you must remember
243
+ to _ALWAYS_ free your pointers after initializing a higher level object.
244
+ This is to ensure that memory is properly freed. Using the FFI API makes
245
+ it very easy to leak memory, so you have been warned.
246
+
247
+ ### Using libvirt-rb Objects as Pointer Arguments
248
+
249
+ In addition to creating libvirt-rb objects, the libvirt-rb objects can
250
+ also be used as pointer arguments for the FFI API. This is because all
251
+ of the objects implement the `to_ptr` method. An example is shown below:
252
+
253
+ c = Libvirt.connect("test:///default")
254
+ puts "URI: #{FFI::Libvirt.virConnectGetURI(c)}"
255
+
256
+ **Warning:** If you store the pointer directly somewhere (assigning
257
+ the `to_ptr` value to a variable), do not forget to increase the
258
+ reference count by calling the respective API, since when the libvirt-rb
259
+ objects are garbage collected, they automatically free the pointer.
@@ -0,0 +1,10 @@
1
+ # Libvirt Ruby Library Exmaples
2
+
3
+ These examples are meant to be run within the source tree of
4
+ libvirt, meaning you can run the without installing the libvirt
5
+ gem beforehand. To try them out, first install the dependencies
6
+ locally using `bundle install`, then run the examples directly
7
+ via `ruby`. Example:
8
+
9
+ ruby print_domain_info.rb
10
+
@@ -0,0 +1,46 @@
1
+ require "rubygems"
2
+ require "bundler/setup"
3
+ require "libvirt"
4
+
5
+ # Warning: In the current version of the libvirt-rb library, the
6
+ # spec classes are not completely thought out and for now it is
7
+ # recommended that full XML strings are used.
8
+
9
+ spec = Libvirt::Spec::Domain.new
10
+
11
+ #
12
+ # Example of valid hypervisors
13
+ # :kvm
14
+ # :xen
15
+ # :test
16
+ #
17
+ spec.hypervisor = :test
18
+ spec.name = "My Test VM"
19
+ #
20
+ # :hvm (FullVirt in KVM anx Xen)
21
+ # :linux (Xen PV)
22
+ #
23
+ spec.os.type = :hvm
24
+ spec.memory = 123456 # KB
25
+
26
+ # Connect to the test hypervisor so we don't actually create a
27
+ # domain somewhere.
28
+ #
29
+ # Example of valid URIs:
30
+ # vbox:///system (local virtualbox)
31
+ # qemu+tcp://10.0.0.1/system (remote qemu over TCP)
32
+ # qemu+ssh://10.0.0.1/system (remote qemu over SSH)
33
+ # qemu+unix:///system (local qemu over unix socket)
34
+ # xen+tcp://10.0.0.1/ (remote Xen over TCP)
35
+ #
36
+ # If no URI is given, libvirt does its best to guess.
37
+ conn = Libvirt.connect("test:///default")
38
+
39
+ # This creates the domain on the hypervisor without starting it.
40
+ # The return value is the {Libvirt::Domain} object associated
41
+ # with it.
42
+ conn.domains.define(spec)
43
+
44
+ puts "Success! A test domain was created with the following XML:"
45
+ puts
46
+ puts spec.to_xml
@@ -0,0 +1,46 @@
1
+ require "rubygems"
2
+ require "bundler/setup"
3
+ require "libvirt"
4
+
5
+ #----------------------------------------------------------------------
6
+ # Helper methods for pretty printing
7
+ #----------------------------------------------------------------------
8
+ def two_columns(str1, str2)
9
+ puts "#{str1}".ljust(40) + "#{str2}"
10
+ end
11
+
12
+ def humanize_bytes(bytes)
13
+ if bytes < 1048576
14
+ "#{bytes/1024} MB"
15
+ else
16
+ "#{bytes/1024/1024} GB"
17
+ end
18
+ end
19
+
20
+ # Example connecting to a node and hypervisor:
21
+ #
22
+ # Example of valid URIs:
23
+ # vbox:///system (local virtualbox)
24
+ # qemu+tcp://10.0.0.1/system (remote qemu over TCP)
25
+ # qemu+ssh://10.0.0.1/system (remote qemu over SSH)
26
+ # qemu+unix:///system (local qemu over unix socket)
27
+ #
28
+ # If no URI is given, libvirt does its best to guess.
29
+ h = Libvirt.connect
30
+
31
+ h.domains.each do |d|
32
+ puts "Domain: #{d.name}"
33
+ puts "-----------"
34
+ two_columns "ID:", d.id
35
+ two_columns "UUID:", d.uuid
36
+ two_columns "Memory:", humanize_bytes(d.memory)
37
+ two_columns "Max Mem", humanize_bytes(d.max_memory)
38
+ two_columns "State", d.state
39
+ two_columns "Virtual CPUs:", d.virtual_cpus
40
+ two_columns "CPU time used (nanosecs):", d.cpu_time_used
41
+ two_columns "Active?:", d.active? ? 'yes': 'no'
42
+ two_columns "Persistent?:", d.persistent? ? 'yes':'no'
43
+ puts
44
+ end
45
+
46
+
@@ -0,0 +1,40 @@
1
+ require "rubygems"
2
+ require "bundler/setup"
3
+ require "libvirt"
4
+
5
+ #----------------------------------------------------------------------
6
+ # Helper methods for pretty printing
7
+ #----------------------------------------------------------------------
8
+ def two_columns(str1, str2)
9
+ puts "#{str1}".ljust(40) + "#{str2}"
10
+ end
11
+
12
+ def humanize_bytes(bytes)
13
+ if bytes < 1048576
14
+ "#{bytes/1024} MB"
15
+ else
16
+ "#{bytes/1024/1024} GB"
17
+ end
18
+ end
19
+
20
+ # Example connecting to a node and hypervisor:
21
+ #
22
+ # Example of valid URIs:
23
+ # vbox:///system (local virtualbox)
24
+ # qemu+tcp://10.0.0.1/system (remote qemu over TCP)
25
+ # qemu+ssh://10.0.0.1/system (remote qemu over SSH)
26
+ # qemu+unix:///system (local qemu over unix socket)
27
+ #
28
+ # If no URI is given, libvirt does its best to guess.
29
+ h = Libvirt.connect
30
+
31
+ puts "Hypervisor INFO"
32
+ puts "---------------"
33
+ two_columns "Hypervisor Type:", h.type
34
+ two_columns "Domains Created:", h.domains.size
35
+ # outputs XML
36
+ # puts h.capabilities
37
+ two_columns "Hostname:", h.hostname
38
+ two_columns "Connection URI:", h.uri
39
+ two_columns "Hypervisor Version:", h.hypervisor_version.join('.')
40
+ two_columns "Libvirt Version:", h.lib_version.join('.')
@@ -0,0 +1,12 @@
1
+ module FFI
2
+ module Libvirt
3
+ # virDomainInfo structure, used to represent a single domain.
4
+ class DomainInfo < ::FFI::Struct
5
+ layout :state, :virDomainState,
6
+ :maxMem, :ulong,
7
+ :memory, :ulong,
8
+ :nrVirtCpu, :ushort,
9
+ :cpuTime, :ulong_long
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,25 @@
1
+ module FFI
2
+ module Libvirt
3
+ # virError structure, which is used to represent any errors raised by
4
+ # libvirt.
5
+ class Error < ::FFI::Struct
6
+ # Note: The "DEPRECATED" notes below are important and if you use
7
+ # these you should take extreme caution since the error struct doesn't
8
+ # properly increaes the reference count on this objects, so its likely
9
+ # they are no longer valid. They exist for backwards compatibility.
10
+
11
+ layout :code, :virErrorNumber,
12
+ :domain, :virErrorDomain,
13
+ :message, :string,
14
+ :level, :virErrorLevel,
15
+ :conn, :virConnectPtr, # DEPRECATED
16
+ :dom, :virDomainPtr, # DEPRECATED
17
+ :str1, :string,
18
+ :str2, :string,
19
+ :str3, :string,
20
+ :int1, :int,
21
+ :int2, :int,
22
+ :net, :virNetworkPtr # DEPRECATED
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,21 @@
1
+ module FFI
2
+ module Libvirt
3
+ libvirt_version "0.6.0" do
4
+ attach_function :virGetLastError, [], :virErrorPtr
5
+ attach_function :virResetLastError, [], :void
6
+ attach_function :virResetError, [:virErrorPtr], :void
7
+ attach_function :virConnGetLastError, [:virConnectPtr], :virErrorPtr
8
+ attach_function :virConnResetLastError, [:virConnectPtr], :void
9
+ attach_function :virCopyLastError, [:virErrorPtr], :int
10
+ attach_function :virDefaultErrorFunc, [:virErrorPtr], :void
11
+ attach_function :virSetErrorFunc, [:void_pointer, :virErrorFunc], :void
12
+ attach_function :virConnSetErrorFunc, [:virConnectPtr, :void_pointer, :virErrorFunc], :void
13
+ attach_function :virConnCopyLastError, [:virConnectPtr, :virErrorPtr], :int
14
+ end
15
+
16
+ libvirt_version "0.6.1" do
17
+ attach_function :virSaveLastError, [], :virErrorPtr
18
+ attach_function :virFreeError, [:virErrorPtr], :void
19
+ end
20
+ end
21
+ end