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