testlab 0.7.6 → 0.8.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/README.md +2 -1
- data/bin/tl +8 -4
- data/features/step_definitions/testlab_steps.rb +5 -1
- data/features/support/Labfile.local +46 -0
- data/features/support/Labfile.vagrant +58 -0
- data/features/support/env.rb +8 -0
- data/features/testlab.feature +4 -8
- data/lib/commands/container.rb +28 -240
- data/lib/commands/network.rb +27 -193
- data/lib/commands/node.rb +9 -160
- data/lib/commands/testlab.rb +72 -10
- data/lib/testlab/container/actions.rb +2 -2
- data/lib/testlab/container/io.rb +21 -12
- data/lib/testlab/container/lifecycle.rb +13 -0
- data/lib/testlab/container/ssh.rb +2 -2
- data/lib/testlab/container.rb +3 -1
- data/lib/testlab/interface.rb +2 -0
- data/lib/testlab/network/actions.rb +2 -2
- data/lib/testlab/network/lifecycle.rb +15 -0
- data/lib/testlab/network/status.rb +1 -1
- data/lib/testlab/network.rb +3 -1
- data/lib/testlab/node/lifecycle.rb +9 -0
- data/lib/testlab/node.rb +2 -0
- data/lib/testlab/user.rb +2 -0
- data/lib/testlab/utility/gli.rb +83 -0
- data/lib/testlab/utility/logger.rb +35 -30
- data/lib/testlab/utility.rb +2 -0
- data/lib/testlab/version.rb +1 -1
- data/lib/testlab.rb +111 -38
- data/spec/container_spec.rb +4 -0
- data/spec/network_spec.rb +4 -0
- metadata +9 -6
- data/features/support/Labfile +0 -85
@@ -13,6 +13,9 @@ class TestLab
|
|
13
13
|
def setup
|
14
14
|
@ui.logger.debug { "Container Setup: #{self.id} " }
|
15
15
|
|
16
|
+
(self.node.state != :running) and return false
|
17
|
+
(self.lxc.state == :not_created) and return false
|
18
|
+
|
16
19
|
please_wait(:ui => @ui, :message => format_object_action(self, 'Setup', :green)) do
|
17
20
|
|
18
21
|
self.container_provisioners.each do |provisioner|
|
@@ -36,6 +39,7 @@ class TestLab
|
|
36
39
|
def teardown
|
37
40
|
@ui.logger.debug { "Container Teardown: #{self.id} " }
|
38
41
|
|
42
|
+
(self.node.state != :running) and return false
|
39
43
|
(self.lxc.state == :not_created) and return false
|
40
44
|
|
41
45
|
please_wait(:ui => @ui, :message => format_object_action(self, 'Teardown', :red)) do
|
@@ -60,6 +64,15 @@ class TestLab
|
|
60
64
|
true
|
61
65
|
end
|
62
66
|
|
67
|
+
# Demolish the container
|
68
|
+
def demolish
|
69
|
+
self.teardown
|
70
|
+
self.down
|
71
|
+
self.destroy
|
72
|
+
|
73
|
+
true
|
74
|
+
end
|
75
|
+
|
63
76
|
# Returns all defined provisioners for this container's networks and the container iteself.
|
64
77
|
def container_provisioners
|
65
78
|
[self.interfaces.map(&:network).map(&:provisioners), self.provisioners].flatten.compact.uniq
|
@@ -20,14 +20,14 @@ class TestLab
|
|
20
20
|
identities = [self.users.map(&:identity), self.node.identity].flatten.compact.uniq
|
21
21
|
|
22
22
|
output = <<-EOF
|
23
|
-
#{ZTK::Template.do_not_edit_notice(:message => %(TestLab "#{self.
|
23
|
+
#{ZTK::Template.do_not_edit_notice(:message => %(TestLab "#{self.id}" SSH Configuration))}
|
24
24
|
Host #{self.id}
|
25
25
|
HostName #{self.ip}
|
26
26
|
Port 22
|
27
27
|
UserKnownHostsFile /dev/null
|
28
28
|
StrictHostKeyChecking no
|
29
29
|
PasswordAuthentication no
|
30
|
-
ForwardAgent
|
30
|
+
ForwardAgent yes
|
31
31
|
IdentitiesOnly yes
|
32
32
|
EOF
|
33
33
|
|
data/lib/testlab/container.rb
CHANGED
@@ -70,7 +70,7 @@ class TestLab
|
|
70
70
|
# An array of symbols of the various keys in our status hash.
|
71
71
|
#
|
72
72
|
# @see TestLab::Container::Status
|
73
|
-
STATUS_KEYS = %w(node_id
|
73
|
+
STATUS_KEYS = %w(id node_id clone fqdn state distro release interfaces provisioners).map(&:to_sym)
|
74
74
|
|
75
75
|
# Sub-Modules
|
76
76
|
autoload :Actions, 'testlab/container/actions'
|
@@ -124,6 +124,8 @@ class TestLab
|
|
124
124
|
@ui = TestLab.ui
|
125
125
|
|
126
126
|
super(*args)
|
127
|
+
|
128
|
+
@ui.logger.info { "Container '#{self.id}' Loaded" }
|
127
129
|
end
|
128
130
|
|
129
131
|
def config_dir
|
data/lib/testlab/interface.rb
CHANGED
@@ -7,7 +7,7 @@ class TestLab
|
|
7
7
|
def create
|
8
8
|
@ui.logger.debug { "Network Create: #{self.id} " }
|
9
9
|
|
10
|
-
(self.node.state
|
10
|
+
(self.node.state != :running) and return false
|
11
11
|
(self.state != :not_created) and return false
|
12
12
|
|
13
13
|
please_wait(:ui => @ui, :message => format_object_action(self, 'Create', :green)) do
|
@@ -21,7 +21,7 @@ class TestLab
|
|
21
21
|
def destroy
|
22
22
|
@ui.logger.debug { "Network Destroy: #{self.id} " }
|
23
23
|
|
24
|
-
(self.node.state
|
24
|
+
(self.node.state != :running) and return false
|
25
25
|
(self.state == :not_created) and return false
|
26
26
|
|
27
27
|
please_wait(:ui => @ui, :message => format_object_action(self, 'Destroy', :red)) do
|
@@ -7,6 +7,9 @@ class TestLab
|
|
7
7
|
def setup
|
8
8
|
@ui.logger.debug { "Network Setup: #{self.id} " }
|
9
9
|
|
10
|
+
(self.node.state != :running) and return false
|
11
|
+
(self.state == :not_created) and return false
|
12
|
+
|
10
13
|
please_wait(:ui => @ui, :message => format_object_action(self, 'Setup', :green)) do
|
11
14
|
|
12
15
|
self.network_provisioners.each do |provisioner|
|
@@ -24,6 +27,9 @@ class TestLab
|
|
24
27
|
def teardown
|
25
28
|
@ui.logger.debug { "Network Teardown: #{self.id} " }
|
26
29
|
|
30
|
+
(self.node.state != :running) and return false
|
31
|
+
(self.state == :not_created) and return false
|
32
|
+
|
27
33
|
please_wait(:ui => @ui, :message => format_object_action(self, 'Teardown', :red)) do
|
28
34
|
|
29
35
|
self.network_provisioners.each do |provisioner|
|
@@ -46,6 +52,15 @@ class TestLab
|
|
46
52
|
true
|
47
53
|
end
|
48
54
|
|
55
|
+
# Demolish the network
|
56
|
+
def demolish
|
57
|
+
self.teardown
|
58
|
+
self.down
|
59
|
+
self.destroy
|
60
|
+
|
61
|
+
true
|
62
|
+
end
|
63
|
+
|
49
64
|
# Returns all defined provisioners for this network's containers and the network iteself.
|
50
65
|
def network_provisioners
|
51
66
|
[self.provisioners, self.interfaces.map(&:container).map(&:provisioners)].flatten.compact.uniq
|
@@ -48,7 +48,7 @@ class TestLab
|
|
48
48
|
:not_created
|
49
49
|
else
|
50
50
|
output = self.node.ssh.exec(%(sudo ifconfig #{self.bridge} 2>&1 | grep 'MTU'), :silence => true, :ignore_exit_status => true).output.strip
|
51
|
-
if ((output =~ /UP/)
|
51
|
+
if ((output =~ /UP/) || (output =~ /RUNNING/))
|
52
52
|
:running
|
53
53
|
else
|
54
54
|
:stopped
|
data/lib/testlab/network.rb
CHANGED
@@ -7,7 +7,7 @@ class TestLab
|
|
7
7
|
#
|
8
8
|
# @author Zachary Patten <zachary AT jovelabs DOT com>
|
9
9
|
class Network < ZTK::DSL::Base
|
10
|
-
STATUS_KEYS = %w(node_id
|
10
|
+
STATUS_KEYS = %w(id node_id state interface network netmask broadcast provisioners).map(&:to_sym)
|
11
11
|
|
12
12
|
# Sub-Modules
|
13
13
|
autoload :Actions, 'testlab/network/actions'
|
@@ -40,6 +40,8 @@ class TestLab
|
|
40
40
|
@ui = TestLab.ui
|
41
41
|
|
42
42
|
super(*args)
|
43
|
+
|
44
|
+
@ui.logger.info { "Network '#{self.id}' Loaded" }
|
43
45
|
end
|
44
46
|
|
45
47
|
end
|
@@ -54,6 +54,15 @@ class TestLab
|
|
54
54
|
true
|
55
55
|
end
|
56
56
|
|
57
|
+
# Demolish the node
|
58
|
+
def demolish
|
59
|
+
self.teardown
|
60
|
+
self.down
|
61
|
+
self.destroy
|
62
|
+
|
63
|
+
true
|
64
|
+
end
|
65
|
+
|
57
66
|
# Returns all defined provisioners for this node and it's networks and containers.
|
58
67
|
def all_provisioners
|
59
68
|
[self.provisioners, self.networks.map(&:provisioners), self.containers.map(&:provisioners)].flatten.compact.uniq
|
data/lib/testlab/node.rb
CHANGED
data/lib/testlab/user.rb
CHANGED
@@ -0,0 +1,83 @@
|
|
1
|
+
class TestLab
|
2
|
+
module Utility
|
3
|
+
|
4
|
+
# GLI Module
|
5
|
+
#
|
6
|
+
# @author Zachary Patten <zachary AT jovelabs DOT com>
|
7
|
+
module GLI
|
8
|
+
require 'ztk'
|
9
|
+
|
10
|
+
LAB_ACTION_ORDER = %W(create destroy up down setup teardown build demolish).map(&:to_sym)
|
11
|
+
|
12
|
+
LAB_ACTIONS = {
|
13
|
+
:create => ["Construct %s", "Attempts to create the <%= @component %>."],
|
14
|
+
:destroy => ["Destruct %s", "Attempts to destroy the <%= @component %>."],
|
15
|
+
:up => ["On-line %s", "Attempts to online the <%= @component %>."],
|
16
|
+
:down => ["Off-line %s", "Attempts to offline the <%= @component %>."],
|
17
|
+
:setup => ["Provision %s", "Attempts to provision the <%= @component %>."],
|
18
|
+
:teardown => ["De-provision %s", "Attempts to deprovision the <%= @component %>."],
|
19
|
+
:build => ["Build %s", <<-EOF],
|
20
|
+
Attempts to build the <%= @component %>. TestLab will attempt to create, online and provision the <%= @component %>.
|
21
|
+
|
22
|
+
The <%= @component %> are taken through the following states:
|
23
|
+
|
24
|
+
Create -> Up -> Setup
|
25
|
+
EOF
|
26
|
+
:demolish => ["Demolish %s", <<-EOF]
|
27
|
+
Attempts to demolish the <%= @component %>. TestLab will attempt to deprovision, offline and destroy the <%= @component %>.
|
28
|
+
|
29
|
+
The <%= @component %> are taken through the following states:
|
30
|
+
|
31
|
+
Teardown -> Down -> Destroy
|
32
|
+
EOF
|
33
|
+
}
|
34
|
+
|
35
|
+
def build_lab_commands(component, klass, &block)
|
36
|
+
desc %(Manage lab #{component}s)
|
37
|
+
command component do |c|
|
38
|
+
c.desc %(Optional #{component} ID or comma separated list of #{component} IDs)
|
39
|
+
c.arg_name %(#{component}[,#{component},...])
|
40
|
+
c.flag [:n, :name]
|
41
|
+
|
42
|
+
LAB_ACTION_ORDER.each do |lab_action|
|
43
|
+
action_desc = LAB_ACTIONS[lab_action]
|
44
|
+
c.desc(action_desc.first % "#{component}s")
|
45
|
+
c.long_desc(ZTK::Template.string(action_desc.last, {:component => "#{component}s"}))
|
46
|
+
|
47
|
+
c.command lab_action do |la|
|
48
|
+
la.action do |global_options, options, args|
|
49
|
+
iterate_objects_by_name(options[:name], klass) do |object|
|
50
|
+
object.send(lab_action)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
!block.nil? and block.call(c)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def iterate_objects_by_name(name, klass, &block)
|
61
|
+
objects = Array.new
|
62
|
+
klass_name = klass.to_s.split('::').last.downcase
|
63
|
+
|
64
|
+
if name.nil?
|
65
|
+
objects = klass.all
|
66
|
+
else
|
67
|
+
names = name.split(',')
|
68
|
+
objects = klass.find(names)
|
69
|
+
end
|
70
|
+
|
71
|
+
(objects.nil? || (objects.count == 0)) and raise TestLab::TestLabError, "We could not find any of the #{klass_name}s you supplied!"
|
72
|
+
|
73
|
+
objects.each do |object|
|
74
|
+
!block.nil? and block.call(object)
|
75
|
+
end
|
76
|
+
|
77
|
+
objects
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
end
|
@@ -16,76 +16,81 @@ class TestLab
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def log_page_break(max_key_length, char='-')
|
19
|
+
(max_key_length > 80) and (max_key_length = 80)
|
19
20
|
(char * max_key_length)
|
20
21
|
end
|
21
22
|
|
22
|
-
def
|
23
|
+
def log_config(testlab)
|
23
24
|
{
|
24
|
-
"hostname" => "%s (%s)" % [Socket.gethostname.inspect, TestLab.hostname.inspect],
|
25
|
-
"program" => $0.to_s.inspect,
|
26
25
|
"config_dir" => testlab.config_dir.inspect,
|
27
26
|
"repo_dir" => testlab.repo_dir.inspect,
|
28
27
|
"labfile_path" => testlab.labfile_path.inspect,
|
29
28
|
"logdev" => testlab.ui.logger.logdev.inspect,
|
30
29
|
"version" => TestLab::VERSION.inspect,
|
31
|
-
"argv" => ARGV.inspect
|
32
30
|
}
|
33
31
|
end
|
34
32
|
|
35
|
-
def
|
33
|
+
def log_details(testlab)
|
34
|
+
{
|
35
|
+
"hostname" => "%s (%s)" % [Socket.gethostname.inspect, TestLab.hostname.inspect],
|
36
|
+
"program" => $0.to_s.inspect,
|
37
|
+
"argv" => ARGV.join(' ').inspect,
|
38
|
+
"timezone" => Time.now.zone.inspect
|
39
|
+
}
|
40
|
+
end
|
41
|
+
|
42
|
+
def log_ruby(testlab)
|
36
43
|
dependencies = {
|
37
44
|
"ruby_version" => RUBY_VERSION.inspect,
|
38
45
|
"ruby_patchlevel" => RUBY_PATCHLEVEL.inspect,
|
39
46
|
"ruby_platform" => RUBY_PLATFORM.inspect
|
40
47
|
}
|
41
48
|
|
42
|
-
defined?(RUBY_ENGINE)
|
49
|
+
defined?(RUBY_ENGINE) and dependencies.merge!("ruby_engine" => RUBY_ENGINE)
|
50
|
+
defined?(RUBY_DESCRIPTION) and dependencies.merge!("ruby_description" => RUBY_DESCRIPTION)
|
51
|
+
defined?(RUBY_RELEASE_DATE) and dependencies.merge!("ruby_release_date" => RUBY_RELEASE_DATE)
|
43
52
|
|
44
53
|
dependencies
|
45
54
|
end
|
46
55
|
|
47
|
-
def
|
48
|
-
@command = ZTK::Command.new(:silence => true, :ignore_exit_status => true)
|
49
|
-
|
56
|
+
def log_gem_dependencies(testlab)
|
50
57
|
{
|
51
58
|
"gli_version" => ::GLI::VERSION.inspect,
|
52
59
|
"lxc_version" => ::LXC::VERSION.inspect,
|
53
60
|
"ztk_version" => ::ZTK::VERSION.inspect,
|
54
|
-
"activesupport_version" => ::ActiveSupport::VERSION::STRING.inspect
|
61
|
+
"activesupport_version" => ::ActiveSupport::VERSION::STRING.inspect
|
62
|
+
}
|
63
|
+
end
|
64
|
+
|
65
|
+
def log_external_dependencies(testlab)
|
66
|
+
@command = ZTK::Command.new(:silence => true, :ignore_exit_status => true)
|
67
|
+
|
68
|
+
{
|
55
69
|
"vagrant_version" => @command.exec(%(/usr/bin/env vagrant --version)).output.strip.inspect,
|
56
|
-
"virtualbox_version" => @command.exec(%(/usr/bin/env vboxmanage --version)).output.strip.inspect
|
70
|
+
"virtualbox_version" => @command.exec(%(/usr/bin/env vboxmanage --version)).output.strip.inspect,
|
71
|
+
"lxc_version" => @command.exec(%(/usr/bin/env lxc-version)).output.strip.inspect
|
57
72
|
}
|
58
73
|
end
|
59
74
|
|
60
75
|
def log_header(testlab)
|
61
76
|
log_lines = Array.new
|
62
77
|
|
63
|
-
|
64
|
-
|
65
|
-
dependencies_hash = log_dependencies
|
78
|
+
log_methods = [:log_details, :log_config, :log_ruby, :log_gem_dependencies, :log_external_dependencies]
|
79
|
+
log_hashes = log_methods.collect{ |log_method| self.send(log_method, testlab) }
|
66
80
|
|
67
|
-
max_key_length =
|
68
|
-
max_value_length =
|
81
|
+
max_key_length = log_hashes.collect{ |log_hash| log_hash.keys }.flatten.compact.map(&:length).max + 2
|
82
|
+
max_value_length = log_hashes.collect{ |log_hash| log_hash.values }.flatten.compact.map(&:length).max + 2
|
69
83
|
|
70
84
|
max_length = (max_key_length + max_value_length + 2)
|
71
85
|
|
72
86
|
log_lines << log_page_break(max_length, '=')
|
73
|
-
|
74
|
-
|
87
|
+
log_hashes.each do |log_hash|
|
88
|
+
log_hash.sort.each do |key, value|
|
89
|
+
log_lines << log_key_value(key, value, max_key_length)
|
90
|
+
end
|
91
|
+
log_lines << log_page_break(max_length, '=')
|
75
92
|
end
|
76
93
|
|
77
|
-
log_lines << log_page_break(max_length)
|
78
|
-
ruby_hash.sort.each do |key, value|
|
79
|
-
log_lines << log_key_value(key, value, max_key_length)
|
80
|
-
end
|
81
|
-
|
82
|
-
log_lines << log_page_break(max_length)
|
83
|
-
dependencies_hash.sort.each do |key, value|
|
84
|
-
log_lines << log_key_value(key, value, max_key_length)
|
85
|
-
end
|
86
|
-
|
87
|
-
log_lines << log_page_break(max_length, '=')
|
88
|
-
|
89
94
|
log_lines.flatten.compact
|
90
95
|
end
|
91
96
|
|
data/lib/testlab/utility.rb
CHANGED
@@ -11,10 +11,12 @@ class TestLab
|
|
11
11
|
# @author Zachary Patten <zachary AT jovelabs DOT com>
|
12
12
|
module Utility
|
13
13
|
autoload :CIDR, 'testlab/utility/cidr'
|
14
|
+
autoload :GLI, 'testlab/utility/gli'
|
14
15
|
autoload :Logger, 'testlab/utility/logger'
|
15
16
|
autoload :Misc, 'testlab/utility/misc'
|
16
17
|
|
17
18
|
extend TestLab::Utility::CIDR
|
19
|
+
extend TestLab::Utility::GLI
|
18
20
|
extend TestLab::Utility::Logger
|
19
21
|
extend TestLab::Utility::Misc
|
20
22
|
|
data/lib/testlab/version.rb
CHANGED
data/lib/testlab.rb
CHANGED
@@ -17,53 +17,85 @@ require 'testlab/monkeys'
|
|
17
17
|
# to accomplish this.
|
18
18
|
#
|
19
19
|
# @example Sample Labfile:
|
20
|
-
#
|
21
|
-
# set -x
|
22
|
-
# apt-get -y update
|
23
|
-
# apt-get -y install dnsutils
|
24
|
-
# EOF
|
20
|
+
# node 'vagrant' do
|
25
21
|
#
|
26
|
-
#
|
27
|
-
#
|
28
|
-
#
|
29
|
-
#
|
30
|
-
#
|
31
|
-
# node :localhost do
|
32
|
-
# components %w(resolv bind)
|
33
|
-
# route true
|
22
|
+
# provider TestLab::Provider::Vagrant
|
23
|
+
# provisioners [
|
24
|
+
# TestLab::Provisioner::Raring,
|
25
|
+
# TestLab::Provisioner::Bind
|
26
|
+
# ]
|
34
27
|
#
|
35
|
-
#
|
36
|
-
# config Hash[
|
28
|
+
# config ({
|
37
29
|
# :vagrant => {
|
38
|
-
# :id => "
|
39
|
-
# :
|
40
|
-
# :
|
41
|
-
# :
|
42
|
-
# :
|
43
|
-
# :
|
44
|
-
#
|
30
|
+
# :id => "chef-rubygem-#{TestLab.hostname}".downcase,
|
31
|
+
# :cpus => ZTK::Parallel::MAX_FORKS.div(2), # use half of the available processors
|
32
|
+
# :memory => ZTK::Parallel::MAX_MEMORY.div(3).div(1024 * 1024), # use a third of available RAM
|
33
|
+
# :box => 'raring64',
|
34
|
+
# :box_url => 'https://dl.dropboxusercontent.com/u/22904185/boxes/raring64.box',
|
35
|
+
# :file => File.dirname(__FILE__)
|
36
|
+
# },
|
37
|
+
# :bind => {
|
38
|
+
# :domain => "default.zone"
|
45
39
|
# }
|
46
|
-
#
|
40
|
+
# })
|
47
41
|
#
|
48
|
-
# network
|
49
|
-
#
|
50
|
-
#
|
42
|
+
# network 'labnet' do
|
43
|
+
# provisioners [TestLab::Provisioner::Route]
|
44
|
+
# address '10.10.0.1/16'
|
45
|
+
# bridge :br0
|
51
46
|
# end
|
52
47
|
#
|
53
|
-
# container "server
|
54
|
-
#
|
48
|
+
# container "chef-server" do
|
49
|
+
# distro "ubuntu"
|
50
|
+
# release "precise"
|
51
|
+
#
|
52
|
+
# provisioners [
|
53
|
+
# TestLab::Provisioner::Resolv,
|
54
|
+
# TestLab::Provisioner::AptCacherNG,
|
55
|
+
# TestLab::Provisioner::Apt,
|
56
|
+
# TestLab::Provisioner::Chef::RubyGemServer
|
57
|
+
# ]
|
58
|
+
#
|
59
|
+
# user 'deployer' do
|
60
|
+
# password 'deployer'
|
61
|
+
# identity File.join(ENV['HOME'], '.ssh', 'id_rsa')
|
62
|
+
# public_identity File.join(ENV['HOME'], '.ssh', 'id_rsa.pub')
|
63
|
+
# uid 2600
|
64
|
+
# gid 2600
|
65
|
+
# end
|
66
|
+
#
|
67
|
+
# interface do
|
68
|
+
# network_id 'labnet'
|
69
|
+
# name :eth0
|
70
|
+
# address '10.10.0.254/16'
|
71
|
+
# mac '00:00:5e:63:b5:9f'
|
72
|
+
# end
|
73
|
+
# end
|
55
74
|
#
|
75
|
+
# container "chef-client" do
|
56
76
|
# distro "ubuntu"
|
57
77
|
# release "precise"
|
58
78
|
#
|
59
|
-
#
|
60
|
-
#
|
79
|
+
# provisioners [
|
80
|
+
# TestLab::Provisioner::Resolv,
|
81
|
+
# TestLab::Provisioner::AptCacherNG,
|
82
|
+
# TestLab::Provisioner::Apt,
|
83
|
+
# TestLab::Provisioner::Chef::RubyGemClient
|
84
|
+
# ]
|
85
|
+
#
|
86
|
+
# user 'deployer' do
|
87
|
+
# password 'deployer'
|
88
|
+
# identity File.join(ENV['HOME'], '.ssh', 'id_rsa')
|
89
|
+
# public_identity File.join(ENV['HOME'], '.ssh', 'id_rsa.pub')
|
90
|
+
# uid 2600
|
91
|
+
# gid 2600
|
92
|
+
# end
|
61
93
|
#
|
62
94
|
# interface do
|
63
|
-
#
|
64
|
-
#
|
65
|
-
# address
|
66
|
-
# mac
|
95
|
+
# network_id 'labnet'
|
96
|
+
# name :eth0
|
97
|
+
# address '10.10.0.20/16'
|
98
|
+
# mac '00:00:5e:b7:e5:15'
|
67
99
|
# end
|
68
100
|
# end
|
69
101
|
#
|
@@ -78,8 +110,8 @@ require 'testlab/monkeys'
|
|
78
110
|
# @example We can control things via code easily as well:
|
79
111
|
# testlab.create # creates the lab
|
80
112
|
# testlab.up # ensures the lab is up and running
|
81
|
-
# testlab.
|
82
|
-
# testlab.
|
113
|
+
# testlab.build # build the lab, creating all networks and containers
|
114
|
+
# testlab.demolish # demolish the lab, destroy all networks and containers
|
83
115
|
#
|
84
116
|
# @author Zachary Patten <zachary AT jovelabs DOT com>
|
85
117
|
class TestLab
|
@@ -115,11 +147,16 @@ class TestLab
|
|
115
147
|
|
116
148
|
labfile_path = (options[:labfile_path] || File.join(@repo_dir, 'Labfile'))
|
117
149
|
@labfile_path = File.expand_path(ZTK::Locator.find(labfile_path))
|
150
|
+
end
|
118
151
|
|
152
|
+
# Boot TestLab
|
153
|
+
#
|
154
|
+
# Change to the defined repository directory and load the *Labfile*.
|
155
|
+
#
|
156
|
+
# @return [Boolean] True if successful.
|
157
|
+
def boot
|
119
158
|
@labfile = TestLab::Labfile.load(labfile_path)
|
120
159
|
@labfile.testlab = self
|
121
|
-
|
122
|
-
Dir.chdir(@repo_dir)
|
123
160
|
end
|
124
161
|
|
125
162
|
# Test Lab Nodes
|
@@ -186,6 +223,30 @@ class TestLab
|
|
186
223
|
!alive?
|
187
224
|
end
|
188
225
|
|
226
|
+
# Test Lab Create
|
227
|
+
#
|
228
|
+
# Attempts to create our lab topology. This calls the create method on all of
|
229
|
+
# our nodes.
|
230
|
+
#
|
231
|
+
# @return [Boolean] True if successful.
|
232
|
+
def create
|
233
|
+
method_proxy(:create)
|
234
|
+
|
235
|
+
true
|
236
|
+
end
|
237
|
+
|
238
|
+
# Test Lab Destroy
|
239
|
+
#
|
240
|
+
# Attempts to destroy our lab topology. This calls the destroy method on all of
|
241
|
+
# our nodes.
|
242
|
+
#
|
243
|
+
# @return [Boolean] True if successful.
|
244
|
+
def destroy
|
245
|
+
reverse_method_proxy(:destroy)
|
246
|
+
|
247
|
+
true
|
248
|
+
end
|
249
|
+
|
189
250
|
# Test Lab Up
|
190
251
|
#
|
191
252
|
# Attempts to up our lab topology. This calls the up method on all of
|
@@ -246,6 +307,18 @@ class TestLab
|
|
246
307
|
true
|
247
308
|
end
|
248
309
|
|
310
|
+
# Test Lab Demolish
|
311
|
+
#
|
312
|
+
# Attempts to demolish our lab topology. This calls various methods on
|
313
|
+
# all of our nodes, networks and containers.
|
314
|
+
#
|
315
|
+
# @return [Boolean] True if successful.
|
316
|
+
def demolish
|
317
|
+
reverse_method_proxy(:demolish)
|
318
|
+
|
319
|
+
true
|
320
|
+
end
|
321
|
+
|
249
322
|
# Node Method Proxy
|
250
323
|
#
|
251
324
|
# Iterates all of the lab nodes, sending the supplied method name and arguments
|
data/spec/container_spec.rb
CHANGED
@@ -195,6 +195,7 @@ describe TestLab::Container do
|
|
195
195
|
describe "#setup" do
|
196
196
|
context "with no provisioner" do
|
197
197
|
it "should setup the container" do
|
198
|
+
subject.node.stub(:state) { :running }
|
198
199
|
subject.lxc.stub(:exists?) { true }
|
199
200
|
subject.lxc.stub(:state) { :stopped }
|
200
201
|
subject.provisioners = Array.new
|
@@ -207,6 +208,7 @@ describe TestLab::Container do
|
|
207
208
|
it "should setup the container" do
|
208
209
|
subject = TestLab::Container.first('server-shell')
|
209
210
|
|
211
|
+
subject.node.stub(:state) { :running }
|
210
212
|
subject.lxc.stub(:exists?) { true }
|
211
213
|
subject.lxc.stub(:state) { :stopped }
|
212
214
|
subject.provisioners = Array.new
|
@@ -219,6 +221,7 @@ describe TestLab::Container do
|
|
219
221
|
describe "#teardown" do
|
220
222
|
context "with no provisioner" do
|
221
223
|
it "should teardown the container" do
|
224
|
+
subject.node.stub(:state) { :running }
|
222
225
|
subject.lxc.stub(:exists?) { true }
|
223
226
|
subject.lxc.stub(:state) { :stopped }
|
224
227
|
subject.provisioners = Array.new
|
@@ -231,6 +234,7 @@ describe TestLab::Container do
|
|
231
234
|
it "should teardown the container" do
|
232
235
|
subject = TestLab::Container.first('server-shell')
|
233
236
|
|
237
|
+
subject.node.stub(:state) { :running }
|
234
238
|
subject.lxc.stub(:exists?) { true }
|
235
239
|
subject.lxc.stub(:state) { :stopped }
|
236
240
|
subject.provisioners = Array.new
|
data/spec/network_spec.rb
CHANGED
@@ -144,6 +144,8 @@ describe TestLab::Network do
|
|
144
144
|
|
145
145
|
describe "#setup" do
|
146
146
|
it "should create and online the network" do
|
147
|
+
subject.node.stub(:state) { :running }
|
148
|
+
subject.stub(:state) { :running }
|
147
149
|
subject.stub(:create) { true }
|
148
150
|
subject.stub(:up) { true }
|
149
151
|
|
@@ -153,6 +155,8 @@ describe TestLab::Network do
|
|
153
155
|
|
154
156
|
describe "#teardown" do
|
155
157
|
it "should create and online the network" do
|
158
|
+
subject.node.stub(:state) { :running }
|
159
|
+
subject.stub(:state) { :running }
|
156
160
|
subject.stub(:down) { true }
|
157
161
|
subject.stub(:destroy) { true }
|
158
162
|
|