ovirt 0.5.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|