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.
- 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
|