ovirt 0.5.0 → 0.6.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.
- checksums.yaml +4 -4
- data/.rspec +0 -1
- data/README.md +1 -1
- data/lib/ovirt/api.rb +3 -4
- data/lib/ovirt/base.rb +47 -44
- data/lib/ovirt/cluster.rb +1 -1
- data/lib/ovirt/data_center.rb +1 -1
- data/lib/ovirt/event.rb +424 -424
- data/lib/ovirt/exception.rb +2 -2
- data/lib/ovirt/inventory.rb +7 -7
- data/lib/ovirt/logging.rb +5 -0
- data/lib/ovirt/null_logger.rb +11 -0
- data/lib/ovirt/service.rb +35 -45
- data/lib/ovirt/snapshot.rb +2 -2
- data/lib/ovirt/statistic.rb +4 -5
- data/lib/ovirt/storage_domain.rb +1 -1
- data/lib/ovirt/template.rb +28 -31
- data/lib/ovirt/user.rb +1 -1
- data/lib/ovirt/version.rb +1 -1
- data/lib/ovirt/vm.rb +18 -24
- data/lib/ovirt.rb +12 -0
- data/spec/base_spec.rb +7 -9
- data/spec/event_spec.rb +3 -13
- data/spec/factories/template.rb +37 -0
- data/spec/factories/vm.rb +1 -3
- data/spec/service_spec.rb +22 -23
- data/spec/spec_helper.rb +89 -9
- data/spec/template_spec.rb +23 -54
- data/spec/vm_spec.rb +47 -49
- metadata +9 -5
data/lib/ovirt/exception.rb
CHANGED
@@ -4,11 +4,11 @@ module Ovirt
|
|
4
4
|
|
5
5
|
# Existence
|
6
6
|
class TemplateAlreadyExists < Error; end
|
7
|
-
class VmAlreadyExists
|
7
|
+
class VmAlreadyExists < Error; end
|
8
8
|
|
9
9
|
# Power State
|
10
10
|
class VmAlreadyRunning < Error; end
|
11
|
-
class VmIsNotRunning
|
11
|
+
class VmIsNotRunning < Error; end
|
12
12
|
class VmNotReadyToBoot < Error; end
|
13
13
|
|
14
14
|
class UsageError < Error; end
|
data/lib/ovirt/inventory.rb
CHANGED
@@ -2,7 +2,7 @@ module Ovirt
|
|
2
2
|
class Inventory
|
3
3
|
attr_accessor :service
|
4
4
|
|
5
|
-
def initialize(options={})
|
5
|
+
def initialize(options = {})
|
6
6
|
@service = Service.new(options)
|
7
7
|
end
|
8
8
|
|
@@ -78,9 +78,9 @@ module Ovirt
|
|
78
78
|
|
79
79
|
def get_vm(path)
|
80
80
|
vm_guid = ::File.basename(path, '.*')
|
81
|
-
vm
|
82
|
-
vm
|
83
|
-
|
81
|
+
vm = get_resource_by_ems_ref("/api/vms/#{vm_guid}") rescue nil
|
82
|
+
vm = get_resource_by_ems_ref("/api/templates/#{vm_guid}") if vm.blank?
|
83
|
+
vm
|
84
84
|
end
|
85
85
|
|
86
86
|
def get_resource_by_ems_ref(uri_suffix, element_name = nil)
|
@@ -131,16 +131,16 @@ module Ovirt
|
|
131
131
|
# > secondary_item_jobs({:vm, => [v1, v2]})
|
132
132
|
# => [[v1, :disks], [v1, :snapshots], [v1, :nics], [v2, :disks], [v2, :snapshots], [v2, :nics]]
|
133
133
|
def secondary_item_jobs(primary_items)
|
134
|
-
SECONDARY_ITEMS.
|
134
|
+
SECONDARY_ITEMS.flat_map do |key, methods|
|
135
135
|
primary_items[key].product(methods)
|
136
|
-
end
|
136
|
+
end
|
137
137
|
end
|
138
138
|
|
139
139
|
def collect_primary_items
|
140
140
|
jobs = primary_item_jobs
|
141
141
|
|
142
142
|
results = collect_in_parallel(jobs) do |_, method|
|
143
|
-
|
143
|
+
send(method)
|
144
144
|
end
|
145
145
|
|
146
146
|
jobs.zip(results).each_with_object({}) do |((key, _), result), hash|
|
data/lib/ovirt/service.rb
CHANGED
@@ -2,6 +2,8 @@ require 'nokogiri'
|
|
2
2
|
|
3
3
|
module Ovirt
|
4
4
|
class Service
|
5
|
+
include Logging
|
6
|
+
|
5
7
|
DEFAULT_OPTIONS = {}
|
6
8
|
REQUIRED_OPTIONS = [:server, :username, :password]
|
7
9
|
DEFAULT_PORT_3_0 = 8443
|
@@ -20,16 +22,16 @@ module Ovirt
|
|
20
22
|
klass.create_from_xml(self, xml)
|
21
23
|
end
|
22
24
|
|
23
|
-
def initialize(options={})
|
25
|
+
def initialize(options = {})
|
24
26
|
@options = DEFAULT_OPTIONS.merge(options)
|
25
27
|
parse_domain_name
|
26
|
-
REQUIRED_OPTIONS.each { |key| raise "No #{key
|
27
|
-
@password
|
28
|
+
REQUIRED_OPTIONS.each { |key| raise "No #{key} specified" unless @options.key?(key) }
|
29
|
+
@password = @options.delete(:password)
|
28
30
|
@session_id = @options[:session_id]
|
29
31
|
end
|
30
32
|
|
31
33
|
def inspect # just like the default inspect, but WITHOUT @password
|
32
|
-
"#<#{self.class.name}:0x#{(
|
34
|
+
"#<#{self.class.name}:0x#{(object_id << 1).to_s(16).rjust(14, '0')} @options=#{@options.inspect}>"
|
33
35
|
end
|
34
36
|
|
35
37
|
def api(reload = false)
|
@@ -95,10 +97,10 @@ module Ovirt
|
|
95
97
|
end
|
96
98
|
|
97
99
|
def get_resource_by_ems_ref(uri_suffix, element_name = nil)
|
98
|
-
xml
|
99
|
-
doc
|
100
|
+
xml = resource_get(uri_suffix)
|
101
|
+
doc = Nokogiri::XML(xml)
|
100
102
|
element_name ||= doc.root.name
|
101
|
-
klass
|
103
|
+
klass = self.class.name_to_class(element_name)
|
102
104
|
xml_to_object(klass, doc.root)
|
103
105
|
end
|
104
106
|
|
@@ -110,17 +112,16 @@ module Ovirt
|
|
110
112
|
doc = Nokogiri::XML(xml)
|
111
113
|
end
|
112
114
|
element_name ||= uri_suffix.singularize
|
113
|
-
klass
|
115
|
+
klass = self.class.name_to_class(element_name)
|
114
116
|
|
115
117
|
xml_path = uri_suffix == 'api' ? element_name : "#{element_name.pluralize}/#{element_name}"
|
116
|
-
objects
|
118
|
+
objects = doc.xpath("//#{xml_path}")
|
117
119
|
objects.collect { |obj| xml_to_object(klass, obj) }
|
118
120
|
end
|
119
121
|
|
120
122
|
def status(link)
|
121
123
|
response = resource_get(link)
|
122
|
-
|
123
|
-
node = Base.xml_to_nokogiri(response)
|
124
|
+
node = Base.xml_to_nokogiri(response)
|
124
125
|
node.xpath('status/state').text
|
125
126
|
end
|
126
127
|
|
@@ -137,7 +138,7 @@ module Ovirt
|
|
137
138
|
|
138
139
|
def self.ovirt?(options)
|
139
140
|
options[:username] = options[:password] = "_unused"
|
140
|
-
!
|
141
|
+
!new(options).engine_ssh_public_key.to_s.blank?
|
141
142
|
rescue RestClient::ResourceNotFound
|
142
143
|
false
|
143
144
|
end
|
@@ -147,36 +148,36 @@ module Ovirt
|
|
147
148
|
RestClient::Resource.new("#{base_uri}/engine.ssh.key.txt", resource_options).get
|
148
149
|
end
|
149
150
|
|
150
|
-
def paginate_resource_get(path = nil, sort_by
|
151
|
+
def paginate_resource_get(path = nil, sort_by = :name, direction = :asc)
|
151
152
|
log_header = "#{self.class.name}#paginate_resource_get"
|
152
|
-
page
|
153
|
-
full_xml
|
153
|
+
page = 1
|
154
|
+
full_xml = nil
|
154
155
|
loop do
|
155
156
|
uri = "#{path}?search=sortby%20#{sort_by}%20#{direction}%20page%20#{page}"
|
156
|
-
partial_xml_str =
|
157
|
+
partial_xml_str = resource_get(uri)
|
157
158
|
if full_xml.nil?
|
158
159
|
full_xml = Nokogiri::XML(partial_xml_str)
|
159
160
|
else
|
160
161
|
partial_xml = Nokogiri::XML(partial_xml_str)
|
161
162
|
break if partial_xml.root.children.count == 0
|
162
|
-
|
163
|
+
logger.debug "#{log_header}: Combining resource elements for <#{path}> from page:<#{page}>"
|
163
164
|
full_xml.root << partial_xml.root.children
|
164
165
|
end
|
165
166
|
page += 1
|
166
167
|
end
|
167
|
-
|
168
|
-
|
168
|
+
logger.debug "#{log_header}: Combined elements for <#{path}>. Total elements:<#{full_xml.root.children.count}>"
|
169
|
+
full_xml
|
169
170
|
end
|
170
171
|
|
171
172
|
def resource_get(path = nil)
|
172
173
|
resource_verb(path, :get)
|
173
174
|
end
|
174
175
|
|
175
|
-
def resource_put(path, payload, additional_headers={:content_type => :xml, :accept => :xml})
|
176
|
+
def resource_put(path, payload, additional_headers = {:content_type => :xml, :accept => :xml})
|
176
177
|
resource_verb(path, :put, payload, additional_headers)
|
177
178
|
end
|
178
179
|
|
179
|
-
def resource_post(path, payload, additional_headers={:content_type => :xml, :accept => :xml})
|
180
|
+
def resource_post(path, payload, additional_headers = {:content_type => :xml, :accept => :xml})
|
180
181
|
resource_verb(path, :post, payload, additional_headers)
|
181
182
|
end
|
182
183
|
|
@@ -193,10 +194,9 @@ module Ovirt
|
|
193
194
|
|
194
195
|
def resource_verb(path, verb, *args)
|
195
196
|
log_header = "#{self.class.name}#resource_#{verb}"
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
$rhevm_log.debug "#{log_header}: With args: <#{args.inspect}>" if $rhevm_log.try(:debug?)
|
197
|
+
resource = create_resource(path)
|
198
|
+
logger.info "#{log_header}: Sending URL: <#{resource.url}>"
|
199
|
+
logger.debug "#{log_header}: With args: <#{args.inspect}>"
|
200
200
|
resource.send(verb, *args) do |response, request, result, &block|
|
201
201
|
case response.code
|
202
202
|
when 200
|
@@ -208,7 +208,7 @@ module Ovirt
|
|
208
208
|
end
|
209
209
|
end
|
210
210
|
rescue RestClient::Unauthorized
|
211
|
-
if
|
211
|
+
if session_id
|
212
212
|
self.session_id = nil
|
213
213
|
retry
|
214
214
|
else
|
@@ -217,22 +217,15 @@ module Ovirt
|
|
217
217
|
rescue RestClient::ResourceNotFound, Ovirt::Error
|
218
218
|
raise
|
219
219
|
rescue Exception => e
|
220
|
-
|
221
|
-
if $rhevm_log.nil?
|
222
|
-
puts msg
|
223
|
-
else
|
224
|
-
$rhevm_log.error msg
|
225
|
-
end
|
220
|
+
logger.error("#{log_header}: class = #{e.class.name}, message=#{e.message}, URI=#{resource ? resource.url : path}")
|
226
221
|
raise
|
227
222
|
end
|
228
223
|
|
229
224
|
def parse_normal_response(response, resource)
|
230
225
|
parse_set_cookie_header(response.headers[:set_cookie])
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
$rhevm_log.debug "#{log_header}: Return from URL: <#{resource.url}> Data:#{response}" if $rhevm_log.debug?
|
235
|
-
end
|
226
|
+
log_header = "#{self.class.name}#parse_normal_response"
|
227
|
+
logger.info "#{log_header}: Return from URL: <#{resource.url}> Data length:#{response.length}"
|
228
|
+
logger.debug "#{log_header}: Return from URL: <#{resource.url}> Data:#{response}"
|
236
229
|
response
|
237
230
|
end
|
238
231
|
|
@@ -262,11 +255,11 @@ module Ovirt
|
|
262
255
|
end
|
263
256
|
|
264
257
|
def resource_options
|
265
|
-
headers = merge_headers(
|
258
|
+
headers = merge_headers('Prefer' => 'persistent-auth')
|
266
259
|
options = {}
|
267
260
|
|
268
|
-
if
|
269
|
-
headers[:cookie] = "#{SESSION_ID_KEY}=#{
|
261
|
+
if session_id
|
262
|
+
headers[:cookie] = "#{SESSION_ID_KEY}=#{session_id}"
|
270
263
|
else
|
271
264
|
options[:user] = fully_qualified_username
|
272
265
|
options[:password] = password
|
@@ -285,7 +278,7 @@ module Ovirt
|
|
285
278
|
end
|
286
279
|
|
287
280
|
def authorization_header
|
288
|
-
@authorization_header ||= {
|
281
|
+
@authorization_header ||= {:authorization => "Basic #{authorization_value}"}
|
289
282
|
end
|
290
283
|
|
291
284
|
def authorization_value
|
@@ -315,9 +308,7 @@ module Ovirt
|
|
315
308
|
@options[:username]
|
316
309
|
end
|
317
310
|
|
318
|
-
|
319
|
-
@password
|
320
|
-
end
|
311
|
+
attr_reader :password
|
321
312
|
|
322
313
|
def domain
|
323
314
|
@options[:domain]
|
@@ -345,6 +336,5 @@ module Ovirt
|
|
345
336
|
end
|
346
337
|
end
|
347
338
|
end
|
348
|
-
|
349
339
|
end
|
350
340
|
end
|
data/lib/ovirt/snapshot.rb
CHANGED
@@ -10,11 +10,11 @@ module Ovirt
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def delete
|
13
|
-
|
13
|
+
destroy
|
14
14
|
while self[:snapshot_status] == "locked" || self[:snapshot_status] == "ok"
|
15
15
|
sleep 2
|
16
16
|
break if (obj = self.class.find_by_href(@service, self[:href])).nil?
|
17
|
-
|
17
|
+
replace(obj)
|
18
18
|
end
|
19
19
|
end
|
20
20
|
end
|
data/lib/ovirt/statistic.rb
CHANGED
@@ -3,10 +3,9 @@ module Ovirt
|
|
3
3
|
self.top_level_strings = [:name, :description, :type, :unit]
|
4
4
|
|
5
5
|
def self.parse_node_extended(node, hash)
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
values = values_node.xpath('value').collect do |v|
|
6
|
+
values_node = node.xpath('values').first
|
7
|
+
values_type = values_node['type']
|
8
|
+
values = values_node.xpath('value').collect do |v|
|
10
9
|
datum = v.xpath('datum').text
|
11
10
|
case values_type
|
12
11
|
when 'INTEGER'
|
@@ -18,7 +17,7 @@ module Ovirt
|
|
18
17
|
end
|
19
18
|
datum
|
20
19
|
end
|
21
|
-
hash[:values]
|
20
|
+
hash[:values] = values
|
22
21
|
|
23
22
|
[:vm, :nic, :disk].each do |type|
|
24
23
|
parent_node = node.xpath(type.to_s).first
|
data/lib/ovirt/storage_domain.rb
CHANGED
@@ -25,7 +25,7 @@ module Ovirt
|
|
25
25
|
|
26
26
|
unless vg_hash.blank?
|
27
27
|
parse_first_node(vg, :logical_unit, vg_hash,
|
28
|
-
|
28
|
+
:node => [:address, :port, :target, :username, :serial, :vendor_id, :product_id, :lun_mapping, :portal, :size, :paths])
|
29
29
|
end
|
30
30
|
end
|
31
31
|
end
|
data/lib/ovirt/template.rb
CHANGED
@@ -17,7 +17,7 @@ module Ovirt
|
|
17
17
|
:node_to_bool => [:enabled])
|
18
18
|
|
19
19
|
parse_first_node_with_hash(node, 'cpu/topology', hash.store_path(:cpu, :topology, {}),
|
20
|
-
|
20
|
+
:attribute_to_i => [:sockets, :cores])
|
21
21
|
|
22
22
|
parse_first_node(node, :high_availability, hash,
|
23
23
|
:node_to_bool => [:enabled],
|
@@ -28,7 +28,7 @@ module Ovirt
|
|
28
28
|
:node => [:kernel, :initrd, :cmdline])
|
29
29
|
|
30
30
|
hash[:os][:boot_order] = boot_order = []
|
31
|
-
#Collect boot order
|
31
|
+
# Collect boot order
|
32
32
|
node.xpath('os/boot').each do |boot|
|
33
33
|
dev = boot['dev']
|
34
34
|
boot_order << {:dev => dev} unless dev.blank?
|
@@ -41,37 +41,34 @@ module Ovirt
|
|
41
41
|
end
|
42
42
|
|
43
43
|
def os_type
|
44
|
-
|
44
|
+
attributes.fetch_path(:os, :type) || 'unassigned'
|
45
45
|
end
|
46
46
|
|
47
|
-
def getCfg(
|
48
|
-
#
|
49
|
-
|
47
|
+
def getCfg(_snap = nil)
|
48
|
+
# TODO: Remove the following MiqException and any others
|
49
|
+
raise MiqException::MiqVimError, "Failed to retrieve configuration information for VM" if attributes.nil?
|
50
50
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
cfgHash['memsize'] = cfgProps[:memory] / 1048576 # in MB
|
57
|
-
cfgHash['numvcpu'] = cfgProps.fetch_path(:cpu, :sockets)
|
51
|
+
cfg_hash = {}
|
52
|
+
cfg_hash['displayname'] = attributes[:name]
|
53
|
+
cfg_hash['guestos'] = attributes.fetch_path(:os, :type)
|
54
|
+
cfg_hash['memsize'] = attributes[:memory] / 1_048_576 # in MB
|
55
|
+
cfg_hash['numvcpu'] = attributes.fetch_path(:cpu, :sockets)
|
58
56
|
|
59
57
|
# Collect disk information
|
60
|
-
|
61
|
-
|
58
|
+
attributes[:disks] = send(:disks, :disk) if self[:disks].nil?
|
59
|
+
disks.each_with_index do |disk, idx|
|
62
60
|
storage_domain = disk[:storage_domains].first
|
63
|
-
storage_id
|
64
|
-
disk_key
|
65
|
-
file_path
|
61
|
+
storage_id = storage_domain && storage_domain[:id]
|
62
|
+
disk_key = disk[:image_id].blank? ? :id : :image_id
|
63
|
+
file_path = storage_id && ::File.join('/dev', storage_id, disk[disk_key])
|
66
64
|
|
67
65
|
tag = "scsi0:#{idx}"
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
#cfgHash["#{tag}.mode"] = dev['backing']['diskMode']
|
66
|
+
cfg_hash["#{tag}.present"] = "true"
|
67
|
+
cfg_hash["#{tag}.devicetype"] = "disk"
|
68
|
+
cfg_hash["#{tag}.filename"] = file_path.to_s
|
69
|
+
cfg_hash["#{tag}.format"] = disk[:format]
|
73
70
|
end
|
74
|
-
|
71
|
+
cfg_hash
|
75
72
|
end
|
76
73
|
|
77
74
|
REQUIRED_CLONE_PARAMETERS = [:name, :cluster]
|
@@ -85,9 +82,9 @@ module Ovirt
|
|
85
82
|
options[:storage] = Base.object_to_id(options[:storage]) if options[:storage]
|
86
83
|
|
87
84
|
case options[:clone_type]
|
88
|
-
when :full
|
89
|
-
when :linked
|
90
|
-
when :skeletal
|
85
|
+
when :full then clone_to_vm(options)
|
86
|
+
when :linked then clone_to_vm(options)
|
87
|
+
when :skeletal then clone_to_vm_via_blank_template(options)
|
91
88
|
end
|
92
89
|
end
|
93
90
|
|
@@ -105,7 +102,7 @@ module Ovirt
|
|
105
102
|
(CLONE_ATTRIBUTES_WITH_SCALARS + CLONE_ATTRIBUTES_WITH_HASHES).each do |key|
|
106
103
|
options[key] ||= self[key]
|
107
104
|
end
|
108
|
-
options[:os_type] ||=
|
105
|
+
options[:os_type] ||= os_type
|
109
106
|
|
110
107
|
skeleton_options = options.dup
|
111
108
|
skeleton_options[:clone_type] = :linked
|
@@ -116,7 +113,7 @@ module Ovirt
|
|
116
113
|
end
|
117
114
|
|
118
115
|
def create_new_disks_from_template(vm, options)
|
119
|
-
|
116
|
+
disks.each do |disk_object|
|
120
117
|
disk_options = disk_object.attributes_for_new_disk
|
121
118
|
disk_options[:sparse] = options[:sparse] unless options[:sparse].nil?
|
122
119
|
disk_options[:storage] = options[:storage] unless options[:storage].blank?
|
@@ -155,14 +152,14 @@ module Ovirt
|
|
155
152
|
end
|
156
153
|
end
|
157
154
|
|
158
|
-
xml.os(:type => options[:os_type] ||
|
155
|
+
xml.os(:type => options[:os_type] || os_type) do
|
159
156
|
xml.boot(:dev => 'hd')
|
160
157
|
end
|
161
158
|
|
162
159
|
if options[:clone_type] == :full
|
163
160
|
xml.disks do
|
164
161
|
xml.clone_ true
|
165
|
-
|
162
|
+
disks.each do |disk_object|
|
166
163
|
xml.disk(:id => disk_object.attributes[:id]) do
|
167
164
|
xml.sparse options[:sparse] unless options[:sparse].nil?
|
168
165
|
xml.storage_domains { xml.storage_domain(:id => options[:storage]) } if options[:storage]
|
data/lib/ovirt/user.rb
CHANGED
@@ -5,7 +5,7 @@ module Ovirt
|
|
5
5
|
|
6
6
|
def self.parse_node_extended(node, hash)
|
7
7
|
groups_node = node.xpath('groups').first
|
8
|
-
hash[:groups] = groups_node.xpath('group').collect
|
8
|
+
hash[:groups] = groups_node.xpath('group').collect(&:text) unless groups_node.nil?
|
9
9
|
end
|
10
10
|
end
|
11
11
|
end
|
data/lib/ovirt/version.rb
CHANGED
data/lib/ovirt/vm.rb
CHANGED
@@ -49,8 +49,7 @@ module Ovirt
|
|
49
49
|
end
|
50
50
|
|
51
51
|
def destroy
|
52
|
-
# TODO:
|
53
|
-
# 1. If VM was running, wait for it to stop
|
52
|
+
# TODO: If VM was running, wait for it to stop
|
54
53
|
begin
|
55
54
|
stop
|
56
55
|
rescue VmIsNotRunning
|
@@ -75,7 +74,7 @@ module Ovirt
|
|
75
74
|
# <state>pending</state>
|
76
75
|
# </status>
|
77
76
|
# </action>
|
78
|
-
doc
|
77
|
+
doc = Nokogiri::XML(response)
|
79
78
|
action = doc.xpath("//action").first
|
80
79
|
raise Ovirt::Error, "No Action in Response: #{response.inspect}" if action.nil?
|
81
80
|
action['href']
|
@@ -210,10 +209,8 @@ module Ovirt
|
|
210
209
|
attach_payload(payload)
|
211
210
|
end
|
212
211
|
|
213
|
-
def detach_payload_3_3(
|
214
|
-
update!
|
215
|
-
xml.payloads
|
216
|
-
end
|
212
|
+
def detach_payload_3_3(_types)
|
213
|
+
update!(&:payloads)
|
217
214
|
end
|
218
215
|
|
219
216
|
# Attaches the +files+ as a floppy drive payload.
|
@@ -237,8 +234,8 @@ module Ovirt
|
|
237
234
|
end
|
238
235
|
end
|
239
236
|
rescue Ovirt::Error => err
|
240
|
-
raise
|
241
|
-
raise
|
237
|
+
raise VmNotReadyToBoot, [err.message, err] if err.message =~ /disks .+ are locked/
|
238
|
+
raise
|
242
239
|
end
|
243
240
|
|
244
241
|
def boot_from_cdrom(iso_file_name)
|
@@ -255,8 +252,8 @@ module Ovirt
|
|
255
252
|
end
|
256
253
|
end
|
257
254
|
rescue Ovirt::Error => err
|
258
|
-
raise
|
259
|
-
raise
|
255
|
+
raise VmNotReadyToBoot, [err.message, err] if err.message =~ /disks .+ are locked/
|
256
|
+
raise
|
260
257
|
end
|
261
258
|
|
262
259
|
def self.parse_xml(xml)
|
@@ -267,7 +264,7 @@ module Ovirt
|
|
267
264
|
:node => [:affinity])
|
268
265
|
|
269
266
|
parse_first_node_with_hash(node, 'placement_policy/host', hash[:placement_policy][:host] = {},
|
270
|
-
|
267
|
+
:attribute => [:id])
|
271
268
|
|
272
269
|
parse_first_node(node, :memory_policy, hash,
|
273
270
|
:node_to_i => [:guaranteed])
|
@@ -323,12 +320,10 @@ module Ovirt
|
|
323
320
|
xml.description desc
|
324
321
|
end
|
325
322
|
end
|
326
|
-
data
|
327
|
-
path
|
328
|
-
|
323
|
+
data = builder.doc.root.to_xml
|
324
|
+
path = "#{api_endpoint}/snapshots"
|
329
325
|
response = @service.resource_post(path, data)
|
330
|
-
|
331
|
-
snap = Snapshot.create_from_xml(@service, response)
|
326
|
+
snap = Snapshot.create_from_xml(@service, response)
|
332
327
|
|
333
328
|
while snap[:snapshot_status] == "locked"
|
334
329
|
sleep 2
|
@@ -337,16 +332,16 @@ module Ovirt
|
|
337
332
|
snap
|
338
333
|
end
|
339
334
|
|
340
|
-
def create_template(options={})
|
335
|
+
def create_template(options = {})
|
341
336
|
builder = Nokogiri::XML::Builder.new do |xml|
|
342
337
|
xml.template do
|
343
338
|
xml.name options[:name]
|
344
339
|
xml.vm(:id => self[:id])
|
345
340
|
end
|
346
341
|
end
|
347
|
-
data
|
348
|
-
|
342
|
+
data = builder.doc.root.to_xml
|
349
343
|
response = @service.resource_post(:templates, data)
|
344
|
+
|
350
345
|
Template.create_from_xml(@service, response)
|
351
346
|
rescue Ovirt::Error => err
|
352
347
|
raise TemplateAlreadyExists, err.message if err.message.include?("Template name already exists")
|
@@ -359,10 +354,9 @@ module Ovirt
|
|
359
354
|
ovirt_cloud_init_keys = %w(active_directory_ou authorized_ssh_keys dns_search dns_servers domain host_name input_locale nic_configurations org_name regenerate_ssh_keys root_password system_locale timezone ui_language user_locale user_name)
|
360
355
|
|
361
356
|
require 'yaml'
|
362
|
-
raw_content
|
363
|
-
|
364
|
-
|
365
|
-
custom_script = YAML.dump(raw_content).to_s.sub("---\n", "")
|
357
|
+
raw_content = YAML.load(content)
|
358
|
+
hash = ovirt_cloud_init_keys.each_with_object({}) { |k, h| h[k] = raw_content.delete(k) }
|
359
|
+
custom_script = YAML.dump(raw_content).to_s.sub("---\n", "")
|
366
360
|
hash[:custom_script] = custom_script unless custom_script.blank?
|
367
361
|
hash.delete_nils
|
368
362
|
end
|
data/lib/ovirt.rb
CHANGED
@@ -2,6 +2,8 @@ require 'active_support/all'
|
|
2
2
|
require 'more_core_extensions/all'
|
3
3
|
|
4
4
|
require 'ovirt/exception'
|
5
|
+
require 'ovirt/logging'
|
6
|
+
require 'ovirt/null_logger'
|
5
7
|
require 'ovirt/base'
|
6
8
|
require 'ovirt/version'
|
7
9
|
|
@@ -32,3 +34,13 @@ require 'ovirt/template'
|
|
32
34
|
require 'ovirt/user'
|
33
35
|
require 'ovirt/vm'
|
34
36
|
require 'ovirt/vmpool'
|
37
|
+
|
38
|
+
module Ovirt
|
39
|
+
class << self
|
40
|
+
attr_writer :logger
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.logger
|
44
|
+
@logger ||= NullLogger.new
|
45
|
+
end
|
46
|
+
end
|
data/spec/base_spec.rb
CHANGED
@@ -1,19 +1,17 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
1
|
describe Ovirt::Base do
|
4
2
|
it ".api_endpoint" do
|
5
|
-
Ovirt::Base.api_endpoint.
|
6
|
-
Ovirt::Template.api_endpoint.
|
7
|
-
Ovirt::Cluster.api_endpoint.
|
8
|
-
Ovirt::Vm.api_endpoint.
|
9
|
-
Ovirt::StorageDomain.api_endpoint.
|
10
|
-
Ovirt::DataCenter.api_endpoint.
|
3
|
+
expect(Ovirt::Base.api_endpoint).to eq("bases")
|
4
|
+
expect(Ovirt::Template.api_endpoint).to eq("templates")
|
5
|
+
expect(Ovirt::Cluster.api_endpoint).to eq("clusters")
|
6
|
+
expect(Ovirt::Vm.api_endpoint).to eq("vms")
|
7
|
+
expect(Ovirt::StorageDomain.api_endpoint).to eq("storagedomains")
|
8
|
+
expect(Ovirt::DataCenter.api_endpoint).to eq("datacenters")
|
11
9
|
end
|
12
10
|
|
13
11
|
it ".href_to_guid" do
|
14
12
|
guid = "1c92b67c-9d10-4f48-85bd-28ba2fd6d9b3"
|
15
13
|
expect(Ovirt::Base.send(:href_to_guid, "/api/clusters/#{guid}")).to eq(guid)
|
16
14
|
expect(Ovirt::Base.send(:href_to_guid, guid)).to eq(guid)
|
17
|
-
expect { Ovirt::Base.send(:href_to_guid,
|
15
|
+
expect { Ovirt::Base.send(:href_to_guid, 12_345) }.to raise_error(ArgumentError)
|
18
16
|
end
|
19
17
|
end
|
data/spec/event_spec.rb
CHANGED
@@ -1,26 +1,16 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
1
|
describe Ovirt::Event do
|
4
2
|
context ".set_event_name" do
|
5
|
-
before :each do
|
6
|
-
@orig_log, $rhevm_log = $rhevm_log, double("logger")
|
7
|
-
end
|
8
|
-
|
9
|
-
after :each do
|
10
|
-
$rhevm_log = @orig_log
|
11
|
-
end
|
12
|
-
|
13
3
|
it "sets the name corresponding to a valid code" do
|
14
4
|
hash = {:code => 1}
|
15
5
|
described_class.send(:set_event_name, hash)
|
16
|
-
hash[:name].
|
6
|
+
expect(hash[:name]).to eq(Ovirt::Event::EVENT_CODES[1])
|
17
7
|
end
|
18
8
|
|
19
9
|
it "sets 'UNKNOWN' as the name with an invalid code" do
|
20
|
-
|
10
|
+
expect(Ovirt.logger).to receive(:warn).with("Ovirt::Event.set_event_name Unknown RHEVM event -1: Invalid Code")
|
21
11
|
hash = {:code => -1, :description => "Invalid Code"}
|
22
12
|
described_class.send(:set_event_name, hash)
|
23
|
-
hash[:name].
|
13
|
+
expect(hash[:name]).to eq("UNKNOWN")
|
24
14
|
end
|
25
15
|
end
|
26
16
|
end
|