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 ADDED
@@ -0,0 +1,4 @@
1
+ === 0.1 / 2008-04-01
2
+
3
+ * Initial pangea release
4
+ * read-only operations implemented
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
@@ -0,0 +1,11 @@
1
+ def ask_host
2
+ host_url = ARGV[0]
3
+
4
+ if host_url.nil? or host_url !~ /http:\/\/.*$/
5
+ puts "Usage: #{$0} <xen-api server url>"
6
+ puts
7
+ puts "Example: #{$0} http://xen.example.net:9363"
8
+ exit
9
+ end
10
+ return host_url
11
+ end
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,8 @@
1
+ module Pangea
2
+ module Memoizers #:nodoc:all
3
+ module DumbMemoizer
4
+ def memoize(method_name, p={})
5
+ end
6
+ end
7
+ end
8
+ 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,14 @@
1
+ module Pangea #:nodoc:
2
+ module Memoizers
3
+
4
+ def self.strategy=(mod)
5
+ puts "using memoizing strategy #{mod}"
6
+ @strategy = mod
7
+ end
8
+
9
+ def self.strategy
10
+ @strategy || Pangea::Memoizers::DumbMemoizer
11
+ end
12
+
13
+ end
14
+ 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