libvirt 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +10 -0
- data/.yardopts +3 -0
- data/CHANGELOG.md +3 -0
- data/Gemfile +12 -0
- data/Gemfile.lock +36 -0
- data/README.md +83 -0
- data/Rakefile +20 -0
- data/docs/user_guide.md +259 -0
- data/examples/README.md +10 -0
- data/examples/create_domain.rb +46 -0
- data/examples/print_domain_info.rb +46 -0
- data/examples/print_hypervisor_info.rb +40 -0
- data/lib/ffi/libvirt/domain_info.rb +12 -0
- data/lib/ffi/libvirt/error.rb +25 -0
- data/lib/ffi/libvirt/error_functions.rb +21 -0
- data/lib/ffi/libvirt/error_types.rb +125 -0
- data/lib/ffi/libvirt/functions.rb +363 -0
- data/lib/ffi/libvirt/node_info.rb +27 -0
- data/lib/ffi/libvirt/storage_pool_info.rb +11 -0
- data/lib/ffi/libvirt/storage_volume_info.rb +14 -0
- data/lib/ffi/libvirt/types.rb +61 -0
- data/lib/ffi/libvirt/util.rb +19 -0
- data/lib/ffi/libvirt/version.rb +46 -0
- data/lib/ffi/libvirt.rb +29 -0
- data/lib/libvirt/collection/abstract_collection.rb +49 -0
- data/lib/libvirt/collection/domain_collection.rb +98 -0
- data/lib/libvirt/collection/interface_collection.rb +16 -0
- data/lib/libvirt/collection/network_collection.rb +58 -0
- data/lib/libvirt/collection/node_device_collection.rb +29 -0
- data/lib/libvirt/collection/nwfilter_collection.rb +15 -0
- data/lib/libvirt/collection/storage_pool_collection.rb +58 -0
- data/lib/libvirt/collection/storage_volume_collection.rb +57 -0
- data/lib/libvirt/collection.rb +12 -0
- data/lib/libvirt/connection.rb +225 -0
- data/lib/libvirt/domain.rb +241 -0
- data/lib/libvirt/error.rb +91 -0
- data/lib/libvirt/exception.rb +19 -0
- data/lib/libvirt/network.rb +118 -0
- data/lib/libvirt/node.rb +118 -0
- data/lib/libvirt/node_device.rb +75 -0
- data/lib/libvirt/spec/device/disk.rb +58 -0
- data/lib/libvirt/spec/device/emulator.rb +23 -0
- data/lib/libvirt/spec/device.rb +8 -0
- data/lib/libvirt/spec/domain/os_booting.rb +69 -0
- data/lib/libvirt/spec/domain.rb +71 -0
- data/lib/libvirt/spec.rb +12 -0
- data/lib/libvirt/storage_pool.rb +164 -0
- data/lib/libvirt/storage_volume.rb +109 -0
- data/lib/libvirt/version.rb +3 -0
- data/lib/libvirt.rb +53 -0
- data/libvirt.gemspec +27 -0
- data/test/libvirt/collection/abstract_collection_test.rb +14 -0
- data/test/libvirt/collection/domain_collection_test.rb +122 -0
- data/test/libvirt/collection/interface_collection_test.rb +9 -0
- data/test/libvirt/collection/network_collection_test.rb +41 -0
- data/test/libvirt/collection/node_device_collection_test.rb +24 -0
- data/test/libvirt/collection/nwfilter_collection_test.rb +7 -0
- data/test/libvirt/collection/storage_pool_collection_test.rb +41 -0
- data/test/libvirt/collection/storage_volume_collection_test.rb +86 -0
- data/test/libvirt/connection_test.rb +133 -0
- data/test/libvirt/domain_test.rb +221 -0
- data/test/libvirt/error_test.rb +93 -0
- data/test/libvirt/libvirt_test.rb +16 -0
- data/test/libvirt/network_test.rb +76 -0
- data/test/libvirt/node_device_test.rb +16 -0
- data/test/libvirt/node_test.rb +24 -0
- data/test/libvirt/spec/devices/disk_test.rb +107 -0
- data/test/libvirt/spec/devices/emulator_test.rb +20 -0
- data/test/libvirt/spec/domain_test.rb +17 -0
- data/test/libvirt/storage_pool_test.rb +133 -0
- data/test/libvirt/storage_volume_test.rb +63 -0
- data/test/support/xml_assertions.rb +29 -0
- data/test/test_helper.rb +23 -0
- metadata +219 -0
data/.gitignore
ADDED
data/.yardopts
ADDED
data/CHANGELOG.md
ADDED
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
|
data/docs/user_guide.md
ADDED
@@ -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.
|
data/examples/README.md
ADDED
@@ -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
|