libvirt 0.1.0

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