testlab 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/lib/testlab/node.rb CHANGED
@@ -1,5 +1,3 @@
1
- require 'lxc'
2
-
3
1
  class TestLab
4
2
 
5
3
  # Node Error Class
@@ -19,111 +17,57 @@ class TestLab
19
17
 
20
18
  attribute :provider
21
19
  attribute :config
20
+ attribute :components
22
21
 
23
- def initialize(*args)
24
- super(*args)
25
-
26
- @ui = TestLab.ui
27
- @provider = self.provider.new(self.config)
28
- end
29
22
 
30
- def status
31
- {
32
- :instance_id => @provider.instance_id,
33
- :state => @provider.state,
34
- :user => @provider.user,
35
- :ip => @provider.ip,
36
- :port => @provider.port,
37
- :provider => @provider.class,
38
- :con => self.containers.count,
39
- :net => self.networks.count,
40
- :rtr => self.routers.count
41
- }
42
- end
23
+ autoload :Bind, 'testlab/node/bind'
24
+ autoload :Lifecycle, 'testlab/node/lifecycle'
25
+ autoload :LXC, 'testlab/node/lxc'
26
+ autoload :Resolv, 'testlab/node/resolv'
27
+ autoload :SSH, 'testlab/node/ssh'
28
+ autoload :Status, 'testlab/node/status'
43
29
 
44
- # SSH to the Node
45
- def ssh(options={})
46
- if (!defined?(@ssh) || @ssh.nil?)
47
- @ssh ||= ZTK::SSH.new({:ui => @ui, :timeout => 1200, :silence => true}.merge(options))
48
- @ssh.config do |c|
49
- c.host_name = @provider.ip
50
- c.user = @provider.user
51
- c.keys = @provider.identity
52
- end
53
- end
54
- @ssh
55
- end
30
+ include TestLab::Node::Bind
31
+ include TestLab::Node::Lifecycle
32
+ include TestLab::Node::LXC
33
+ include TestLab::Node::Resolv
34
+ include TestLab::Node::SSH
35
+ include TestLab::Node::Status
56
36
 
57
- # SSH to a container running on the Node
58
- def ssh_container(id, options={})
59
- end
60
37
 
61
- # Returns the LXC object for this Node
62
- #
63
- # This object is used to control containers on the node via it's provider
64
- def lxc(options={})
65
- if (!defined?(@lxc) || @lxc.nil?)
66
- @lxc ||= LXC.new
67
- @lxc.use_sudo = true
68
- @lxc.use_ssh = self.ssh
69
- end
70
- @lxc
71
- end
38
+ def initialize(*args)
39
+ super(*args)
72
40
 
73
- def arch
74
- @arch ||= self.ssh.exec(%(uname -m)).output.strip
41
+ @ui = TestLab.ui
42
+ @provider = self.provider.new(self.config)
75
43
  end
76
44
 
77
45
  ################################################################################
78
46
 
79
- # Callback: After Create
80
- # Ensure our packages are installed.
81
- def after_create
82
- self.ssh.exec(%(sudo apt-get -qq -y --force-yes update))
83
- self.ssh.exec(%(sudo apt-get -qq -y --force-yes install lxc bridge-utils debootstrap yum isc-dhcp-server bind9 ntpdate ntp))
84
- end
85
-
86
- # Callback: After Up
87
- def after_up
47
+ # Iterates an array of arrays calling the specified method on all the
48
+ # collections of objects
49
+ def call_collections(collections, method_name)
50
+ collections.each do |collection|
51
+ call_methods(collection, method_name)
52
+ end
88
53
  end
89
54
 
90
- ################################################################################
91
-
92
- # Provides a generic interface for triggering our callback framework
93
- def proxy_callbacks(action, objects, method_name, *method_args)
94
- callback_method = "#{action}_#{method_name}".to_sym
95
-
55
+ # Calls the specified method on all the objects supplied
56
+ def call_methods(objects, method_name)
96
57
  objects.each do |object|
97
- if object.respond_to?(callback_method)
98
- object.send(callback_method, *method_args)
58
+ if object.respond_to?(method_name)
59
+ object.send(method_name)
99
60
  end
100
61
  end
101
62
  end
102
63
 
103
- # Provides a generic interface for triggering our callback framework
104
- def self_callbacks(action, method_name, *method_args)
105
- callback_method = "#{action}_#{method_name}".to_sym
106
-
107
- if self.respond_to?(callback_method)
108
- self.send(callback_method, *method_args)
109
- end
110
- end
111
-
112
64
  # Method missing handler
113
65
  def method_missing(method_name, *method_args)
114
66
  @ui.logger.debug { "NODE METHOD MISSING: #{method_name.inspect}(#{method_args.inspect})" }
115
67
 
116
68
  if TestLab::Provider::PROXY_METHODS.include?(method_name)
117
69
  result = nil
118
- object_collections = [self.containers, self.routers, self.networks]
119
70
 
120
- self_callbacks(:before, method_name, *method_args)
121
-
122
- object_collections.each do |object_collection|
123
- proxy_callbacks(:before, object_collection, method_name, *method_args)
124
- end
125
-
126
- @ui.logger.debug { "method_name == #{method_name.inspect}" }
127
71
  if @provider.respond_to?(method_name)
128
72
  @ui.logger.debug { "@provider.send(#{method_name.inspect}, #{method_args.inspect})" }
129
73
  result = @provider.send(method_name, *method_args)
@@ -131,18 +75,21 @@ class TestLab
131
75
  raise TestLab::ProviderError, "Your provider does not respond to the method '#{method_name}'!"
132
76
  end
133
77
 
134
- self_callbacks(:after, method_name, *method_args)
135
-
136
- object_collections.reverse.each do |object_collection|
137
- proxy_callbacks(:after, object_collection, method_name, *method_args)
138
- end
139
-
140
78
  result
141
79
  else
142
80
  super(method_name, *method_args)
143
81
  end
144
82
  end
145
83
 
84
+ class << self
85
+
86
+ # Returns the path to the gems provider templates
87
+ def template_dir
88
+ File.join(TestLab.gem_dir, "lib", "testlab", "node", "templates")
89
+ end
90
+
91
+ end
92
+
146
93
  end
147
94
 
148
95
  end
@@ -192,7 +192,15 @@ class TestLab
192
192
 
193
193
  vagrantfile_template = File.join(TestLab::Provider.template_dir, "vagrant", "Vagrantfile.erb")
194
194
  vagrantfile = File.join(@config[:repo], "Vagrantfile")
195
- IO.write(vagrantfile, ZTK::Template.render(vagrantfile_template, context))
195
+
196
+ # UGLY; but it makes it run under 1.9.2
197
+ if RUBY_VERSION < "1.9.3"
198
+ File.open(vagrantfile, 'w') do |file|
199
+ file.puts(ZTK::Template.render(vagrantfile_template, context))
200
+ end
201
+ else
202
+ IO.write(vagrantfile, ZTK::Template.render(vagrantfile_template, context))
203
+ end
196
204
  end
197
205
 
198
206
  ################################################################################
@@ -7,7 +7,6 @@ class TestLab
7
7
  #
8
8
  # @author Zachary Patten <zachary@jovelabs.net>
9
9
  class Provisioner
10
-
11
10
  autoload :Shell, 'testlab/provisioners/shell'
12
11
  autoload :Chef, 'testlab/provisioners/chef'
13
12
 
@@ -37,27 +37,22 @@ class TestLab
37
37
  @ui.logger.debug { "Router Down: #{self.id} " }
38
38
  end
39
39
 
40
- # Reload the router
41
- def reload
42
- self.down
43
- self.up
44
- end
45
-
46
40
  # State of the router
47
41
  def state
48
42
  end
49
43
 
50
44
  # Router Callback: after_up
51
- def after_up
45
+ def setup
52
46
  @ui.logger.debug { "Router Callback: After Up: #{self.id} " }
53
47
  self.create
54
48
  self.up
55
49
  end
56
50
 
57
51
  # Router Callback: before_down
58
- def before_down
52
+ def teardown
59
53
  @ui.logger.debug { "Router Callback: Before Down: #{self.id} " }
60
54
  self.down
55
+ self.destroy
61
56
  end
62
57
 
63
58
  # Method missing handler
@@ -1,6 +1,6 @@
1
1
  class TestLab
2
2
  unless const_defined?(:VERSION)
3
3
  # TestLab Gem Version
4
- VERSION = "0.0.3"
4
+ VERSION = "0.0.4"
5
5
  end
6
6
  end
data/lib/testlab.rb CHANGED
@@ -22,11 +22,13 @@ class TestLab
22
22
 
23
23
  @@ui ||= nil
24
24
 
25
- def initialize(ui=ZTK::UI.new)
26
- labfile = ZTK::Locator.find('Labfile')
25
+ def initialize(options={})
26
+ labfile = (options[:labfile] || 'Labfile')
27
+ labfile_path = ZTK::Locator.find(labfile)
27
28
 
28
- @@ui = ui
29
- @labfile = TestLab::Labfile.load(labfile)
29
+ @@ui = (options[:ui] || ZTK::UI.new)
30
+
31
+ @labfile = TestLab::Labfile.load(labfile_path)
30
32
  end
31
33
 
32
34
  def nodes
@@ -82,8 +84,20 @@ class TestLab
82
84
  end
83
85
  end
84
86
 
87
+ def setup
88
+ self.dead? and raise TestLabError, "You must have a running node in order to setup your infrastructure!"
89
+
90
+ node_method_proxy(:setup)
91
+ end
92
+
93
+ def teardown
94
+ self.dead? and raise TestLabError, "You must have a running node in order to teardown your infrastructure!"
95
+
96
+ node_method_proxy(:teardown)
97
+ end
98
+
85
99
  # Proxy various method calls to our subordinate classes
86
- def method_proxy(method_name, *method_args)
100
+ def node_method_proxy(method_name, *method_args)
87
101
  @@ui.logger.debug { "TestLab.#{method_name}" }
88
102
  TestLab::Node.all.map do |node|
89
103
  node.send(method_name.to_sym, *method_args)
@@ -94,8 +108,8 @@ class TestLab
94
108
  def method_missing(method_name, *method_args)
95
109
  @@ui.logger.debug { "TESTLAB METHOD MISSING: #{method_name.inspect}(#{method_args.inspect})" }
96
110
 
97
- if TestLab::Provider::PROXY_METHODS.include?(method_name)
98
- method_proxy(method_name, *method_args)
111
+ if TestLab::Provider::PROXY_METHODS.include?(method_name) # || %w(setup teardown).map(&:to_sym).include?(method_name))
112
+ node_method_proxy(method_name, *method_args)
99
113
  else
100
114
  super(method_name, *method_args)
101
115
  end
data/spec/spec_helper.rb CHANGED
@@ -21,3 +21,5 @@ require 'coveralls'
21
21
  Coveralls.wear!
22
22
  ################################################################################
23
23
  require 'testlab'
24
+
25
+ LABFILE = File.join(File.dirname(__FILE__), 'support', 'Labfile')
data/spec/testlab_spec.rb CHANGED
@@ -2,7 +2,7 @@ require "spec_helper"
2
2
 
3
3
  describe TestLab do
4
4
 
5
- subject { TestLab.new(File.join(File.dirname(__FILE__), 'support', 'Labfile')) }
5
+ subject { TestLab.new(:labfile => LABFILE) }
6
6
 
7
7
  describe "class" do
8
8
 
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@jovelabs.com"]
29
- spec.description = %q{A framework for building virtual laboratories}
30
- spec.summary = %q{A framework for building virtual laboratories}
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}
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.0.3
4
+ version: 0.0.4
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-04-25 00:00:00.000000000 Z
12
+ date: 2013-04-28 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: lxc
@@ -139,7 +139,7 @@ dependencies:
139
139
  - - ! '>='
140
140
  - !ruby/object:Gem::Version
141
141
  version: '0'
142
- description: A framework for building virtual laboratories
142
+ description: A framework for building lightweight virtual infrastructure using LXC
143
143
  email:
144
144
  - zachary@jovelabs.com
145
145
  executables:
@@ -160,9 +160,31 @@ files:
160
160
  - bin/testlab-console
161
161
  - lib/testlab.rb
162
162
  - lib/testlab/container.rb
163
+ - lib/testlab/container/actions.rb
164
+ - lib/testlab/container/generators.rb
165
+ - lib/testlab/container/lifecycle.rb
166
+ - lib/testlab/container/lxc.rb
167
+ - lib/testlab/container/network.rb
168
+ - lib/testlab/container/status.rb
163
169
  - lib/testlab/labfile.rb
164
170
  - lib/testlab/network.rb
171
+ - lib/testlab/network/actions.rb
172
+ - lib/testlab/network/cidr.rb
173
+ - lib/testlab/network/lifecycle.rb
174
+ - lib/testlab/network/status.rb
165
175
  - lib/testlab/node.rb
176
+ - lib/testlab/node/bind.rb
177
+ - lib/testlab/node/lifecycle.rb
178
+ - lib/testlab/node/lxc.rb
179
+ - lib/testlab/node/resolv.rb
180
+ - lib/testlab/node/ssh.rb
181
+ - lib/testlab/node/status.rb
182
+ - lib/testlab/node/templates/bind-db.erb
183
+ - lib/testlab/node/templates/bind-setup.erb
184
+ - lib/testlab/node/templates/bind-zone.erb
185
+ - lib/testlab/node/templates/bind.erb
186
+ - lib/testlab/node/templates/node-setup.erb
187
+ - lib/testlab/node/templates/resolv.erb
166
188
  - lib/testlab/provider.rb
167
189
  - lib/testlab/providers/aws.rb
168
190
  - lib/testlab/providers/local.rb
@@ -195,7 +217,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
195
217
  version: '0'
196
218
  segments:
197
219
  - 0
198
- hash: -2122627985172332229
220
+ hash: -3944268925164045043
199
221
  required_rubygems_version: !ruby/object:Gem::Requirement
200
222
  none: false
201
223
  requirements:
@@ -204,13 +226,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
204
226
  version: '0'
205
227
  segments:
206
228
  - 0
207
- hash: -2122627985172332229
229
+ hash: -3944268925164045043
208
230
  requirements: []
209
231
  rubyforge_project:
210
232
  rubygems_version: 1.8.25
211
233
  signing_key:
212
234
  specification_version: 3
213
- summary: A framework for building virtual laboratories
235
+ summary: A framework for building lightweight virtual infrastructure using LXC
214
236
  test_files:
215
237
  - spec/provider_spec.rb
216
238
  - spec/provisioner_spec.rb