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.
- 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
|