testlab 0.1.0 → 0.2.0
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/.gitignore +2 -0
- data/README.md +8 -0
- data/bin/tl +167 -0
- data/lib/testlab/container/actions.rb +21 -13
- data/lib/testlab/container/interface.rb +3 -14
- data/lib/testlab/container/lifecycle.rb +16 -0
- data/lib/testlab/container.rb +4 -1
- data/lib/testlab/network/actions.rb +12 -4
- data/lib/testlab/network.rb +3 -1
- data/lib/testlab/node/bind.rb +2 -0
- data/lib/testlab/node/lifecycle.rb +17 -6
- data/lib/testlab/node/ssh.rb +5 -1
- data/lib/testlab/node.rb +5 -1
- data/lib/testlab/providers/vagrant.rb +1 -1
- data/lib/testlab/provisioners/chef.rb +7 -1
- data/lib/testlab/provisioners/shell.rb +19 -2
- data/lib/testlab/utility.rb +2 -0
- data/lib/testlab/version.rb +1 -1
- data/lib/testlab.rb +17 -7
- data/testlab.gemspec +1 -0
- metadata +22 -6
- data/bin/testlab-console +0 -12
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -14,8 +14,16 @@ A framework for building lightweight virtual infrastructure using LXC
|
|
14
14
|
* Latest Vagrant Package (non-gem version)
|
15
15
|
* Ubuntu 13.04 Server 64-bit (Raring) Base Box - https://github.com/zpatten/raring64
|
16
16
|
|
17
|
+
# EXAMPLE USE
|
18
|
+
|
19
|
+
* See the `testlab-repo` - https://github.com/zpatten/testlab-repo
|
20
|
+
|
17
21
|
# RESOURCES
|
18
22
|
|
23
|
+
IRC:
|
24
|
+
|
25
|
+
* #jovelabs on irc.freenode.net
|
26
|
+
|
19
27
|
Documentation:
|
20
28
|
|
21
29
|
* http://zpatten.github.io/testlab/
|
data/bin/tl
ADDED
@@ -0,0 +1,167 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'gli'
|
3
|
+
require 'testlab'
|
4
|
+
|
5
|
+
include GLI::App
|
6
|
+
|
7
|
+
program_desc %(TestLab #{TestLab::VERSION} - A framework for building lightweight virtual infrastructure using LXC)
|
8
|
+
|
9
|
+
version Testlab::VERSION
|
10
|
+
|
11
|
+
# desc 'Describe some switch here'
|
12
|
+
# switch [:s,:switch]
|
13
|
+
|
14
|
+
# desc 'Describe some flag here'
|
15
|
+
# default_value 'the default'
|
16
|
+
# arg_name 'The name of the argument'
|
17
|
+
# flag [:f,:flagname]
|
18
|
+
|
19
|
+
# desc 'Manage the test lab'
|
20
|
+
# arg_name 'Describe arguments to lab here'
|
21
|
+
# command :lab do |c|
|
22
|
+
|
23
|
+
# # c.desc 'Describe a switch to lab'
|
24
|
+
# # c.switch :s
|
25
|
+
|
26
|
+
# # c.desc 'Describe a flag to lab'
|
27
|
+
# # c.default_value 'default'
|
28
|
+
# # c.flag :f
|
29
|
+
# # c.action do |global_options,options,args|
|
30
|
+
|
31
|
+
# # # Your command logic here
|
32
|
+
|
33
|
+
# # # If you have any errors, just raise them
|
34
|
+
# # # raise "that command made no sense"
|
35
|
+
|
36
|
+
# # puts "lab command ran"
|
37
|
+
# # end
|
38
|
+
# end
|
39
|
+
|
40
|
+
desc 'Create the test lab'
|
41
|
+
command :create do |create|
|
42
|
+
create.action do |global_options,options,args|
|
43
|
+
@testlab.create
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
desc 'Destroy the test lab'
|
48
|
+
command :destroy do |destroy|
|
49
|
+
destroy.action do |global_options,options,args|
|
50
|
+
@testlab.destroy
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
desc 'Online the test lab'
|
55
|
+
command :up do |up|
|
56
|
+
up.action do |global_options,options,args|
|
57
|
+
@testlab.up
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
desc 'Offline the test lab'
|
62
|
+
command :down do |down|
|
63
|
+
down.action do |global_options,options,args|
|
64
|
+
@testlab.down
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
desc 'Setup the test lab infrastructure'
|
69
|
+
command :setup do |setup|
|
70
|
+
setup.action do |global_options,options,args|
|
71
|
+
@testlab.setup
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
desc 'Teardown the test lab infrastructure'
|
76
|
+
command :teardown do |teardown|
|
77
|
+
teardown.action do |global_options,options,args|
|
78
|
+
@testlab.teardown
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
desc 'Display information on the status of the test lab'
|
83
|
+
command :status do |status|
|
84
|
+
status.action do |global_options,options,args|
|
85
|
+
@testlab.status
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
desc 'Manage nodes'
|
90
|
+
arg_name 'Describe arguments to node here'
|
91
|
+
command :node do |c|
|
92
|
+
|
93
|
+
c.desc 'Node ID'
|
94
|
+
c.flag [:i, :id]
|
95
|
+
|
96
|
+
c.desc 'Open an SSH console to a node'
|
97
|
+
c.command :ssh do |ssh|
|
98
|
+
ssh.action do |global_options,options,args|
|
99
|
+
help_now!('id is required') if options[:id].nil?
|
100
|
+
|
101
|
+
node = @testlab.nodes.select{ |n| n.id.to_sym == options[:id].to_sym }.first
|
102
|
+
node.ssh.console
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
|
108
|
+
desc 'Manage networks'
|
109
|
+
arg_name 'Describe arguments to network here'
|
110
|
+
command :network do |c|
|
111
|
+
c.action do |global_options,options,args|
|
112
|
+
puts "network command ran"
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
desc 'Manage containers'
|
117
|
+
arg_name 'Describe arguments to container here'
|
118
|
+
command :container do |c|
|
119
|
+
|
120
|
+
c.desc 'Container ID'
|
121
|
+
c.flag [:i, :id]
|
122
|
+
|
123
|
+
c.desc 'Open an SSH console to a container'
|
124
|
+
c.command :ssh do |ssh|
|
125
|
+
ssh.action do |global_options,options,args|
|
126
|
+
help_now!('id is required') if options[:id].nil?
|
127
|
+
|
128
|
+
container = @testlab.containers.select{ |n| n.id.to_sym == options[:id].to_sym }.first
|
129
|
+
container.ssh.console
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|
134
|
+
|
135
|
+
pre do |global,command,options,args|
|
136
|
+
# Pre logic here
|
137
|
+
# Return true to proceed; false to abort and not call the
|
138
|
+
# chosen command
|
139
|
+
# Use skips_pre before a command to skip this block
|
140
|
+
# on that command only
|
141
|
+
|
142
|
+
log_file = File.join(Dir.pwd, "testlab.log")
|
143
|
+
@logger = ZTK::Logger.new(log_file)
|
144
|
+
@ui = ZTK::UI.new(:logger => @logger)
|
145
|
+
@testlab = TestLab.new(:ui => @ui)
|
146
|
+
|
147
|
+
message = TestLab::Utility.format_message("TestLab v#{TestLab::VERSION} Loaded".black.bold)
|
148
|
+
@testlab.ui.stdout.puts(message)
|
149
|
+
|
150
|
+
true
|
151
|
+
end
|
152
|
+
|
153
|
+
post do |global,command,options,args|
|
154
|
+
# Post logic here
|
155
|
+
# Use skips_post before a command to skip this
|
156
|
+
# block on that command only
|
157
|
+
end
|
158
|
+
|
159
|
+
on_error do |exception|
|
160
|
+
# Error logic here
|
161
|
+
# return false to skip default error handling
|
162
|
+
puts(["EXCEPTION:".red.bold, exception.inspect.red].join(' '))
|
163
|
+
|
164
|
+
false
|
165
|
+
end
|
166
|
+
|
167
|
+
exit run(ARGV)
|
@@ -7,40 +7,48 @@ class TestLab
|
|
7
7
|
def create
|
8
8
|
@ui.logger.debug { "Container Create: #{self.id} " }
|
9
9
|
|
10
|
-
self
|
11
|
-
|
12
|
-
|
10
|
+
please_wait(:ui => @ui, :message => format_object_action(self, 'Create', :green)) do
|
11
|
+
self.domain ||= self.node.labfile.config[:domain]
|
12
|
+
self.distro ||= "ubuntu"
|
13
|
+
self.release ||= "precise"
|
13
14
|
|
14
|
-
|
15
|
+
self.arch ||= detect_arch
|
15
16
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
17
|
+
self.lxc.config.clear
|
18
|
+
self.lxc.config['lxc.utsname'] = self.id
|
19
|
+
self.lxc.config['lxc.arch'] = self.arch
|
20
|
+
self.lxc.config.networks = build_lxc_network_conf(self.interfaces)
|
21
|
+
self.lxc.config.save
|
21
22
|
|
22
|
-
|
23
|
+
self.lxc.create(*create_args)
|
24
|
+
end
|
23
25
|
end
|
24
26
|
|
25
27
|
# Destroy the container
|
26
28
|
def destroy
|
27
29
|
@ui.logger.debug { "Container Destroy: #{self.id} " }
|
28
30
|
|
29
|
-
self
|
31
|
+
please_wait(:ui => @ui, :message => format_object_action(self, 'Destroy', :red)) do
|
32
|
+
self.lxc.destroy
|
33
|
+
end
|
30
34
|
end
|
31
35
|
|
32
36
|
# Start the container
|
33
37
|
def up
|
34
38
|
@ui.logger.debug { "Container Up: #{self.id} " }
|
35
39
|
|
36
|
-
self
|
40
|
+
please_wait(:ui => @ui, :message => format_object_action(self, 'Up', :green)) do
|
41
|
+
self.lxc.start
|
42
|
+
end
|
37
43
|
end
|
38
44
|
|
39
45
|
# Stop the container
|
40
46
|
def down
|
41
47
|
@ui.logger.debug { "Container Down: #{self.id} " }
|
42
48
|
|
43
|
-
self
|
49
|
+
please_wait(:ui => @ui, :message => format_object_action(self, 'Down', :red)) do
|
50
|
+
self.lxc.stop
|
51
|
+
end
|
44
52
|
end
|
45
53
|
|
46
54
|
end
|
@@ -3,6 +3,7 @@ class TestLab
|
|
3
3
|
|
4
4
|
module Interface
|
5
5
|
|
6
|
+
# Returns the IP of the container
|
6
7
|
def ip
|
7
8
|
TestLab::Utility.ip(self.primary_interface.last[:ip])
|
8
9
|
end
|
@@ -12,21 +13,9 @@ class TestLab
|
|
12
13
|
TestLab::Utility.cidr(self.primary_interface.last[:ip]).to_i
|
13
14
|
end
|
14
15
|
|
16
|
+
# Returns a BIND PTR record
|
15
17
|
def ptr
|
16
|
-
|
17
|
-
|
18
|
-
result = case self.cidr
|
19
|
-
when 0..7 then
|
20
|
-
octets[-4,4]
|
21
|
-
when 8..15 then
|
22
|
-
octets[-3,3]
|
23
|
-
when 16..23 then
|
24
|
-
octets[-2,2]
|
25
|
-
when 24..31 then
|
26
|
-
octets[-1,1]
|
27
|
-
end
|
28
|
-
|
29
|
-
result.reverse.join('.')
|
18
|
+
TestLab::Utility.ptr(self.primary_interface.last[:ip])
|
30
19
|
end
|
31
20
|
|
32
21
|
def primary_interface
|
@@ -9,14 +9,30 @@ class TestLab
|
|
9
9
|
|
10
10
|
self.create
|
11
11
|
self.up
|
12
|
+
|
13
|
+
if (!@provisioner.nil? && @provisioner.respond_to?(:setup))
|
14
|
+
please_wait(:ui => @ui, :message => format_object_action(self, 'Setup', :green)) do
|
15
|
+
@provisioner.setup(self)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
true
|
12
20
|
end
|
13
21
|
|
14
22
|
# Container Teardown
|
15
23
|
def teardown
|
16
24
|
@ui.logger.debug { "Container Teardown: #{self.id} " }
|
17
25
|
|
26
|
+
if (!@provisioner.nil? && @provisioner.respond_to?(:teardown))
|
27
|
+
please_wait(:ui => @ui, :message => format_object_action(self, 'Teardown', :red)) do
|
28
|
+
@provisioner.teardown(self)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
18
32
|
self.down
|
19
33
|
self.destroy
|
34
|
+
|
35
|
+
true
|
20
36
|
end
|
21
37
|
|
22
38
|
end
|
data/lib/testlab/container.rb
CHANGED
@@ -29,6 +29,8 @@ class TestLab
|
|
29
29
|
|
30
30
|
extend TestLab::Container::ClassMethods
|
31
31
|
|
32
|
+
include TestLab::Utility::Misc
|
33
|
+
|
32
34
|
# Associations and Attributes
|
33
35
|
belongs_to :node, :class_name => 'TestLab::Node'
|
34
36
|
|
@@ -38,6 +40,7 @@ class TestLab
|
|
38
40
|
attribute :domain
|
39
41
|
|
40
42
|
attribute :user
|
43
|
+
attribute :passwd
|
41
44
|
attribute :keys
|
42
45
|
|
43
46
|
attribute :interfaces
|
@@ -53,7 +56,7 @@ class TestLab
|
|
53
56
|
super(*args)
|
54
57
|
|
55
58
|
@ui = TestLab.ui
|
56
|
-
@provisioner = self.provisioner.new(self.config) if !self.provisioner.nil?
|
59
|
+
@provisioner = self.provisioner.new(self.config, @ui) if !self.provisioner.nil?
|
57
60
|
end
|
58
61
|
|
59
62
|
end
|
@@ -7,28 +7,36 @@ class TestLab
|
|
7
7
|
def create
|
8
8
|
@ui.logger.debug { "Network Create: #{self.id} " }
|
9
9
|
|
10
|
-
|
10
|
+
please_wait(:ui => @ui, :message => format_object_action(self, 'Create', :green)) do
|
11
|
+
self.node.ssh.exec(%(sudo brctl addbr #{self.bridge}), :silence => true, :ignore_exit_status => true)
|
12
|
+
end
|
11
13
|
end
|
12
14
|
|
13
15
|
# Destroy the network
|
14
16
|
def destroy
|
15
17
|
@ui.logger.debug { "Network Destroy: #{self.id} " }
|
16
18
|
|
17
|
-
|
19
|
+
please_wait(:ui => @ui, :message => format_object_action(self, 'Destroy', :red)) do
|
20
|
+
self.node.ssh.exec(%(sudo brctl delbr #{self.bridge}), :silence => true, :ignore_exit_status => true)
|
21
|
+
end
|
18
22
|
end
|
19
23
|
|
20
24
|
# Start the network
|
21
25
|
def up
|
22
26
|
@ui.logger.debug { "Network Up: #{self.id} " }
|
23
27
|
|
24
|
-
|
28
|
+
please_wait(:ui => @ui, :message => format_object_action(self, 'Up', :green)) do
|
29
|
+
self.node.ssh.exec(%(sudo ifconfig #{self.bridge} #{self.ip} up), :silence => true, :ignore_exit_status => true)
|
30
|
+
end
|
25
31
|
end
|
26
32
|
|
27
33
|
# Stop the network
|
28
34
|
def down
|
29
35
|
@ui.logger.debug { "Network Down: #{self.id} " }
|
30
36
|
|
31
|
-
|
37
|
+
please_wait(:ui => @ui, :message => format_object_action(self, 'Down', :red)) do
|
38
|
+
self.node.ssh.exec(%(sudo ifconfig #{self.bridge} down), :silence => true, :ignore_exit_status => true)
|
39
|
+
end
|
32
40
|
end
|
33
41
|
|
34
42
|
end
|
data/lib/testlab/network.rb
CHANGED
@@ -23,6 +23,8 @@ class TestLab
|
|
23
23
|
|
24
24
|
extend TestLab::Network::ClassMethods
|
25
25
|
|
26
|
+
include TestLab::Utility::Misc
|
27
|
+
|
26
28
|
# Associations and Attributes
|
27
29
|
belongs_to :node, :class_name => 'TestLab::Node'
|
28
30
|
|
@@ -35,7 +37,7 @@ class TestLab
|
|
35
37
|
def initialize(*args)
|
36
38
|
super(*args)
|
37
39
|
|
38
|
-
@ui
|
40
|
+
@ui = TestLab.ui
|
39
41
|
end
|
40
42
|
|
41
43
|
end
|
data/lib/testlab/node/bind.rb
CHANGED
@@ -79,9 +79,11 @@ class TestLab
|
|
79
79
|
|
80
80
|
def bind_install
|
81
81
|
self.ssh.exec(%(sudo apt-get -y install bind9))
|
82
|
+
self.ssh.exec(%(sudo rm -fv /etc/bind/{*.arpa,*.zone,*.conf*}))
|
82
83
|
end
|
83
84
|
|
84
85
|
def bind_reload
|
86
|
+
self.ssh.exec(%(sudo chown -Rv bind:bind /etc/bind))
|
85
87
|
self.ssh.exec(%(sudo rndc reload))
|
86
88
|
end
|
87
89
|
|
@@ -14,6 +14,8 @@ class TestLab
|
|
14
14
|
# Calls the specified method on all the objects supplied
|
15
15
|
def call_methods(objects, method_name)
|
16
16
|
objects.each do |object|
|
17
|
+
# @ui.stdout.puts(format_message(format_object(object, (method_name == :setup ? :green : :red))))
|
18
|
+
|
17
19
|
if object.respond_to?(method_name)
|
18
20
|
object.send(method_name)
|
19
21
|
end
|
@@ -30,14 +32,18 @@ class TestLab
|
|
30
32
|
def setup
|
31
33
|
@ui.logger.debug { "Node Setup: #{self.id} " }
|
32
34
|
|
33
|
-
|
35
|
+
# @ui.stdout.puts(format_message(format_object(self, :green)))
|
34
36
|
|
35
|
-
|
36
|
-
|
37
|
-
end
|
37
|
+
please_wait(:ui => @ui, :message => format_object_action(self, 'Setup', :green)) do
|
38
|
+
node_setup
|
38
39
|
|
39
|
-
|
40
|
-
|
40
|
+
if self.components.include?('resolv')
|
41
|
+
build_resolv_conf
|
42
|
+
end
|
43
|
+
|
44
|
+
if self.components.include?('bind')
|
45
|
+
bind_setup
|
46
|
+
end
|
41
47
|
end
|
42
48
|
|
43
49
|
call_collections([self.networks, self.routers, self.containers], :setup)
|
@@ -53,8 +59,13 @@ class TestLab
|
|
53
59
|
def teardown
|
54
60
|
@ui.logger.debug { "Node Teardown: #{self.id} " }
|
55
61
|
|
62
|
+
# @ui.stdout.puts(format_message(format_object(self, :red)))
|
63
|
+
|
56
64
|
call_collections([self.containers, self.routers, self.networks], :teardown)
|
57
65
|
|
66
|
+
please_wait(:ui => @ui, :message => format_object_action(self, 'Teardown', :red)) do
|
67
|
+
end
|
68
|
+
|
58
69
|
true
|
59
70
|
end
|
60
71
|
|
data/lib/testlab/node/ssh.rb
CHANGED
@@ -31,7 +31,11 @@ class TestLab
|
|
31
31
|
|
32
32
|
c.host_name = container.ip
|
33
33
|
c.user = (container.user || "ubuntu")
|
34
|
-
|
34
|
+
if container.keys.nil?
|
35
|
+
c.password = (container.passwd || "ubuntu")
|
36
|
+
else
|
37
|
+
c.keys = container.keys
|
38
|
+
end
|
35
39
|
end
|
36
40
|
end
|
37
41
|
@container_ssh[name]
|
data/lib/testlab/node.rb
CHANGED
@@ -10,6 +10,7 @@ class TestLab
|
|
10
10
|
STATUS_KEYS = %w(id instance_id state user ip port provider con net rtr).map(&:to_sym)
|
11
11
|
|
12
12
|
# Sub-Modules
|
13
|
+
autoload :Actions, 'testlab/node/actions'
|
13
14
|
autoload :Bind, 'testlab/node/bind'
|
14
15
|
autoload :ClassMethods, 'testlab/node/class_methods'
|
15
16
|
autoload :Lifecycle, 'testlab/node/lifecycle'
|
@@ -19,6 +20,7 @@ class TestLab
|
|
19
20
|
autoload :SSH, 'testlab/node/ssh'
|
20
21
|
autoload :Status, 'testlab/node/status'
|
21
22
|
|
23
|
+
include TestLab::Node::Actions
|
22
24
|
include TestLab::Node::Bind
|
23
25
|
include TestLab::Node::Lifecycle
|
24
26
|
include TestLab::Node::LXC
|
@@ -29,6 +31,8 @@ class TestLab
|
|
29
31
|
|
30
32
|
extend TestLab::Node::ClassMethods
|
31
33
|
|
34
|
+
include TestLab::Utility::Misc
|
35
|
+
|
32
36
|
# Associations and Attributes
|
33
37
|
belongs_to :labfile, :class_name => 'TestLab::Lab'
|
34
38
|
|
@@ -45,7 +49,7 @@ class TestLab
|
|
45
49
|
super(*args)
|
46
50
|
|
47
51
|
@ui = TestLab.ui
|
48
|
-
@provider = self.provider.new(self.config)
|
52
|
+
@provider = self.provider.new(self.config, @ui)
|
49
53
|
end
|
50
54
|
|
51
55
|
end
|
@@ -11,10 +11,16 @@ class TestLab
|
|
11
11
|
class Chef
|
12
12
|
|
13
13
|
def initialize(config={}, ui=nil)
|
14
|
-
@config = config
|
14
|
+
@config = (config || Hash.new)
|
15
15
|
@ui = (ui || TestLab.ui)
|
16
16
|
end
|
17
17
|
|
18
|
+
def setup(container)
|
19
|
+
end
|
20
|
+
|
21
|
+
def teardown(container)
|
22
|
+
end
|
23
|
+
|
18
24
|
end
|
19
25
|
|
20
26
|
end
|
@@ -9,10 +9,27 @@ class TestLab
|
|
9
9
|
#
|
10
10
|
# @author Zachary Patten <zachary@jovelabs.net>
|
11
11
|
class Shell
|
12
|
+
require 'tempfile'
|
12
13
|
|
13
14
|
def initialize(config={}, ui=nil)
|
14
|
-
@config
|
15
|
-
@ui
|
15
|
+
@config = (config || Hash.new)
|
16
|
+
@ui = (ui || TestLab.ui)
|
17
|
+
|
18
|
+
@config[:shell] ||= "/bin/bash"
|
19
|
+
end
|
20
|
+
|
21
|
+
def setup(container)
|
22
|
+
if !@config[:setup].nil?
|
23
|
+
tempfile = Tempfile.new("bootstrap")
|
24
|
+
container.node.ssh.file(:target => File.join(container.lxc.fs_root, tempfile.path), :chmod => '0777', :chown => 'root:root') do |file|
|
25
|
+
file.puts(@config[:setup])
|
26
|
+
end
|
27
|
+
container.lxc.attach(@config[:shell], tempfile.path)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def teardown(container)
|
32
|
+
# NOOP
|
16
33
|
end
|
17
34
|
|
18
35
|
end
|
data/lib/testlab/utility.rb
CHANGED
data/lib/testlab/version.rb
CHANGED
data/lib/testlab.rb
CHANGED
@@ -2,6 +2,11 @@ require 'ztk'
|
|
2
2
|
|
3
3
|
require 'testlab/version'
|
4
4
|
|
5
|
+
# Monkey Patch the String class so we can have some easy ANSI methods
|
6
|
+
class String
|
7
|
+
include ZTK::ANSI
|
8
|
+
end
|
9
|
+
|
5
10
|
# Top-Level LXC Class
|
6
11
|
#
|
7
12
|
# @author Zachary Patten <zachary@jovelabs.net>
|
@@ -20,6 +25,8 @@ class TestLab
|
|
20
25
|
autoload :Router, 'testlab/router'
|
21
26
|
autoload :Utility, 'testlab/utility'
|
22
27
|
|
28
|
+
include TestLab::Utility::Misc
|
29
|
+
|
23
30
|
@@ui ||= nil
|
24
31
|
|
25
32
|
def initialize(options={})
|
@@ -61,18 +68,18 @@ class TestLab
|
|
61
68
|
|
62
69
|
def status
|
63
70
|
if alive?
|
64
|
-
@@ui.stdout.puts("NODES:")
|
65
|
-
ZTK::Report.new(:ui => @@ui).
|
71
|
+
@@ui.stdout.puts("NODES:".green.bold)
|
72
|
+
ZTK::Report.new(:ui => @@ui).list(TestLab::Node.all, TestLab::Node::STATUS_KEYS) do |node|
|
66
73
|
OpenStruct.new(node.status)
|
67
74
|
end
|
68
75
|
@@ui.stdout.puts
|
69
|
-
@@ui.stdout.puts("NETWORKS:")
|
70
|
-
ZTK::Report.new(:ui => @@ui).
|
76
|
+
@@ui.stdout.puts("NETWORKS:".green.bold)
|
77
|
+
ZTK::Report.new(:ui => @@ui).list(TestLab::Network.all, TestLab::Network::STATUS_KEYS) do |network|
|
71
78
|
OpenStruct.new(network.status)
|
72
79
|
end
|
73
80
|
@@ui.stdout.puts
|
74
|
-
@@ui.stdout.puts("CONTAINERS:")
|
75
|
-
ZTK::Report.new(:ui => @@ui).
|
81
|
+
@@ui.stdout.puts("CONTAINERS:".green.bold)
|
82
|
+
ZTK::Report.new(:ui => @@ui).list(TestLab::Container.all, TestLab::Container::STATUS_KEYS) do |container|
|
76
83
|
OpenStruct.new(container.status)
|
77
84
|
end
|
78
85
|
|
@@ -98,7 +105,6 @@ class TestLab
|
|
98
105
|
|
99
106
|
# Proxy various method calls to our subordinate classes
|
100
107
|
def node_method_proxy(method_name, *method_args)
|
101
|
-
@@ui.logger.debug { "TestLab.#{method_name}" }
|
102
108
|
TestLab::Node.all.map do |node|
|
103
109
|
node.send(method_name.to_sym, *method_args)
|
104
110
|
end
|
@@ -115,6 +121,10 @@ class TestLab
|
|
115
121
|
end
|
116
122
|
end
|
117
123
|
|
124
|
+
def ui
|
125
|
+
@@ui ||= ZTK::UI.new
|
126
|
+
end
|
127
|
+
|
118
128
|
# Class Helpers
|
119
129
|
class << self
|
120
130
|
|
data/testlab.gemspec
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: testlab
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,8 +9,24 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-04-
|
12
|
+
date: 2013-04-30 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: gli
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
14
30
|
- !ruby/object:Gem::Dependency
|
15
31
|
name: lxc
|
16
32
|
requirement: !ruby/object:Gem::Requirement
|
@@ -143,7 +159,7 @@ description: A framework for building lightweight virtual infrastructure using L
|
|
143
159
|
email:
|
144
160
|
- zachary@jovelabs.com
|
145
161
|
executables:
|
146
|
-
-
|
162
|
+
- tl
|
147
163
|
extensions: []
|
148
164
|
extra_rdoc_files: []
|
149
165
|
files:
|
@@ -157,7 +173,7 @@ files:
|
|
157
173
|
- LICENSE
|
158
174
|
- README.md
|
159
175
|
- Rakefile
|
160
|
-
- bin/
|
176
|
+
- bin/tl
|
161
177
|
- lib/testlab.rb
|
162
178
|
- lib/testlab/container.rb
|
163
179
|
- lib/testlab/container/actions.rb
|
@@ -223,7 +239,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
223
239
|
version: '0'
|
224
240
|
segments:
|
225
241
|
- 0
|
226
|
-
hash:
|
242
|
+
hash: 3639724075672475487
|
227
243
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
228
244
|
none: false
|
229
245
|
requirements:
|
@@ -232,7 +248,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
232
248
|
version: '0'
|
233
249
|
segments:
|
234
250
|
- 0
|
235
|
-
hash:
|
251
|
+
hash: 3639724075672475487
|
236
252
|
requirements: []
|
237
253
|
rubyforge_project:
|
238
254
|
rubygems_version: 1.8.25
|