ovirt-engine-sdk 4.1.8 → 4.1.9

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d87b36d7e0dc5dab224115c5a5109b052ab6cc2c
4
- data.tar.gz: 163217911308f7c56022498e6eeb07e6d6d6f0c4
3
+ metadata.gz: 818f63a1a783df790fbf5fc8f254ded435a90ac8
4
+ data.tar.gz: 2a51cba1a01c8a8c62647ee2c256f3a1684684a4
5
5
  SHA512:
6
- metadata.gz: 85c29a2a9c062fcbb605de0af9829735ea350f36a13ccde2dd0ce26d2733cb76a77c8a56040078c29bab6c7b2565b3a643a2d424dcc689a91f3e5e0728c468c1
7
- data.tar.gz: 60c16dabedce63e73662269d961b7bf7a14d62c6b92670153378b10a654a954cbf36298d77d795862351c65aa8650e7d3bda097ab2ee38bf6d3f28ce4cd43058
6
+ metadata.gz: 9445021acbd41f225e882fe6ef4fc537bd97972ef9c978f0b4ed50c4b91ac53cb6f4ec5b116a7abef4f183b4764a94737fc730453278b094ff86aa7c72fbf5cd
7
+ data.tar.gz: 43097db69c7d043a11e147a55739e40a37455e4c2738714f451ca4b8f752a375f26be5575042643747fcd848f2639a4e6aa2c96ef4368175667e8d18bec15839
data/CHANGES.adoc CHANGED
@@ -2,6 +2,27 @@
2
2
 
3
3
  This document describes the relevant changes between releases of the SDK.
4
4
 
5
+ == 4.1.9 / Oct 13 2017
6
+
7
+ Update to model 4.1.39:
8
+
9
+ * Add a `refresh` parameter to `FilesService.list`.
10
+
11
+ * Add support for Link Layer Discovery Protocol (LLDP).
12
+
13
+ * Add support for listing cluster level features, and enabling/disabing
14
+ them for clusters.
15
+
16
+ New features:
17
+
18
+ * Improve log messages so that in addition to the response codes they
19
+ also contain the request method and URL.
20
+
21
+ Bug fixes:
22
+
23
+ * Add support for multiple threads
24
+ https://bugzilla.redhat.com/1496846[#1496846].
25
+
5
26
  == 4.1.8 / Jul 17 2017
6
27
 
7
28
  Update to model 4.1.37:
data/README.adoc CHANGED
@@ -106,7 +106,7 @@ locators_ and _service methods_ (described later) may change in the
106
106
  future.
107
107
 
108
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
109
+ These are used to implement the HTTP communication, and for XML
110
110
  parsing and rendering. Refrain from using them, as they are internal
111
111
  implementation details that may change in the future: backwards
112
112
  compatibility isn't guaranteed.
@@ -127,6 +127,9 @@ connection = OvirtSDK4::Connection.new(
127
127
  password: '...',
128
128
  ca_file: 'ca.pem',
129
129
  )
130
+
131
+ # Get the reference to the root of the tree of services:
132
+ system_service = connection.system_service
130
133
  ----
131
134
 
132
135
  The connection holds expensive resources, including a pool of HTTP
@@ -139,7 +142,8 @@ important to free these resources when they are no longer in use:
139
142
  connection.close
140
143
  ----
141
144
 
142
- Once a connection is closed it can't be reused.
145
+ The connection and all the services that have been obtained from it
146
+ can't be used after the connection has been closed.
143
147
 
144
148
  The `ca.pem` file is required when connecting to a server protected
145
149
  with TLS. In an usual oVirt installation it will be in
@@ -156,9 +160,9 @@ The type classes are pure data containers, they don't have any logic or
156
160
  operations. Instances can be created and modified at will.
157
161
 
158
162
  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
163
+ in the server side, unless they are explicitly passed to a call to one
164
+ of the service methods described below. Changes in the server side are
165
+ *not* automatically reflected in the instances that already exist in
162
166
  memory.
163
167
 
164
168
  The constructors of these classes have multiple optional arguments, one
@@ -181,6 +185,28 @@ vm = OvirtSDK4::Vm.new(
181
185
  )
182
186
  ----
183
187
 
188
+ The hashes passed to these constructors are processed recursively. For
189
+ example, in the above code instead of explicitly calling the constructor
190
+ for the `Cluster` and `Template` classes it is also possible to use
191
+ plain hashes:
192
+
193
+ [source,ruby]
194
+ ----
195
+ vm = OvirtSDK4::Vm.new(
196
+ name: 'myvm',
197
+ cluster: {
198
+ name: 'mycluster'
199
+ },
200
+ template: {
201
+ name: 'mytemplate'
202
+ },
203
+ memory: 1073741824
204
+ )
205
+ ----
206
+
207
+ The SDK will internally convert those hashes to the required classes, so
208
+ the result will be exactly the same.
209
+
184
210
  Using the constructors in this way is recommended, but not mandatory.
185
211
  You can also create the instance with no arguments in the call to the
186
212
  constructor, and then populate the object step by step, using the
@@ -192,7 +218,7 @@ vm = OvirtSDK4::Vm.new
192
218
  vm.name = 'myvm'
193
219
  vm.cluster = OvirtSDK4::Cluster.new(name: 'mycluster')
194
220
  vm.template = OvirtSDK4::Template.new(name: 'mytemplate')
195
- vm.memory=1073741824
221
+ vm.memory = 1073741824
196
222
  ----
197
223
 
198
224
  Attributes that are defined as lists of objects in the specification of
@@ -299,7 +325,7 @@ manages the collection of virtual machines of the system lives in
299
325
 
300
326
  In the SDK the root of that tree of services is implemented by the
301
327
  _system service_. It is obtained calling the
302
- {rererence}/Connection#system_service-instance_method[system_service]
328
+ {reference}/Connection#system_service-instance_method[system_service]
303
329
  method of the connection:
304
330
 
305
331
  [source,ruby]
@@ -352,7 +378,8 @@ The services that manage a single object usually have the `get`,
352
378
 
353
379
  Both kinds of services can also have additional _action methods_, which
354
380
  perform actions other than retrieving, creating, updating or removing.
355
- Most frequently they available in services that manage a single object.
381
+ Most frequently they are available in services that manage a single
382
+ object.
356
383
 
357
384
  ==== Using the _get_ methods
358
385
 
@@ -427,7 +454,7 @@ vms_service = system_service.vms_service
427
454
  vms = vms_service.list
428
455
  ----
429
456
 
430
- The result will be a Ruby array containing the instances of
457
+ The result will be a Ruby array containing the instances of the
431
458
  corresponding types. For example, in this case, the result will be a
432
459
  list of instances of the Ruby class {reference}/Vm[Vm].
433
460
 
@@ -456,8 +483,8 @@ of the failure.
456
483
 
457
484
  ==== Using the _add_ methods
458
485
 
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
486
+ These service methods add new elements to collections. They receive an
487
+ instance of the relevant type describing the object to add, send the
461
488
  request to add it, and return an instance of the type describing the
462
489
  added object.
463
490
 
@@ -469,12 +496,12 @@ For example, to add a new virtual machine named `myvm`:
469
496
  vm = vms_service.add(
470
497
  OvirtSDK4::Vm.new(
471
498
  name: 'myvm',
472
- cluster: OvirtSDK4::Cluster.new(
499
+ cluster: {
473
500
  name: 'mycluster'
474
- ),
475
- template: OvirtSDK4::Template.new(
501
+ },
502
+ template: {
476
503
  name: 'mytemplate'
477
- )
504
+ }
478
505
  )
479
506
  )
480
507
  ----
@@ -539,10 +566,10 @@ updated.
539
566
 
540
567
  ==== Using the _update_ methods
541
568
 
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.
569
+ These service methods update existing objects. They receive an instance
570
+ of the relevant type describing the update to perform, send the request
571
+ to update it, and return an instance of the type describing the updated
572
+ object.
546
573
 
547
574
  For example, to update the name of a virtual machine from `myvm` to
548
575
  `newvm`:
@@ -569,7 +596,7 @@ update. For example, try to *avoid* this:
569
596
  [source,ruby]
570
597
  ----
571
598
  # Retrieve the current representation:
572
- vm = vm_service.get()
599
+ vm = vm_service.get
573
600
 
574
601
  # Update the representation, in memory, no request sent
575
602
  # to the server:
@@ -587,6 +587,7 @@ static void* ov_http_client_complete_task(void* data) {
587
587
  VALUE transfer;
588
588
  long code;
589
589
  ov_http_client_object* client_ptr;
590
+ ov_http_request_object* request_ptr;
590
591
  ov_http_response_object* response_ptr;
591
592
  ov_http_transfer_object* transfer_ptr;
592
593
 
@@ -600,6 +601,7 @@ static void* ov_http_client_complete_task(void* data) {
600
601
  /* Get the pointers to the transfer, client and response: */
601
602
  ov_http_transfer_ptr(transfer, transfer_ptr);
602
603
  ov_http_client_ptr(transfer_ptr->client, client_ptr);
604
+ ov_http_request_ptr(transfer_ptr->request, request_ptr);
603
605
  ov_http_response_ptr(transfer_ptr->response, response_ptr);
604
606
 
605
607
  /* Remove the transfer from the pending hash: */
@@ -617,8 +619,10 @@ static void* ov_http_client_complete_task(void* data) {
617
619
  /* Send a summary of the response to the log: */
618
620
  ov_http_client_log_info(
619
621
  client_ptr->log,
620
- "Received response code '%"PRIsVALUE"'.",
621
- response_ptr->code
622
+ "Received response code %"PRIsVALUE" for %"PRIsVALUE" request to URL '%"PRIsVALUE"'.",
623
+ response_ptr->code,
624
+ request_ptr->method,
625
+ request_ptr->url
622
626
  );
623
627
  }
624
628
  else {
@@ -806,7 +810,7 @@ static void ov_http_client_prepare_handle(ov_http_client_object* client_ptr, ov_
806
810
  /* Send a summary of the request to the log: */
807
811
  ov_http_client_log_info(
808
812
  client_ptr->log,
809
- "Sending '%"PRIsVALUE"' request to URL '%"PRIsVALUE"'.",
813
+ "Sending %"PRIsVALUE" request to URL '%"PRIsVALUE"'.",
810
814
  request_ptr->method,
811
815
  url
812
816
  );
@@ -16,6 +16,7 @@
16
16
 
17
17
  require 'json'
18
18
  require 'tempfile'
19
+ require 'thread'
19
20
  require 'uri'
20
21
 
21
22
  module OvirtSDK4
@@ -145,6 +146,9 @@ module OvirtSDK4
145
146
  @ca_store.close
146
147
  end
147
148
 
149
+ # Create the mutex that will be used to prevents simultaneous access to the same HTTP client by multiple threads:
150
+ @mutex = Mutex.new
151
+
148
152
  # Create the HTTP client:
149
153
  @client = HttpClient.new(
150
154
  insecure: @insecure,
@@ -184,65 +188,24 @@ module OvirtSDK4
184
188
  end
185
189
 
186
190
  #
187
- # Sends an HTTP request.
191
+ # Sends an HTTP request, making sure that multiple threads are coordinated correctly.
188
192
  #
189
193
  # @param request [HttpRequest] The request object containing the details of the HTTP request to send.
190
194
  #
191
195
  # @api private
192
196
  #
193
197
  def send(request)
194
- # Add the base URL to the request:
195
- request.url = request.url.nil? ? request.url = @url : "#{@url}#{request.url}"
196
-
197
- # Set the headers common to all requests:
198
- request.headers.merge!(
199
- 'User-Agent' => "RubySDK/#{VERSION}",
200
- 'Version' => '4',
201
- 'Content-Type' => 'application/xml',
202
- 'Accept' => 'application/xml'
203
- )
204
-
205
- # Older versions of the engine (before 4.1) required the 'all_content' as an HTTP header instead of a query
206
- # parameter. In order to better support those older versions of the engine we need to check if this parameter is
207
- # included in the request, and add the corresponding header.
208
- unless request.query.nil?
209
- all_content = request.query['all_content']
210
- request.headers['All-Content'] = all_content unless all_content.nil?
211
- end
212
-
213
- # Add the global headers, but without replacing the values that may already exist:
214
- request.headers.merge!(@headers) { |_name, local, _global| local } if @headers
215
-
216
- # Set the authentication token:
217
- @token ||= create_access_token
218
- request.token = @token
219
-
220
- # Send the request:
221
- @client.send(request)
198
+ @mutex.synchronize { internal_send(request) }
222
199
  end
223
200
 
224
201
  #
225
- # Waits for the response to the given request.
202
+ # Waits for the response to the given request, making sure that multiple threads are coordinated correctly.
226
203
  #
227
204
  # @param request [HttpRequest] The request object whose corresponding response you want to wait for.
228
- # @return [Response] A request object containing the details of the HTTP response received.
205
+ # @return [HttpResponse] A request object containing the details of the HTTP response received.
229
206
  #
230
207
  def wait(request)
231
- # Wait for the response:
232
- response = @client.wait(request)
233
- raise response if response.is_a?(Exception)
234
-
235
- # If the request failed because of authentication, and it wasn't a request to the SSO service, then the
236
- # most likely cause is an expired SSO token. In this case we need to request a new token, and try the original
237
- # request again, but only once. It if fails again, we just return the failed response.
238
- if response.code == 401 && request.token
239
- @token = create_access_token
240
- request.token = @token
241
- @client.send(request)
242
- response = @client.wait(request)
243
- end
244
-
245
- response
208
+ @mutex.synchronize { internal_wait(request) }
246
209
  end
247
210
 
248
211
  #
@@ -466,17 +429,10 @@ module OvirtSDK4
466
429
  end
467
430
 
468
431
  #
469
- # Releases the resources used by this connection.
432
+ # Releases the resources used by this connection, making sure that multiple threads are coordinated correctly.
470
433
  #
471
434
  def close
472
- # Revoke the SSO access token:
473
- revoke_access_token if @token
474
-
475
- # Close the HTTP client:
476
- @client.close if @client
477
-
478
- # Remove the temporary file that contains the trusted CA certificates:
479
- @ca_store.unlink if @ca_store
435
+ @mutex.synchronize { internal_close }
480
436
  end
481
437
 
482
438
  #
@@ -596,5 +552,85 @@ module OvirtSDK4
596
552
  end
597
553
  raise_error(response, detail)
598
554
  end
555
+
556
+ #
557
+ # Sends an HTTP request.
558
+ #
559
+ # @param request [HttpRequest] The request object containing the details of the HTTP request to send.
560
+ #
561
+ # @api private
562
+ #
563
+ def internal_send(request)
564
+ # Add the base URL to the request:
565
+ request.url = request.url.nil? ? request.url = @url : "#{@url}/#{request.url}"
566
+
567
+ # Set the headers common to all requests:
568
+ request.headers.merge!(
569
+ 'User-Agent' => "RubySDK/#{VERSION}",
570
+ 'Version' => '4',
571
+ 'Content-Type' => 'application/xml',
572
+ 'Accept' => 'application/xml'
573
+ )
574
+
575
+ # Older versions of the engine (before 4.1) required the 'all_content' as an HTTP header instead of a query
576
+ # parameter. In order to better support those older versions of the engine we need to check if this parameter is
577
+ # included in the request, and add the corresponding header.
578
+ unless request.query.nil?
579
+ all_content = request.query['all_content']
580
+ request.headers['All-Content'] = all_content unless all_content.nil?
581
+ end
582
+
583
+ # Add the global headers, but without replacing the values that may already exist:
584
+ request.headers.merge!(@headers) { |_name, local, _global| local } if @headers
585
+
586
+ # Set the authentication token:
587
+ @token ||= create_access_token
588
+ request.token = @token
589
+
590
+ # Send the request:
591
+ @client.send(request)
592
+ end
593
+
594
+ #
595
+ # Waits for the response to the given request.
596
+ #
597
+ # @param request [HttpRequest] The request object whose corresponding response you want to wait for.
598
+ # @return [Response] A request object containing the details of the HTTP response received.
599
+ #
600
+ # @api private
601
+ #
602
+ def internal_wait(request)
603
+ # Wait for the response:
604
+ response = @client.wait(request)
605
+ raise response if response.is_a?(Exception)
606
+
607
+ # If the request failed because of authentication, and it wasn't a request to the SSO service, then the
608
+ # most likely cause is an expired SSO token. In this case we need to request a new token, and try the original
609
+ # request again, but only once. It if fails again, we just return the failed response.
610
+ if response.code == 401 && request.token
611
+ @token = create_access_token
612
+ request.token = @token
613
+ @client.send(request)
614
+ response = @client.wait(request)
615
+ end
616
+
617
+ response
618
+ end
619
+
620
+ #
621
+ # Releases the resources used by this connection.
622
+ #
623
+ # @api private
624
+ #
625
+ def internal_close
626
+ # Revoke the SSO access token:
627
+ revoke_access_token if @token
628
+
629
+ # Close the HTTP client:
630
+ @client.close if @client
631
+
632
+ # Remove the temporary file that contains the trusted CA certificates:
633
+ @ca_store.unlink if @ca_store
634
+ end
599
635
  end
600
636
  end
@@ -92,7 +92,7 @@ module OvirtSDK4
92
92
  return nil if text.nil?
93
93
  begin
94
94
  return Integer(text, 10)
95
- rescue
95
+ rescue ArgumentError
96
96
  raise Error, "The text '#{text}' isn't a valid integer value."
97
97
  end
98
98
  end
@@ -127,7 +127,7 @@ module OvirtSDK4
127
127
  return nil if text.nil?
128
128
  begin
129
129
  return Float(text)
130
- rescue
130
+ rescue ArgumentError
131
131
  raise Error, "The text '#{text}' isn't a valid decimal value."
132
132
  end
133
133
  end
@@ -163,7 +163,7 @@ module OvirtSDK4
163
163
  return nil if text.nil?
164
164
  begin
165
165
  return DateTime.xmlschema(text)
166
- rescue
166
+ rescue ArgumentError
167
167
  raise Error, "The text '#{text}' isn't a valid date."
168
168
  end
169
169
  end