rubiojr-pangea 0.1.20090403134419
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +4 -0
- data/Manifest.txt +30 -0
- data/README.txt +64 -0
- data/Rakefile +31 -0
- data/examples/base.rb +11 -0
- data/examples/host.rb +37 -0
- data/examples/host_cpu.rb +21 -0
- data/examples/host_metrics.rb +18 -0
- data/examples/vif.rb +26 -0
- data/examples/vm.rb +25 -0
- data/lib/memoizers/dumb_memoizer.rb +8 -0
- data/lib/memoizers/simple_memoizer.rb +40 -0
- data/lib/memoizers/strategy.rb +14 -0
- data/lib/memoizers/timed_memoizer.rb +40 -0
- data/lib/pangea.rb +9 -0
- data/lib/pangea/cluster.rb +46 -0
- data/lib/pangea/exceptions.rb +6 -0
- data/lib/pangea/objects.rb +675 -0
- data/lib/util/string.rb +15 -0
- data/pangea.gemspec +36 -0
- data/scripts/newrelease +6 -0
- data/scripts/publish_release +4 -0
- data/test/config.rb +1 -0
- data/test/suite.rb +19 -0
- data/test/test_network.rb +43 -0
- data/test/test_pangea.rb +23 -0
- data/test/test_vif.rb +59 -0
- data/test/test_vif_metrics.rb +35 -0
- data/test/test_vm.rb +71 -0
- data/test/test_vm_metrics.rb +17 -0
- metadata +109 -0
data/History.txt
ADDED
data/Manifest.txt
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
History.txt
|
2
|
+
Manifest.txt
|
3
|
+
README.txt
|
4
|
+
Rakefile
|
5
|
+
examples/base.rb
|
6
|
+
examples/host.rb
|
7
|
+
examples/host_cpu.rb
|
8
|
+
examples/host_metrics.rb
|
9
|
+
examples/vif.rb
|
10
|
+
examples/vm.rb
|
11
|
+
lib/memoizers/dumb_memoizer.rb
|
12
|
+
lib/memoizers/simple_memoizer.rb
|
13
|
+
lib/memoizers/strategy.rb
|
14
|
+
lib/memoizers/timed_memoizer.rb
|
15
|
+
lib/pangea.rb
|
16
|
+
lib/pangea/cluster.rb
|
17
|
+
lib/pangea/exceptions.rb
|
18
|
+
lib/pangea/objects.rb
|
19
|
+
lib/util/string.rb
|
20
|
+
pangea.gemspec
|
21
|
+
scripts/newrelease
|
22
|
+
scripts/publish_release
|
23
|
+
test/config.rb
|
24
|
+
test/suite.rb
|
25
|
+
test/test_network.rb
|
26
|
+
test/test_pangea.rb
|
27
|
+
test/test_vif.rb
|
28
|
+
test/test_vif_metrics.rb
|
29
|
+
test/test_vm.rb
|
30
|
+
test/test_vm_metrics.rb
|
data/README.txt
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
= Pangea 0.1
|
2
|
+
|
3
|
+
* http://www.xen-fu.org/blog
|
4
|
+
|
5
|
+
== DESCRIPTION:
|
6
|
+
|
7
|
+
Xen-Api Ruby Implementation
|
8
|
+
|
9
|
+
== FEATURES/PROBLEMS:
|
10
|
+
|
11
|
+
* Read-only operations implemented ATM
|
12
|
+
* Needs documentation
|
13
|
+
* Add more examples
|
14
|
+
* API is subject to change till we reach 1.0
|
15
|
+
|
16
|
+
== SYNOPSIS:
|
17
|
+
|
18
|
+
require 'rubygems'
|
19
|
+
|
20
|
+
require 'pangea'
|
21
|
+
|
22
|
+
host = Pangea::Host.connect('http://xen.example.net:9363', 'foo', 'bar')
|
23
|
+
|
24
|
+
host.resident_vms.each do |vm|
|
25
|
+
# do something with the Pangea::VM object
|
26
|
+
end
|
27
|
+
|
28
|
+
host.networks.each do |net|
|
29
|
+
# do something with the Pangea::Network object
|
30
|
+
end
|
31
|
+
|
32
|
+
== REQUIREMENTS:
|
33
|
+
|
34
|
+
* Ruby1.8.7 is required (XObject.ref_call doesn't work in ruby1.8.6
|
35
|
+
|
36
|
+
== INSTALL:
|
37
|
+
|
38
|
+
* gem source -a \http://gems.xen-fu.org
|
39
|
+
* gem install pangea
|
40
|
+
|
41
|
+
== LICENSE:
|
42
|
+
|
43
|
+
(The MIT License)
|
44
|
+
|
45
|
+
Copyright (c) 2008 FIX
|
46
|
+
|
47
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
48
|
+
a copy of this software and associated documentation files (the
|
49
|
+
'Software'), to deal in the Software without restriction, including
|
50
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
51
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
52
|
+
permit persons to whom the Software is furnished to do so, subject to
|
53
|
+
the following conditions:
|
54
|
+
|
55
|
+
The above copyright notice and this permission notice shall be
|
56
|
+
included in all copies or substantial portions of the Software.
|
57
|
+
|
58
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
59
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
60
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
61
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
62
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
63
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
64
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'rake'
|
2
|
+
$:.unshift(File.dirname(__FILE__) + "/lib")
|
3
|
+
require 'pangea'
|
4
|
+
require 'hoe'
|
5
|
+
|
6
|
+
Hoe.new('Pangea', Pangea::VERSION) do |p|
|
7
|
+
p.name = "pangea"
|
8
|
+
p.author = "Sergio Rubio"
|
9
|
+
p.description = %q{Xen-API Ruby Implementation}
|
10
|
+
p.email = 'sergio@rubio.name'
|
11
|
+
p.summary = "Ruby Xen API"
|
12
|
+
p.url = "http://github.com/rubiojr/pangea"
|
13
|
+
#p.clean_globs = ['test/output/*.png']
|
14
|
+
#p.changes = p.paragraphs_of('CHANGELOG', 0..1).join("\n\n")
|
15
|
+
p.remote_rdoc_dir = '' # Release to root
|
16
|
+
p.extra_deps << [ "term-ansicolor",">= 1.0" ]
|
17
|
+
p.developer('Sergio Rubio', 'sergio@rubio.name')
|
18
|
+
end
|
19
|
+
|
20
|
+
task :publish_gem do
|
21
|
+
`scp pkg/*.gem xen-fu.org:~/gems.xen-fu.org/gems/`
|
22
|
+
`ssh xen-fu.org gem generate_index -d /home/rubiojr/gems.xen-fu.org/`
|
23
|
+
end
|
24
|
+
task :upload_docs do
|
25
|
+
`rsync --delete -rtlz doc/ xen-fu.org:~/xen-fu.org/pangea/doc/`
|
26
|
+
end
|
27
|
+
task :upload_edge_docs do
|
28
|
+
`rsync --delete -rtlz doc/ xen-fu.org:~/xen-fu.org/pangea-edge/doc/`
|
29
|
+
end
|
30
|
+
task :docs_all => [:redocs, :upload_docs, :upload_edge_docs] do
|
31
|
+
end
|
data/examples/base.rb
ADDED
data/examples/host.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
begin
|
3
|
+
require '../lib/pangea'
|
4
|
+
rescue
|
5
|
+
require 'pangea'
|
6
|
+
end
|
7
|
+
# cmdline helper
|
8
|
+
require "#{File.join(File.dirname(__FILE__), 'base.rb')}"
|
9
|
+
# from base.rb
|
10
|
+
host_url = ask_host
|
11
|
+
|
12
|
+
host = Pangea::Host.connect(host_url, 'foo', 'bar')
|
13
|
+
|
14
|
+
puts "******* HOST DETAILS *******"
|
15
|
+
# host unique identifier
|
16
|
+
puts "UUID: #{host.uuid}"
|
17
|
+
# is the host (dom0) alive?
|
18
|
+
puts "Alive?: #{host.alive?}"
|
19
|
+
# get the hostname
|
20
|
+
puts "Hostname: #{host.label}"
|
21
|
+
puts "Memory Free: #{host.metrics.memory_free}"
|
22
|
+
puts "CPUs: #{host.cpus.size}"
|
23
|
+
puts "Xen Version: #{host.software_version['Xen']}"
|
24
|
+
puts "Arch: #{host.software_version['machine']}"
|
25
|
+
puts "Kernel Version: #{host.software_version['release']}"
|
26
|
+
|
27
|
+
# list all the domUs
|
28
|
+
puts "******* RESIDENT VMs *******"
|
29
|
+
host.resident_vms.each do |vm|
|
30
|
+
puts vm.label
|
31
|
+
end
|
32
|
+
|
33
|
+
# list all the networks
|
34
|
+
puts "******* NETWORKS *******"
|
35
|
+
host.networks.each do |net|
|
36
|
+
puts net.label
|
37
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
begin
|
3
|
+
require '../lib/pangea'
|
4
|
+
rescue
|
5
|
+
require 'pangea'
|
6
|
+
end
|
7
|
+
# cmdline helper
|
8
|
+
require "#{File.join(File.dirname(__FILE__), 'base.rb')}"
|
9
|
+
# from base.rb
|
10
|
+
host_url = ask_host
|
11
|
+
|
12
|
+
host = Pangea::Host.connect(host_url, 'foo', 'bar')
|
13
|
+
|
14
|
+
puts "Host CPUs"
|
15
|
+
host.cpus.each do |cpu|
|
16
|
+
puts "*** CPU #{cpu.number} ***"
|
17
|
+
puts "Speed: #{cpu.speed}"
|
18
|
+
puts "Vendor: #{cpu.vendor}"
|
19
|
+
puts "Model: #{cpu.model_name}"
|
20
|
+
puts "Utilisation: #{cpu.utilisation * 100} %"
|
21
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
begin
|
3
|
+
require '../lib/pangea'
|
4
|
+
rescue
|
5
|
+
require 'pangea'
|
6
|
+
end
|
7
|
+
# cmdline helper
|
8
|
+
require "#{File.join(File.dirname(__FILE__), 'base.rb')}"
|
9
|
+
# from base.rb
|
10
|
+
host_url = ask_host
|
11
|
+
|
12
|
+
host = Pangea::Host.connect(host_url, 'foo', 'bar')
|
13
|
+
metrics = host.metrics
|
14
|
+
|
15
|
+
puts "Metrics for #{host.label}"
|
16
|
+
# Pange::Util.humanize_bytes translate bytes to MB, GB, TB...
|
17
|
+
puts "Total Memory: #{Pangea::Util.humanize_bytes( metrics.memory_total )}"
|
18
|
+
puts "Free Memory: #{Pangea::Util.humanize_bytes( metrics.memory_free )}"
|
data/examples/vif.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
begin
|
3
|
+
require '../lib/pangea'
|
4
|
+
rescue
|
5
|
+
require 'pangea'
|
6
|
+
end
|
7
|
+
# cmdline helper
|
8
|
+
require "#{File.join(File.dirname(__FILE__), 'base.rb')}"
|
9
|
+
# from base.rb
|
10
|
+
host_url = ask_host
|
11
|
+
|
12
|
+
host = Pangea::Host.connect(host_url, 'foo', 'bar')
|
13
|
+
|
14
|
+
# skip if only one VM available (Dom0)
|
15
|
+
if host.resident_vms.size > 1
|
16
|
+
vm = host.resident_vms[1]
|
17
|
+
puts "VM Label: #{vm.label}"
|
18
|
+
vm.vifs.each do |vif|
|
19
|
+
puts "Device: #{vif.device}"
|
20
|
+
puts "MAC Address: " + vif.mac
|
21
|
+
metrics = vif.metrics
|
22
|
+
puts "Kbs Out: #{metrics.io_write_kbs}"
|
23
|
+
puts "Kbs In: #{metrics.io_read_kbs}"
|
24
|
+
puts "----"
|
25
|
+
end
|
26
|
+
end
|
data/examples/vm.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
begin
|
3
|
+
require '../lib/pangea'
|
4
|
+
rescue
|
5
|
+
require 'pangea'
|
6
|
+
end
|
7
|
+
# cmdline helper
|
8
|
+
require "#{File.join(File.dirname(__FILE__), 'base.rb')}"
|
9
|
+
# from base.rb
|
10
|
+
host_url = ask_host
|
11
|
+
|
12
|
+
host = Pangea::Host.connect(host_url, 'foo', 'bar')
|
13
|
+
|
14
|
+
host.resident_vms.each do |vm|
|
15
|
+
puts "**** VM #{vm.label} ****"
|
16
|
+
puts "On Crash: #{vm.actions_after_crash}"
|
17
|
+
puts "On Reboot: #{vm.actions_after_reboot}"
|
18
|
+
puts "Domain ID: #{vm.domid}"
|
19
|
+
puts "Current Memory: #{vm.dyn_min_mem}"
|
20
|
+
puts "Max Memory: #{vm.dyn_max_mem}"
|
21
|
+
puts "Power State: #{vm.power_state}"
|
22
|
+
puts "Virtual Interfaces: #{vm.vifs.size}"
|
23
|
+
puts "Host: #{vm.resident_on.label}"
|
24
|
+
puts
|
25
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Pangea #:nodoc:
|
2
|
+
module Memoizers #:nodoc:
|
3
|
+
#
|
4
|
+
# based on http://github.com/JackDanger/simple_memoize
|
5
|
+
#
|
6
|
+
module SimpleMemoizer
|
7
|
+
def memoize(method_name, p={})
|
8
|
+
method_name = method_name.to_s
|
9
|
+
stripped_method_name = method_name.sub(/([!?])$/, '')
|
10
|
+
|
11
|
+
punctuation = $1
|
12
|
+
wordy_punctuation = (punctuation == '!' ? '_bang' : '_huh') if punctuation
|
13
|
+
ivar_name = "@#{stripped_method_name}#{wordy_punctuation}"
|
14
|
+
|
15
|
+
memoized_method_name = "#{stripped_method_name}_with_timed_memo#{punctuation}"
|
16
|
+
regular_method_name = "#{stripped_method_name}_without_memo#{punctuation}"
|
17
|
+
|
18
|
+
unless (instance_methods + private_instance_methods).include?(method_name)
|
19
|
+
raise NoMethodError, "The Method '#{method_name}' cannot be memoized because it doesn't exist in #{self}"
|
20
|
+
end
|
21
|
+
return if self.method_defined?(memoized_method_name)
|
22
|
+
|
23
|
+
self.class_eval "
|
24
|
+
def #{memoized_method_name}(*args)
|
25
|
+
if defined?(#{ivar_name})
|
26
|
+
#{ivar_name}
|
27
|
+
else
|
28
|
+
#{ivar_name} = #{regular_method_name}(*args)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
alias_method :#{regular_method_name}, :#{method_name}
|
32
|
+
alias_method :#{method_name}, :#{memoized_method_name}
|
33
|
+
|
34
|
+
protected :#{method_name} if protected_instance_methods.include?('#{regular_method_name}')
|
35
|
+
private :#{method_name} if private_instance_methods.include?('#{regular_method_name}')
|
36
|
+
"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Pangea #:nodoc:
|
2
|
+
module Memoizers
|
3
|
+
module TimedMemoizer
|
4
|
+
def memoize(method_name, p={})
|
5
|
+
method_name = method_name.to_s
|
6
|
+
stripped_method_name = method_name.sub(/([!?])$/, '')
|
7
|
+
|
8
|
+
punctuation = $1
|
9
|
+
wordy_punctuation = (punctuation == '!' ? '_bang' : '_huh') if punctuation
|
10
|
+
ivar_name = "@#{stripped_method_name}#{wordy_punctuation}"
|
11
|
+
|
12
|
+
memoized_method_name = "#{stripped_method_name}_with_timed_memo#{punctuation}"
|
13
|
+
regular_method_name = "#{stripped_method_name}_without_memo#{punctuation}"
|
14
|
+
|
15
|
+
unless (instance_methods + private_instance_methods).include?(method_name)
|
16
|
+
raise NoMethodError, "The Method '#{method_name}' cannot be memoized because it doesn't exist in #{self}"
|
17
|
+
end
|
18
|
+
return if self.method_defined?(memoized_method_name)
|
19
|
+
|
20
|
+
self.class_eval "
|
21
|
+
@@refreshing_time = #{p[:refreshing_time] || 30}
|
22
|
+
def #{memoized_method_name}(*args)
|
23
|
+
if defined?(#{ivar_name}) and (Time.now - #{ivar_name}_tsample) < @@refreshing_time
|
24
|
+
#{ivar_name}
|
25
|
+
else
|
26
|
+
#{ivar_name}_tsample = Time.now
|
27
|
+
#{ivar_name} = #{regular_method_name}(*args)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
alias_method :#{regular_method_name}, :#{method_name}
|
31
|
+
alias_method :#{method_name}, :#{memoized_method_name}
|
32
|
+
|
33
|
+
protected :#{method_name} if protected_instance_methods.include?('#{regular_method_name}')
|
34
|
+
private :#{method_name} if private_instance_methods.include?('#{regular_method_name}')
|
35
|
+
"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
data/lib/pangea.rb
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
require 'xmlrpc/client'
|
2
|
+
require "#{File.join(File.dirname(__FILE__), 'util/string.rb')}"
|
3
|
+
require "#{File.join(File.dirname(__FILE__), 'pangea/objects.rb')}"
|
4
|
+
require "#{File.join(File.dirname(__FILE__), 'pangea/exceptions.rb')}"
|
5
|
+
|
6
|
+
module Pangea
|
7
|
+
VERSION = "0.1.20090403134419"
|
8
|
+
end # module Pangea
|
9
|
+
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Pangea
|
2
|
+
#
|
3
|
+
# A Xen Cluster is a group of Hosts
|
4
|
+
#
|
5
|
+
class Cluster #:nodoc:
|
6
|
+
|
7
|
+
def initialize(config={})
|
8
|
+
@index = {}
|
9
|
+
@config = config
|
10
|
+
@nodes = []
|
11
|
+
end
|
12
|
+
|
13
|
+
def [](name)
|
14
|
+
# initialize the node list
|
15
|
+
nodes if @index.empty?
|
16
|
+
@index[name]
|
17
|
+
end
|
18
|
+
|
19
|
+
# Deprecated, use Cluster.nodes
|
20
|
+
def hosts
|
21
|
+
puts "WARNING: Cluster.hosts is deprecated. Use Cluster.nodes instead"
|
22
|
+
nodes
|
23
|
+
end
|
24
|
+
|
25
|
+
#
|
26
|
+
# Returns the list of nodes in the Cluster
|
27
|
+
#
|
28
|
+
def nodes
|
29
|
+
return @nodes if (not @nodes.nil? and @nodes.size > 0)
|
30
|
+
init_nodes
|
31
|
+
@nodes
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
def init_nodes
|
36
|
+
@config.each_key do |n|
|
37
|
+
h = Host.connect(@config[n]['url'],
|
38
|
+
@config[n]['username'] || '',
|
39
|
+
@config[n]['password'] || ''
|
40
|
+
)
|
41
|
+
@index[h.label] = h
|
42
|
+
@nodes << h
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|