testlab 0.5.4 → 0.6.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.
Files changed (36) hide show
  1. data/bin/tl +80 -2
  2. data/lib/testlab/container/lifecycle.rb +2 -2
  3. data/lib/testlab/container/status.rb +1 -1
  4. data/lib/testlab/container.rb +3 -3
  5. data/lib/testlab/network/lifecycle.rb +12 -2
  6. data/lib/testlab/node/lifecycle.rb +5 -39
  7. data/lib/testlab/node/ssh.rb +2 -2
  8. data/lib/testlab/node.rb +7 -9
  9. data/lib/testlab/providers/local.rb +74 -2
  10. data/lib/testlab/provisioner.rb +4 -0
  11. data/lib/testlab/provisioners/apt.rb +39 -0
  12. data/lib/testlab/provisioners/apt_cacher_ng.rb +33 -35
  13. data/lib/testlab/{node → provisioners}/bind.rb +51 -24
  14. data/lib/testlab/provisioners/chef_gem.rb +3 -81
  15. data/lib/testlab/provisioners/raring.rb +37 -0
  16. data/lib/testlab/provisioners/resolv.rb +61 -0
  17. data/lib/testlab/provisioners/shell.rb +0 -11
  18. data/lib/testlab/provisioners/templates/apt/bootstrap.erb +11 -0
  19. data/lib/testlab/provisioners/templates/apt_cacher_ng/00proxy.erb +4 -0
  20. data/lib/testlab/provisioners/templates/apt_cacher_ng/bootstrap.erb +7 -0
  21. data/lib/testlab/{node/templates → provisioners/templates/bind}/bind-db.erb +0 -0
  22. data/lib/testlab/{node/templates → provisioners/templates/bind}/bind-zone.erb +0 -0
  23. data/lib/testlab/{node/templates → provisioners/templates/bind}/bind.erb +0 -0
  24. data/lib/testlab/provisioners/templates/chef/omnibus.erb +2 -0
  25. data/lib/testlab/provisioners/templates/chef/omnitruck.erb +1 -1
  26. data/lib/testlab/provisioners/templates/chef/rubygem.erb +0 -0
  27. data/lib/testlab/{node/templates/node-setup.erb → provisioners/templates/raring/bootstrap.erb} +2 -0
  28. data/lib/testlab/provisioners/templates/resolv/resolv.conf.erb +9 -0
  29. data/lib/testlab/version.rb +1 -1
  30. data/lib/testlab.rb +58 -2
  31. data/spec/node_spec.rb +4 -19
  32. data/spec/provisioners/shell_spec.rb +3 -9
  33. data/spec/support/Labfile +29 -10
  34. metadata +17 -11
  35. data/lib/testlab/node/resolv.rb +0 -29
  36. data/lib/testlab/node/templates/resolv.erb +0 -4
data/bin/tl CHANGED
@@ -149,6 +149,82 @@ command :node do |c|
149
149
  end
150
150
  end
151
151
 
152
+ # NODE UP
153
+ ##########
154
+ c.desc 'Up a node'
155
+ c.long_desc <<-EOF
156
+ Up a node. The node is started and brought online.
157
+ EOF
158
+ c.command :up do |up|
159
+ up.action do |global_options, options, args|
160
+ if options[:id].nil?
161
+ help_now!('id is required') if options[:id].nil?
162
+ else
163
+ node = @testlab.nodes.select{ |c| c.id.to_sym == options[:id].to_sym }.first
164
+ node.nil? and raise TestLab::TestLabError, "We could not find the node you supplied!"
165
+
166
+ node.up
167
+ end
168
+ end
169
+ end
170
+
171
+ # NODE DOWN
172
+ ############
173
+ c.desc 'Down a node'
174
+ c.long_desc <<-EOF
175
+ Down a node. The node is stopped taking it offline.
176
+ EOF
177
+ c.command :down do |down|
178
+ down.action do |global_options, options, args|
179
+ if options[:id].nil?
180
+ help_now!('id is required') if options[:id].nil?
181
+ else
182
+ node = @testlab.nodes.select{ |c| c.id.to_sym == options[:id].to_sym }.first
183
+ node.nil? and raise TestLab::TestLabError, "We could not find the node you supplied!"
184
+
185
+ node.down
186
+ end
187
+ end
188
+ end
189
+
190
+ # NODE SETUP
191
+ #############
192
+ c.desc 'Setup a node'
193
+ c.long_desc <<-EOF
194
+ Setup a node. The node is created, started and provisioned.
195
+ EOF
196
+ c.command :setup do |setup|
197
+ setup.action do |global_options, options, args|
198
+ if options[:id].nil?
199
+ help_now!('id is required') if options[:id].nil?
200
+ else
201
+ node = @testlab.nodes.select{ |c| c.id.to_sym == options[:id].to_sym }.first
202
+ node.nil? and raise TestLab::TestLabError, "We could not find the node you supplied!"
203
+
204
+ node.setup
205
+ end
206
+ end
207
+ end
208
+
209
+ # NODE TEARDOWN
210
+ ################
211
+ c.desc 'Teardown a node'
212
+ c.long_desc <<-EOF
213
+ Teardown a node. The node is offlined and destroyed.
214
+ EOF
215
+ c.command :teardown do |teardown|
216
+ teardown.action do |global_options, options, args|
217
+ if options[:id].nil?
218
+ help_now!('id is required') if options[:id].nil?
219
+ else
220
+ node = @testlab.nodes.select{ |c| c.id.to_sym == options[:id].to_sym }.first
221
+ node.nil? and raise TestLab::TestLabError, "We could not find the node you supplied!"
222
+
223
+ node.teardown
224
+ end
225
+ end
226
+ end
227
+
152
228
  end
153
229
 
154
230
  # NETWORKS
@@ -377,8 +453,10 @@ EOF
377
453
  if containers.count == 0
378
454
  @testlab.ui.stderr.puts("You either have no containers defined or dead nodes!".yellow)
379
455
  else
380
- ZTK::Report.new(:ui => @testlab.ui).spreadsheet(containers, TestLab::Container::STATUS_KEYS.reject{|k| k == :fqdn}) do |container|
381
- OpenStruct.new(container.status.reject{|k,v| k == :fqdn})
456
+ # ZTK::Report.new(:ui => @testlab.ui).spreadsheet(containers, TestLab::Container::STATUS_KEYS.reject{|k| k == :fqdn}) do |container|
457
+ ZTK::Report.new(:ui => @testlab.ui).list(containers, TestLab::Container::STATUS_KEYS) do |container|
458
+ # OpenStruct.new(container.status.reject{|k,v| k == :fqdn})
459
+ OpenStruct.new(container.status)
382
460
  end
383
461
  end
384
462
  else
@@ -23,7 +23,7 @@ class TestLab
23
23
  end
24
24
 
25
25
  self.provisioners.each do |provisioner|
26
- @ui.logger.info { ">>>>> PROVISIONER SETUP #{provisioner} <<<<<" }
26
+ @ui.logger.info { ">>>>> SETUP CONTAINER PROVISIONER: #{provisioner} <<<<<" }
27
27
  p = provisioner.new(self.config, @ui)
28
28
  p.respond_to?(:setup) and p.setup(self)
29
29
  end
@@ -46,7 +46,7 @@ class TestLab
46
46
  please_wait(:ui => @ui, :message => format_object_action(self, 'Teardown', :red)) do
47
47
 
48
48
  self.provisioners.each do |provisioner|
49
- @ui.logger.info { ">>>>> PROVISIONER TEARDOWN #{provisioner} <<<<<" }
49
+ @ui.logger.info { ">>>>> TEARDOWN CONTAINER PROVISIONER: #{provisioner} <<<<<" }
50
50
  p = provisioner.new(self.config, @ui)
51
51
  p.respond_to?(:teardown) and p.teardown(self)
52
52
  end
@@ -59,7 +59,7 @@ class TestLab
59
59
  :distro => self.distro,
60
60
  :release => self.release,
61
61
  :interfaces => interfaces,
62
- :provisioner => self.provisioners.map(&:to_s).join(','),
62
+ :provisioners => self.provisioners.map(&:to_s).collect{ |p| p.split('::').last }.join('/'),
63
63
  :node_id => self.node.id
64
64
  }
65
65
  end
@@ -15,9 +15,9 @@ class TestLab
15
15
  # release "precise"
16
16
  #
17
17
  # user "deployer" do
18
+ # password "deployer"
18
19
  # uid 2600
19
20
  # gid 2600
20
- # password "deployer"
21
21
  # end
22
22
  #
23
23
  # interface do
@@ -34,9 +34,9 @@ class TestLab
34
34
  # release "precise"
35
35
  #
36
36
  # user "deployer" do
37
+ # password "deployer"
37
38
  # uid 2600
38
39
  # gid 2600
39
- # password "deployer"
40
40
  # end
41
41
  #
42
42
  # interface do
@@ -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 id clone fqdn state distro release interfaces provisioner).map(&:to_sym)
73
+ STATUS_KEYS = %w(node_id id clone fqdn state distro release interfaces provisioners).map(&:to_sym)
74
74
 
75
75
  # Sub-Modules
76
76
  autoload :Actions, 'testlab/container/actions'
@@ -9,16 +9,26 @@ class TestLab
9
9
 
10
10
  self.create
11
11
  self.up
12
- self.route and manage_route(:add)
12
+
13
+ please_wait(:ui => @ui, :message => format_object_action(self, 'Setup', :green)) do
14
+ self.route and manage_route(:add)
15
+ end
16
+
17
+ true
13
18
  end
14
19
 
15
20
  # Network Teardown
16
21
  def teardown
17
22
  @ui.logger.debug { "Network Teardown: #{self.id} " }
18
23
 
19
- self.route and manage_route(:del)
24
+ please_wait(:ui => @ui, :message => format_object_action(self, 'Teardown', :red)) do
25
+ self.route and manage_route(:del)
26
+ end
27
+
20
28
  self.down
21
29
  self.destroy
30
+
31
+ true
22
32
  end
23
33
 
24
34
  def manage_route(action)
@@ -3,23 +3,6 @@ class TestLab
3
3
 
4
4
  module Lifecycle
5
5
 
6
- # Iterates an array of arrays calling the specified method on all the
7
- # collections of objects
8
- def call_collections(collections, method_name)
9
- collections.each do |collection|
10
- call_methods(collection, method_name)
11
- end
12
- end
13
-
14
- # Calls the specified method on all the objects supplied
15
- def call_methods(objects, method_name)
16
- objects.each do |object|
17
- if object.respond_to?(method_name)
18
- object.send(method_name)
19
- end
20
- end
21
- end
22
-
23
6
  # Bootstrap the node
24
7
  def node_setup
25
8
  node_setup_template = File.join(self.class.template_dir, 'node-setup.erb')
@@ -35,31 +18,16 @@ class TestLab
35
18
 
36
19
  please_wait(:ui => @ui, :message => format_object_action(self, 'Setup', :green)) do
37
20
 
38
- node_setup
21
+ global_provisioners = [self.provisioners, self.containers.map(&:provisioners)].flatten.compact.uniq
39
22
 
40
- if self.components.include?('resolv')
41
- build_resolv_conf
42
- end
43
-
44
- if self.components.include?('bind')
45
- bind_setup
46
- end
47
-
48
- self.containers.each do |container|
49
- container.provisioners.each do |provisioner|
50
- p = provisioner.new(container.config, @ui)
51
- p.respond_to?(:node) and p.node(self)
52
- end
23
+ global_provisioners.each do |provisioner|
24
+ @ui.logger.info { ">>>>> NODE PROVISIONER: #{provisioner} <<<<<" }
25
+ p = provisioner.new(self.config, @ui)
26
+ p.respond_to?(:node) and p.node(self)
53
27
  end
54
28
 
55
29
  end
56
30
 
57
- call_collections([self.networks, self.containers], :setup)
58
-
59
- if self.components.include?('bind')
60
- bind_reload
61
- end
62
-
63
31
  true
64
32
  end
65
33
 
@@ -67,8 +35,6 @@ class TestLab
67
35
  def teardown
68
36
  @ui.logger.debug { "Node Teardown: #{self.id} " }
69
37
 
70
- call_collections([self.containers.reverse, self.networks.reverse], :teardown)
71
-
72
38
  please_wait(:ui => @ui, :message => format_object_action(self, 'Teardown', :red)) do
73
39
  # NOOP
74
40
  end
@@ -6,7 +6,7 @@ class TestLab
6
6
  # SSH to the Node
7
7
  def ssh(options={})
8
8
  if (!defined?(@ssh) || @ssh.nil?)
9
- @ssh ||= ZTK::SSH.new({:ui => @ui, :timeout => 1800, :silence => true}.merge(options))
9
+ @ssh ||= ZTK::SSH.new({:ui => @ui, :timeout => 3600, :silence => true}.merge(options))
10
10
  @ssh.config do |c|
11
11
  c.host_name = @provider.ip
12
12
  c.port = @provider.port
@@ -22,7 +22,7 @@ class TestLab
22
22
  name = container.id
23
23
  @container_ssh ||= Hash.new
24
24
  if @container_ssh[name].nil?
25
- @container_ssh[name] ||= ZTK::SSH.new({:ui => @ui, :timeout => 1800, :silence => true}.merge(options))
25
+ @container_ssh[name] ||= ZTK::SSH.new({:ui => @ui, :timeout => 3600, :silence => true}.merge(options))
26
26
  @container_ssh[name].config do |c|
27
27
  c.proxy_host_name = @provider.ip
28
28
  c.proxy_port = @provider.port
data/lib/testlab/node.rb CHANGED
@@ -11,21 +11,17 @@ class TestLab
11
11
 
12
12
  # Sub-Modules
13
13
  autoload :Actions, 'testlab/node/actions'
14
- autoload :Bind, 'testlab/node/bind'
15
14
  autoload :ClassMethods, 'testlab/node/class_methods'
16
15
  autoload :Lifecycle, 'testlab/node/lifecycle'
17
16
  autoload :LXC, 'testlab/node/lxc'
18
17
  autoload :MethodMissing, 'testlab/node/method_missing'
19
- autoload :Resolv, 'testlab/node/resolv'
20
18
  autoload :SSH, 'testlab/node/ssh'
21
19
  autoload :Status, 'testlab/node/status'
22
20
 
23
21
  include TestLab::Node::Actions
24
- include TestLab::Node::Bind
25
22
  include TestLab::Node::Lifecycle
26
23
  include TestLab::Node::LXC
27
24
  include TestLab::Node::MethodMissing
28
- include TestLab::Node::Resolv
29
25
  include TestLab::Node::SSH
30
26
  include TestLab::Node::Status
31
27
 
@@ -34,19 +30,21 @@ class TestLab
34
30
  include TestLab::Utility::Misc
35
31
 
36
32
  # Associations and Attributes
37
- belongs_to :labfile, :class_name => 'TestLab::Labfile'
33
+ belongs_to :labfile, :class_name => 'TestLab::Labfile'
38
34
 
39
- has_many :containers, :class_name => 'TestLab::Container'
40
- has_many :networks, :class_name => 'TestLab::Network'
35
+ has_many :containers, :class_name => 'TestLab::Container'
36
+ has_many :networks, :class_name => 'TestLab::Network'
41
37
 
42
38
  attribute :provider
43
- attribute :config, :default => Hash.new
44
- attribute :components, :default => Array.new
39
+ attribute :provisioners, :default => Array.new
40
+ attribute :config, :default => Hash.new
45
41
 
46
42
 
47
43
  def initialize(*args)
48
44
  super(*args)
49
45
 
46
+ raise NodeError, "You must specify a provider class!" if self.provider.nil?
47
+
50
48
  @ui = TestLab.ui
51
49
  @provider = self.provider.new(self.config, @ui)
52
50
  end
@@ -10,8 +10,80 @@ class TestLab
10
10
  # @author Zachary Patten <zachary AT jovelabs DOT com>
11
11
  class Local
12
12
 
13
- def initialize(ui=ZTK::UI.new)
14
- @ui = ui
13
+ def initialize(config={}, ui=nil)
14
+ @config = (config || Hash.new)
15
+ @ui = (ui || TestLab.ui)
16
+
17
+ # ensure our local key is there
18
+ @config[:local] ||= Hash.new
19
+ end
20
+
21
+ # This is a NO-OP
22
+ def create
23
+ true
24
+ end
25
+
26
+ # This is a NO-OP
27
+ def destroy
28
+ true
29
+ end
30
+
31
+ # This is a NO-OP
32
+ def up
33
+ self.state
34
+ end
35
+
36
+ # This is a NO-OP
37
+ def down
38
+ self.state
39
+ end
40
+
41
+ # This is a NO-OP
42
+ def reload
43
+ self.down
44
+ self.up
45
+
46
+ self.state
47
+ end
48
+
49
+ # This is a NO-OP
50
+ def state
51
+ :running
52
+ end
53
+
54
+ # This is a NO-OP
55
+ def exists?
56
+ true
57
+ end
58
+
59
+ # This is a NO-OP
60
+ def alive?
61
+ true
62
+ end
63
+
64
+ # This is a NO-OP
65
+ def dead?
66
+ false
67
+ end
68
+
69
+ def instance_id
70
+ %x(hostname).strip
71
+ end
72
+
73
+ def user
74
+ ENV['USER']
75
+ end
76
+
77
+ def identity
78
+ File.join(ENV['HOME'], ".ssh", "id_rsa")
79
+ end
80
+
81
+ def ip
82
+ "127.0.0.1"
83
+ end
84
+
85
+ def port
86
+ (@config[:local][:port] || 22)
15
87
  end
16
88
 
17
89
  end
@@ -7,10 +7,14 @@ class TestLab
7
7
  #
8
8
  # @author Zachary Patten <zachary AT jovelabs DOT com>
9
9
  class Provisioner
10
+ autoload :Apt, 'testlab/provisioners/apt'
10
11
  autoload :AptCacherNG, 'testlab/provisioners/apt_cacher_ng'
12
+ autoload :Bind, 'testlab/provisioners/bind'
11
13
  autoload :ChefGem, 'testlab/provisioners/chef_gem'
12
14
  autoload :OmniBus, 'testlab/provisioners/omnibus'
13
15
  autoload :OmniTruck, 'testlab/provisioners/omnitruck'
16
+ autoload :Resolv, 'testlab/provisioners/resolv'
17
+ autoload :Raring, 'testlab/provisioners/raring'
14
18
  autoload :Shell, 'testlab/provisioners/shell'
15
19
 
16
20
  class << self
@@ -0,0 +1,39 @@
1
+ class TestLab
2
+
3
+ class Provisioner
4
+
5
+ # APT Provisioner Error Class
6
+ class AptError < ProvisionerError; end
7
+
8
+ # APT Provisioner Class
9
+ #
10
+ # @author Zachary Patten <zachary AT jovelabs DOT com>
11
+ class Apt
12
+
13
+ def initialize(config={}, ui=nil)
14
+ @config = (config || Hash.new)
15
+ @ui = (ui || TestLab.ui)
16
+
17
+ @config[:apt] ||= Hash.new
18
+ @config[:apt][:install] ||= Array.new
19
+ @config[:apt][:remove] ||= Array.new
20
+
21
+ @ui.logger.debug { "config(#{@config.inspect})" }
22
+ end
23
+
24
+ # APT Provisioner Container Setup
25
+ #
26
+ # @param [TestLab::Container] container The container which we want to
27
+ # provision.
28
+ # @return [Boolean] True if successful.
29
+ def setup(container)
30
+ @ui.logger.debug { "APT Provisioner: Container #{container.id}" }
31
+
32
+ bootstrap_template = File.join(TestLab::Provisioner.template_dir, "apt", "bootstrap.erb")
33
+ container.ssh.bootstrap(ZTK::Template.render(bootstrap_template, @config))
34
+ end
35
+
36
+ end
37
+
38
+ end
39
+ end
@@ -14,65 +14,63 @@ class TestLab
14
14
  @config = (config || Hash.new)
15
15
  @ui = (ui || TestLab.ui)
16
16
 
17
+ @config[:apt] ||= Hash.new
18
+ @config[:apt][:cacher_ng] ||= Hash.new
19
+ @config[:apt][:cacher_ng][:exclude_hosts] ||= Array.new
20
+
21
+ @apt_conf_d_proxy_file_template = File.join(TestLab::Provisioner.template_dir, "apt_cacher_ng", "00proxy.erb")
22
+
17
23
  @ui.logger.debug { "config(#{@config.inspect})" }
18
24
  end
19
25
 
20
- # AptCacherNG Provisioner Node Setup
26
+ # APT-CacherNG Provisioner Node Setup
21
27
  #
22
28
  # @param [TestLab::Node] node The node which we want to provision.
23
29
  # @return [Boolean] True if successful.
24
30
  def node(node)
25
- @ui.logger.debug { "AptCacherNG Provisioner: Node #{node.id}" }
26
-
27
- script = <<-EOF
28
- apt-get -y install apt-cacher-ng
29
- service apt-cacher-ng restart || service apt-cacher-ng start
30
- echo 'Acquire::HTTP { Proxy "http://127.0.0.1:3142"; };' | tee /etc/apt/apt.conf.d/00proxy
31
- 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
32
- EOF
33
-
34
- node.ssh.bootstrap(script)
31
+ @ui.logger.debug { "APT-CacherNG Provisioner: Node #{node.id}" }
32
+
33
+ bootstrap_template = File.join(TestLab::Provisioner.template_dir, "apt_cacher_ng", "bootstrap.erb")
34
+ node.ssh.bootstrap(ZTK::Template.render(bootstrap_template, @config))
35
+
36
+ context = {
37
+ :apt => {
38
+ :cacher_ng => {
39
+ :proxy_url => "http://127.0.0.1:3142",
40
+ :exclude_hosts => Array.new
41
+ }
42
+ }
43
+ }
44
+
45
+ apt_conf_d_proxy_file = File.join("/etc", "apt", "apt.conf.d", "00proxy")
46
+ node.ssh.file(:target => apt_conf_d_proxy_file, :chown => "root:root", :chmod => "0644") do |file|
47
+ file.puts(ZTK::Template.render(@apt_conf_d_proxy_file_template, context))
48
+ end
35
49
 
36
50
  true
37
51
  end
38
52
 
39
- # AptCacherNG Provisioner Container Setup
53
+ # APT-CacherNG Provisioner Container Setup
40
54
  #
41
55
  # @param [TestLab::Container] container The container which we want to
42
56
  # provision.
43
57
  # @return [Boolean] True if successful.
44
58
  def setup(container)
45
- @ui.logger.debug { "AptCacherNG Provisioner: Container #{container.id}" }
59
+ @ui.logger.debug { "APT-CacherNG Provisioner: Container #{container.id}" }
46
60
 
47
61
  # Ensure the container APT calls use apt-cacher-ng on the node
48
- gateway_ip = container.primary_interface.network.ip
49
- apt_conf_d_proxy_file = File.join(container.lxc.fs_root, "etc", "apt", "apt.conf.d", "00proxy")
62
+ gateway_ip = container.primary_interface.network.ip
63
+ apt_conf_d_proxy_file = File.join(container.lxc.fs_root, "etc", "apt", "apt.conf.d", "00proxy")
50
64
 
51
- script = <<-EOF
52
- mkdir -pv #{File.dirname(apt_conf_d_proxy_file)}
53
- echo 'Acquire::HTTP { Proxy "http://#{gateway_ip}:3142"; };' | tee #{apt_conf_d_proxy_file}
54
- EOF
65
+ @config[:apt][:cacher_ng] = { :proxy_url => "http://#{gateway_ip}:3142" }.merge(@config[:apt][:cacher_ng])
55
66
 
56
- container.config[:apt_cacher_exclude_hosts].nil? or container.config[:apt_cacher_exclude_hosts].each do |host|
57
- script << %(echo 'Acquire::HTTP::Proxy::#{host} "DIRECT";' | tee -a #{apt_conf_d_proxy_file}\n)
67
+ container.node.ssh.file(:target => apt_conf_d_proxy_file, :chown => "root:root", :chmod => "0644") do |file|
68
+ file.puts(ZTK::Template.render(@apt_conf_d_proxy_file_template, @config))
58
69
  end
59
70
 
60
71
  # Fix the APT sources since LXC mudges them when using apt-cacher-ng
61
72
  apt_conf_sources_file = File.join(container.lxc.fs_root, "etc", "apt", "sources.list")
62
- script << %(sed -i 's/127.0.0.1:3142\\///g' #{apt_conf_sources_file}\n)
63
-
64
- container.node.ssh.bootstrap(script)
65
- end
66
-
67
- # AptCacherNG Provisioner Container Teardown
68
- #
69
- # This is a NO-OP currently.
70
- #
71
- # @return [Boolean] True if successful.
72
- def teardown(container)
73
- # NOOP
74
-
75
- true
73
+ container.node.ssh.exec(%(sudo sed -i 's/127.0.0.1:3142\\///g' #{apt_conf_sources_file}))
76
74
  end
77
75
 
78
76
  end
@@ -1,12 +1,39 @@
1
1
  class TestLab
2
- class Node
3
2
 
4
- module Bind
5
- require 'tempfile'
3
+ class Provisioner
4
+
5
+ # Bind Provisioner Error Class
6
+ class BindError < ProvisionerError; end
7
+
8
+ # Bind Provisioner Class
9
+ #
10
+ # @author Zachary Patten <zachary AT jovelabs DOT com>
11
+ class Bind
12
+
13
+ def initialize(config={}, ui=nil)
14
+ @config = (config || Hash.new)
15
+ @ui = (ui || TestLab.ui)
16
+
17
+ @config[:bind] ||= Hash.new
18
+
19
+ @ui.logger.debug { "config(#{@config.inspect})" }
20
+ end
21
+
22
+ # Bind Provisioner Node Setup
23
+ #
24
+ # @param [TestLab::Node] node The node which we want to provision.
25
+ # @return [Boolean] True if successful.
26
+ def node(node)
27
+ @ui.logger.debug { "BIND Provisioner: Node #{node.id}" }
28
+
29
+ bind_setup(node.ssh)
30
+
31
+ true
32
+ end
6
33
 
7
34
  # Builds the main bind configuration sections
8
35
  def build_bind_main_partial(file)
9
- bind_conf_template = File.join(self.class.template_dir, "bind.erb")
36
+ bind_conf_template = File.join(TestLab::Provisioner.template_dir, "bind", "bind.erb")
10
37
 
11
38
  file.puts(ZTK::Template.do_not_edit_notice(:message => "TestLab v#{TestLab::VERSION} BIND Configuration", :char => '//'))
12
39
  file.puts(ZTK::Template.render(bind_conf_template, {}))
@@ -32,8 +59,8 @@ class TestLab
32
59
  end
33
60
 
34
61
  # Builds the bind configuration sections for our zones
35
- def build_bind_zone_partial(file)
36
- bind_zone_template = File.join(self.class.template_dir, 'bind-zone.erb')
62
+ def build_bind_zone_partial(ssh, file)
63
+ bind_zone_template = File.join(TestLab::Provisioner.template_dir, "bind", 'bind-zone.erb')
37
64
 
38
65
  bind_records = build_bind_records
39
66
  forward_records = bind_records[:forward]
@@ -47,7 +74,7 @@ class TestLab
47
74
  file.puts
48
75
  file.puts(ZTK::Template.render(bind_zone_template, context))
49
76
 
50
- build_bind_db(network.arpa, reverse_records[network.id])
77
+ build_bind_db(ssh, network.arpa, reverse_records[network.id])
51
78
  end
52
79
 
53
80
  TestLab::Container.domains.each do |domain|
@@ -58,41 +85,41 @@ class TestLab
58
85
  file.puts
59
86
  file.puts(ZTK::Template.render(bind_zone_template, context))
60
87
 
61
- build_bind_db(domain, forward_records[domain])
88
+ build_bind_db(ssh, domain, forward_records[domain])
62
89
  end
63
90
  end
64
91
 
65
- def build_bind_db(zone, records)
66
- bind_db_template = File.join(self.class.template_dir, 'bind-db.erb')
92
+ def build_bind_db(ssh, zone, records)
93
+ bind_db_template = File.join(TestLab::Provisioner.template_dir, "bind", 'bind-db.erb')
67
94
 
68
- self.ssh.file(:target => "/etc/bind/db.#{zone}", :chown => "bind:bind") do |file|
95
+ ssh.file(:target => "/etc/bind/db.#{zone}", :chown => "bind:bind") do |file|
69
96
  file.puts(ZTK::Template.do_not_edit_notice(:message => "TestLab v#{TestLab::VERSION} BIND DB: #{zone}", :char => ';'))
70
97
  file.puts(ZTK::Template.render(bind_db_template, { :zone => zone, :records => records }))
71
98
  end
72
99
  end
73
100
 
74
101
  # Builds the BIND configuration
75
- def build_bind_conf
76
- self.ssh.file(:target => File.join("/etc/bind/named.conf"), :chown => "bind:bind") do |file|
102
+ def build_bind_conf(ssh)
103
+ ssh.file(:target => File.join("/etc/bind/named.conf"), :chown => "bind:bind") do |file|
77
104
  build_bind_main_partial(file)
78
- build_bind_zone_partial(file)
105
+ build_bind_zone_partial(ssh, file)
79
106
  end
80
107
  end
81
108
 
82
- def bind_install
83
- self.ssh.exec(%(sudo apt-get -y install bind9))
84
- self.ssh.exec(%(sudo rm -fv /etc/bind/{*.arpa,*.zone,*.conf*}))
109
+ def bind_install(ssh)
110
+ ssh.exec(%(sudo apt-get -y install bind9))
111
+ ssh.exec(%(sudo rm -fv /etc/bind/{*.arpa,*.zone,*.conf*}))
85
112
  end
86
113
 
87
- def bind_reload
88
- self.ssh.exec(%(sudo chown -Rv bind:bind /etc/bind))
89
- self.ssh.exec(%(sudo rndc reload))
114
+ def bind_reload(ssh)
115
+ ssh.exec(%(sudo chown -Rv bind:bind /etc/bind))
116
+ ssh.exec(%(sudo rndc reload))
90
117
  end
91
118
 
92
- def bind_setup
93
- bind_install
94
- build_bind_conf
95
- bind_reload
119
+ def bind_setup(ssh)
120
+ bind_install(ssh)
121
+ build_bind_conf(ssh)
122
+ bind_reload(ssh)
96
123
  end
97
124
 
98
125
  end