foreman_xen 0.2.1 → 0.2.2
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/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>
|