foreman_xen 0.2.1 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Rakefile +1 -1
- data/app/controllers/foreman_xen/snapshots_controller.rb +78 -74
- data/app/helpers/xen_compute_helper.rb +35 -34
- data/app/models/concerns/fog_extensions/xenserver/server.rb +7 -6
- data/app/models/concerns/foreman_xen/host_helper_extensions.rb +17 -40
- data/app/models/foreman_xen/xenserver.rb +152 -113
- data/app/views/compute_resources/form/_xenserver.html.erb +2 -2
- data/app/views/compute_resources_vms/form/_hypervisors.html.erb +4 -4
- data/app/views/compute_resources_vms/form/_templates.html.erb +2 -2
- data/app/views/compute_resources_vms/form/_volume.html.erb +1 -1
- data/app/views/compute_resources_vms/form/_xenstore.html.erb +7 -1
- data/app/views/compute_resources_vms/form/xenserver/_base.html.erb +95 -95
- data/app/views/compute_resources_vms/index/_xenserver.html.erb +7 -7
- data/app/views/foreman_xen/snapshots/new.html.erb +14 -14
- data/app/views/foreman_xen/snapshots/show.html.erb +4 -4
- data/config/routes.rb +0 -2
- data/lib/foreman_xen/engine.rb +3 -11
- data/lib/foreman_xen/version.rb +1 -1
- data/lib/foreman_xen/vnc_tunnel.rb +28 -30
- data/test/foreman_xen_test.rb +1 -1
- data/test/test_helper.rb +4 -4
- metadata +5 -19
- data/app/overrides/hosts/show/snapshot_override.html.erb.deface +0 -2
- data/app/overrides/hosts/show/snapshot_override_legacy.html.erb.deface +0 -2
@@ -1,12 +1,11 @@
|
|
1
1
|
module ForemanXen
|
2
2
|
class Xenserver < ComputeResource
|
3
|
-
|
3
|
+
validates :url, :user, :password, :presence => true
|
4
4
|
|
5
5
|
def provided_attributes
|
6
6
|
super.merge(
|
7
|
-
|
8
|
-
|
9
|
-
})
|
7
|
+
:uuid => :reference,
|
8
|
+
:mac => :mac)
|
10
9
|
end
|
11
10
|
|
12
11
|
def capabilities
|
@@ -23,8 +22,8 @@ module ForemanXen
|
|
23
22
|
|
24
23
|
# we default to destroy the VM's storage as well.
|
25
24
|
def destroy_vm(ref, args = {})
|
26
|
-
logger.info "destroy_vm: #{
|
27
|
-
|
25
|
+
logger.info "destroy_vm: #{ref} #{args}"
|
26
|
+
find_vm_by_uuid(ref).destroy
|
28
27
|
rescue ActiveRecord::RecordNotFound
|
29
28
|
true
|
30
29
|
end
|
@@ -39,115 +38,143 @@ module ForemanXen
|
|
39
38
|
end
|
40
39
|
|
41
40
|
def max_memory
|
42
|
-
|
43
|
-
[hypervisor.metrics.memory_total.to_i,
|
41
|
+
xenserver_max_doc = 128 * 1024 * 1024 * 1024
|
42
|
+
[hypervisor.metrics.memory_total.to_i, xenserver_max_doc].min
|
44
43
|
rescue => e
|
45
44
|
logger.error "unable to figure out free memory, guessing instead due to:#{e}"
|
46
|
-
16*1024*1024*1024
|
45
|
+
16 * 1024 * 1024 * 1024
|
47
46
|
end
|
48
47
|
|
49
48
|
def test_connection(options = {})
|
50
49
|
super
|
51
|
-
errors[:url].empty?
|
50
|
+
errors[:url].empty? && errors[:user].empty? && errors[:password].empty? && hypervisor
|
52
51
|
rescue => e
|
53
|
-
|
52
|
+
begin
|
53
|
+
disconnect
|
54
|
+
rescue
|
55
|
+
nil
|
56
|
+
end
|
54
57
|
errors[:base] << e.message
|
55
58
|
end
|
56
|
-
|
57
|
-
def avalable_hypervisors
|
58
|
-
tmps = client.hosts rescue []
|
59
|
-
tmps.sort { |a, b| a.name <=> b.name }
|
60
|
-
end
|
61
59
|
|
62
|
-
def
|
60
|
+
def available_hypervisors
|
61
|
+
tmps = begin
|
62
|
+
client.hosts
|
63
|
+
rescue
|
64
|
+
[]
|
65
|
+
end
|
66
|
+
tmps.sort { |a, b| a.name <=> b.name }
|
67
|
+
end
|
68
|
+
|
69
|
+
def new_nic(attr = {})
|
63
70
|
client.networks.new attr
|
64
71
|
end
|
65
72
|
|
66
|
-
def new_volume(attr={})
|
73
|
+
def new_volume(attr = {})
|
67
74
|
client.storage_repositories.new attr
|
68
75
|
end
|
69
76
|
|
70
77
|
def storage_pools
|
71
|
-
|
72
|
-
results = Array.new
|
73
|
-
|
74
|
-
storages = client.storage_repositories.select { |sr| sr.type!= 'udev' && sr.type!= 'iso'} rescue []
|
75
|
-
hosts = client.hosts
|
76
|
-
|
77
|
-
storages.each do |sr|
|
78
|
-
subresults = Hash.new()
|
79
|
-
found = 0
|
80
|
-
hosts.each do |host|
|
81
|
-
|
82
|
-
if (sr.reference == host.suspend_image_sr)
|
83
|
-
found = 1
|
84
|
-
subresults[:name] = sr.name
|
85
|
-
subresults[:display_name] = sr.name + '(' + host.hostname + ')'
|
86
|
-
subresults[:uuid] = sr.uuid
|
87
|
-
break
|
88
|
-
end
|
89
|
-
|
90
|
-
end
|
91
|
-
|
92
|
-
if (found==0)
|
93
|
-
subresults[:name] = sr.name
|
94
|
-
subresults[:display_name] = sr.name
|
95
|
-
subresults[:uuid] = sr.uuid
|
96
|
-
end
|
97
|
-
results.push(subresults)
|
98
|
-
end
|
99
|
-
|
100
|
-
results.sort_by!{|item| item[:display_name] }
|
101
|
-
return results
|
78
|
+
results = []
|
102
79
|
|
80
|
+
storages = begin
|
81
|
+
client.storage_repositories.select { |sr| sr.type != 'udev' && sr.type != 'iso' }
|
82
|
+
rescue
|
83
|
+
[]
|
84
|
+
end
|
85
|
+
hosts = client.hosts
|
86
|
+
|
87
|
+
storages.each do |sr|
|
88
|
+
subresults = {}
|
89
|
+
found = 0
|
90
|
+
hosts.each do |host|
|
91
|
+
next until sr.reference == host.suspend_image_sr
|
92
|
+
found = 1
|
93
|
+
subresults[:name] = sr.name
|
94
|
+
subresults[:display_name] = sr.name + '(' + host.hostname + ')'
|
95
|
+
subresults[:uuid] = sr.uuid
|
96
|
+
break
|
97
|
+
end
|
98
|
+
|
99
|
+
if found == 0
|
100
|
+
subresults[:name] = sr.name
|
101
|
+
subresults[:display_name] = sr.name
|
102
|
+
subresults[:uuid] = sr.uuid
|
103
|
+
end
|
104
|
+
results.push(subresults)
|
105
|
+
end
|
106
|
+
|
107
|
+
results.sort_by! { |item| item[:display_name] }
|
108
|
+
results
|
103
109
|
end
|
104
110
|
|
105
111
|
def interfaces
|
106
|
-
client.interfaces
|
112
|
+
client.interfaces
|
113
|
+
rescue
|
114
|
+
[]
|
107
115
|
end
|
108
116
|
|
109
117
|
def networks
|
110
|
-
networks =
|
118
|
+
networks = begin
|
119
|
+
client.networks
|
120
|
+
rescue
|
121
|
+
[]
|
122
|
+
end
|
111
123
|
networks.sort { |a, b| a.name <=> b.name }
|
112
124
|
end
|
113
125
|
|
114
126
|
def templates
|
115
|
-
client.servers.templates
|
127
|
+
client.servers.templates
|
128
|
+
rescue
|
129
|
+
[]
|
116
130
|
end
|
117
131
|
|
118
132
|
def custom_templates
|
119
|
-
tmps =
|
133
|
+
tmps = begin
|
134
|
+
client.servers.custom_templates.select { |t| !t.is_a_snapshot }
|
135
|
+
rescue
|
136
|
+
[]
|
137
|
+
end
|
120
138
|
tmps.sort { |a, b| a.name <=> b.name }
|
121
139
|
end
|
122
140
|
|
123
141
|
def builtin_templates
|
124
|
-
tmps =
|
142
|
+
tmps = begin
|
143
|
+
client.servers.builtin_templates.select { |t| !t.is_a_snapshot }
|
144
|
+
rescue
|
145
|
+
[]
|
146
|
+
end
|
125
147
|
tmps.sort { |a, b| a.name <=> b.name }
|
126
148
|
end
|
127
149
|
|
128
150
|
def associated_host(vm)
|
129
|
-
associate_by(
|
151
|
+
associate_by('mac', vm.interfaces.map(&:mac))
|
130
152
|
end
|
131
153
|
|
132
|
-
def
|
133
|
-
if vm.snapshots.empty?
|
134
|
-
|
154
|
+
def find_snapshots_for_vm(vm)
|
155
|
+
return [] if vm.snapshots.empty?
|
156
|
+
tmps = begin
|
157
|
+
client.servers.templates.select(&:is_a_snapshot)
|
158
|
+
rescue
|
159
|
+
[]
|
135
160
|
end
|
136
|
-
tmps = client.servers.templates.select { |t| t.is_a_snapshot } rescue []
|
137
161
|
retval = []
|
138
|
-
tmps.each do |
|
162
|
+
tmps.each do |snapshot|
|
139
163
|
retval << snapshot if vm.snapshots.include?(snapshot.reference)
|
140
164
|
end
|
141
165
|
retval
|
142
166
|
end
|
143
167
|
|
144
|
-
def
|
145
|
-
tmps =
|
168
|
+
def find_snapshots
|
169
|
+
tmps = begin
|
170
|
+
client.servers.templates.select(&:is_a_snapshot)
|
171
|
+
rescue
|
172
|
+
[]
|
173
|
+
end
|
146
174
|
tmps.sort { |a, b| a.name <=> b.name }
|
147
175
|
end
|
148
176
|
|
149
|
-
def new_vm(attr={})
|
150
|
-
|
177
|
+
def new_vm(attr = {})
|
151
178
|
test_connection
|
152
179
|
return unless errors.empty?
|
153
180
|
opts = vm_instance_defaults.merge(attr.to_hash).symbolize_keys
|
@@ -161,22 +188,21 @@ module ForemanXen
|
|
161
188
|
end
|
162
189
|
|
163
190
|
def create_vm(args = {})
|
164
|
-
|
165
|
-
custom_template_name = args[:custom_template_name]
|
191
|
+
custom_template_name = args[:custom_template_name]
|
166
192
|
builtin_template_name = args[:builtin_template_name]
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
if builtin_template_name!= ''
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
193
|
+
custom_template_name = custom_template_name.to_s
|
194
|
+
builtin_template_name = builtin_template_name.to_s
|
195
|
+
|
196
|
+
if builtin_template_name != '' && custom_template_name != ''
|
197
|
+
logger.info "custom_template_name: #{custom_template_name}"
|
198
|
+
logger.info "builtin_template_name: #{builtin_template_name}"
|
199
|
+
fail 'you can select at most one template type'
|
200
|
+
end
|
175
201
|
begin
|
176
202
|
vm = nil
|
177
|
-
|
178
|
-
|
179
|
-
if custom_template_name != ''
|
203
|
+
logger.info "create_vm(): custom_template_name: #{custom_template_name}"
|
204
|
+
logger.info "create_vm(): builtin_template_name: #{builtin_template_name}"
|
205
|
+
if custom_template_name != ''
|
180
206
|
vm = create_vm_from_custom args
|
181
207
|
else
|
182
208
|
vm = create_vm_from_builtin args
|
@@ -200,28 +226,31 @@ module ForemanXen
|
|
200
226
|
end
|
201
227
|
|
202
228
|
def create_vm_from_custom(args)
|
203
|
-
|
204
|
-
mem_max = args[:memory_max]
|
229
|
+
mem_max = args[:memory_max]
|
205
230
|
mem_min = args[:memory_min]
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
231
|
+
|
232
|
+
if args[:hypervisor_host] != ''
|
233
|
+
host = client.hosts.find { |host| host.name == args[:hypervisor_host] }
|
234
|
+
logger.info "create_vm_from_builtin: host : #{host.name}"
|
235
|
+
else
|
236
|
+
host = client.hosts.first
|
237
|
+
logger.info "create_vm_from_builtin: host : #{host.name}"
|
238
|
+
end
|
239
|
+
|
240
|
+
fail 'Memory max cannot be lower than Memory min' if mem_min.to_i > mem_max.to_i
|
216
241
|
vm = client.servers.new :name => args[:name],
|
217
|
-
|
242
|
+
:affinity => host,
|
218
243
|
:template_name => args[:custom_template_name]
|
219
244
|
|
220
245
|
vm.save :auto_start => false
|
221
246
|
|
222
247
|
vm.provision
|
223
248
|
|
224
|
-
|
249
|
+
begin
|
250
|
+
vm.vifs.first.destroy
|
251
|
+
rescue
|
252
|
+
nil
|
253
|
+
end
|
225
254
|
|
226
255
|
create_network(vm, args)
|
227
256
|
|
@@ -246,27 +275,26 @@ module ForemanXen
|
|
246
275
|
i = 0
|
247
276
|
disks.each do |vbd|
|
248
277
|
vbd.vdi.set_attribute('name-label', "#{args[:name]}_#{i}")
|
249
|
-
i+=1
|
278
|
+
i += 1
|
250
279
|
end
|
251
280
|
vm
|
252
281
|
end
|
253
282
|
|
254
283
|
def create_vm_from_builtin(args)
|
255
|
-
|
256
284
|
builtin_template_name = args[:builtin_template_name]
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
285
|
+
builtin_template_name = builtin_template_name.to_s
|
286
|
+
|
287
|
+
if args[:hypervisor_host] != ''
|
288
|
+
host = client.hosts.find { |host| host.name == args[:hypervisor_host] }
|
289
|
+
logger.info "create_vm_from_builtin: host : #{host.name}"
|
290
|
+
else
|
291
|
+
host = client.hosts.first
|
292
|
+
logger.info "create_vm_from_builtin: host : #{host.name}"
|
293
|
+
end
|
266
294
|
|
267
295
|
storage_repository = client.storage_repositories.find { |sr| sr.uuid == "#{args[:VBDs][:sr_uuid]}" }
|
268
296
|
|
269
|
-
gb =
|
297
|
+
gb = 1_073_741_824 # 1gb in bytes
|
270
298
|
size = args[:VBDs][:physical_size].to_i * gb
|
271
299
|
vdi = client.vdis.create :name => "#{args[:name]}-disk1",
|
272
300
|
:storage_repository => storage_repository,
|
@@ -304,19 +332,26 @@ module ForemanXen
|
|
304
332
|
vm
|
305
333
|
end
|
306
334
|
|
307
|
-
def console
|
335
|
+
def console(uuid)
|
308
336
|
vm = find_vm_by_uuid(uuid)
|
309
|
-
|
337
|
+
fail 'VM is not running!' unless vm.ready?
|
310
338
|
|
311
339
|
console = vm.service.consoles.find { |c| c.__vm == vm.reference && c.protocol == 'rfb' }
|
312
|
-
|
340
|
+
fail "No console for vm #{vm.name}" if console.nil?
|
313
341
|
|
314
342
|
session_ref = (vm.service.instance_variable_get :@connection).instance_variable_get :@credentials
|
315
|
-
|
316
|
-
tunnel = VNCTunnel.new
|
343
|
+
full_url = "#{console.location}&session_id=#{session_ref}"
|
344
|
+
tunnel = VNCTunnel.new full_url
|
317
345
|
tunnel.start
|
318
346
|
logger.info 'VNCTunnel started'
|
319
|
-
WsProxy.start(
|
347
|
+
WsProxy.start(
|
348
|
+
:host => tunnel.host,
|
349
|
+
:host_port => tunnel.port,
|
350
|
+
:password => ''
|
351
|
+
).merge(
|
352
|
+
:type => 'vnc',
|
353
|
+
:name => vm.name
|
354
|
+
)
|
320
355
|
|
321
356
|
rescue Error => e
|
322
357
|
logger.warn e
|
@@ -330,7 +365,13 @@ module ForemanXen
|
|
330
365
|
protected
|
331
366
|
|
332
367
|
def client
|
333
|
-
@client ||= ::Fog::Compute.new(
|
368
|
+
@client ||= ::Fog::Compute.new(
|
369
|
+
:provider => 'XenServer',
|
370
|
+
:xenserver_url => url,
|
371
|
+
:xenserver_username => user,
|
372
|
+
:xenserver_password => password,
|
373
|
+
:xenserver_redirect_to_master => true
|
374
|
+
)
|
334
375
|
end
|
335
376
|
|
336
377
|
def disconnect
|
@@ -342,7 +383,6 @@ module ForemanXen
|
|
342
383
|
super.merge({})
|
343
384
|
end
|
344
385
|
|
345
|
-
|
346
386
|
private
|
347
387
|
|
348
388
|
def create_network(vm, args)
|
@@ -362,7 +402,7 @@ module ForemanXen
|
|
362
402
|
vm.reload
|
363
403
|
end
|
364
404
|
|
365
|
-
def xenstore_hash_flatten(nested_hash, key=nil, keychain=nil, out_hash={})
|
405
|
+
def xenstore_hash_flatten(nested_hash, key = nil, keychain = nil, out_hash = {})
|
366
406
|
nested_hash.each do |k, v|
|
367
407
|
if v.is_a? Hash
|
368
408
|
xenstore_hash_flatten(v, k, "#{keychain}#{k}/", out_hash)
|
@@ -371,7 +411,6 @@ module ForemanXen
|
|
371
411
|
end
|
372
412
|
end
|
373
413
|
out_hash
|
374
|
-
# @key = key
|
375
414
|
end
|
376
415
|
end
|
377
416
|
end
|
@@ -2,9 +2,9 @@
|
|
2
2
|
<%= text_f f, :user %>
|
3
3
|
<%= password_f f, :password %>
|
4
4
|
|
5
|
-
<% hypervisor = f.object.hypervisor.uuid rescue nil%>
|
5
|
+
<% hypervisor = f.object.hypervisor.uuid rescue nil %>
|
6
6
|
<% if hypervisor -%>
|
7
|
-
|
7
|
+
<%= f.hidden_field :uuid, :value => hypervisor %>
|
8
8
|
<% end -%>
|
9
9
|
<%= link_to_function _("Test Connection"), "testConnection(this)", :class => "btn + #{hypervisor.nil? ? "btn-default" : "btn-success"}", :'data-url' => test_connection_compute_resources_path %>
|
10
10
|
|
@@ -1,5 +1,5 @@
|
|
1
1
|
<div id='templates' class=''>
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
</div>
|
2
|
+
<div class="form-group">
|
3
|
+
<%= selectable_f f, :hypervisor_host, [[_("Automatic allocation"), ""]] + compute_resource.available_hypervisors.map { |t| [t.name + " - " + (t.metrics.memory_free.to_f / t.metrics.memory_total.to_f * 100).round(2).to_s + "% free mem", t.name] }, {}, :class => 'form-control span2', :disabled => (controller_name != 'hosts'), :label => 'Hypervisor' %>
|
4
|
+
</div>
|
5
|
+
</div>
|
@@ -1,11 +1,11 @@
|
|
1
1
|
<div class="fields">
|
2
2
|
<div id='templates' class=''>
|
3
3
|
<div class="form-group">
|
4
|
-
<%= selectable_f f, :custom_template_name,[[_("No template"), ""]] + compute_resource.custom_templates.map { |t| [t.name, t.name] }, { :selected => attribute_map[:template_selected_custom] }, :class => 'form-control span2', :label => 'Custom Template' %>
|
4
|
+
<%= selectable_f f, :custom_template_name, [[_("No template"), ""]] + compute_resource.custom_templates.map { |t| [t.name, t.name] }, { :selected => attribute_map[:template_selected_custom] }, :class => 'form-control span2', :label => 'Custom Template' %>
|
5
5
|
</div>
|
6
6
|
|
7
7
|
<div class="form-group ">
|
8
|
-
<%= selectable_f f, :builtin_template_name,[[_("No template"), ""]] + compute_resource.builtin_templates.map { |t| [t.name, t.name] }, { :selected => attribute_map[:template_selected_builtin] }, :class => 'form-control span2', :label => 'Builtin Template' %>
|
8
|
+
<%= selectable_f f, :builtin_template_name, [[_("No template"), ""]] + compute_resource.builtin_templates.map { |t| [t.name, t.name] }, { :selected => attribute_map[:template_selected_builtin] }, :class => 'form-control span2', :label => 'Builtin Template' %>
|
9
9
|
</div>
|
10
10
|
</div>
|
11
11
|
</div>
|