ovirt-engine-sdk 4.1.7 → 4.1.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGES.adoc +34 -0
- data/README.adoc +656 -27
- data/ext/ovirtsdk4c/ov_http_client.c +9 -1
- data/lib/ovirtsdk4/probe.rb +55 -2
- data/lib/ovirtsdk4/readers.rb +4 -0
- data/lib/ovirtsdk4/service.rb +1 -1
- data/lib/ovirtsdk4/services.rb +843 -114
- data/lib/ovirtsdk4/types.rb +23 -0
- data/lib/ovirtsdk4/version.rb +1 -1
- data/lib/ovirtsdk4/writers.rb +1 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d87b36d7e0dc5dab224115c5a5109b052ab6cc2c
|
4
|
+
data.tar.gz: 163217911308f7c56022498e6eeb07e6d6d6f0c4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 85c29a2a9c062fcbb605de0af9829735ea350f36a13ccde2dd0ce26d2733cb76a77c8a56040078c29bab6c7b2565b3a643a2d424dcc689a91f3e5e0728c468c1
|
7
|
+
data.tar.gz: 60c16dabedce63e73662269d961b7bf7a14d62c6b92670153378b10a654a954cbf36298d77d795862351c65aa8650e7d3bda097ab2ee38bf6d3f28ce4cd43058
|
data/CHANGES.adoc
CHANGED
@@ -2,6 +2,40 @@
|
|
2
2
|
|
3
3
|
This document describes the relevant changes between releases of the SDK.
|
4
4
|
|
5
|
+
== 4.1.8 / Jul 17 2017
|
6
|
+
|
7
|
+
Update to model 4.1.37:
|
8
|
+
|
9
|
+
* Add the `all_content` parameter to `Host.Get` and `Hosts.List`
|
10
|
+
https://bugzilla.redhat.com/1444081[#1444081].
|
11
|
+
|
12
|
+
* Fix the documentation of the method that lists events
|
13
|
+
https://bugzilla.redhat.com/1447622[#1447622].
|
14
|
+
|
15
|
+
* Fix the direction of the main parameter of the method that adds a
|
16
|
+
CDROM to a virtual machine. It should be input and output.
|
17
|
+
|
18
|
+
* Improve the documentation explaining that in general the order of the
|
19
|
+
results of _list_ methods isn't guaranteed.
|
20
|
+
|
21
|
+
* Add the `index` attribute to the `Event` type
|
22
|
+
https://bugzilla.redhat.com/1448511[#1448511].
|
23
|
+
|
24
|
+
New features:
|
25
|
+
|
26
|
+
* Add a new `Probe.exists?` method to check whether an oVirt instance
|
27
|
+
exists.
|
28
|
+
|
29
|
+
Bug fixes:
|
30
|
+
|
31
|
+
* Handle correctly HTTP 201 and 200 response codes.
|
32
|
+
|
33
|
+
* Ignore unreleated responses from server
|
34
|
+
https://bugzilla.redhat.com/1459254[#1459254].
|
35
|
+
|
36
|
+
* Use `bundler` instead of `bundle`
|
37
|
+
https://bugzilla.redhat.com/1462664[#1462664].
|
38
|
+
|
5
39
|
== 4.1.7 / Jun 2 2017
|
6
40
|
|
7
41
|
Bug fixes:
|
data/README.adoc
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
= oVirt Engine API Ruby SDK
|
2
|
+
:reference: http://www.rubydoc.info/gems/ovirt-engine-sdk/OvirtSDK4
|
2
3
|
|
3
4
|
== Introduction
|
4
5
|
|
@@ -11,67 +12,695 @@ just installed the gem then you will have everything already, but if you
|
|
11
12
|
downloaded the source then you will need to generate it, follow the
|
12
13
|
instructions in the `README.adoc` file of the parent directory.
|
13
14
|
|
15
|
+
== Installation
|
16
|
+
|
17
|
+
The SDK can be installed in Fedora 24 and CentOS 7 using the RPM packages
|
18
|
+
provided by the oVirt project. To do so install the oVirt release package:
|
19
|
+
|
20
|
+
# dnf install http://resources.ovirt.org/pub/yum-repo/ovirt-release41.rpm
|
21
|
+
|
22
|
+
Then install the SDK package:
|
23
|
+
|
24
|
+
# dnf install rubygem-ovirt-engine-sdk4
|
25
|
+
|
26
|
+
For other operating systems (and also for Fedora and CentOS) you can
|
27
|
+
install the SDK using the `gem` command, which will download the source
|
28
|
+
from https://rubygems.org[RubyGems], build and install it:
|
29
|
+
|
30
|
+
$ gem install ovirt-engine-sdk
|
31
|
+
|
32
|
+
The SDK uses http://www.xmlsoft.org[libxml2] for parsing and rendering
|
33
|
+
XML and https://curl.haxx.se/libcurl[libcurl] for HTTP transfers. The
|
34
|
+
parts of the SDK that interact with those libraries are written in C.
|
35
|
+
This means that before building you must make sure you have the C
|
36
|
+
compiler and the required header and libraries files installed in your
|
37
|
+
system. For example, if you are using distributions like Fedora, or
|
38
|
+
CentOS:
|
39
|
+
|
40
|
+
# dnf -y install \
|
41
|
+
gcc \
|
42
|
+
libcurl-devel \
|
43
|
+
libxml2-devel \
|
44
|
+
ruby-devel
|
45
|
+
|
46
|
+
If you are using distributions like Debian, or Ubuntu:
|
47
|
+
|
48
|
+
# apt-get --assume-yes install \
|
49
|
+
gcc \
|
50
|
+
libxml2-dev \
|
51
|
+
libcurl-dev \
|
52
|
+
ruby-dev
|
53
|
+
|
54
|
+
NOTE: The examples above use the `dnf` command, which is the default in
|
55
|
+
Fedora 24. In CentOS 7 you may need to use the `yum` command, as `dnf`
|
56
|
+
is optional.
|
57
|
+
|
14
58
|
== Usage
|
15
59
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
60
|
+
=== Modules and classes
|
61
|
+
|
62
|
+
All the classes of the SDK are inside the {reference}[OvirtSDK4] module.
|
63
|
+
Within the module there are several kinds of classes:
|
64
|
+
|
65
|
+
Connection::
|
20
66
|
|
67
|
+
The {reference}/Connection[Connection] class, as is the mechanism to
|
68
|
+
connect to the server and to get the reference to the root of the
|
69
|
+
services tree.
|
70
|
+
|
71
|
+
Error::
|
72
|
+
|
73
|
+
The {reference}/Error[Error] class is the exception that the SDK will
|
74
|
+
raise when it needs to report any error.
|
75
|
+
|
76
|
+
Types::
|
77
|
+
|
78
|
+
These classes implement the _types_ used by the API. For example, the
|
79
|
+
{reference}/Vm[Vm] Ruby class is the implementation of the virtual
|
80
|
+
machine type. These classes are just containers of data, they don't
|
81
|
+
contain any logic.
|
82
|
+
+
|
83
|
+
Instances of these classes are used as parameters and return values of
|
84
|
+
_service methods_. The conversion to/from the underlying representation
|
85
|
+
is handled transparently by the SDK.
|
86
|
+
|
87
|
+
Services::
|
88
|
+
|
89
|
+
These classes implement the _services_ supported by the API. For
|
90
|
+
example, the {reference}/VmsService[VmsService] Ruby class is the
|
91
|
+
implementation of the service that manages the collection of virtual
|
92
|
+
machines of the system.
|
93
|
+
+
|
94
|
+
Instances of these classes are automatically created by the SDK when a
|
95
|
+
service is located. For example, a new instance of the `VmsService`
|
96
|
+
class will be automatically created by the SDK when doing the following:
|
97
|
+
+
|
21
98
|
[source,ruby]
|
22
99
|
----
|
23
|
-
|
100
|
+
vms_service = connection.system_service.vms_service
|
101
|
+
----
|
102
|
+
+
|
103
|
+
Avoid creating instances of these classes manually, as the parameters of
|
104
|
+
the constructors, and in general all the methods except the _service
|
105
|
+
locators_ and _service methods_ (described later) may change in the
|
106
|
+
future.
|
24
107
|
|
108
|
+
There are other classes, like HTTP client classes, readers and writers.
|
109
|
+
These are used to implement the HTTP communication, and to for XML
|
110
|
+
parsing and rendering. Refrain from using them, as they are internal
|
111
|
+
implementation details that may change in the future: backwards
|
112
|
+
compatibility isn't guaranteed.
|
113
|
+
|
114
|
+
=== Connecting to the server
|
115
|
+
|
116
|
+
To connect to the server require the `ovirtsdk4` file. That will give to
|
117
|
+
the {reference}/Connection[Connection] class. This is the entry point of
|
118
|
+
the SDK, and gives you access to the root of the tree of services of the
|
119
|
+
API:
|
120
|
+
|
121
|
+
[source,ruby]
|
122
|
+
----
|
25
123
|
# Create a connection to the server:
|
26
124
|
connection = OvirtSDK4::Connection.new(
|
27
125
|
url: 'https://engine.example.com/ovirt-engine/api',
|
28
126
|
username: 'admin@internal',
|
29
127
|
password: '...',
|
30
|
-
ca_file: 'ca.pem'
|
128
|
+
ca_file: 'ca.pem',
|
31
129
|
)
|
130
|
+
----
|
32
131
|
|
33
|
-
|
34
|
-
|
132
|
+
The connection holds expensive resources, including a pool of HTTP
|
133
|
+
connections to the server and an authentication token. It is very
|
134
|
+
important to free these resources when they are no longer in use:
|
35
135
|
|
36
|
-
|
136
|
+
[source,ruby]
|
137
|
+
----
|
138
|
+
# Close the connection to the server:
|
37
139
|
connection.close
|
38
140
|
----
|
39
141
|
|
142
|
+
Once a connection is closed it can't be reused.
|
143
|
+
|
40
144
|
The `ca.pem` file is required when connecting to a server protected
|
41
145
|
with TLS. In an usual oVirt installation it will be in
|
42
146
|
`/etc/pki/ovirt-engine/ca.pem`. If you don't specify `ca_file`, then
|
43
|
-
|
147
|
+
system wide CA certificate store will be used.
|
148
|
+
|
149
|
+
If something fails when trying to create the connection (authentication
|
150
|
+
failure, communication failure, etc) the SDK will raise a
|
151
|
+
{reference}/Error[Error] exception containing the details.
|
152
|
+
|
153
|
+
=== Using _types_
|
154
|
+
|
155
|
+
The type classes are pure data containers, they don't have any logic or
|
156
|
+
operations. Instances can be created and modified at will.
|
157
|
+
|
158
|
+
Creating or modifying one of this instances does *not* have any effect
|
159
|
+
in the server side, unless one they are explicitly passed to a call to
|
160
|
+
one of the service methods described below. Changes in the server side
|
161
|
+
are *not* automatically reflected in the instances that already exist in
|
162
|
+
memory.
|
163
|
+
|
164
|
+
The constructors of these classes have multiple optional arguments, one
|
165
|
+
for each attribute of the type. This is intended to simplify creation of
|
166
|
+
objects using nested calls to multiple constructors. For example, to
|
167
|
+
create an instance of a virtual machine, with an specification of the
|
168
|
+
cluster and template that it should use, and the memory it should have:
|
169
|
+
|
170
|
+
[source,ruby]
|
171
|
+
----
|
172
|
+
vm = OvirtSDK4::Vm.new(
|
173
|
+
name: 'myvm',
|
174
|
+
cluster: OvirtSDK4::Cluster.new(
|
175
|
+
name: 'mycluster'
|
176
|
+
),
|
177
|
+
template: OvirtSDK4::Template.new(
|
178
|
+
name: 'mytemplate'
|
179
|
+
),
|
180
|
+
memory: 1073741824
|
181
|
+
)
|
182
|
+
----
|
183
|
+
|
184
|
+
Using the constructors in this way is recommended, but not mandatory.
|
185
|
+
You can also create the instance with no arguments in the call to the
|
186
|
+
constructor, and then populate the object step by step, using the
|
187
|
+
setters, or using a mix of both approaches:
|
188
|
+
|
189
|
+
[source,ruby]
|
190
|
+
----
|
191
|
+
vm = OvirtSDK4::Vm.new
|
192
|
+
vm.name = 'myvm'
|
193
|
+
vm.cluster = OvirtSDK4::Cluster.new(name: 'mycluster')
|
194
|
+
vm.template = OvirtSDK4::Template.new(name: 'mytemplate')
|
195
|
+
vm.memory=1073741824
|
196
|
+
----
|
197
|
+
|
198
|
+
Attributes that are defined as lists of objects in the specification of
|
199
|
+
the API are implemented as Ruby arrays. For example, the
|
200
|
+
`custom_properties` attributes of the
|
201
|
+
http://ovirt.github.io/ovirt-engine-api-model/master/#types/vm[Vm] type
|
202
|
+
is defined as a list of objects of type `CustomProperty`, so when using
|
203
|
+
it in the SDK it will be a Ruby array:
|
204
|
+
|
205
|
+
[source,ruby]
|
206
|
+
----
|
207
|
+
vm = OvirtSDK4::Vm.new(
|
208
|
+
name: 'myvm',
|
209
|
+
custom_properties: [
|
210
|
+
OvirtSDK4::CustomProperty.new(...),
|
211
|
+
OvirtSDK4::CustomProperty.new(...),
|
212
|
+
...
|
213
|
+
]
|
214
|
+
)
|
215
|
+
----
|
216
|
+
|
217
|
+
Attributes that are defined as enumerated values in the specification of
|
218
|
+
the API are implemented as constatns within a module that has the same
|
219
|
+
name than the enumerated type. For example, the `status` attribute of
|
220
|
+
the `Vm` type is defined using the
|
221
|
+
http://ovirt.github.io/ovirt-engine-api-model/master/#types/vm_status[VmStatus]
|
222
|
+
enum:
|
44
223
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
224
|
+
[source,ruby]
|
225
|
+
----
|
226
|
+
case vm.status
|
227
|
+
when OvirtSDK4::VmStatus::DOWN
|
228
|
+
...
|
229
|
+
when OvirtSDK4::VmStatus::IMAGE_LOCKED
|
230
|
+
...
|
231
|
+
end
|
232
|
+
----
|
233
|
+
|
234
|
+
NOTE: In the specification of the API the values of enum types appear in
|
235
|
+
lower case, because that is what is used in the XML or JSON documents,
|
236
|
+
but in Ruby it is common practice to use upper case for this kind of
|
237
|
+
constants, so that is how they are defined in the Ruby SDK: all upper
|
238
|
+
case.
|
239
|
+
|
240
|
+
Reading the attributes of instances of types is done using the
|
241
|
+
corresponding attribute readers:
|
50
242
|
|
51
243
|
[source,ruby]
|
52
244
|
----
|
53
|
-
|
245
|
+
puts "vm.name: #{vm.name}"
|
246
|
+
puts "vm.memory: #{vm.memory}"
|
247
|
+
vm.custom_properties.each do |custom_property|
|
248
|
+
...
|
249
|
+
end
|
250
|
+
----
|
251
|
+
|
252
|
+
=== Using _links_
|
253
|
+
|
254
|
+
Some of the attributes of types are defined as _links_ in the
|
255
|
+
specification of the API. This is done to indicate that their value
|
256
|
+
won't usually be populated when retrieving the representation of that
|
257
|
+
object, only a link will be returned instead. For example, when
|
258
|
+
retrieving a virtual machine, the XML returned by the server will look
|
259
|
+
like this:
|
260
|
+
|
261
|
+
[source,xml]
|
262
|
+
----
|
263
|
+
<vm id="123" href="/ovirt-engine/api/vms/123">
|
264
|
+
<name>myvm</name>
|
265
|
+
<link rel="diskattachments" href="/ovirt-engine/api/vms/123/diskattachments/>
|
266
|
+
...
|
267
|
+
</vm>
|
268
|
+
----
|
269
|
+
|
270
|
+
That link is available as `vm.disk_attachments`, but it doesn't contain
|
271
|
+
the actual disk attachments. To get the actual data the
|
272
|
+
{reference}/Connection[Connection] class provides a
|
273
|
+
{reference}/Connection#follow_link-instance_method[follow_link] method
|
274
|
+
that uses the value of the `href` XML attribute to retrieve the actual
|
275
|
+
data. For example, to retrieve the details of the disks of the virtual
|
276
|
+
machine, you can first follow the link to the disk attachments, and then
|
277
|
+
follow the link to each of the disks:
|
278
|
+
|
279
|
+
[source,ruby]
|
280
|
+
----
|
281
|
+
# Retrieve the virtual machine:
|
282
|
+
vm = vm_service.get
|
283
|
+
|
284
|
+
# Follow the link to the disk attachments, and then to the disks:
|
285
|
+
attachments = connection.follow_link(vm.disk_attachments)
|
286
|
+
attachments.each do |attachment|
|
287
|
+
disk = connection.follow_link(attachment.disk)
|
288
|
+
puts "disk.alias: #{disk.alias}"
|
289
|
+
end
|
290
|
+
----
|
291
|
+
|
292
|
+
=== Locating services
|
293
|
+
|
294
|
+
The API provides a set of _services_, each associated to a particular
|
295
|
+
path within the URL space of the server. For example, the service that
|
296
|
+
manages the collection of virtual machines of the system lives in
|
297
|
+
`/vms`, and the service that manages the virtual machine with identifier
|
298
|
+
`123` lives in `/vms/123`.
|
299
|
+
|
300
|
+
In the SDK the root of that tree of services is implemented by the
|
301
|
+
_system service_. It is obtained calling the
|
302
|
+
{rererence}/Connection#system_service-instance_method[system_service]
|
303
|
+
method of the connection:
|
304
|
+
|
305
|
+
[source,ruby]
|
306
|
+
----
|
307
|
+
system_service = connection.system_service
|
308
|
+
----
|
309
|
+
|
310
|
+
Once you have the reference to this system service you can use it to get
|
311
|
+
references to other services, calling the `+*_service+` methods (called
|
312
|
+
_service locators_) of the previous service. For example, to get a
|
313
|
+
reference to the service that manages the collection of virtual machines
|
314
|
+
of the system use the
|
315
|
+
{reference}/SystemService#vms_service-instance_method[vms_service]
|
316
|
+
service locator:
|
317
|
+
|
318
|
+
[source,ruby]
|
319
|
+
----
|
320
|
+
vms_service = system_service.vms_service
|
321
|
+
----
|
322
|
+
|
323
|
+
To get a reference to the service that manages the virtual machine with
|
324
|
+
identifier `123`, use the
|
325
|
+
{reference}/VmsService#vm_service-instance_method[vm_service] service
|
326
|
+
locator of the service that manages the collection of virtual machines.
|
327
|
+
It receives as a parameter the identifier of the virtual machine:
|
328
|
+
|
329
|
+
[source,ruby]
|
330
|
+
----
|
331
|
+
vm_service = vms_service.vms_service('123')
|
332
|
+
----
|
333
|
+
|
334
|
+
IMPORTANT: Calling the service locators doesn't send any request to the
|
335
|
+
server. The Ruby objects that they return are pure services, they
|
336
|
+
don't contain any data. For example, the `vm_service` Ruby object
|
337
|
+
obtained in the previous example is *not* the representation of a
|
338
|
+
virtual machine. It is the service that can be used to retrieve, update,
|
339
|
+
delete, start and stop that virtual machine.
|
340
|
+
|
341
|
+
=== Using services
|
342
|
+
|
343
|
+
Once you have located the service you are interested on, you can start
|
344
|
+
calling its _service methods_, the methods that send requests to the
|
345
|
+
server and do the real work.
|
346
|
+
|
347
|
+
The services that manage collections of object usually have the `list`
|
348
|
+
and `add` methods.
|
349
|
+
|
350
|
+
The services that manage a single object usually have the `get`,
|
351
|
+
`update` and `remove` methods.
|
352
|
+
|
353
|
+
Both kinds of services can also have additional _action methods_, which
|
354
|
+
perform actions other than retrieving, creating, updating or removing.
|
355
|
+
Most frequently they available in services that manage a single object.
|
356
|
+
|
357
|
+
==== Using the _get_ methods
|
358
|
+
|
359
|
+
These service methods are used to retrieve the representation of a
|
360
|
+
single object. For example, to retrieve the representation of the
|
361
|
+
virtual machine with identifier `123`:
|
362
|
+
|
363
|
+
[source,ruby]
|
364
|
+
----
|
365
|
+
# Find the service that manages the virtual machine:
|
54
366
|
vms_service = system_service.vms_service
|
367
|
+
vm_service = vms_service.vm_service('123')
|
368
|
+
|
369
|
+
# Retrieve the representation of the virtual machine:
|
370
|
+
vm = vm_service.get
|
55
371
|
----
|
56
372
|
|
57
|
-
|
58
|
-
|
59
|
-
|
373
|
+
The result will be an instance of the corresponding type. For example,
|
374
|
+
in this case, the result will be an instance of the Ruby class
|
375
|
+
{reference}/Vm[Vm].
|
376
|
+
|
377
|
+
The `get` methods of some services support additional parameters that
|
378
|
+
control how to retrieve the representation of the object, or what
|
379
|
+
representation to retrieve in case there are multiple representations.
|
380
|
+
For example, for virtual machines you may want to retrieve its current
|
381
|
+
state, or the state that will be used the next time it is started, as
|
382
|
+
they may be different. To do so the `get` method of the service that
|
383
|
+
manages a virtual machine supports a
|
384
|
+
http://ovirt.github.io/ovirt-engine-api-model/master/#services/vm/methods/get/parameters/next_run[next_run]
|
385
|
+
boolean parameter:
|
60
386
|
|
61
387
|
[source,ruby]
|
62
388
|
----
|
63
|
-
# Retrieve the virtual
|
389
|
+
# Retrieve the representation of the virtual machine, not the
|
390
|
+
# current one, but the one that will be used after the next
|
391
|
+
# boot:
|
392
|
+
vm = vm_service.get(next_run: true)
|
393
|
+
----
|
394
|
+
|
395
|
+
Check the {reference}[reference] documentation of the SDK to find out
|
396
|
+
the details.
|
397
|
+
|
398
|
+
If the object can't be retrieved, for whatever reason, the SDK will
|
399
|
+
raise an {reference}/Error[Error] exception, containing the details of
|
400
|
+
the failure. This includes the situation when the object doesn't
|
401
|
+
actually exist. Note that the exception will be raised when calling the
|
402
|
+
`get` service method, the call to the service locator method never
|
403
|
+
fails, even if the object doesn't exist, because it doesn't send any
|
404
|
+
request to the server. For example:
|
405
|
+
|
406
|
+
[source,ruby]
|
407
|
+
----
|
408
|
+
# Find the service that manages a virtual machine that does
|
409
|
+
# not exist. This will succeed.
|
410
|
+
vm_service = vms_service.vm_service('junk')
|
411
|
+
|
412
|
+
# Retrieve the virtual machine. This will raise an exception.
|
413
|
+
vm = vm_service.get
|
414
|
+
----
|
415
|
+
|
416
|
+
==== Using the _list_ methods
|
417
|
+
|
418
|
+
These service methods are used to retrieve the representations of the
|
419
|
+
objects of the collection. For example, to retrieve the complete
|
420
|
+
collection of virtual machines of the system:
|
421
|
+
|
422
|
+
[source,ruby]
|
423
|
+
----
|
424
|
+
# Find the service that manages the collection of virtual
|
425
|
+
# machines:
|
426
|
+
vms_service = system_service.vms_service
|
64
427
|
vms = vms_service.list
|
428
|
+
----
|
65
429
|
|
66
|
-
|
67
|
-
|
68
|
-
|
430
|
+
The result will be a Ruby array containing the instances of
|
431
|
+
corresponding types. For example, in this case, the result will be a
|
432
|
+
list of instances of the Ruby class {reference}/Vm[Vm].
|
433
|
+
|
434
|
+
The `list` methods of some services support additional parameters. For
|
435
|
+
example, almost all the top level collections support a `search`
|
436
|
+
parameter that can be used ask the server to filter the results, and a
|
437
|
+
`max` parameter that can be used to limit the number of results returned
|
438
|
+
by the server. For example, to get the list of virtual machines whose
|
439
|
+
name starts with `my`, and to get at most 10 results:
|
440
|
+
|
441
|
+
[source,ruby]
|
442
|
+
----
|
443
|
+
vms = vms_service.list(search: 'name=my*', max: 10)
|
444
|
+
----
|
445
|
+
|
446
|
+
NOTE: Not all the `list` methods support these parameters, and some
|
447
|
+
`list` methods may support other additional parameters. Check the
|
448
|
+
{reference}[reference] documentation of the SDK to find out the details.
|
449
|
+
|
450
|
+
If list of results is empty, for whatever reason, the returned value
|
451
|
+
will be an empty Ruby array, it will never be `nil`.
|
452
|
+
|
453
|
+
If there is an error while trying to retrieve the result, then the SDK
|
454
|
+
will raise an {reference}/Error[Error] exception containing the details
|
455
|
+
of the failure.
|
456
|
+
|
457
|
+
==== Using the _add_ methods
|
458
|
+
|
459
|
+
These service methods add new elements to the collection. They receive
|
460
|
+
an instance of the relevant type describing the object to add, send the
|
461
|
+
request to add it, and return an instance of the type describing the
|
462
|
+
added object.
|
463
|
+
|
464
|
+
For example, to add a new virtual machine named `myvm`:
|
465
|
+
|
466
|
+
[source,ruby]
|
467
|
+
----
|
468
|
+
# Add the virtual machine:
|
469
|
+
vm = vms_service.add(
|
470
|
+
OvirtSDK4::Vm.new(
|
471
|
+
name: 'myvm',
|
472
|
+
cluster: OvirtSDK4::Cluster.new(
|
473
|
+
name: 'mycluster'
|
474
|
+
),
|
475
|
+
template: OvirtSDK4::Template.new(
|
476
|
+
name: 'mytemplate'
|
477
|
+
)
|
478
|
+
)
|
479
|
+
)
|
480
|
+
----
|
481
|
+
|
482
|
+
If the object can't be created, for whatever reason, the SDK will
|
483
|
+
raise an {reference}/Error[Error] exception containing the details of
|
484
|
+
the failure. It will never return `nil`.
|
485
|
+
|
486
|
+
It is very important to understand that the Ruby object returned by this
|
487
|
+
`add` method is an instance of the relevant type, it isn't a service,
|
488
|
+
just a container of data. In this particular example the returned object
|
489
|
+
will be an instance of the {reference}/Vm[Vm] class. If once the
|
490
|
+
virtual machine is created you need to perform some operation on it,
|
491
|
+
like retrieving it again, or starting it, you will first need to find
|
492
|
+
the service that manages it, calling the corresponding service locator:
|
493
|
+
|
494
|
+
[source,ruby]
|
495
|
+
----
|
496
|
+
# Add the virtual machine:
|
497
|
+
vm = vms_service.add(
|
498
|
+
...
|
499
|
+
)
|
500
|
+
|
501
|
+
# Find the service that manages the virtual machine:
|
502
|
+
vm_service = vms_service.vm_service(vm.id)
|
503
|
+
|
504
|
+
# Perform some other operation on the virtual machine, like
|
505
|
+
# starting it:
|
506
|
+
vm_service.start
|
507
|
+
----
|
508
|
+
|
509
|
+
Note that the creation of most objects is an asynchronous task. That
|
510
|
+
means, for example, that when creating a new virtual machine the `add`
|
511
|
+
method will return *before* the virtual machine is completely created
|
512
|
+
and ready to be used. It is good practice to poll the status of the
|
513
|
+
object till it is completely created. For a virtual machine that means
|
514
|
+
checking till the status is _down_. So the recommended approach to create
|
515
|
+
a virtual machine is the following:
|
516
|
+
|
517
|
+
[source,ruby]
|
518
|
+
----
|
519
|
+
# Add the virtual machine:
|
520
|
+
vm = vms_service.add(
|
521
|
+
...
|
522
|
+
)
|
523
|
+
|
524
|
+
# Find the service that manages the virtual machine:
|
525
|
+
vm_service = vms_service.vm_service(vm.id)
|
526
|
+
|
527
|
+
# Wait till the virtual machine is down, which indicats that all the
|
528
|
+
# disks have been created:
|
529
|
+
loop do
|
530
|
+
sleep(5)
|
531
|
+
vm = vm_service.get
|
532
|
+
break if vm.status == OvirtSDK4::VmStatus::DOWN
|
69
533
|
end
|
70
534
|
----
|
71
535
|
|
72
|
-
|
536
|
+
In the above loop it is very important to retrieve the object each time,
|
537
|
+
using the `get` method, otherwise the `status` attribute won't be
|
538
|
+
updated.
|
539
|
+
|
540
|
+
==== Using the _update_ methods
|
541
|
+
|
542
|
+
These service methods update existing objects. They receive
|
543
|
+
an instance of the relevant type describing the update to perform, send
|
544
|
+
the request to update it, and return an instance of the type describing
|
545
|
+
the updated object.
|
546
|
+
|
547
|
+
For example, to update the name of a virtual machine from `myvm` to
|
548
|
+
`newvm`:
|
549
|
+
|
550
|
+
[source,ruby]
|
551
|
+
----
|
552
|
+
# Find the virtual machine, and then the service that
|
553
|
+
# manages it:
|
554
|
+
vm = vms_service.list(search: 'name=myvm').first
|
555
|
+
vm_service = vms_service.vm_service(vm.id)
|
556
|
+
|
557
|
+
# Update the name:
|
558
|
+
updated_vm = vms_service.update(
|
559
|
+
OvirtSDK4::Vm.new(
|
560
|
+
name: 'newvm'
|
561
|
+
)
|
562
|
+
)
|
563
|
+
----
|
564
|
+
|
565
|
+
When performing updates, try to avoid sending the complete
|
566
|
+
representation of the object, send only the attributes that you want to
|
567
|
+
update. For example, try to *avoid* this:
|
568
|
+
|
569
|
+
[source,ruby]
|
570
|
+
----
|
571
|
+
# Retrieve the current representation:
|
572
|
+
vm = vm_service.get()
|
573
|
+
|
574
|
+
# Update the representation, in memory, no request sent
|
575
|
+
# to the server:
|
576
|
+
vm.name = 'newvm'
|
577
|
+
|
578
|
+
# Send the update. Do *not* do this.
|
579
|
+
vms_service.update(vm)
|
580
|
+
----
|
581
|
+
|
582
|
+
The problem with that is double. First you are sending much more
|
583
|
+
information than what the server needs, thus wasting resources. Second,
|
584
|
+
and more important, the server will try to update all the attributes of
|
585
|
+
the object, even those that you didn't need to change. Usually that
|
586
|
+
isn't a problem, but has caused many unexpected bugs in the server side
|
587
|
+
in the past.
|
588
|
+
|
589
|
+
The `update` methods of some services support additional parameters that
|
590
|
+
control how or what to update. For example, for virtual machines you may
|
591
|
+
want to update its current state, or the state that will be used the
|
592
|
+
next time it is started. To do so the `update` method of the service
|
593
|
+
that manages a virtual machine supports a
|
594
|
+
http://ovirt.github.io/ovirt-engine-api-model/master/#services/vm/methods/update/parameters/next_run[next_run]
|
595
|
+
boolean parameter:
|
596
|
+
|
597
|
+
[source,ruby]
|
598
|
+
----
|
599
|
+
# Update the memory of the virtual machine 1 GiB, but not the current
|
600
|
+
# one, the one it will have after the next boot:
|
601
|
+
vm = vm_service.update(
|
602
|
+
OvirtSDK4::Vm.new(
|
603
|
+
memory: 1073741824
|
604
|
+
),
|
605
|
+
next_run: true
|
606
|
+
)
|
607
|
+
----
|
608
|
+
|
609
|
+
If the update can't be performed, for whatever reason, the SDK will
|
610
|
+
raise an {reference}/Error[Error] exception containing the details of
|
611
|
+
the failure. It will never return `nil`.
|
612
|
+
|
613
|
+
The Ruby object returned by this `update` method is an instance of the
|
614
|
+
relevant type, it isn't a service, just a container of data. In this
|
615
|
+
particular example the returned object will be an instance of the
|
616
|
+
{reference}/Vm[Vm] class.
|
617
|
+
|
618
|
+
==== Using the _remove_ methods
|
619
|
+
|
620
|
+
These service methods remove existing objects. They usually don't
|
621
|
+
receive any parameters, as they are methods of the services that manage
|
622
|
+
single objects, therefore the service already knows what object to
|
623
|
+
remove.
|
624
|
+
|
625
|
+
For example, to remove the virtual machine with identifier `123`:
|
626
|
+
|
627
|
+
[source,ruby]
|
628
|
+
----
|
629
|
+
# Find the service that manages the virtual machine:
|
630
|
+
vm_service = vms_service.vm_service('123')
|
631
|
+
|
632
|
+
# Remove the virtual machine:
|
633
|
+
vms_service.remove
|
634
|
+
----
|
635
|
+
|
636
|
+
The `remove` methods of some services support additional parameters that
|
637
|
+
control how or what to remove. For example, for virtual machines it is
|
638
|
+
possible to remove the virtual machine while preserving the disks.
|
639
|
+
To do so the `remove` method of the service that manages a virtual machine supports a
|
640
|
+
http://ovirt.github.io/ovirt-engine-api-model/master/#services/vm/methods/remove[detach_only]
|
641
|
+
boolean parameter:
|
642
|
+
|
643
|
+
[source,ruby]
|
644
|
+
----
|
645
|
+
# Remove the virtual machine, but preserve the disks:
|
646
|
+
vm_service.remove(detach_only: true)
|
647
|
+
----
|
648
|
+
|
649
|
+
The `remove` methods return `nil` if the object is removed successfully.
|
650
|
+
It does *not* return the removed object. If the object can't be removed,
|
651
|
+
for whatever reason, the SDK will raise an {reference}/Vm[Vm]
|
652
|
+
exception containing the details of the failure.
|
653
|
+
|
654
|
+
==== Using _action_ methods
|
655
|
+
|
656
|
+
These service methods perform miscellaneous operations. For example, the
|
657
|
+
service that manages a virtual machine has methods to start and stop it:
|
658
|
+
|
659
|
+
[source,ruby]
|
660
|
+
----
|
661
|
+
# Start the virtual machine:
|
662
|
+
vm_service.start
|
663
|
+
----
|
664
|
+
|
665
|
+
Many of these methods include parameters that modify the operation. For
|
666
|
+
example, the method that starts a virtual machine supports a
|
667
|
+
http://ovirt.github.io/ovirt-engine-api-model/master/#services/vm/methods/start/parameters/use_cloud_init[use_cloud_init]
|
668
|
+
parameter that indicates if you want to start it using
|
669
|
+
https://cloudinit.readthedocs.io/cloud-init[cloud-init]:
|
670
|
+
|
671
|
+
[source,ruby]
|
672
|
+
----
|
673
|
+
# Start the virtual machine:
|
674
|
+
vm_service.start(cloud_init: true)
|
675
|
+
----
|
676
|
+
|
677
|
+
Most action methods return `nil` when they succeed, and raise a
|
678
|
+
{reference}/Error[Error] when they fail. But a few action methods return
|
679
|
+
values. For example, the service that manages a storage domains has an
|
680
|
+
http://ovirt.github.io/ovirt-engine-api-model/master/#services/storage_domain/methods/is_attachedd[is_attached]
|
681
|
+
action method that checks if the storage domain is already attached to a
|
682
|
+
data center. That method returns a boolean:
|
683
|
+
|
684
|
+
[source,ruby]
|
685
|
+
----
|
686
|
+
# Check if the storage domain is attached to a data center:
|
687
|
+
sds_service = system_service.storage_domains_service
|
688
|
+
sd_service = sds_service.storage_domain_service('123')
|
689
|
+
if sd_service.is_attached
|
690
|
+
...
|
691
|
+
end
|
692
|
+
----
|
693
|
+
|
694
|
+
Check the {reference}[reference] documentation of the SDK to see the
|
695
|
+
action methods supported by each service, the parameters that they
|
696
|
+
support, and the values that they return.
|
697
|
+
|
698
|
+
== More information
|
699
|
+
|
700
|
+
The reference documentation of the API is available
|
701
|
+
http://ovirt.github.io/ovirt-engine-api-model[here].
|
73
702
|
|
74
|
-
|
703
|
+
The reference documentation of the SDK is available {reference}[here].
|
75
704
|
|
76
|
-
|
77
|
-
|
705
|
+
There is a collection of examples that show how to use the SDK
|
706
|
+
https://github.com/oVirt/ovirt-engine-sdk-ruby/tree/master/sdk/examples[here].
|