testlab 0.6.5 → 0.6.6

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.
Files changed (44) hide show
  1. data/README.md +35 -32
  2. data/bin/tl +13 -640
  3. data/lib/commands/container.rb +292 -0
  4. data/lib/commands/network.rb +233 -0
  5. data/lib/commands/node.rb +182 -0
  6. data/lib/commands/testlab.rb +98 -0
  7. data/lib/testlab/container/actions.rb +15 -5
  8. data/lib/testlab/container/io.rb +69 -0
  9. data/lib/testlab/container/lifecycle.rb +6 -10
  10. data/lib/testlab/container/status.rb +1 -1
  11. data/lib/testlab/container.rb +2 -0
  12. data/lib/testlab/network/actions.rb +16 -0
  13. data/lib/testlab/network/lifecycle.rb +14 -20
  14. data/lib/testlab/network/status.rb +11 -5
  15. data/lib/testlab/network.rb +6 -6
  16. data/lib/testlab/node/actions.rb +16 -0
  17. data/lib/testlab/node/lifecycle.rb +15 -11
  18. data/lib/testlab/node/status.rb +1 -2
  19. data/lib/testlab/node.rb +1 -1
  20. data/lib/testlab/provisioner.rb +2 -1
  21. data/lib/testlab/provisioners/apt.rb +1 -1
  22. data/lib/testlab/provisioners/apt_cacher_ng.rb +2 -2
  23. data/lib/testlab/provisioners/bind.rb +1 -1
  24. data/lib/testlab/provisioners/chef_gem.rb +2 -2
  25. data/lib/testlab/provisioners/omnibus.rb +2 -2
  26. data/lib/testlab/provisioners/omnitruck.rb +2 -2
  27. data/lib/testlab/provisioners/raring.rb +1 -1
  28. data/lib/testlab/provisioners/resolv.rb +2 -2
  29. data/lib/testlab/provisioners/route.rb +51 -0
  30. data/lib/testlab/provisioners/shell.rb +1 -1
  31. data/lib/testlab/provisioners/templates/apt/bootstrap.erb +6 -1
  32. data/lib/testlab/provisioners/templates/apt_cacher_ng/bootstrap.erb +4 -1
  33. data/lib/testlab/provisioners/templates/raring/bootstrap.erb +9 -4
  34. data/lib/testlab/utility/logger.rb +87 -0
  35. data/lib/testlab/utility.rb +4 -2
  36. data/lib/testlab/version.rb +1 -1
  37. data/lib/testlab.rb +28 -0
  38. data/spec/container_spec.rb +18 -12
  39. data/spec/network_spec.rb +4 -0
  40. data/spec/node_spec.rb +6 -19
  41. data/spec/provisioners/shell_spec.rb +2 -2
  42. data/spec/support/Labfile +3 -3
  43. data/testlab.gemspec +2 -2
  44. metadata +13 -6
@@ -30,7 +30,7 @@ class TestLab
30
30
  # @param [TestLab::Container] container The container which we want to
31
31
  # provision.
32
32
  # @return [Boolean] True if successful.
33
- def setup(container)
33
+ def on_container_setup(container)
34
34
  omnibus_template = File.join(TestLab::Provisioner.template_dir, 'chef', 'omnitruck.erb')
35
35
  config = {}.merge!({
36
36
  :server_name => container.fqdn,
@@ -53,7 +53,7 @@ class TestLab
53
53
  # This is a NO-OP currently.
54
54
  #
55
55
  # @return [Boolean] True if successful.
56
- def teardown(container)
56
+ def on_container_teardown(container)
57
57
  # NOOP
58
58
 
59
59
  true
@@ -24,7 +24,7 @@ class TestLab
24
24
  # @param [TestLab::Node] node The node which we want to
25
25
  # provision.
26
26
  # @return [Boolean] True if successful.
27
- def node(node)
27
+ def on_node_setup(node)
28
28
  @ui.logger.debug { "Ubuntu Raring Provisioner: Node #{node.id}" }
29
29
 
30
30
  bootstrap_template = File.join(TestLab::Provisioner.template_dir, "raring", "bootstrap.erb")
@@ -25,7 +25,7 @@ class TestLab
25
25
  #
26
26
  # @param [TestLab::Node] node The node which we want to provision.
27
27
  # @return [Boolean] True if successful.
28
- def node(node)
28
+ def on_node_setup(node)
29
29
  @ui.logger.debug { "RESOLV Provisioner: Node #{node.id}" }
30
30
 
31
31
  render_resolv_conf(node)
@@ -38,7 +38,7 @@ class TestLab
38
38
  # @param [TestLab::Container] container The container which we want to
39
39
  # provision.
40
40
  # @return [Boolean] True if successful.
41
- def setup(container)
41
+ def on_container_setup(container)
42
42
  @ui.logger.debug { "RESOLV Provisioner: Container #{container.id}" }
43
43
 
44
44
  render_resolv_conf(container)
@@ -0,0 +1,51 @@
1
+ class TestLab
2
+
3
+ class Provisioner
4
+
5
+ # Route Provisioner Error Class
6
+ class RouteError < ProvisionerError; end
7
+
8
+ # Route Provisioner Class
9
+ #
10
+ # @author Zachary Patten <zachary AT jovelabs DOT com>
11
+ class Route
12
+
13
+ def initialize(config={}, ui=nil)
14
+ @config = (config || Hash.new)
15
+ @ui = (ui || TestLab.ui)
16
+
17
+ @config[:route] ||= Hash.new
18
+
19
+ @ui.logger.debug { "config(#{@config.inspect})" }
20
+ end
21
+
22
+ # Route Provisioner Network Setup
23
+ def on_network_setup(network)
24
+ manage_route(:add, network)
25
+
26
+ true
27
+ end
28
+
29
+ # Route Provisioner Network Teardown
30
+ def on_network_teardown(network)
31
+ manage_route(:del, network)
32
+
33
+ true
34
+ end
35
+
36
+ def manage_route(action, network)
37
+ command = ZTK::Command.new(:ui => @ui, :silence => true, :ignore_exit_status => true)
38
+
39
+ case RUBY_PLATFORM
40
+ when /darwin/ then
41
+ action = ((action == :del) ? :delete : :add)
42
+ command.exec(%(sudo route #{action} -net #{TestLab::Utility.network(network.address)} #{network.node.ip} #{TestLab::Utility.netmask(network.address)}))
43
+ when /linux/ then
44
+ command.exec(%(sudo route #{action} -net #{TestLab::Utility.network(network.address)} netmask #{TestLab::Utility.netmask(network.address)} gw #{network.node.ip}))
45
+ end
46
+ end
47
+
48
+ end
49
+
50
+ end
51
+ end
@@ -24,7 +24,7 @@ class TestLab
24
24
  # @param [TestLab::Container] container The container which we want to
25
25
  # provision.
26
26
  # @return [Boolean] True if successful.
27
- def setup(container)
27
+ def on_container_setup(container)
28
28
  if !@config[:script].nil?
29
29
  container.bootstrap(@config[:script])
30
30
  end
@@ -1,11 +1,16 @@
1
1
  set -x
2
+ set -e
3
+
4
+ [[ -f /.testlab-apt-bootstrap ]] && exit 0
2
5
 
3
6
  export DEBIAN_FRONTEND="noninteractive"
4
7
 
5
- apt-get -y --force-yes update
8
+ apt-get -y update
6
9
  <% if !@apt[:install].nil? -%>
7
10
  apt-get -y install <%= @apt[:install].flatten.compact.join(' ') %>
8
11
  <% end -%>
9
12
  <% if !@apt[:remove].nil? -%>
10
13
  apt-get -y remove <%= @apt[:remove].flatten.compact.join(' ') %>
11
14
  <% end -%>
15
+
16
+ touch /.testlab-apt-bootstrap
@@ -1,7 +1,10 @@
1
1
  set -x
2
+ set -e
2
3
 
3
4
  export DEBIAN_FRONTEND="noninteractive"
4
5
 
5
6
  apt-get -y install apt-cacher-ng
6
7
  service apt-cacher-ng restart || service apt-cacher-ng start
7
- grep "^MIRROR" /etc/default/lxc || echo 'MIRROR="http://127.0.0.1:3142/archive.ubuntu.com/ubuntu"' | tee -a /etc/default/lxc && service lxc restart || service lxc start
8
+ grep "^MIRROR" /etc/default/lxc || echo 'MIRROR="http://127.0.0.1:3142/archive.ubuntu.com/ubuntu"' | tee -a /etc/default/lxc
9
+
10
+ # && service lxc restart || service lxc start
@@ -1,13 +1,18 @@
1
1
  set -x
2
+ set -e
2
3
 
3
4
  export DEBIAN_FRONTEND="noninteractive"
4
5
 
5
- # Update APT and ensure our required packages are installed
6
- apt-get -y update
7
- apt-get -y install lxc bridge-utils debootstrap yum iptables ntpdate ntp
6
+ if [ ! -f /.testlab-raring-bootstrap ]; then
7
+ # Update APT and ensure our required packages are installed
8
+ apt-get -y update
9
+ apt-get -y install lxc bridge-utils debootstrap yum iptables ntpdate ntp pbzip2
10
+
11
+ touch /.testlab-raring-bootstrap
12
+ fi
8
13
 
9
14
  # Ensure the default lxc networking services are off
10
- service lxc-net stop
15
+ service lxc-net stop || (service lxc-net start ; service lxc-net stop)
11
16
 
12
17
  # Ensure NTP services are enabled and running
13
18
  service ntp restart || service ntp start
@@ -0,0 +1,87 @@
1
+ class TestLab
2
+ module Utility
3
+
4
+ # Logger Error Class
5
+ class LoggerError < UtilityError; end
6
+
7
+ # Logger Module
8
+ #
9
+ # @author Zachary Patten <zachary AT jovelabs DOT com>
10
+ module Logger
11
+ require 'active_support/version'
12
+
13
+ def log_key_value(key, value, max_key_length)
14
+ " %s%s: %s" % [ key.upcase, '.' * (max_key_length - key.length), value.to_s ]
15
+ end
16
+
17
+ def log_page_break(max_key_length, char='-')
18
+ (char * max_key_length)
19
+ end
20
+
21
+ def log_details
22
+ @command = ZTK::Command.new(:silence => true, :ignore_exit_status => true)
23
+ {
24
+ "program" => $0.to_s.inspect,
25
+ "vagrant_version" => @command.exec(%(/usr/bin/env vagrant --version)).output.strip.inspect,
26
+ "virtualbox_version" => @command.exec(%(/usr/bin/env vboxmanage --version)).output.strip.inspect
27
+ }
28
+ end
29
+
30
+ def log_ruby
31
+ dependencies = {
32
+ "ruby_version" => RUBY_VERSION.inspect,
33
+ "ruby_patchlevel" => RUBY_PATCHLEVEL.inspect,
34
+ "ruby_platform" => RUBY_PLATFORM.inspect
35
+ }
36
+
37
+ defined?(RUBY_ENGINE) and dependencies.merge!("ruby_engine" => RUBY_ENGINE)
38
+
39
+ dependencies
40
+ end
41
+
42
+ def log_dependencies
43
+ {
44
+ "gli_version" => ::GLI::VERSION.inspect,
45
+ "lxc_version" => ::LXC::VERSION.inspect,
46
+ "ztk_version" => ::ZTK::VERSION.inspect,
47
+ "activesupport_version" => ::ActiveSupport::VERSION::STRING.inspect,
48
+ }
49
+ end
50
+
51
+ def log_header
52
+ log_lines = Array.new
53
+
54
+ details_hash = log_details
55
+ ruby_hash = log_ruby
56
+ dependencies_hash = log_dependencies
57
+
58
+ max_key_length = [details_hash.keys, ruby_hash.keys, dependencies_hash.keys].flatten.compact.map(&:length).max + 2
59
+ max_value_length = [details_hash.values, ruby_hash.values, dependencies_hash.values].flatten.compact.map(&:length).max + 2
60
+
61
+ max_length = (max_key_length + max_value_length + 2)
62
+
63
+ log_lines << log_page_break(max_length, '=')
64
+ details_hash.sort.each do |key, value|
65
+ log_lines << log_key_value(key, value, max_key_length)
66
+ end
67
+
68
+ log_lines << log_page_break(max_length)
69
+ ruby_hash.sort.each do |key, value|
70
+ log_lines << log_key_value(key, value, max_key_length)
71
+ end
72
+
73
+ log_lines << log_page_break(max_length)
74
+ dependencies_hash.sort.each do |key, value|
75
+ log_lines << log_key_value(key, value, max_key_length)
76
+ end
77
+
78
+ log_lines << log_page_break(max_length, '=')
79
+
80
+ log_lines.flatten.compact
81
+ end
82
+
83
+
84
+ end
85
+
86
+ end
87
+ end
@@ -10,10 +10,12 @@ class TestLab
10
10
  #
11
11
  # @author Zachary Patten <zachary AT jovelabs DOT com>
12
12
  module Utility
13
- autoload :CIDR, 'testlab/utility/cidr'
14
- autoload :Misc, 'testlab/utility/misc'
13
+ autoload :CIDR, 'testlab/utility/cidr'
14
+ autoload :Logger, 'testlab/utility/logger'
15
+ autoload :Misc, 'testlab/utility/misc'
15
16
 
16
17
  extend TestLab::Utility::CIDR
18
+ extend TestLab::Utility::Logger
17
19
  extend TestLab::Utility::Misc
18
20
 
19
21
  end
@@ -1,6 +1,6 @@
1
1
  class TestLab
2
2
  unless const_defined?(:VERSION)
3
3
  # TestLab Gem Version
4
- VERSION = "0.6.5"
4
+ VERSION = "0.6.6"
5
5
  end
6
6
  end
data/lib/testlab.rb CHANGED
@@ -210,6 +210,34 @@ class TestLab
210
210
  true
211
211
  end
212
212
 
213
+ # Test Lab Build
214
+ #
215
+ # Attempts to build our lab topology. This calls various methods on
216
+ # all of our nodes, networks and containers.
217
+ #
218
+ # @return [Boolean] True if successful.
219
+ def build
220
+ nodes.each do |node|
221
+ node.create
222
+ node.up
223
+ node.setup
224
+
225
+ node.networks.each do |network|
226
+ network.create
227
+ network.up
228
+ network.setup
229
+ end
230
+
231
+ node.containers.each do |container|
232
+ container.create
233
+ container.up
234
+ container.setup
235
+ end
236
+ end
237
+
238
+ true
239
+ end
240
+
213
241
  # Node Method Proxy
214
242
  #
215
243
  # Iterates all of the lab nodes, sending the supplied method name and arguments
@@ -156,6 +156,8 @@ describe TestLab::Container do
156
156
 
157
157
  describe "#destroy" do
158
158
  it "should destroy the container" do
159
+ subject.lxc.stub(:exists?) { true }
160
+ subject.lxc.stub(:state) { :stopped }
159
161
  subject.lxc.stub(:destroy) { true }
160
162
  subject.lxc_clone.stub(:destroy) { true }
161
163
  subject.destroy
@@ -164,6 +166,7 @@ describe TestLab::Container do
164
166
 
165
167
  describe "#up" do
166
168
  it "should up the container" do
169
+ subject.lxc.stub(:exists?) { true }
167
170
  subject.lxc.stub(:start) { true }
168
171
  subject.lxc.stub(:wait) { true }
169
172
  subject.lxc.stub(:state) { :running }
@@ -177,6 +180,7 @@ describe TestLab::Container do
177
180
 
178
181
  describe "#down" do
179
182
  it "should down the container" do
183
+ subject.lxc.stub(:exists?) { true }
180
184
  subject.lxc.stub(:stop) { true }
181
185
  subject.lxc.stub(:wait) { true }
182
186
  subject.lxc.stub(:state) { :stopped }
@@ -186,9 +190,9 @@ describe TestLab::Container do
186
190
 
187
191
  describe "#setup" do
188
192
  context "with no provisioner" do
189
- it "should create and online the container" do
190
- subject.stub(:create) { true }
191
- subject.stub(:up) { true }
193
+ it "should setup the container" do
194
+ subject.lxc.stub(:exists?) { true }
195
+ subject.lxc.stub(:state) { :stopped }
192
196
  subject.provisioners = Array.new
193
197
 
194
198
  subject.setup
@@ -196,10 +200,11 @@ describe TestLab::Container do
196
200
  end
197
201
 
198
202
  context "with the shell provisioner" do
199
- it "should create and online the container" do
203
+ it "should setup the container" do
200
204
  subject = TestLab::Container.first('server-shell')
201
- subject.stub(:create) { true }
202
- subject.stub(:up) { true }
205
+
206
+ subject.lxc.stub(:exists?) { true }
207
+ subject.lxc.stub(:state) { :stopped }
203
208
  subject.provisioners = Array.new
204
209
 
205
210
  subject.setup
@@ -209,9 +214,9 @@ describe TestLab::Container do
209
214
 
210
215
  describe "#teardown" do
211
216
  context "with no provisioner" do
212
- it "should create and online the container" do
213
- subject.stub(:down) { true }
214
- subject.stub(:destroy) { true }
217
+ it "should teardown the container" do
218
+ subject.lxc.stub(:exists?) { true }
219
+ subject.lxc.stub(:state) { :stopped }
215
220
  subject.provisioners = Array.new
216
221
 
217
222
  subject.teardown
@@ -219,10 +224,11 @@ describe TestLab::Container do
219
224
  end
220
225
 
221
226
  context "with the shell provisioner" do
222
- it "should create and online the container" do
227
+ it "should teardown the container" do
223
228
  subject = TestLab::Container.first('server-shell')
224
- subject.stub(:down) { true }
225
- subject.stub(:destroy) { true }
229
+
230
+ subject.lxc.stub(:exists?) { true }
231
+ subject.lxc.stub(:state) { :stopped }
226
232
  subject.provisioners = Array.new
227
233
 
228
234
  subject.teardown
data/spec/network_spec.rb CHANGED
@@ -108,6 +108,7 @@ describe TestLab::Network do
108
108
 
109
109
  describe "#create" do
110
110
  it "should create the network bridge" do
111
+ subject.stub(:state) { :not_created }
111
112
  subject.node.ssh.stub(:exec) { true }
112
113
  subject.create
113
114
  end
@@ -115,6 +116,7 @@ describe TestLab::Network do
115
116
 
116
117
  describe "#destroy" do
117
118
  it "should destroy the network bridge" do
119
+ subject.stub(:state) { :stopped }
118
120
  subject.node.ssh.stub(:exec) { true }
119
121
  subject.destroy
120
122
  end
@@ -122,6 +124,7 @@ describe TestLab::Network do
122
124
 
123
125
  describe "#up" do
124
126
  it "should online the network bridge" do
127
+ subject.stub(:state) { :stopped }
125
128
  subject.node.ssh.stub(:exec) { true }
126
129
  subject.up
127
130
  end
@@ -129,6 +132,7 @@ describe TestLab::Network do
129
132
 
130
133
  describe "#down" do
131
134
  it "should offline the network bridge" do
135
+ subject.stub(:state) { :running }
132
136
  subject.node.ssh.stub(:exec) { true }
133
137
  subject.down
134
138
  end
data/spec/node_spec.rb CHANGED
@@ -69,6 +69,7 @@ describe TestLab::Node do
69
69
  describe "#create" do
70
70
  it "should create the node" do
71
71
  subject.instance_variable_get(:@provider).stub(:create) { true }
72
+ subject.stub(:state) { :not_created }
72
73
  subject.create
73
74
  end
74
75
  end
@@ -76,6 +77,7 @@ describe TestLab::Node do
76
77
  describe "#destroy" do
77
78
  it "should destroy the node" do
78
79
  subject.instance_variable_get(:@provider).stub(:destroy) { true }
80
+ subject.stub(:state) { :stopped }
79
81
  subject.destroy
80
82
  end
81
83
  end
@@ -83,6 +85,7 @@ describe TestLab::Node do
83
85
  describe "#up" do
84
86
  it "should online the node" do
85
87
  subject.instance_variable_get(:@provider).stub(:up) { true }
88
+ subject.stub(:state) { :stopped }
86
89
  subject.up
87
90
  end
88
91
  end
@@ -90,6 +93,7 @@ describe TestLab::Node do
90
93
  describe "#down" do
91
94
  it "should offline the node" do
92
95
  subject.instance_variable_get(:@provider).stub(:down) { true }
96
+ subject.stub(:state) { :running }
93
97
  subject.down
94
98
  end
95
99
  end
@@ -98,16 +102,7 @@ describe TestLab::Node do
98
102
  it "should setup the node" do
99
103
  subject.provisioners = Array.new
100
104
  subject.containers.each { |c| c.provisioners = Array.new }
101
- subject.ssh.stub(:bootstrap) { true }
102
- subject.stub(:route_setup) { true }
103
- subject.stub(:create) { true }
104
- subject.stub(:up) { true }
105
- subject.containers.each do |container|
106
- container.stub(:setup) { true }
107
- end
108
- subject.networks.each do |network|
109
- network.stub(:setup) { true }
110
- end
105
+ subject.stub(:state) { :running }
111
106
  subject.setup
112
107
  end
113
108
  end
@@ -116,15 +111,7 @@ describe TestLab::Node do
116
111
  it "should teardown the node" do
117
112
  subject.provisioners = Array.new
118
113
  subject.containers.each { |c| c.provisioners = Array.new }
119
- subject.stub(:route_setup) { true }
120
- subject.stub(:down) { true }
121
- subject.stub(:destroy) { true }
122
- subject.containers.each do |container|
123
- container.stub(:teardown) { true }
124
- end
125
- subject.networks.each do |network|
126
- network.stub(:teardown) { true }
127
- end
114
+ subject.stub(:state) { :running }
128
115
  subject.teardown
129
116
  end
130
117
  end
@@ -42,7 +42,7 @@ describe TestLab::Provisioner::Shell do
42
42
  it "should provision the container" do
43
43
  subject.node.ssh.stub(:file).and_yield(StringIO.new)
44
44
  subject.lxc.stub(:attach) { "" }
45
- subject.provisioners.last.new(subject.config, @ui).setup(subject)
45
+ subject.provisioners.last.new(subject.config, @ui).on_container_setup(subject)
46
46
  end
47
47
  end
48
48
 
@@ -50,7 +50,7 @@ describe TestLab::Provisioner::Shell do
50
50
  it "should raise an exception" do
51
51
  subject.node.ssh.stub(:file).and_yield(StringIO.new)
52
52
  subject.lxc.stub(:attach) { "No such file or directory" }
53
- lambda{ subject.provisioners.last.new(subject.config, @ui).setup(subject) }.should raise_error TestLab::ContainerError
53
+ lambda{ subject.provisioners.last.new(subject.config, @ui).on_container_setup(subject) }.should raise_error TestLab::ContainerError
54
54
  end
55
55
  end
56
56
  end
data/spec/support/Labfile CHANGED
@@ -33,9 +33,9 @@ node :localhost do
33
33
  })
34
34
 
35
35
  network 'testnet' do
36
- address '192.168.255.254/16'
37
- bridge :br0
38
- route true
36
+ provisioners [TestLab::Provisioner::Route]
37
+ address '192.168.255.254/16'
38
+ bridge :br0
39
39
  end
40
40
 
41
41
  # DUAL NICs
data/testlab.gemspec CHANGED
@@ -26,8 +26,8 @@ Gem::Specification.new do |spec|
26
26
  spec.version = TestLab::VERSION
27
27
  spec.authors = ["Zachary Patten"]
28
28
  spec.email = ["zachary AT jovelabs DOT com"]
29
- spec.description = %q{A framework for building lightweight virtual infrastructure using LXC}
30
- spec.summary = %q{A framework for building lightweight virtual infrastructure using LXC}
29
+ spec.description = %q{A toolkit for building virtual computer labs}
30
+ spec.summary = %q{A toolkit for building virtual computer labs}
31
31
  spec.homepage = "https://github.com/zpatten/testlab"
32
32
  spec.license = "Apache 2.0"
33
33
 
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.6.5
4
+ version: 0.6.6
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-06-14 00:00:00.000000000 Z
12
+ date: 2013-06-16 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: gli
@@ -187,7 +187,7 @@ dependencies:
187
187
  - - ! '>='
188
188
  - !ruby/object:Gem::Version
189
189
  version: '0'
190
- description: A framework for building lightweight virtual infrastructure using LXC
190
+ description: A toolkit for building virtual computer labs
191
191
  email:
192
192
  - zachary AT jovelabs DOT com
193
193
  executables:
@@ -206,12 +206,17 @@ files:
206
206
  - README.md
207
207
  - Rakefile
208
208
  - bin/tl
209
+ - lib/commands/container.rb
210
+ - lib/commands/network.rb
211
+ - lib/commands/node.rb
212
+ - lib/commands/testlab.rb
209
213
  - lib/testlab.rb
210
214
  - lib/testlab/container.rb
211
215
  - lib/testlab/container/actions.rb
212
216
  - lib/testlab/container/class_methods.rb
213
217
  - lib/testlab/container/generators.rb
214
218
  - lib/testlab/container/interface.rb
219
+ - lib/testlab/container/io.rb
215
220
  - lib/testlab/container/lifecycle.rb
216
221
  - lib/testlab/container/lxc.rb
217
222
  - lib/testlab/container/method_missing.rb
@@ -249,6 +254,7 @@ files:
249
254
  - lib/testlab/provisioners/omnitruck.rb
250
255
  - lib/testlab/provisioners/raring.rb
251
256
  - lib/testlab/provisioners/resolv.rb
257
+ - lib/testlab/provisioners/route.rb
252
258
  - lib/testlab/provisioners/shell.rb
253
259
  - lib/testlab/provisioners/templates/apt/bootstrap.erb
254
260
  - lib/testlab/provisioners/templates/apt_cacher_ng/00proxy.erb
@@ -265,6 +271,7 @@ files:
265
271
  - lib/testlab/user/lifecycle.rb
266
272
  - lib/testlab/utility.rb
267
273
  - lib/testlab/utility/cidr.rb
274
+ - lib/testlab/utility/logger.rb
268
275
  - lib/testlab/utility/misc.rb
269
276
  - lib/testlab/version.rb
270
277
  - spec/container_spec.rb
@@ -293,7 +300,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
293
300
  version: '0'
294
301
  segments:
295
302
  - 0
296
- hash: -1637961077093843979
303
+ hash: -2743048303371547587
297
304
  required_rubygems_version: !ruby/object:Gem::Requirement
298
305
  none: false
299
306
  requirements:
@@ -302,13 +309,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
302
309
  version: '0'
303
310
  segments:
304
311
  - 0
305
- hash: -1637961077093843979
312
+ hash: -2743048303371547587
306
313
  requirements: []
307
314
  rubyforge_project:
308
315
  rubygems_version: 1.8.25
309
316
  signing_key:
310
317
  specification_version: 3
311
- summary: A framework for building lightweight virtual infrastructure using LXC
318
+ summary: A toolkit for building virtual computer labs
312
319
  test_files:
313
320
  - spec/container_spec.rb
314
321
  - spec/network_spec.rb