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.
- data/bin/tl +80 -2
- data/lib/testlab/container/lifecycle.rb +2 -2
- data/lib/testlab/container/status.rb +1 -1
- data/lib/testlab/container.rb +3 -3
- data/lib/testlab/network/lifecycle.rb +12 -2
- data/lib/testlab/node/lifecycle.rb +5 -39
- data/lib/testlab/node/ssh.rb +2 -2
- data/lib/testlab/node.rb +7 -9
- data/lib/testlab/providers/local.rb +74 -2
- data/lib/testlab/provisioner.rb +4 -0
- data/lib/testlab/provisioners/apt.rb +39 -0
- data/lib/testlab/provisioners/apt_cacher_ng.rb +33 -35
- data/lib/testlab/{node → provisioners}/bind.rb +51 -24
- data/lib/testlab/provisioners/chef_gem.rb +3 -81
- data/lib/testlab/provisioners/raring.rb +37 -0
- data/lib/testlab/provisioners/resolv.rb +61 -0
- data/lib/testlab/provisioners/shell.rb +0 -11
- data/lib/testlab/provisioners/templates/apt/bootstrap.erb +11 -0
- data/lib/testlab/provisioners/templates/apt_cacher_ng/00proxy.erb +4 -0
- data/lib/testlab/provisioners/templates/apt_cacher_ng/bootstrap.erb +7 -0
- data/lib/testlab/{node/templates → provisioners/templates/bind}/bind-db.erb +0 -0
- data/lib/testlab/{node/templates → provisioners/templates/bind}/bind-zone.erb +0 -0
- data/lib/testlab/{node/templates → provisioners/templates/bind}/bind.erb +0 -0
- data/lib/testlab/provisioners/templates/chef/omnibus.erb +2 -0
- data/lib/testlab/provisioners/templates/chef/omnitruck.erb +1 -1
- data/lib/testlab/provisioners/templates/chef/rubygem.erb +0 -0
- data/lib/testlab/{node/templates/node-setup.erb → provisioners/templates/raring/bootstrap.erb} +2 -0
- data/lib/testlab/provisioners/templates/resolv/resolv.conf.erb +9 -0
- data/lib/testlab/version.rb +1 -1
- data/lib/testlab.rb +58 -2
- data/spec/node_spec.rb +4 -19
- data/spec/provisioners/shell_spec.rb +3 -9
- data/spec/support/Labfile +29 -10
- metadata +17 -11
- data/lib/testlab/node/resolv.rb +0 -29
- 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
|
-
|
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
|
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
|
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
|
-
:
|
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
|
data/lib/testlab/container.rb
CHANGED
@@ -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
|
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
|
-
|
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
|
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
|
-
|
21
|
+
global_provisioners = [self.provisioners, self.containers.map(&:provisioners)].flatten.compact.uniq
|
39
22
|
|
40
|
-
|
41
|
-
|
42
|
-
|
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
|
data/lib/testlab/node/ssh.rb
CHANGED
@@ -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 =>
|
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 =>
|
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,
|
33
|
+
belongs_to :labfile, :class_name => 'TestLab::Labfile'
|
38
34
|
|
39
|
-
has_many :containers,
|
40
|
-
has_many :networks,
|
35
|
+
has_many :containers, :class_name => 'TestLab::Container'
|
36
|
+
has_many :networks, :class_name => 'TestLab::Network'
|
41
37
|
|
42
38
|
attribute :provider
|
43
|
-
attribute :
|
44
|
-
attribute :
|
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=
|
14
|
-
@
|
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
|
data/lib/testlab/provisioner.rb
CHANGED
@@ -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
|
-
#
|
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 { "
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
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
|
-
#
|
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 { "
|
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
|
49
|
-
apt_conf_d_proxy_file
|
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
|
-
|
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.
|
57
|
-
|
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
|
-
|
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
|
-
|
5
|
-
|
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(
|
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(
|
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(
|
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
|
-
|
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
|
-
|
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
|
-
|
84
|
-
|
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
|
-
|
89
|
-
|
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
|