testlab 0.3.1 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +17 -1
- data/bin/tl +124 -8
- data/lib/testlab/container/lxc.rb +25 -0
- data/lib/testlab/container.rb +5 -5
- data/lib/testlab/interface.rb +2 -2
- data/lib/testlab/labfile.rb +2 -2
- data/lib/testlab/node/ssh.rb +2 -2
- data/lib/testlab/node/templates/node-setup.erb +1 -1
- data/lib/testlab/node.rb +2 -2
- data/lib/testlab/provisioner.rb +3 -2
- data/lib/testlab/provisioners/omnibus.rb +48 -0
- data/lib/testlab/provisioners/omnitruck.rb +115 -0
- data/lib/testlab/provisioners/shell.rb +18 -11
- data/lib/testlab/provisioners/templates/chef/omnibus.erb +6 -0
- data/lib/testlab/provisioners/templates/chef/omnitruck.erb +102 -0
- data/lib/testlab/version.rb +1 -1
- data/lib/testlab.rb +2 -4
- data/spec/container_spec.rb +55 -20
- data/spec/network_spec.rb +5 -1
- data/spec/node_spec.rb +51 -1
- data/spec/provisioners/shell_spec.rb +66 -0
- data/spec/support/Labfile +32 -4
- data/spec/testlab_spec.rb +4 -1
- data/spec/utility_spec.rb +114 -0
- metadata +12 -6
- data/lib/testlab/provisioners/chef.rb +0 -27
- data/lib/testlab/provisioners/templates/chef/bootstrap.erb +0 -0
data/README.md
CHANGED
@@ -6,13 +6,29 @@
|
|
6
6
|
|
7
7
|
# TestLab
|
8
8
|
|
9
|
-
|
9
|
+
What is TestLab? TestLab lets you iterate virtual infrastructure quickly. Using a `Labfile` you can define how you want your virtual infrastructure laid out. You can define multiple network segments and containers (i.e. boxen). TestLab will then setup and teardown this virtual infrastructure as you have dictated in the `Labfile`.
|
10
|
+
|
11
|
+
TestLab can be run directly on the command-line or can be interfaced with directly via code. Unlike the trend with some popular open-source software recently, I want you to build off this API interface and hopefully create tools I would of never dreamed up.
|
12
|
+
|
13
|
+
Accessing TestLab via code is meant to be fairly easy and straightforward. To get an instance of TestLab you only need about four lines of code:
|
14
|
+
|
15
|
+
log_file = File.join(Dir.pwd, "testlab.log")
|
16
|
+
@logger = ZTK::Logger.new(log_file)
|
17
|
+
@ui = ZTK::UI.new(:logger => @logger)
|
18
|
+
@testlab = TestLab.new(:ui => @ui)
|
19
|
+
|
20
|
+
Calling `TestLab.new` without a `:labfile` option will, by default, attempt to read `Labfile` from the current directory. This behaviour can be changed by passing the `:labfile` key with a path to your desired "Labfile" as the value to your `TestLab.new`.
|
21
|
+
|
22
|
+
For more information see the TestLab Documentation, `testlab-repo`, command-line binary and it never hurts to look at the TestLab source itself.
|
10
23
|
|
11
24
|
# REQUIREMENTS
|
12
25
|
|
13
26
|
* Latest VirtualBox Package
|
14
27
|
* Latest Vagrant Package (non-gem version)
|
28
|
+
* Ubuntu 13.04 Recommended; 12.10 Minimum
|
29
|
+
|
15
30
|
* Ubuntu 13.04 Server 64-bit (Raring) Base Box - https://github.com/zpatten/raring64
|
31
|
+
* Ubuntu 12.10 Server 64-bit (Quantal) Base Box - https://github.com/zpatten/quantal64
|
16
32
|
|
17
33
|
# EXAMPLE USE
|
18
34
|
|
data/bin/tl
CHANGED
@@ -27,11 +27,13 @@ include TestLab::Utility::Misc
|
|
27
27
|
version TestLab::VERSION
|
28
28
|
|
29
29
|
program_desc %(A framework for building lightweight virtual infrastructure using LXC)
|
30
|
-
program_long_desc %(Program Long Description)
|
30
|
+
# program_long_desc %(Program Long Description)
|
31
31
|
|
32
32
|
sort_help :manually
|
33
33
|
default_command :help
|
34
34
|
|
35
|
+
# LAB CREATE
|
36
|
+
#############
|
35
37
|
desc 'Create the test lab'
|
36
38
|
command :create do |create|
|
37
39
|
create.action do |global_options,options,args|
|
@@ -39,6 +41,8 @@ command :create do |create|
|
|
39
41
|
end
|
40
42
|
end
|
41
43
|
|
44
|
+
# LAB DESTROY
|
45
|
+
##############
|
42
46
|
desc 'Destroy the test lab'
|
43
47
|
command :destroy do |destroy|
|
44
48
|
destroy.action do |global_options,options,args|
|
@@ -46,6 +50,8 @@ command :destroy do |destroy|
|
|
46
50
|
end
|
47
51
|
end
|
48
52
|
|
53
|
+
# LAB ONLINE
|
54
|
+
#############
|
49
55
|
desc 'Online the test lab'
|
50
56
|
command :up do |up|
|
51
57
|
up.action do |global_options,options,args|
|
@@ -53,6 +59,8 @@ command :up do |up|
|
|
53
59
|
end
|
54
60
|
end
|
55
61
|
|
62
|
+
# LAB OFFLINE
|
63
|
+
##############
|
56
64
|
desc 'Offline the test lab'
|
57
65
|
command :down do |down|
|
58
66
|
down.action do |global_options,options,args|
|
@@ -60,6 +68,8 @@ command :down do |down|
|
|
60
68
|
end
|
61
69
|
end
|
62
70
|
|
71
|
+
# LAB SETUP
|
72
|
+
############
|
63
73
|
desc 'Setup the test lab infrastructure'
|
64
74
|
command :setup do |setup|
|
65
75
|
setup.action do |global_options,options,args|
|
@@ -67,6 +77,8 @@ command :setup do |setup|
|
|
67
77
|
end
|
68
78
|
end
|
69
79
|
|
80
|
+
# LAB TEARDOWN
|
81
|
+
###############
|
70
82
|
desc 'Teardown the test lab infrastructure'
|
71
83
|
command :teardown do |teardown|
|
72
84
|
teardown.action do |global_options,options,args|
|
@@ -74,6 +86,8 @@ command :teardown do |teardown|
|
|
74
86
|
end
|
75
87
|
end
|
76
88
|
|
89
|
+
# LAB STATUS
|
90
|
+
#############
|
77
91
|
desc 'Display information on the status of the test lab'
|
78
92
|
command :status do |status|
|
79
93
|
status.action do |global_options,options,args|
|
@@ -88,6 +102,8 @@ command :status do |status|
|
|
88
102
|
end
|
89
103
|
end
|
90
104
|
|
105
|
+
# NODES
|
106
|
+
########
|
91
107
|
desc 'Manage nodes'
|
92
108
|
arg_name 'Describe arguments to node here'
|
93
109
|
command :node do |c|
|
@@ -96,6 +112,8 @@ command :node do |c|
|
|
96
112
|
c.arg_name 'node'
|
97
113
|
c.flag [:i, :id]
|
98
114
|
|
115
|
+
# NODE SSH
|
116
|
+
###########
|
99
117
|
c.desc 'Open an SSH console to a node'
|
100
118
|
c.command :ssh do |ssh|
|
101
119
|
ssh.action do |global_options,options,args|
|
@@ -108,15 +126,19 @@ command :node do |c|
|
|
108
126
|
end
|
109
127
|
end
|
110
128
|
|
129
|
+
# NODE STATUS
|
130
|
+
##############
|
111
131
|
c.desc 'Display the status of node(s)'
|
112
|
-
c.long_desc 'Displays the status of all nodes or a single node if supplied via the
|
132
|
+
c.long_desc 'Displays the status of all nodes or a single node if supplied via the ID parameter.'
|
113
133
|
c.command :status do |status|
|
114
134
|
status.action do |global_options, options, args|
|
115
135
|
if options[:id].nil?
|
136
|
+
# No ID supplied; show everything
|
116
137
|
ZTK::Report.new(:ui => @testlab.ui).spreadsheet(@testlab.nodes, TestLab::Node::STATUS_KEYS) do |node|
|
117
138
|
OpenStruct.new(node.status)
|
118
139
|
end
|
119
140
|
else
|
141
|
+
# ID supplied; show just that item
|
120
142
|
node = @testlab.nodes.select{ |c| c.id.to_sym == options[:id].to_sym }.first
|
121
143
|
node.nil? and raise TestLab::TestLabError, "We could not find the node you supplied!"
|
122
144
|
|
@@ -129,6 +151,8 @@ command :node do |c|
|
|
129
151
|
|
130
152
|
end
|
131
153
|
|
154
|
+
# NETWORKS
|
155
|
+
###########
|
132
156
|
desc 'Manage networks'
|
133
157
|
arg_name 'Describe arguments to network here'
|
134
158
|
command :network do |c|
|
@@ -137,15 +161,24 @@ command :network do |c|
|
|
137
161
|
c.arg_name 'network'
|
138
162
|
c.flag [:i, :id]
|
139
163
|
|
164
|
+
# NETWORK STATUS
|
165
|
+
#################
|
140
166
|
c.desc 'Display the status of network(s)'
|
141
|
-
c.long_desc 'Displays the status of all networks or a single network if supplied via the
|
167
|
+
c.long_desc 'Displays the status of all networks or a single network if supplied via the ID parameter.'
|
142
168
|
c.command :status do |status|
|
143
169
|
status.action do |global_options, options, args|
|
144
170
|
if options[:id].nil?
|
145
|
-
|
146
|
-
|
171
|
+
# No ID supplied; show everything
|
172
|
+
networks = @testlab.networks.delete_if{|n| n.node.dead? }
|
173
|
+
if networks.count == 0
|
174
|
+
@testlab.ui.stderr.puts("You either have no networks defined or dead nodes!".yellow)
|
175
|
+
else
|
176
|
+
ZTK::Report.new(:ui => @testlab.ui).spreadsheet(networks, TestLab::Network::STATUS_KEYS) do |network|
|
177
|
+
OpenStruct.new(network.status)
|
178
|
+
end
|
147
179
|
end
|
148
180
|
else
|
181
|
+
# ID supplied; show just that item
|
149
182
|
network = @testlab.networks.select{ |c| c.id.to_sym == options[:id].to_sym }.first
|
150
183
|
network.nil? and raise TestLab::TestLabError, "We could not find the network you supplied!"
|
151
184
|
|
@@ -158,6 +191,8 @@ command :network do |c|
|
|
158
191
|
|
159
192
|
end
|
160
193
|
|
194
|
+
# CONTAINERS
|
195
|
+
#############
|
161
196
|
desc 'Manage containers'
|
162
197
|
arg_name 'Describe arguments to container here'
|
163
198
|
command :container do |c|
|
@@ -166,6 +201,8 @@ command :container do |c|
|
|
166
201
|
c.arg_name 'container'
|
167
202
|
c.flag [:i, :id]
|
168
203
|
|
204
|
+
# CONTAINER SSH
|
205
|
+
################
|
169
206
|
c.desc 'Open an SSH console to a container'
|
170
207
|
c.command :ssh do |ssh|
|
171
208
|
ssh.action do |global_options, options, args|
|
@@ -178,15 +215,26 @@ command :container do |c|
|
|
178
215
|
end
|
179
216
|
end
|
180
217
|
|
218
|
+
# CONTAINER STATUS
|
219
|
+
###################
|
181
220
|
c.desc 'Display the status of container(s)'
|
182
|
-
c.long_desc
|
221
|
+
c.long_desc <<-EOF
|
222
|
+
Displays the status of all containers or a single container if supplied via the ID parameter.
|
223
|
+
EOF
|
183
224
|
c.command :status do |status|
|
184
225
|
status.action do |global_options, options, args|
|
185
226
|
if options[:id].nil?
|
186
|
-
|
187
|
-
|
227
|
+
# No ID supplied; show everything
|
228
|
+
containers = @testlab.containers.delete_if{ |c| c.node.dead? }
|
229
|
+
if containers.count == 0
|
230
|
+
@testlab.ui.stderr.puts("You either have no containers defined or dead nodes!".yellow)
|
231
|
+
else
|
232
|
+
ZTK::Report.new(:ui => @testlab.ui).spreadsheet(containers, TestLab::Container::STATUS_KEYS.reject{|k| k == :fqdn}) do |container|
|
233
|
+
OpenStruct.new(container.status.reject{|k,v| k == :fqdn})
|
234
|
+
end
|
188
235
|
end
|
189
236
|
else
|
237
|
+
# ID supplied; show just that item
|
190
238
|
container = @testlab.containers.select{ |c| c.id.to_sym == options[:id].to_sym }.first
|
191
239
|
container.nil? and raise TestLab::TestLabError, "We could not find the container you supplied!"
|
192
240
|
|
@@ -197,11 +245,77 @@ command :container do |c|
|
|
197
245
|
end
|
198
246
|
end
|
199
247
|
|
248
|
+
# CONTAINER RECYCLE
|
249
|
+
####################
|
250
|
+
c.desc 'Recycles a container'
|
251
|
+
c.long_desc <<-EOF
|
252
|
+
Recycles a container. The container is taken through a series of state changes to ensure it is pristine.
|
253
|
+
|
254
|
+
The containers is cycled in this order:
|
255
|
+
|
256
|
+
Down -> Destroy -> Create -> Up
|
257
|
+
EOF
|
258
|
+
c.command :recycle do |recycle|
|
259
|
+
recycle.action do |global_options, options, args|
|
260
|
+
if options[:id].nil?
|
261
|
+
help_now!('id is required') if options[:id].nil?
|
262
|
+
else
|
263
|
+
container = @testlab.containers.select{ |c| c.id.to_sym == options[:id].to_sym }.first
|
264
|
+
container.nil? and raise TestLab::TestLabError, "We could not find the container you supplied!"
|
265
|
+
|
266
|
+
container.teardown
|
267
|
+
container.setup
|
268
|
+
end
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
# CONTAINER SETUP
|
273
|
+
####################
|
274
|
+
c.desc 'Setup a container'
|
275
|
+
c.long_desc <<-EOF
|
276
|
+
Setup a container. The container is created, started and provisioned.
|
277
|
+
EOF
|
278
|
+
c.command :setup do |setup|
|
279
|
+
setup.action do |global_options, options, args|
|
280
|
+
if options[:id].nil?
|
281
|
+
help_now!('id is required') if options[:id].nil?
|
282
|
+
else
|
283
|
+
container = @testlab.containers.select{ |c| c.id.to_sym == options[:id].to_sym }.first
|
284
|
+
container.nil? and raise TestLab::TestLabError, "We could not find the container you supplied!"
|
285
|
+
|
286
|
+
container.setup
|
287
|
+
end
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
# CONTAINER TEARDOWN
|
292
|
+
####################
|
293
|
+
c.desc 'Teardown a container'
|
294
|
+
c.long_desc <<-EOF
|
295
|
+
Teardown a container. The container is offlined and destroyed.
|
296
|
+
EOF
|
297
|
+
c.command :teardown do |teardown|
|
298
|
+
teardown.action do |global_options, options, args|
|
299
|
+
if options[:id].nil?
|
300
|
+
help_now!('id is required') if options[:id].nil?
|
301
|
+
else
|
302
|
+
container = @testlab.containers.select{ |c| c.id.to_sym == options[:id].to_sym }.first
|
303
|
+
container.nil? and raise TestLab::TestLabError, "We could not find the container you supplied!"
|
304
|
+
|
305
|
+
container.teardown
|
306
|
+
end
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
200
310
|
end
|
201
311
|
|
312
|
+
# ROUTES
|
313
|
+
#########
|
202
314
|
desc 'Manage routes'
|
203
315
|
command :route do |c|
|
204
316
|
|
317
|
+
# ROUTE ADD
|
318
|
+
############
|
205
319
|
c.desc 'Add routes to lab networks'
|
206
320
|
c.command :add do |add|
|
207
321
|
add.action do |global_options,options,args|
|
@@ -213,6 +327,8 @@ command :route do |c|
|
|
213
327
|
end
|
214
328
|
end
|
215
329
|
|
330
|
+
# ROUTE DEL
|
331
|
+
############
|
216
332
|
c.desc 'Delete routes to lab networks'
|
217
333
|
c.command :del do |del|
|
218
334
|
del.action do |global_options,options,args|
|
@@ -3,6 +3,31 @@ class TestLab
|
|
3
3
|
|
4
4
|
module LXC
|
5
5
|
|
6
|
+
# Container Bootstrap
|
7
|
+
#
|
8
|
+
# Renders the supplied content into a file on the container and proceeds
|
9
|
+
# to execute it on the container as root.
|
10
|
+
#
|
11
|
+
# @param [String] content The content to render on the container and
|
12
|
+
# execute. This is generally a bash script of some sort for example.
|
13
|
+
# @return [String] The output of *lxc-attach*.
|
14
|
+
def bootstrap(content)
|
15
|
+
output = nil
|
16
|
+
|
17
|
+
ZTK::RescueRetry.try(:tries => 3, :on => ContainerError) do
|
18
|
+
tempfile = Tempfile.new("bootstrap")
|
19
|
+
self.node.ssh.file(:target => File.join(self.lxc.fs_root, tempfile.path), :chmod => '0777', :chown => 'root:root') do |file|
|
20
|
+
file.puts(content)
|
21
|
+
end
|
22
|
+
output = self.lxc.attach(%(/bin/bash), tempfile.path)
|
23
|
+
if output =~ /No such file or directory/
|
24
|
+
raise ContainerError, "We could not find the bootstrap file!"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
output
|
29
|
+
end
|
30
|
+
|
6
31
|
# LXC::Container object
|
7
32
|
#
|
8
33
|
# Returns a *LXC::Container* class instance configured for this container.
|
data/lib/testlab/container.rb
CHANGED
@@ -87,16 +87,16 @@ class TestLab
|
|
87
87
|
has_many :interfaces, :class_name => 'TestLab::Interface'
|
88
88
|
|
89
89
|
attribute :provisioner
|
90
|
-
attribute :config
|
90
|
+
attribute :config, :default => Hash.new
|
91
91
|
|
92
92
|
attribute :domain
|
93
93
|
|
94
|
-
attribute :user
|
95
|
-
attribute :passwd
|
94
|
+
attribute :user, :default => 'ubuntu'
|
95
|
+
attribute :passwd, :default => 'ubuntu'
|
96
96
|
attribute :keys
|
97
97
|
|
98
|
-
attribute :distro
|
99
|
-
attribute :release
|
98
|
+
attribute :distro, :default => 'ubuntu'
|
99
|
+
attribute :release, :default => 'precise'
|
100
100
|
attribute :arch
|
101
101
|
|
102
102
|
attribute :persist
|
data/lib/testlab/interface.rb
CHANGED
@@ -10,13 +10,13 @@ class TestLab
|
|
10
10
|
|
11
11
|
# Associations and Attributes
|
12
12
|
belongs_to :container, :class_name => 'TestLab::Container'
|
13
|
-
belongs_to :network,
|
13
|
+
belongs_to :network, :class_name => 'TestLab::Network'
|
14
14
|
|
15
15
|
attribute :address
|
16
16
|
attribute :mac
|
17
17
|
attribute :name
|
18
18
|
|
19
|
-
attribute :primary
|
19
|
+
attribute :primary, :default => false
|
20
20
|
|
21
21
|
def initialize(*args)
|
22
22
|
super(*args)
|
data/lib/testlab/labfile.rb
CHANGED
@@ -7,9 +7,9 @@ class TestLab
|
|
7
7
|
#
|
8
8
|
# @author Zachary Patten <zachary AT jovelabs DOT com>
|
9
9
|
class Labfile < ZTK::DSL::Base
|
10
|
-
has_many
|
10
|
+
has_many :nodes, :class_name => 'TestLab::Node'
|
11
11
|
|
12
|
-
attribute
|
12
|
+
attribute :config, :default => Hash.new
|
13
13
|
end
|
14
14
|
|
15
15
|
end
|
data/lib/testlab/node/ssh.rb
CHANGED
@@ -30,9 +30,9 @@ class TestLab
|
|
30
30
|
c.proxy_keys = @provider.identity
|
31
31
|
|
32
32
|
c.host_name = container.ip
|
33
|
-
c.user =
|
33
|
+
c.user = container.user
|
34
34
|
if container.keys.nil?
|
35
|
-
c.password =
|
35
|
+
c.password = container.passwd
|
36
36
|
else
|
37
37
|
c.keys = container.keys
|
38
38
|
end
|
@@ -2,7 +2,7 @@ set -x
|
|
2
2
|
|
3
3
|
# Update APT and ensure our required packages are installed
|
4
4
|
apt-get -y update
|
5
|
-
apt-get -y install lxc bridge-utils debootstrap yum iptables ntpdate ntp
|
5
|
+
apt-get -y install lxc bridge-utils debootstrap yum iptables ntpdate ntp sshpass
|
6
6
|
|
7
7
|
# Ensure the default lxc networking services are off
|
8
8
|
service lxc-net stop
|
data/lib/testlab/node.rb
CHANGED
data/lib/testlab/provisioner.rb
CHANGED
@@ -7,8 +7,9 @@ class TestLab
|
|
7
7
|
#
|
8
8
|
# @author Zachary Patten <zachary AT jovelabs DOT com>
|
9
9
|
class Provisioner
|
10
|
-
autoload :Shell,
|
11
|
-
autoload :
|
10
|
+
autoload :Shell, 'testlab/provisioners/shell'
|
11
|
+
autoload :OmniBus, 'testlab/provisioners/omnibus'
|
12
|
+
autoload :OmniTruck, 'testlab/provisioners/omnitruck'
|
12
13
|
|
13
14
|
class << self
|
14
15
|
|
@@ -0,0 +1,48 @@
|
|
1
|
+
class TestLab
|
2
|
+
|
3
|
+
class Provisioner
|
4
|
+
|
5
|
+
# OmniBus Provisioner Error Class
|
6
|
+
class OmniBusError < ProvisionerError; end
|
7
|
+
|
8
|
+
# OmniBus Provisioner Class
|
9
|
+
#
|
10
|
+
# @author Zachary Patten <zachary AT jovelabs DOT com>
|
11
|
+
class OmniBus
|
12
|
+
|
13
|
+
def initialize(config={}, ui=nil)
|
14
|
+
@config = (config || Hash.new)
|
15
|
+
@ui = (ui || TestLab.ui)
|
16
|
+
|
17
|
+
@config[:version] ||= %(latest)
|
18
|
+
@config[:omnibus_url] ||= %(https://www.opscode.com/chef/install.sh)
|
19
|
+
end
|
20
|
+
|
21
|
+
# OmniBus Provisioner Container Setup
|
22
|
+
#
|
23
|
+
# Renders the defined script to a temporary file on the target container
|
24
|
+
# and proceeds to execute said script as root via *lxc-attach*.
|
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
|
+
omnibus_template = File.join(TestLab::Provisioner.template_dir, 'chef', 'omnibus.erb')
|
31
|
+
container.bootstrap(ZTK::Template.render(omnibus_template, @config))
|
32
|
+
end
|
33
|
+
|
34
|
+
# OmniBus Provisioner Container Teardown
|
35
|
+
#
|
36
|
+
# This is a NO-OP currently.
|
37
|
+
#
|
38
|
+
# @return [Boolean] True if successful.
|
39
|
+
def teardown(container)
|
40
|
+
# NOOP
|
41
|
+
|
42
|
+
true
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
class TestLab
|
2
|
+
|
3
|
+
class Provisioner
|
4
|
+
|
5
|
+
# OmniTruck Provisioner Error Class
|
6
|
+
class OmniTruckError < ProvisionerError; end
|
7
|
+
|
8
|
+
# OmniTruck Provisioner Class
|
9
|
+
#
|
10
|
+
# @author Zachary Patten <zachary AT jovelabs DOT com>
|
11
|
+
class OmniTruck
|
12
|
+
require 'json'
|
13
|
+
|
14
|
+
def initialize(config={}, ui=nil)
|
15
|
+
@config = (config || Hash.new)
|
16
|
+
@ui = (ui || TestLab.ui)
|
17
|
+
|
18
|
+
@config[:version] ||= "latest"
|
19
|
+
@config[:prereleases] ||= false
|
20
|
+
@config[:nightlies] ||= false
|
21
|
+
end
|
22
|
+
|
23
|
+
# OmniTruck Provisioner Container Setup
|
24
|
+
#
|
25
|
+
# Renders the defined script to a temporary file on the target container
|
26
|
+
# and proceeds to execute said script as root via *lxc-attach*.
|
27
|
+
#
|
28
|
+
# @param [TestLab::Container] container The container which we want to
|
29
|
+
# provision.
|
30
|
+
# @return [Boolean] True if successful.
|
31
|
+
def setup(container)
|
32
|
+
omnibus_template = File.join(TestLab::Provisioner.template_dir, 'chef', 'omnitruck.erb')
|
33
|
+
config = {}.merge!({
|
34
|
+
:server_name => container.fqdn,
|
35
|
+
:chef_pre_11 => chef_pre_11?,
|
36
|
+
:chef_solo_attributes => build_chef_solo_attributes(container),
|
37
|
+
:chef_validator => (chef_pre_11? ? '/etc/chef/validation.pem' : '/etc/chef-server/chef-validator.pem'),
|
38
|
+
:chef_webui => (chef_pre_11? ? '/etc/chef/webui.pem' : '/etc/chef-server/chef-webui.pem'),
|
39
|
+
:chef_admin => (chef_pre_11? ? '/etc/chef/admin.pem' : '/etc/chef-server/admin.pem'),
|
40
|
+
:default_password => "p@ssw01d",
|
41
|
+
:user => ENV['USER'],
|
42
|
+
:hostname_short => container.id,
|
43
|
+
:hostname_full => container.fqdn
|
44
|
+
}).merge!(@config)
|
45
|
+
container.bootstrap(ZTK::Template.render(omnibus_template, config))
|
46
|
+
end
|
47
|
+
|
48
|
+
# OmniTruck Provisioner Container Teardown
|
49
|
+
#
|
50
|
+
# This is a NO-OP currently.
|
51
|
+
#
|
52
|
+
# @return [Boolean] True if successful.
|
53
|
+
def teardown(container)
|
54
|
+
# NOOP
|
55
|
+
|
56
|
+
true
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def build_chef_solo_10_attributes(container)
|
62
|
+
{
|
63
|
+
"chef-server" => {
|
64
|
+
"webui_enabled" => true
|
65
|
+
},
|
66
|
+
"run_list" => %w(recipe[chef-server::rubygems-install] recipe[chef-server::apache-proxy])
|
67
|
+
}
|
68
|
+
end
|
69
|
+
|
70
|
+
def build_chef_solo_11_attributes(container)
|
71
|
+
{
|
72
|
+
"chef-server" => {
|
73
|
+
"api_fqdn" => container.fqdn,
|
74
|
+
"nginx" => {
|
75
|
+
"enable_non_ssl" => true,
|
76
|
+
"server_name" => container.fqdn,
|
77
|
+
"url" => "https://#{container.fqdn}"
|
78
|
+
},
|
79
|
+
"lb" => {
|
80
|
+
"fqdn" => container.fqdn
|
81
|
+
},
|
82
|
+
"bookshelf" => {
|
83
|
+
"vip" => container.fqdn
|
84
|
+
},
|
85
|
+
"chef_server_webui" => {
|
86
|
+
"enable" => true
|
87
|
+
},
|
88
|
+
"version" => @config[:version],
|
89
|
+
"prereleases" => @config[:prereleases],
|
90
|
+
"nightlies" => @config[:nightlies]
|
91
|
+
},
|
92
|
+
"run_list" => %w(recipe[chef-server::default])
|
93
|
+
}
|
94
|
+
end
|
95
|
+
|
96
|
+
def build_chef_solo_attributes(container)
|
97
|
+
if chef_pre_11?
|
98
|
+
build_chef_solo_10_attributes(container)
|
99
|
+
else
|
100
|
+
build_chef_solo_11_attributes(container)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def chef_pre_11?
|
105
|
+
if (@config[:version].to_s.downcase != "latest") && (@config[:version].to_f < 11.0)
|
106
|
+
true
|
107
|
+
else
|
108
|
+
false
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
end
|
@@ -14,26 +14,33 @@ class TestLab
|
|
14
14
|
def initialize(config={}, ui=nil)
|
15
15
|
@config = (config || Hash.new)
|
16
16
|
@ui = (ui || TestLab.ui)
|
17
|
-
|
18
|
-
@config[:shell] ||= "/bin/bash"
|
19
17
|
end
|
20
18
|
|
19
|
+
# Shell Provisioner Container Setup
|
20
|
+
#
|
21
|
+
# Renders the defined script to a temporary file on the target container
|
22
|
+
# and proceeds to execute said script as root via *lxc-attach*.
|
23
|
+
#
|
24
|
+
# @param [TestLab::Container] container The container which we want to
|
25
|
+
# provision.
|
26
|
+
# @return [Boolean] True if successful.
|
21
27
|
def setup(container)
|
22
28
|
if !@config[:setup].nil?
|
23
|
-
|
24
|
-
tempfile = Tempfile.new("bootstrap")
|
25
|
-
container.node.ssh.file(:target => File.join(container.lxc.fs_root, tempfile.path), :chmod => '0777', :chown => 'root:root') do |file|
|
26
|
-
file.puts(@config[:setup])
|
27
|
-
end
|
28
|
-
if container.lxc.attach(@config[:shell], tempfile.path) =~ /No such file or directory/
|
29
|
-
raise ShellError, "We could not find the bootstrap file!"
|
30
|
-
end
|
31
|
-
end
|
29
|
+
container.bootstrap(@config[:setup])
|
32
30
|
end
|
31
|
+
|
32
|
+
true
|
33
33
|
end
|
34
34
|
|
35
|
+
# Shell Provisioner Container Teardown
|
36
|
+
#
|
37
|
+
# This is a NO-OP currently.
|
38
|
+
#
|
39
|
+
# @return [Boolean] True if successful.
|
35
40
|
def teardown(container)
|
36
41
|
# NOOP
|
42
|
+
|
43
|
+
true
|
37
44
|
end
|
38
45
|
|
39
46
|
end
|