rubiojr-domctl 0.2.20090414130028
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 +11 -0
- data/Manifest.txt +24 -0
- data/README.txt +54 -0
- data/Rakefile +26 -0
- data/bin/domctl +86 -0
- data/domctl.gemspec +40 -0
- data/lib/domctl.rb +6 -0
- data/lib/domctl/commands.rb +11 -0
- data/lib/domctl/commands/cluster_nodes.rb +10 -0
- data/lib/domctl/commands/cpu_utilisation.rb +30 -0
- data/lib/domctl/commands/dom0_info.rb +35 -0
- data/lib/domctl/commands/domu_info.rb +55 -0
- data/lib/domctl/commands/farm_info.rb +24 -0
- data/lib/domctl/commands/help.rb +30 -0
- data/lib/domctl/commands/list_running.rb +58 -0
- data/lib/domctl/commands/locate_domu.rb +30 -0
- data/lib/domctl/commands/mem_info.rb +29 -0
- data/lib/domctl/commands/oldest_domus.rb +16 -0
- data/lib/domctl/commands/recent_domus.rb +16 -0
- data/lib/domctl/commands/show_vifs.rb +57 -0
- data/lib/domctl/config.rb +78 -0
- data/scripts/devrelease +4 -0
- data/scripts/newrelease +7 -0
- data/scripts/publish_release +4 -0
- metadata +108 -0
data/History.txt
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
=== 0.1 / 2009-04-03
|
2
|
+
|
3
|
+
* Initial release
|
4
|
+
* locate a domU within a group of Xen host (dom0)
|
5
|
+
* list the running domUs in a given host (dom0)
|
6
|
+
* list the VIFs from a given guest (domU)
|
7
|
+
|
8
|
+
=== 0.2 / 2009-04-14
|
9
|
+
|
10
|
+
* lots of new commands implemented
|
11
|
+
* bug fixes
|
data/Manifest.txt
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
History.txt
|
2
|
+
Manifest.txt
|
3
|
+
README.txt
|
4
|
+
Rakefile
|
5
|
+
bin/domctl
|
6
|
+
domctl.gemspec
|
7
|
+
lib/domctl.rb
|
8
|
+
lib/domctl/commands.rb
|
9
|
+
lib/domctl/commands/cluster_nodes.rb
|
10
|
+
lib/domctl/commands/cpu_utilisation.rb
|
11
|
+
lib/domctl/commands/dom0_info.rb
|
12
|
+
lib/domctl/commands/domu_info.rb
|
13
|
+
lib/domctl/commands/farm_info.rb
|
14
|
+
lib/domctl/commands/help.rb
|
15
|
+
lib/domctl/commands/list_running.rb
|
16
|
+
lib/domctl/commands/locate_domu.rb
|
17
|
+
lib/domctl/commands/mem_info.rb
|
18
|
+
lib/domctl/commands/oldest_domus.rb
|
19
|
+
lib/domctl/commands/recent_domus.rb
|
20
|
+
lib/domctl/commands/show_vifs.rb
|
21
|
+
lib/domctl/config.rb
|
22
|
+
scripts/devrelease
|
23
|
+
scripts/newrelease
|
24
|
+
scripts/publish_release
|
data/README.txt
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
= Xen Cluster Management Tool
|
2
|
+
|
3
|
+
* http://domctl.xen-fu.org
|
4
|
+
|
5
|
+
== DESCRIPTION:
|
6
|
+
|
7
|
+
Simple tool to manage a farm of Xen physical hosts.
|
8
|
+
|
9
|
+
It also serves as an example of Pangea xen-api ruby implementation (http://pangea.xen-fu.org)
|
10
|
+
|
11
|
+
== FEATURES/PROBLEMS:
|
12
|
+
|
13
|
+
* FEATURES
|
14
|
+
- not many
|
15
|
+
* PROBLEMS
|
16
|
+
- a few of them :D
|
17
|
+
|
18
|
+
== SYNOPSIS:
|
19
|
+
|
20
|
+
FIX (code sample of usage)
|
21
|
+
|
22
|
+
== REQUIREMENTS:
|
23
|
+
|
24
|
+
* Dependencies are pulled when installing the gem
|
25
|
+
|
26
|
+
== INSTALL:
|
27
|
+
|
28
|
+
gem source -a http://gems.xen-fu.org
|
29
|
+
gem install domctl
|
30
|
+
|
31
|
+
== LICENSE:
|
32
|
+
|
33
|
+
(The MIT License)
|
34
|
+
|
35
|
+
Copyright (c) 2009 FIX
|
36
|
+
|
37
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
38
|
+
a copy of this software and associated documentation files (the
|
39
|
+
'Software'), to deal in the Software without restriction, including
|
40
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
41
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
42
|
+
permit persons to whom the Software is furnished to do so, subject to
|
43
|
+
the following conditions:
|
44
|
+
|
45
|
+
The above copyright notice and this permission notice shall be
|
46
|
+
included in all copies or substantial portions of the Software.
|
47
|
+
|
48
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
49
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
50
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
51
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
52
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
53
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
54
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'rake'
|
2
|
+
$:.unshift(File.dirname(__FILE__) + "/lib")
|
3
|
+
require 'domctl'
|
4
|
+
require 'hoe'
|
5
|
+
|
6
|
+
Hoe.new('domctl', Domctl::VERSION) do |p|
|
7
|
+
p.name = "domctl"
|
8
|
+
p.author = "Sergio Rubio"
|
9
|
+
p.description = %q{Xen Cluster Management Tool}
|
10
|
+
p.email = 'sergio@rubio.name'
|
11
|
+
p.summary = "Manage a cluster of Xen hosts"
|
12
|
+
p.url = "http://github.com/rubiojr/domctl"
|
13
|
+
p.remote_rdoc_dir = '' # Release to root
|
14
|
+
p.extra_deps << [ "pangea","~> 0.1" ]
|
15
|
+
p.extra_deps << [ "term-ansicolor",">= 1.0" ]
|
16
|
+
p.developer('Sergio Rubio', 'sergio@rubio.name')
|
17
|
+
end
|
18
|
+
|
19
|
+
task :publish_dev_gem do
|
20
|
+
`scp pkg/*.gem xen-fu.org:~/dev.xen-fu.org/gems/`
|
21
|
+
`ssh xen-fu.org gem generate_index -d /home/rubiojr/dev.xen-fu.org/`
|
22
|
+
end
|
23
|
+
task :publish_gem do
|
24
|
+
`scp pkg/*.gem xen-fu.org:~/gems.xen-fu.org/gems/`
|
25
|
+
`ssh xen-fu.org gem generate_index -d /home/rubiojr/gems.xen-fu.org/`
|
26
|
+
end
|
data/bin/domctl
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
require 'rubygems'
|
3
|
+
require 'ostruct'
|
4
|
+
require 'term/ansicolor'
|
5
|
+
gem 'pangea', '~> 0.1'
|
6
|
+
require 'pangea'
|
7
|
+
|
8
|
+
begin
|
9
|
+
require "#{File.join(File.dirname(__FILE__), '../lib/domctl.rb')}"
|
10
|
+
rescue
|
11
|
+
require 'domctl'
|
12
|
+
end
|
13
|
+
require 'yaml'
|
14
|
+
|
15
|
+
include Domctl
|
16
|
+
|
17
|
+
DOMCTL_COMMANDS = {
|
18
|
+
:cpu_utilisation => {
|
19
|
+
:help => "domctl cpu_utilisation",
|
20
|
+
:proc => CpuUtilisationCommand
|
21
|
+
},
|
22
|
+
:farm_info => {
|
23
|
+
:help => "domctl farm_info",
|
24
|
+
:proc => FarmInfoCommand
|
25
|
+
},
|
26
|
+
:mem_info => {
|
27
|
+
:help => "domctl mem_info [host]",
|
28
|
+
:proc => MemInfoCommand
|
29
|
+
},
|
30
|
+
:locate_domu => {
|
31
|
+
:help => "domctl locate_domu <domU name>",
|
32
|
+
:proc => LocateDomuCommand
|
33
|
+
},
|
34
|
+
:list_running => {
|
35
|
+
:help => "domctl list_running <dom0|all>",
|
36
|
+
:proc => ListRunningCommand
|
37
|
+
},
|
38
|
+
:cluster_nodes => {
|
39
|
+
:help => "domctl cluster_nodes",
|
40
|
+
:proc => ClusterNodesCommand
|
41
|
+
},
|
42
|
+
:show_vifs => {
|
43
|
+
:help => "domctl show_vifs <domU>",
|
44
|
+
:proc => ShowVifsCommand
|
45
|
+
},
|
46
|
+
:domu_info => {
|
47
|
+
:help => "domctl domu_info <domU>",
|
48
|
+
:proc => DomuInfoCommand
|
49
|
+
},
|
50
|
+
:dom0_info => {
|
51
|
+
:help => "domctl dom0_info <dom0>",
|
52
|
+
:proc => Dom0InfoCommand
|
53
|
+
},
|
54
|
+
:recent_domus => {
|
55
|
+
:help => "domctl recent_domus",
|
56
|
+
:proc => RecentDomusCommand
|
57
|
+
},
|
58
|
+
:oldest_domus => {
|
59
|
+
:help => "domctl oldest_domus",
|
60
|
+
:proc => OldestDomusCommand
|
61
|
+
},
|
62
|
+
:version => {
|
63
|
+
:help => "domctl version",
|
64
|
+
:proc => Proc.new { puts Domctl::VERSION }
|
65
|
+
},
|
66
|
+
:help => {
|
67
|
+
:proc => HelpCommand
|
68
|
+
}
|
69
|
+
}
|
70
|
+
|
71
|
+
Domctl::Config.validate
|
72
|
+
command = ARGV.shift
|
73
|
+
if command.nil? or DOMCTL_COMMANDS[command.to_sym].nil?
|
74
|
+
HelpCommand.call
|
75
|
+
exit 1
|
76
|
+
end
|
77
|
+
begin
|
78
|
+
args = ARGV
|
79
|
+
DOMCTL_COMMANDS[command.to_sym][:args] = args
|
80
|
+
DOMCTL_COMMANDS[command.to_sym][:proc].call
|
81
|
+
rescue Exception => e
|
82
|
+
if not e.is_a? SystemExit
|
83
|
+
puts e.message
|
84
|
+
puts e.backtrace
|
85
|
+
end
|
86
|
+
end
|
data/domctl.gemspec
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = %q{domctl}
|
3
|
+
s.version = "0.2.20090414130028"
|
4
|
+
|
5
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
6
|
+
s.authors = ["Sergio RubioSergio Rubio"]
|
7
|
+
s.date = %q{2009-04-14}
|
8
|
+
s.default_executable = %q{domctl}
|
9
|
+
s.description = %q{Xen Cluster Management Tool}
|
10
|
+
s.email = %q{sergio@rubio.namesergio@rubio.name}
|
11
|
+
s.executables = ["domctl"]
|
12
|
+
s.extra_rdoc_files = ["History.txt", "Manifest.txt", "README.txt"]
|
13
|
+
s.files = ["History.txt", "Manifest.txt", "README.txt", "Rakefile", "bin/domctl", "domctl.gemspec", "lib/domctl.rb", "lib/domctl/commands.rb", "lib/domctl/commands/cluster_nodes.rb", "lib/domctl/commands/cpu_utilisation.rb", "lib/domctl/commands/dom0_info.rb", "lib/domctl/commands/domu_info.rb", "lib/domctl/commands/farm_info.rb", "lib/domctl/commands/help.rb", "lib/domctl/commands/list_running.rb", "lib/domctl/commands/locate_domu.rb", "lib/domctl/commands/mem_info.rb", "lib/domctl/commands/oldest_domus.rb", "lib/domctl/commands/recent_domus.rb", "lib/domctl/commands/show_vifs.rb", "lib/domctl/config.rb", "scripts/devrelease", "scripts/newrelease", "scripts/publish_release"]
|
14
|
+
s.has_rdoc = true
|
15
|
+
s.homepage = %q{http://github.com/rubiojr/domctl}
|
16
|
+
s.rdoc_options = ["--main", "README.txt"]
|
17
|
+
s.require_paths = ["lib"]
|
18
|
+
s.rubyforge_project = %q{domctl}
|
19
|
+
s.rubygems_version = %q{1.3.1}
|
20
|
+
s.summary = %q{Manage a cluster of Xen hosts}
|
21
|
+
|
22
|
+
if s.respond_to? :specification_version then
|
23
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
24
|
+
s.specification_version = 2
|
25
|
+
|
26
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
27
|
+
s.add_runtime_dependency(%q<pangea>, ["~> 0.1"])
|
28
|
+
s.add_runtime_dependency(%q<term-ansicolor>, [">= 1.0"])
|
29
|
+
s.add_development_dependency(%q<hoe>, [">= 1.12.1"])
|
30
|
+
else
|
31
|
+
s.add_dependency(%q<pangea>, ["~> 0.1"])
|
32
|
+
s.add_dependency(%q<term-ansicolor>, [">= 1.0"])
|
33
|
+
s.add_dependency(%q<hoe>, [">= 1.12.1"])
|
34
|
+
end
|
35
|
+
else
|
36
|
+
s.add_dependency(%q<pangea>, ["~> 0.1"])
|
37
|
+
s.add_dependency(%q<term-ansicolor>, [">= 1.0"])
|
38
|
+
s.add_dependency(%q<hoe>, [">= 1.12.1"])
|
39
|
+
end
|
40
|
+
end
|
data/lib/domctl.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
module Domctl
|
2
|
+
CpuUtilisationCommand = Proc.new do
|
3
|
+
puts "Gathering info..."
|
4
|
+
table = {}
|
5
|
+
Domctl::Config.each_host do |h|
|
6
|
+
table[h.label] = h.cpus.sort { |a,b| a.number <=> b.number }
|
7
|
+
end
|
8
|
+
cols = 0
|
9
|
+
rows = []
|
10
|
+
rc = 0
|
11
|
+
table = table.sort { |a,b| a[0] <=> b[0] }
|
12
|
+
table.each do |l,cpus|
|
13
|
+
cols = cpus.size if cpus.size > cols
|
14
|
+
r = Term::ANSIColor.bold("[#{l}]") + "\n"
|
15
|
+
cpus.each do |c|
|
16
|
+
r += ("%.2f" % (c.utilisation * 100)).ljust(8)
|
17
|
+
end
|
18
|
+
rows << r
|
19
|
+
end
|
20
|
+
header = ''
|
21
|
+
0.upto(cols - 1) do |i|
|
22
|
+
header += "CPU#{i}".ljust(8)
|
23
|
+
end
|
24
|
+
puts header
|
25
|
+
puts "-" * header.size
|
26
|
+
rows.each do |r|
|
27
|
+
puts r
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Domctl
|
2
|
+
################
|
3
|
+
# dom0_info
|
4
|
+
################
|
5
|
+
Dom0InfoCommand = Proc.new do
|
6
|
+
def print_dom0_info(h)
|
7
|
+
puts "Label: #{h.label}"
|
8
|
+
puts "Memory Free: #{Pangea::Util.humanize_bytes(h.metrics.memory_free)}"
|
9
|
+
puts "Resident VMs: #{h.resident_vms.size}"
|
10
|
+
puts "Scheduler Policy: #{h.sched_policy}"
|
11
|
+
puts "CPUs: #{h.cpus.size}"
|
12
|
+
puts "Xen Version: #{h.software_version['Xen']}"
|
13
|
+
puts "Arch: #{h.software_version['machine']}"
|
14
|
+
puts "Kernel Version: #{h.software_version['release']}"
|
15
|
+
print "CPUs: "
|
16
|
+
h.cpus.each do |c|
|
17
|
+
print "%.2f " % (c.utilisation * 100)
|
18
|
+
end
|
19
|
+
puts
|
20
|
+
end
|
21
|
+
dom0 = DOMCTL_COMMANDS[:dom0_info][:args][0]
|
22
|
+
if dom0.nil?
|
23
|
+
$stderr.puts DOMCTL_COMMANDS[:dom0_info][:help]
|
24
|
+
exit 1
|
25
|
+
end
|
26
|
+
dom0.strip.chomp!
|
27
|
+
settings = Domctl::Config.cluster_nodes[dom0]
|
28
|
+
begin
|
29
|
+
h = Pangea::Host.connect(settings['url'], settings['username'], settings['password'])
|
30
|
+
print_dom0_info(h)
|
31
|
+
rescue Exception
|
32
|
+
puts "Error connecting to host #{node}. Skipping."
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Domctl
|
2
|
+
################
|
3
|
+
# domu_info
|
4
|
+
################
|
5
|
+
DomuInfoCommand = Proc.new do
|
6
|
+
def print_vm_status(vm)
|
7
|
+
puts "Dom ID: #{vm.domid}"
|
8
|
+
puts "Max Mem: #{Pangea::Util::humanize_bytes(vm.dyn_max_mem)}"
|
9
|
+
puts "Min Mem: #{Pangea::Util::humanize_bytes(vm.dyn_min_mem)}"
|
10
|
+
puts "Power State: #{vm.power_state}"
|
11
|
+
puts "Resident On: #{vm.resident_on.label}"
|
12
|
+
puts "Actions:"
|
13
|
+
puts " after crash: #{vm.actions_after_crash}"
|
14
|
+
puts " after reboot: #{vm.actions_after_reboot}"
|
15
|
+
puts " after shutdown: #{vm.actions_after_shutdown}"
|
16
|
+
end
|
17
|
+
args = DOMCTL_COMMANDS[:domu_info][:args][0]
|
18
|
+
if args.nil?
|
19
|
+
$stderr.puts DOMCTL_COMMANDS[:domu_info][:help]
|
20
|
+
exit 1
|
21
|
+
end
|
22
|
+
args.strip.chomp!
|
23
|
+
found = false
|
24
|
+
# dom0:domU notation
|
25
|
+
if args =~ /^.*:.*$/
|
26
|
+
host, domu = args.split(':')
|
27
|
+
settings = Domctl::Config.cluster_nodes[host]
|
28
|
+
h = Pangea::Host.connect(settings['url'], settings['username'], settings['password'])
|
29
|
+
h.resident_vms.each do |vm|
|
30
|
+
if vm.label == domu
|
31
|
+
found = true
|
32
|
+
print_vm_status(vm)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
puts "DomU #{domu} not found in #{host}" if not found
|
36
|
+
else
|
37
|
+
domu = args
|
38
|
+
puts "Searching..."
|
39
|
+
Domctl::Config.cluster_nodes.each do |node, settings|
|
40
|
+
begin
|
41
|
+
h = Pangea::Host.connect(settings['url'], settings['username'], settings['password'])
|
42
|
+
rescue Exception
|
43
|
+
puts "Error connecting to host #{node}. Skipping."
|
44
|
+
end
|
45
|
+
h.resident_vms.each do |vm|
|
46
|
+
if vm.label == domu
|
47
|
+
found = true
|
48
|
+
print_vm_status(vm)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
puts "DomU #{domu} not found" if not found
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Domctl
|
2
|
+
################
|
3
|
+
# farm_info
|
4
|
+
# ##############
|
5
|
+
FarmInfoCommand = Proc.new do
|
6
|
+
puts "Gathering Info..."
|
7
|
+
Domctl::Config.each_host do |h|
|
8
|
+
puts h.label
|
9
|
+
puts "-------"
|
10
|
+
metrics = h.metrics
|
11
|
+
mfree = Pangea::Util.humanize_bytes(metrics.memory_free)
|
12
|
+
mtotal = Pangea::Util.humanize_bytes(metrics.memory_total)
|
13
|
+
puts "Resident VMs: #{h.resident_vms.size}"
|
14
|
+
puts "Mem Free: #{mfree} Mem Total: #{mtotal}"
|
15
|
+
cpus = h.cpus.sort { |a,b| a.number <=> b.number }
|
16
|
+
print "CPUs: "
|
17
|
+
cpus.each do |c|
|
18
|
+
print "%.2f " % (c.utilisation * 100)
|
19
|
+
end
|
20
|
+
puts
|
21
|
+
puts
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Domctl
|
2
|
+
################
|
3
|
+
# help
|
4
|
+
# ##############
|
5
|
+
HelpCommand = Proc.new do
|
6
|
+
puts """
|
7
|
+
domctl #{Domctl::VERSION}
|
8
|
+
|
9
|
+
Usage: #{File.basename(__FILE__)} command [arguments...]
|
10
|
+
|
11
|
+
Available commands:
|
12
|
+
|
13
|
+
help print this help or the help associated
|
14
|
+
to a command
|
15
|
+
list_running list all running domUs in the specified dom0
|
16
|
+
locate_domu find the dom0 hosting the specified domU
|
17
|
+
show_vifs list the VIFs from a given domU
|
18
|
+
domu_info print DomU info
|
19
|
+
dom0_info print Dom0 info
|
20
|
+
recent_domus print the last 10 domus created
|
21
|
+
oldest_domus print the first 10 domus created
|
22
|
+
mem_info print the memory available in a host
|
23
|
+
farm_info print statistics from all the Hosts
|
24
|
+
cpu_utilisation CPU utilisation from all the Hosts
|
25
|
+
|
26
|
+
Type domctl help <command> to get specific command help.
|
27
|
+
|
28
|
+
"""
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Domctl
|
2
|
+
################
|
3
|
+
# list_running
|
4
|
+
# ##############
|
5
|
+
ListRunningCommand = Proc.new do
|
6
|
+
node = DOMCTL_COMMANDS[:list_running][:args][0]
|
7
|
+
if node.nil?
|
8
|
+
$stderr.puts DOMCTL_COMMANDS[:list_running][:help]
|
9
|
+
exit 1
|
10
|
+
end
|
11
|
+
if node == 'all'
|
12
|
+
Domctl::Config.each_host do |h|
|
13
|
+
puts
|
14
|
+
header = 'label'.ljust(30) + 'memory'.ljust(15) + 'power state'.ljust(15) + 'cpus'
|
15
|
+
puts "[#{h.label}]".rjust(header.size)
|
16
|
+
puts header
|
17
|
+
puts "-" * header.size
|
18
|
+
h.resident_vms.each do |vm|
|
19
|
+
label = vm.label
|
20
|
+
next if vm.is_control_domain?
|
21
|
+
print "#{label}".ljust(30)
|
22
|
+
metrics = vm.metrics
|
23
|
+
m = Pangea::Util.humanize_bytes(metrics.memory_actual)
|
24
|
+
print m.ljust(15)
|
25
|
+
print vm.power_state.to_s.ljust(15)
|
26
|
+
print metrics.vcpus_number
|
27
|
+
puts
|
28
|
+
end
|
29
|
+
end
|
30
|
+
else
|
31
|
+
if not Domctl::Config.node_defined?(node)
|
32
|
+
$stderr.puts "ERROR: Xen host not defined in #{Domctl::Config.config_file}"
|
33
|
+
exit 1
|
34
|
+
end
|
35
|
+
settings = Domctl::Config.cluster_nodes[node]
|
36
|
+
begin
|
37
|
+
h = Pangea::Host.connect(settings['url'], settings['username'], settings['password'])
|
38
|
+
header = 'label'.ljust(30) + 'memory'.ljust(15) + 'power state'.ljust(15) + 'cpus'
|
39
|
+
puts header
|
40
|
+
puts "-" * header.size
|
41
|
+
h.resident_vms.each do |vm|
|
42
|
+
label = vm.label
|
43
|
+
next if vm.is_control_domain?
|
44
|
+
print "#{label}".ljust(30)
|
45
|
+
metrics = vm.metrics
|
46
|
+
m = Pangea::Util.humanize_bytes(metrics.memory_actual)
|
47
|
+
print m.ljust(15)
|
48
|
+
print vm.power_state.to_s.ljust(15)
|
49
|
+
print metrics.vcpus_number
|
50
|
+
puts
|
51
|
+
end
|
52
|
+
rescue Exception => e
|
53
|
+
puts e.message
|
54
|
+
puts "Error connecting to host #{node}. Skipping."
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Domctl
|
2
|
+
################
|
3
|
+
# locate_domu
|
4
|
+
# ##############
|
5
|
+
LocateDomuCommand = Proc.new do
|
6
|
+
domus = []
|
7
|
+
args = DOMCTL_COMMANDS[:locate_domu][:args]
|
8
|
+
if args.nil?
|
9
|
+
$stderr.puts DOMCTL_COMMANDS[:locate_domu][:help]
|
10
|
+
exit 1
|
11
|
+
end
|
12
|
+
print "Searching"
|
13
|
+
Domctl::Config.cluster_nodes.sort.each do |node, settings|
|
14
|
+
begin
|
15
|
+
h = Pangea::Host.connect(settings['url'], settings['username'], settings['password'])
|
16
|
+
rescue Exception
|
17
|
+
puts "Error connecting to host #{node}. Skipping."
|
18
|
+
end
|
19
|
+
h.resident_vms.each do |vm|
|
20
|
+
if vm.label =~ /^.*#{args}.*$/
|
21
|
+
domus << "#{node}: #{vm.label}"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
print '.'
|
25
|
+
end
|
26
|
+
puts
|
27
|
+
puts " Not found." if domus.empty?
|
28
|
+
domus.each { |d| puts d }
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Domctl
|
2
|
+
################
|
3
|
+
# mem_info
|
4
|
+
# ##############
|
5
|
+
MemInfoCommand = Proc.new do
|
6
|
+
node = DOMCTL_COMMANDS[:mem_info][:args][0]
|
7
|
+
if node.nil?
|
8
|
+
Domctl::Config.each_host do |h|
|
9
|
+
mfree = Pangea::Util.humanize_bytes(h.metrics.memory_free)
|
10
|
+
mtotal = Pangea::Util.humanize_bytes(h.metrics.memory_total)
|
11
|
+
print "#{h.label}".ljust(30)
|
12
|
+
print "#{mfree} free".ljust(15)
|
13
|
+
puts "#{mtotal} available"
|
14
|
+
end
|
15
|
+
else
|
16
|
+
settings = Domctl::Config.cluster_nodes[node]
|
17
|
+
begin
|
18
|
+
h = Pangea::Host.connect(settings['url'], settings['username'], settings['password'])
|
19
|
+
mfree = Pangea::Util.humanize_bytes(h.metrics.memory_free)
|
20
|
+
mtotal = Pangea::Util.humanize_bytes(h.metrics.memory_total)
|
21
|
+
print "#{h.label}".ljust(30)
|
22
|
+
print "#{mfree} free".ljust(15)
|
23
|
+
puts "#{mtotal} available"
|
24
|
+
rescue Exception
|
25
|
+
puts "Error connecting to host #{node}. Skipping."
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Domctl
|
2
|
+
OldestDomusCommand = Proc.new do
|
3
|
+
oldest = []
|
4
|
+
print 'Working '
|
5
|
+
Domctl::Config.each_host do |h|
|
6
|
+
print '.'
|
7
|
+
h.resident_vms.each do |vm|
|
8
|
+
oldest << [vm.label, vm.metrics.start_time] if vm.label != 'Domain-0'
|
9
|
+
end
|
10
|
+
end
|
11
|
+
puts ' done.'
|
12
|
+
oldest.sort { |a,b| a[1] <=> b[1] }[0..9].each do |label, date|
|
13
|
+
puts "#{label}".ljust(30) + date.to_s
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Domctl
|
2
|
+
RecentDomusCommand = Proc.new do
|
3
|
+
recent = []
|
4
|
+
print 'Working '
|
5
|
+
Domctl::Config.each_host do |h|
|
6
|
+
print '.'
|
7
|
+
h.resident_vms.each do |vm|
|
8
|
+
recent << [vm.label, vm.metrics.start_time] if vm.label != 'Domain-0'
|
9
|
+
end
|
10
|
+
end
|
11
|
+
puts ' done.'
|
12
|
+
recent.sort { |a,b| a[1] <=> b[1] }[-10..-1].each do |label, date|
|
13
|
+
puts "#{label}".ljust(30) + date.to_s
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Domctl
|
2
|
+
################
|
3
|
+
# show_vifs
|
4
|
+
# ##############
|
5
|
+
ShowVifsCommand = Proc.new do
|
6
|
+
def print_vif(vif)
|
7
|
+
puts "Device: #{vif.device}"
|
8
|
+
puts "MAC Address: #{vif.mac}"
|
9
|
+
metrics = vif.metrics
|
10
|
+
puts "KBits/s IN: #{metrics.io_read_kbs}"
|
11
|
+
puts "KBits/s OUT: #{metrics.io_write_kbs}"
|
12
|
+
end
|
13
|
+
found = false
|
14
|
+
args = DOMCTL_COMMANDS[:show_vifs][:args][0]
|
15
|
+
if args.nil?
|
16
|
+
$stderr.puts DOMCTL_COMMANDS[:show_vifs][:help]
|
17
|
+
exit 1
|
18
|
+
end
|
19
|
+
if args =~ /^.*:.*$/
|
20
|
+
host, domu = args.split(':')
|
21
|
+
Domctl::Config.exit_if_not_defined(host)
|
22
|
+
settings = Domctl::Config.cluster_nodes[host]
|
23
|
+
h = Pangea::Host.connect(settings['url'], settings['username'], settings['password'])
|
24
|
+
h.resident_vms.each do |vm|
|
25
|
+
if vm.label == domu
|
26
|
+
found = true
|
27
|
+
puts "#{vm.label}"
|
28
|
+
puts "------------------"
|
29
|
+
vm.vifs.each do |vif|
|
30
|
+
print_vif(vif)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
puts "DomU #{domu} not found in #{host}" if not found
|
35
|
+
else
|
36
|
+
puts "Searching..."
|
37
|
+
Domctl::Config.cluster_nodes.each do |node, settings|
|
38
|
+
begin
|
39
|
+
h = Pangea::Host.connect(settings['url'], settings['username'], settings['password'])
|
40
|
+
rescue Exception
|
41
|
+
puts "Error connecting to host #{node}. Skipping."
|
42
|
+
end
|
43
|
+
h.resident_vms.each do |vm|
|
44
|
+
if vm.label == args
|
45
|
+
found = true
|
46
|
+
puts "#{vm.label}"
|
47
|
+
puts "------------------"
|
48
|
+
vm.vifs.each do |vif|
|
49
|
+
print_vif(vif)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
puts "#{args} not found." if not found
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module Domctl
|
2
|
+
class Config
|
3
|
+
def self.cluster_nodes
|
4
|
+
yaml = YAML.load_file(self.config_file)
|
5
|
+
yaml['cluster']
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.validate
|
9
|
+
if not File.exist?(self.config_file)
|
10
|
+
self.create_sample_config
|
11
|
+
$stderr.puts
|
12
|
+
$stderr.puts "domctl config file does not exist.\n"
|
13
|
+
$stderr.puts "I have created an example one for you (#{config_file}). Configure it first."
|
14
|
+
$stderr.puts
|
15
|
+
exit 1
|
16
|
+
end
|
17
|
+
yaml = YAML.load_file(self.config_file)
|
18
|
+
if not yaml or yaml['cluster'].nil? or not yaml['cluster'].is_a?(Hash)
|
19
|
+
$stderr.puts
|
20
|
+
$stderr.puts "Invalid config file found.\n"
|
21
|
+
$stderr.puts
|
22
|
+
exit 1
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.create_sample_config
|
27
|
+
if not File.exist?(self.config_file)
|
28
|
+
File.open(self.config_file, 'w') do |f|
|
29
|
+
cfg = { 'cluster' => {
|
30
|
+
'xen0' => {
|
31
|
+
'url' => 'http://xen0.example.net:9363',
|
32
|
+
'username' => 'foo',
|
33
|
+
'password' => 'bar'
|
34
|
+
},
|
35
|
+
'xen1' => {
|
36
|
+
'url' => 'http://xen1.example.net:9363',
|
37
|
+
'username' => 'foo',
|
38
|
+
'password' => 'bar'
|
39
|
+
}
|
40
|
+
}
|
41
|
+
}
|
42
|
+
YAML.dump(cfg, f)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.each_host
|
48
|
+
cluster_nodes.sort.each do |node, settings|
|
49
|
+
begin
|
50
|
+
h = Pangea::Host.connect(settings['url'], settings['username'], settings['password'])
|
51
|
+
yield h
|
52
|
+
rescue Exception
|
53
|
+
puts "Error connecting to host #{node}. Skipping."
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.exit_if_not_defined(node)
|
59
|
+
settings = Domctl::Config.cluster_nodes[node]
|
60
|
+
if settings.nil?
|
61
|
+
$stderr.puts "ERROR: Xen host not defined in #{Domctl::Config.config_file}"
|
62
|
+
exit 1
|
63
|
+
end
|
64
|
+
end
|
65
|
+
def self.node_defined?(node)
|
66
|
+
settings = Domctl::Config.cluster_nodes[node]
|
67
|
+
if settings.nil?
|
68
|
+
return false
|
69
|
+
end
|
70
|
+
true
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.config_file
|
74
|
+
"#{ENV['HOME']}/.domctlrc"
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
end
|
data/scripts/devrelease
ADDED
data/scripts/newrelease
ADDED
metadata
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rubiojr-domctl
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.20090414130028
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Sergio RubioSergio Rubio
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-04-14 00:00:00 -07:00
|
13
|
+
default_executable: domctl
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: pangea
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ~>
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0.1"
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: term-ansicolor
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: "1.0"
|
34
|
+
version:
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: hoe
|
37
|
+
type: :development
|
38
|
+
version_requirement:
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 1.12.1
|
44
|
+
version:
|
45
|
+
description: Xen Cluster Management Tool
|
46
|
+
email: sergio@rubio.namesergio@rubio.name
|
47
|
+
executables:
|
48
|
+
- domctl
|
49
|
+
extensions: []
|
50
|
+
|
51
|
+
extra_rdoc_files:
|
52
|
+
- History.txt
|
53
|
+
- Manifest.txt
|
54
|
+
- README.txt
|
55
|
+
files:
|
56
|
+
- History.txt
|
57
|
+
- Manifest.txt
|
58
|
+
- README.txt
|
59
|
+
- Rakefile
|
60
|
+
- bin/domctl
|
61
|
+
- domctl.gemspec
|
62
|
+
- lib/domctl.rb
|
63
|
+
- lib/domctl/commands.rb
|
64
|
+
- lib/domctl/commands/cluster_nodes.rb
|
65
|
+
- lib/domctl/commands/cpu_utilisation.rb
|
66
|
+
- lib/domctl/commands/dom0_info.rb
|
67
|
+
- lib/domctl/commands/domu_info.rb
|
68
|
+
- lib/domctl/commands/farm_info.rb
|
69
|
+
- lib/domctl/commands/help.rb
|
70
|
+
- lib/domctl/commands/list_running.rb
|
71
|
+
- lib/domctl/commands/locate_domu.rb
|
72
|
+
- lib/domctl/commands/mem_info.rb
|
73
|
+
- lib/domctl/commands/oldest_domus.rb
|
74
|
+
- lib/domctl/commands/recent_domus.rb
|
75
|
+
- lib/domctl/commands/show_vifs.rb
|
76
|
+
- lib/domctl/config.rb
|
77
|
+
- scripts/devrelease
|
78
|
+
- scripts/newrelease
|
79
|
+
- scripts/publish_release
|
80
|
+
has_rdoc: true
|
81
|
+
homepage: http://github.com/rubiojr/domctl
|
82
|
+
post_install_message:
|
83
|
+
rdoc_options:
|
84
|
+
- --main
|
85
|
+
- README.txt
|
86
|
+
require_paths:
|
87
|
+
- lib
|
88
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
89
|
+
requirements:
|
90
|
+
- - ">="
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: "0"
|
93
|
+
version:
|
94
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
95
|
+
requirements:
|
96
|
+
- - ">="
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: "0"
|
99
|
+
version:
|
100
|
+
requirements: []
|
101
|
+
|
102
|
+
rubyforge_project: domctl
|
103
|
+
rubygems_version: 1.2.0
|
104
|
+
signing_key:
|
105
|
+
specification_version: 2
|
106
|
+
summary: Manage a cluster of Xen hosts
|
107
|
+
test_files: []
|
108
|
+
|