rubiojr-pangea 0.1.20090403134419

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.
@@ -0,0 +1,6 @@
1
+ module Pangea
2
+ class LinkConnectError < Exception
3
+ end
4
+ class ProxyCallError < Exception
5
+ end
6
+ end
@@ -0,0 +1,675 @@
1
+ module Pangea
2
+
3
+ #
4
+ # Link is the connection to the hypervisor
5
+ #
6
+ # Every Link is associated to one host
7
+ #
8
+ class Link #:nodoc:
9
+
10
+ attr_reader :client, :sid, :url, :connected
11
+
12
+ def initialize(url, username='foo', password='bar')
13
+ @xmlrpc_url = url
14
+ @username = username
15
+ @password = password
16
+ end
17
+
18
+ def connect
19
+ #puts "hyperlinking to #{@xmlrpc_url}"
20
+ $stdout.flush
21
+ begin
22
+ @client = XMLRPC::Client.new2(@xmlrpc_url)
23
+ @session = @client.proxy('session')
24
+ @sid = @session.login_with_password(@username, @password)['Value']
25
+ @connected = true
26
+ rescue Exception => e
27
+ raise LinkConnectError.new("Error connecting to the hypervisor #{@xmlrpc_url} (#{e.message})")
28
+ end
29
+ end
30
+
31
+ end
32
+
33
+ #
34
+ # Base class for every Xen Object
35
+ #
36
+ # Do not use this class.
37
+ #
38
+ # There's no direct mapping to xen-api AFAIK
39
+ #
40
+ class XObject #:nodoc:
41
+
42
+ def initialize(link, ref)
43
+ @ref = ref
44
+ @link = link
45
+ @proxy_name = nil
46
+ end
47
+
48
+ def ref_call(method)
49
+ if @proxy.nil?
50
+ # first ref_call, init proxy
51
+ @proxy = @link.client.proxy(@proxy_name)
52
+ end
53
+ begin
54
+ return @proxy.send(method, @link.sid, @ref)['Value']
55
+ rescue Exception => e
56
+ raise ProxyCallError.new("Error sending request to proxy #{@proxy_name}. Link might be dead (#{e.message})")
57
+ end
58
+ end
59
+
60
+ #
61
+ # This is standard in every Xen Object
62
+ #
63
+ # Returns the unique identifier
64
+ #
65
+ def uuid
66
+ ref_call :get_uuid
67
+ end
68
+
69
+ end
70
+
71
+ #
72
+ # A Physical Host
73
+ #
74
+ # xen-api: Class host
75
+ #
76
+ # <tt>
77
+ # require 'pangea'
78
+ #
79
+ # host = Host.connect(\'http://xen.example.net', 'username', 'password')
80
+ # </tt>
81
+ #
82
+ class Host < XObject
83
+
84
+ def initialize(link, ref) #:nodoc:
85
+ super(link, ref)
86
+ @proxy_name = 'host'
87
+ end
88
+
89
+ #
90
+ # Returns the label of the Host (hostname)
91
+ #
92
+ def label
93
+ ref_call :get_name_label
94
+ end
95
+
96
+ #
97
+ # Get the list of resident virtual machines controlled
98
+ # by the hypervisor.
99
+ #
100
+ # Returns an Array of Pangea::VM objects
101
+ #
102
+ # xen-api: host.get_resident_VMs
103
+ #
104
+ def resident_vms
105
+ vms = []
106
+ ref_call(:get_resident_VMs).each do |vm|
107
+ vms << VM.new(@link, vm)
108
+ end
109
+ vms
110
+ end
111
+
112
+ #
113
+ # Get the list of resident virtual machines controlled
114
+ # by the hypervisor.
115
+ #
116
+ # Returns an Array of Pangea::HostCpu objects
117
+ #
118
+ # xen-api: host.get_host_cpus
119
+ #
120
+ def cpus
121
+ list = []
122
+ ref_call(:get_host_CPUs).each do |hcpu|
123
+ list << HostCpu.new(@link, hcpu)
124
+ end
125
+ list
126
+ end
127
+
128
+ #
129
+ # List some properties from the hypervisor:
130
+ #
131
+ # machine: Host Architecture
132
+ # Xen: Xen Version
133
+ # system: Host OS (i.e. Linux)
134
+ # release: Xen Kernel Version
135
+ # host: hostname
136
+ #
137
+ # Returns a Hash
138
+ #
139
+ # xen-api: host.get_software_version
140
+ #
141
+ def software_version
142
+ ref_call :get_software_version
143
+ end
144
+
145
+ #
146
+ # Get the Xen scheduling policy
147
+ #
148
+ # Returns a string
149
+ #
150
+ # xen-api: host.get_sched_policy
151
+ #
152
+ def sched_policy
153
+ ref_call :get_sched_policy
154
+ end
155
+
156
+ #
157
+ # Get the Pangea::HostMetrics object for this host
158
+ #
159
+ # xen-api: host.get_metrics
160
+ #
161
+ def metrics
162
+ HostMetrics.new(@link, ref_call(:get_metrics))
163
+ end
164
+
165
+ #
166
+ # Returns the list of networks available in this host
167
+ #
168
+ # If you are using a bridged network configuration
169
+ # ('network-script network-bridge' in xend-config.sxp), it will
170
+ # return an Array of Pangea::Network objects available in the host,
171
+ # one for each bridge available.
172
+ #
173
+ # There's no direct mapping to xen-api AFAIK
174
+ #
175
+ def networks
176
+ nets = []
177
+ p = @link.client.proxy( 'network' )
178
+ p.get_all(@link.sid)['Value'].each do |ref|
179
+ nets << Network.new(@link, ref)
180
+ end
181
+ nets
182
+ end
183
+
184
+ def to_s
185
+ "Label: #{label}\n" +
186
+ "UUID: #{uuid}\n" +
187
+ "Sched Policy: #{sched_policy}\n" +
188
+ "Xen Version: #{software_version['Xen']}"
189
+ end
190
+
191
+ #
192
+ # Connect to the Host xml-rpc server
193
+ #
194
+ # Returns a Pangea::Host object
195
+ #
196
+ # There's no direct mapping to xen-api
197
+ #
198
+ def self.connect(url, username, password)
199
+ @link = Link.new(url, username, password)
200
+ @link.connect
201
+ @ref = @link.client.call('host.get_all', @link.sid)['Value'][0]
202
+ Host.new(@link, @ref)
203
+ end
204
+
205
+ #
206
+ # Reconnect to the Host
207
+ #
208
+ # There's no direct mapping to xen-api
209
+ #
210
+ def reconnect
211
+ raise LinkConnectError.new("You need to connect at least once before reconnecting") if @link.nil?
212
+ @link.connect
213
+ @ref = @link.client.call('host.get_all', @link.sid)['Value'][0]
214
+ end
215
+
216
+ #
217
+ # Checks if the connection to the host xml-rpc server is alive
218
+ #
219
+ # There's no direct mapping to xen-api
220
+ #
221
+ def alive?
222
+ begin
223
+ ref_call :get_uuid
224
+ rescue Exception => e
225
+ #puts e.message
226
+ return false
227
+ end
228
+ true
229
+ end
230
+
231
+ end
232
+
233
+ #
234
+ # The metrics associated with a host
235
+ #
236
+ # xen-api: Class host_metrics
237
+ #
238
+ class HostMetrics < XObject
239
+
240
+ def initialize(link, ref) #:nodoc:
241
+ super(link, ref)
242
+ @proxy_name = 'host_metrics'
243
+ end
244
+
245
+ def memory_total
246
+ ref_call :get_memory_total
247
+ end
248
+
249
+ def memory_free
250
+ ref_call :get_memory_free
251
+ end
252
+
253
+ def to_s
254
+ "Total Memory: #{Pangea::Util.humanize_bytes(memory_total)}\n" +
255
+ "Free Memory: #{Pangea::Util.humanize_bytes(memory_free)}"
256
+ end
257
+
258
+ end
259
+
260
+ #
261
+ # A Physical CPU
262
+ #
263
+ # xen-api: Class host_cpu
264
+ #
265
+ class HostCpu < XObject
266
+
267
+ def initialize(link, ref) #:nodoc:
268
+ super(link, ref)
269
+ @proxy_name = 'host_cpu'
270
+ end
271
+
272
+ #
273
+ # xen-api: host_cpu.get_number
274
+ #
275
+ def number
276
+ ref_call :get_number
277
+ end
278
+
279
+ #
280
+ # xen-api: host_cpu.get_vendor
281
+ #
282
+ def vendor
283
+ ref_call :get_vendor
284
+ end
285
+
286
+ #
287
+ # xen-api: host_cpu.get_speed
288
+ #
289
+ # CPU Speed in MHz
290
+ #
291
+ def speed
292
+ ref_call :get_speed
293
+ end
294
+
295
+ #
296
+ # xen-api: host_cpu.get_modelname
297
+ #
298
+ # CPU Model
299
+ #
300
+ def model_name
301
+ ref_call :get_modelname
302
+ end
303
+
304
+ #
305
+ # xen-api: host_cpu.get_utilisation
306
+ #
307
+ # CPU Utilisation
308
+ #
309
+ def utilisation
310
+ ref_call :get_utilisation
311
+ end
312
+
313
+ end
314
+
315
+
316
+ #
317
+ # A Virtual Machine or Guest (DomU)
318
+ #
319
+ # xen-api: VM
320
+ #
321
+ class VM < XObject
322
+
323
+ def initialize(link, ref) #:nodoc:
324
+ super(link, ref)
325
+ @proxy_name = 'VM'
326
+ end
327
+
328
+ #
329
+ # VM Label (same one you see when you run 'xm list')
330
+ #
331
+ # xen-api: VM.get_name_label
332
+ #
333
+ def label
334
+ ref_call :get_name_label
335
+ end
336
+
337
+ #
338
+ # xen-api: VM.get_metrics
339
+ #
340
+ def metrics
341
+ VMMetrics.new(@link, ref_call(:get_metrics))
342
+ end
343
+
344
+ #
345
+ # xen-api: VM.get_guest_metrics
346
+ #
347
+ def guest_metrics
348
+ VMGuestMetrics.new(@link, ref_call(:get_guest_metrics))
349
+ end
350
+
351
+ #
352
+ # xen-api: VM.get_VIFs
353
+ #
354
+ def vifs
355
+ list = []
356
+ ref_call(:get_VIFs).each do |vif|
357
+ list << VIF.new(@link, vif)
358
+ end
359
+ list
360
+ end
361
+
362
+ #
363
+ # xen-api: VM.get_power_state
364
+ #
365
+ def power_state
366
+ ref_call :get_power_state
367
+ end
368
+
369
+ #
370
+ # xen-api: VM.get_memory_static_max
371
+ #
372
+ def max_mem
373
+ ref_call :get_memory_static_max
374
+ end
375
+
376
+ def dyn_max_mem
377
+ ref_call :get_memory_dynamic_max
378
+ end
379
+
380
+ def dyn_min_mem
381
+ ref_call :get_memory_dynamic_min
382
+ end
383
+
384
+ #
385
+ # xen-api: VM.get_memory_static_min
386
+ #
387
+ def min_mem
388
+ ref_call :get_memory_static_min
389
+ end
390
+
391
+ #
392
+ # xen-api: VM.get_resident_on
393
+ #
394
+ def resident_on
395
+ ref = ref_call(:get_resident_on)
396
+ Host.new(@link, ref)
397
+ end
398
+
399
+ #
400
+ # xen-api: VM.get_domid
401
+ #
402
+ def domid
403
+ (ref = ref_call :get_domid).to_i
404
+ end
405
+
406
+ #
407
+ # xen-api: VM.get_is_control_domain
408
+ #
409
+ def is_control_domain?
410
+ ref_call :get_is_control_domain
411
+ end
412
+
413
+ #
414
+ # xen-api: VM.get_auto_power_on
415
+ #
416
+ #def auto_power_on?
417
+ # puts ref_call :get_auto_power_on
418
+ #end
419
+
420
+ #
421
+ # xen-api: VM.get_actions_after_shutdown
422
+ #
423
+ def actions_after_shutdown
424
+ ref_call :get_actions_after_shutdown
425
+ end
426
+
427
+ #
428
+ # xen-api: VM.get_pv_kernel
429
+ #
430
+ def pv_kernel
431
+ ref_call :get_PV_kernel
432
+ end
433
+
434
+ #
435
+ # xen-api: VM.get_actions_after_reboot
436
+ #
437
+ def actions_after_reboot
438
+ ref_call :get_actions_after_reboot
439
+ end
440
+
441
+ #
442
+ # xen-api: VM.get_actions_after_crash
443
+ #
444
+ def actions_after_crash
445
+ ref_call :get_actions_after_crash
446
+ end
447
+
448
+ def to_s
449
+ eol = "\n"
450
+ "Label: #{label}" + eol +
451
+ "UUID: #{uuid}" + eol +
452
+ "Power State: #{power_state}" + eol +
453
+ "Mem: #{Util::humanize_bytes(dyn_min_mem)}" + eol +
454
+ "Max Mem: #{Util::humanize_bytes(max_mem)}" + eol
455
+ end
456
+
457
+ end
458
+
459
+
460
+ #
461
+ # Metrics reported by the guest (from 'inside' the guest)
462
+ #
463
+ # xen-api: Class VM_guest_metrics
464
+ #
465
+ class VMGuestMetrics < XObject
466
+ def initialize(link, ref) #:nodoc:
467
+ super(link, ref)
468
+ @proxy_name = 'VM_guest_metrics'
469
+ end
470
+ end
471
+
472
+ #
473
+ # Metrics associated with a VM
474
+ #
475
+ # xen-api class: VM_metrics
476
+ #
477
+ class VMMetrics < XObject
478
+
479
+ def initialize(link, ref) #:nodoc:
480
+ super(link, ref)
481
+ @proxy_name = 'VM_metrics'
482
+ end
483
+
484
+ #
485
+ # xen-api: VM_metrics.get_memory_actual
486
+ #
487
+ def memory_actual
488
+ ref_call :get_memory_actual
489
+ end
490
+
491
+ #
492
+ # xen-api: VM_metrics.get_VCPUs_number
493
+ # Number of cpus assigned to the domU
494
+ #
495
+ def vcpus_number
496
+ ref_call :get_VCPUs_number
497
+ end
498
+
499
+ #
500
+ # xen-api: VM_metrics.get_VCPUs_utilisation
501
+ #
502
+ # returns a hash
503
+ # {
504
+ # cpu0 => utilisation,
505
+ # cpu1 => utilization,
506
+ # ...
507
+ # }
508
+ #
509
+ def vcpus_utilisation
510
+ ref_call :get_VCPUs_utilisation
511
+ end
512
+
513
+ #
514
+ # xen-api: VM_metrics.get_state
515
+ #
516
+ def state
517
+ ref_call :get_state
518
+ end
519
+
520
+ #
521
+ # xen-api: VM_metrics.get_start_time
522
+ #
523
+ def start_time
524
+ (ref_call :get_start_time).to_time
525
+ end
526
+
527
+ #
528
+ # xen-api: VM_metrics.get_last_updated
529
+ #
530
+ def last_updated
531
+ (ref_call :get_last_updated).to_time
532
+ end
533
+
534
+ def to_s
535
+ vcpu_u = ""
536
+ vcpus_utilisation.each do |k, v|
537
+ vcpu_u += "#{k}: %0.2f\n" % (v * 100)
538
+ end
539
+ eol = "\n"
540
+ "[VM Metrics]" + eol +
541
+ "State: #{state}" + eol +
542
+ "Start Time: #{start_time}" + eol +
543
+ "Last Updated: #{last_updated}" + eol +
544
+ "VCPUs Utilisation:" + eol +
545
+ vcpu_u
546
+ end
547
+ end
548
+
549
+ class VIF < XObject
550
+
551
+ def initialize(link, ref) #:nodoc:
552
+ super(link, ref)
553
+ @proxy_name = 'VIF'
554
+ end
555
+
556
+ #
557
+ # xen-api: VIF.get_device
558
+ #
559
+ def device
560
+ ref_call :get_device
561
+ end
562
+
563
+ #
564
+ # xen-api: VIF.get_MAC
565
+ #
566
+ def mac
567
+ ref_call :get_MAC
568
+ end
569
+
570
+ #
571
+ # xen-api: VIF.get_metrics
572
+ #
573
+ def metrics
574
+ VIFMetrics.new(@link, ref_call(:get_metrics))
575
+ end
576
+
577
+ #
578
+ # xen-api: VIF.get_vm
579
+ #
580
+ def vm
581
+ VM.new(@link, ref_call(:get_VM))
582
+ end
583
+
584
+ #
585
+ # xen-api: VIF.get_network
586
+ # FIXME
587
+ #
588
+ #def network
589
+ # Network.new(@link, ref_call(:get_network), @link.client.proxy('network'))
590
+ #end
591
+
592
+ end
593
+
594
+ #
595
+ # Metrics associated with a virtual network device
596
+ #
597
+ # xen-api: Class VIF_metrics
598
+ #
599
+ class VIFMetrics < XObject
600
+
601
+ def initialize(link, ref) #:nodoc:
602
+ super(link, ref)
603
+ @proxy_name = 'VIF_metrics'
604
+ end
605
+
606
+ #
607
+ # VIF input Kbits/s
608
+ #
609
+ # xen-api: VIF_metrics.get_io_read_kbs
610
+ #
611
+ def io_read_kbs
612
+ ref_call :get_io_read_kbs
613
+ end
614
+
615
+ #
616
+ # VIF output Kbits/s
617
+ #
618
+ # xen-api: VIF_metrics.get_io_read_kbs
619
+ #
620
+ def io_write_kbs
621
+ ref_call :get_io_write_kbs
622
+ end
623
+ end
624
+
625
+ class Network < XObject
626
+ def initialize(link, ref) #:nodoc:
627
+ super(link, ref)
628
+ @proxy_name = 'network'
629
+ end
630
+
631
+ def label
632
+ ref_call :get_name_label
633
+ end
634
+
635
+ #
636
+ # Returns a string or nil if the gateway is not
637
+ # defined.
638
+ #
639
+ # xen-api: network.get_default_gateway
640
+ #
641
+ def default_gateway
642
+ gw = ref_call :get_default_gateway
643
+ return nil if gw.strip.chomp.empty?
644
+ gw
645
+ end
646
+
647
+ #
648
+ # Returns a string or nil if the netmask is not
649
+ # defined.
650
+ #
651
+ # xen-api: network.get_default_netmask
652
+ #
653
+ def default_netmask
654
+ nm = ref_call :get_default_netmask
655
+ return nil if nm.strip.chomp.empty?
656
+ gw
657
+ end
658
+
659
+ #
660
+ # Virtual Interfaces bridged to the network bridge
661
+ #
662
+ # xen-api: network.get_VIFs
663
+ #
664
+ def vifs
665
+ l = []
666
+ ref_call(:get_VIFs).each do |ref|
667
+ l << VIF.new(@link, ref)
668
+ end
669
+ l
670
+ end
671
+
672
+ end
673
+
674
+ end # module Pangea
675
+