cucumber-chef 2.1.0.rc.1 → 2.1.0.rc.2
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/cc-knife +1 -1
- data/bin/cc-push +9 -14
- data/bin/cc-server +2 -3
- data/bin/cucumber-chef +111 -47
- data/chef_repo/cookbooks/cucumber-chef/recipes/test_lab.rb +2 -1
- data/cucumber-chef.gemspec +12 -4
- data/lib/cucumber/chef/bootstrap.rb +4 -3
- data/lib/cucumber/chef/config.rb +32 -17
- data/lib/cucumber/chef/helpers/chef_client.rb +6 -9
- data/lib/cucumber/chef/helpers/command.rb +1 -1
- data/lib/cucumber/chef/helpers/container.rb +5 -12
- data/lib/cucumber/chef/provider.rb +102 -0
- data/lib/cucumber/chef/providers/aws.rb +294 -0
- data/lib/cucumber/chef/providers/vagrant.rb +121 -0
- data/lib/cucumber/chef/provisioner.rb +32 -29
- data/lib/cucumber/chef/server.rb +133 -0
- data/lib/cucumber/chef/steps/ssh_steps.rb +23 -8
- data/lib/cucumber/chef/templates/bootstrap/ubuntu-precise-test-lab.erb +1 -1
- data/lib/cucumber/chef/templates/cucumber/cc-hooks.rb +8 -68
- data/lib/cucumber/chef/test_lab.rb +20 -309
- data/lib/cucumber/chef/utility.rb +109 -41
- data/lib/cucumber/chef/version.rb +1 -1
- data/lib/cucumber/chef.rb +5 -0
- metadata +42 -22
@@ -0,0 +1,102 @@
|
|
1
|
+
################################################################################
|
2
|
+
#
|
3
|
+
# Author: Zachary Patten <zachary@jovelabs.com>
|
4
|
+
# Copyright: Copyright (c) 2011-2013 Atalanta Systems Ltd
|
5
|
+
# License: Apache License, Version 2.0
|
6
|
+
#
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
+
# you may not use this file except in compliance with the License.
|
9
|
+
# You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16
|
+
# See the License for the specific language governing permissions and
|
17
|
+
# limitations under the License.
|
18
|
+
#
|
19
|
+
################################################################################
|
20
|
+
|
21
|
+
require 'cucumber/chef/providers/aws'
|
22
|
+
require 'cucumber/chef/providers/vagrant'
|
23
|
+
|
24
|
+
module Cucumber
|
25
|
+
module Chef
|
26
|
+
|
27
|
+
class ProviderError < Error; end
|
28
|
+
|
29
|
+
class Provider
|
30
|
+
attr_accessor :stdout, :stderr, :stdin, :logger
|
31
|
+
|
32
|
+
PROXY_METHODS = %w(create destroy up down status lab_exists? labs labs_running labs_shutdown id state username ip port chef_server_webui)
|
33
|
+
|
34
|
+
################################################################################
|
35
|
+
|
36
|
+
def initialize(stdout=STDOUT, stderr=STDERR, stdin=STDIN, logger=$logger)
|
37
|
+
@stdout, @stderr, @stdin, @logger = stdout, stderr, stdin, logger
|
38
|
+
@stdout.sync = true if @stdout.respond_to?(:sync=)
|
39
|
+
|
40
|
+
@provider = case Cucumber::Chef::Config[:provider]
|
41
|
+
when :aws then
|
42
|
+
Cucumber::Chef::Provider::AWS.new(@stdout, @stderr, @stdin, @logger)
|
43
|
+
when :vagrant then
|
44
|
+
Cucumber::Chef::Provider::Vagrant.new(@stdout, @stderr, @stdin, @logger)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
################################################################################
|
49
|
+
|
50
|
+
def chef_server_webui
|
51
|
+
"http://#{ip}:4040/"
|
52
|
+
end
|
53
|
+
|
54
|
+
def chef_server_api
|
55
|
+
"http://#{ip}:4000/"
|
56
|
+
end
|
57
|
+
|
58
|
+
def status
|
59
|
+
if lab_exists?
|
60
|
+
details = {
|
61
|
+
"Provider" => @provider.class,
|
62
|
+
"ID" => self.id,
|
63
|
+
"State" => self.state,
|
64
|
+
"Username" => self.username,
|
65
|
+
"IP Address" => self.ip,
|
66
|
+
"Port" => self.port,
|
67
|
+
"Chef-Server API" => self.chef_server_api,
|
68
|
+
"Chef-Server WebUI" => self.chef_server_webui
|
69
|
+
}
|
70
|
+
max_key_length = details.collect{ |k,v| k.to_s.length }.max
|
71
|
+
details.each do |key,value|
|
72
|
+
@stdout.puts("%#{max_key_length}s: %s" % [key,value.inspect])
|
73
|
+
end
|
74
|
+
else
|
75
|
+
@stdout.puts("There are no cucumber-chef test labs to display information for!")
|
76
|
+
end
|
77
|
+
|
78
|
+
rescue Exception => e
|
79
|
+
Cucumber::Chef.logger.fatal { e.message }
|
80
|
+
Cucumber::Chef.logger.fatal { e.backtrace.join("\n") }
|
81
|
+
raise ProviderError, e.message
|
82
|
+
end
|
83
|
+
|
84
|
+
################################################################################
|
85
|
+
|
86
|
+
def method_missing(method_name, *method_args)
|
87
|
+
if Cucumber::Chef::Provider::PROXY_METHODS.include?(method_name.to_s)
|
88
|
+
Cucumber::Chef.logger.debug { "provider: #{method_name} #{method_args.inspect}" }
|
89
|
+
@provider.send(method_name.to_sym, *method_args)
|
90
|
+
else
|
91
|
+
super(method_name, *method_args)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
################################################################################
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
################################################################################
|
@@ -0,0 +1,294 @@
|
|
1
|
+
################################################################################
|
2
|
+
#
|
3
|
+
# Author: Zachary Patten <zachary@jovelabs.com>
|
4
|
+
# Copyright: Copyright (c) 2011-2013 Atalanta Systems Ltd
|
5
|
+
# License: Apache License, Version 2.0
|
6
|
+
#
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
+
# you may not use this file except in compliance with the License.
|
9
|
+
# You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16
|
+
# See the License for the specific language governing permissions and
|
17
|
+
# limitations under the License.
|
18
|
+
#
|
19
|
+
################################################################################
|
20
|
+
|
21
|
+
module Cucumber
|
22
|
+
module Chef
|
23
|
+
class Provider
|
24
|
+
|
25
|
+
class AWSError < Error; end
|
26
|
+
|
27
|
+
class AWS
|
28
|
+
attr_accessor :stdout, :stderr, :stdin, :logger
|
29
|
+
|
30
|
+
INVALID_STATES = %w( terminated pending )
|
31
|
+
RUNNING_STATES = %w( running starting-up )
|
32
|
+
SHUTDOWN_STATES = %w( shutdown stopping stopped shutting-down )
|
33
|
+
VALID_STATES = RUNNING_STATES+SHUTDOWN_STATES
|
34
|
+
|
35
|
+
################################################################################
|
36
|
+
|
37
|
+
def initialize(stdout=STDOUT, stderr=STDERR, stdin=STDIN, logger=$logger)
|
38
|
+
@stdout, @stderr, @stdin, @logger = stdout, stderr, stdin, logger
|
39
|
+
@stdout.sync = true if @stdout.respond_to?(:sync=)
|
40
|
+
|
41
|
+
@connection = Fog::Compute.new(
|
42
|
+
:provider => 'AWS',
|
43
|
+
:aws_access_key_id => Cucumber::Chef::Config[:aws][:aws_access_key_id],
|
44
|
+
:aws_secret_access_key => Cucumber::Chef::Config[:aws][:aws_secret_access_key],
|
45
|
+
:region => Cucumber::Chef::Config[:aws][:region]
|
46
|
+
)
|
47
|
+
ensure_security_group
|
48
|
+
end
|
49
|
+
|
50
|
+
################################################################################
|
51
|
+
|
52
|
+
def create
|
53
|
+
if (lab_exists? && (@server = labs_running.first))
|
54
|
+
@stdout.puts("A test lab already exists using the AWS credentials you have supplied; attempting to reprovision it.")
|
55
|
+
else
|
56
|
+
server_definition = {
|
57
|
+
:image_id => Cucumber::Chef::Config.aws_image_id,
|
58
|
+
:groups => Cucumber::Chef::Config[:aws][:aws_security_group],
|
59
|
+
:flavor_id => Cucumber::Chef::Config[:aws][:aws_instance_type],
|
60
|
+
:key_name => Cucumber::Chef::Config[:aws][:aws_ssh_key_id],
|
61
|
+
:availability_zone => Cucumber::Chef::Config[:aws][:availability_zone],
|
62
|
+
:tags => { "purpose" => "cucumber-chef", "cucumber-chef-mode" => Cucumber::Chef::Config[:mode] },
|
63
|
+
:identity_file => Cucumber::Chef::Config[:aws][:identity_file]
|
64
|
+
}
|
65
|
+
if (@server = @connection.servers.create(server_definition))
|
66
|
+
@stdout.puts("Provisioning cucumber-chef test lab platform.")
|
67
|
+
|
68
|
+
@stdout.print("Waiting for instance...")
|
69
|
+
Cucumber::Chef.spinner do
|
70
|
+
@server.wait_for { ready? }
|
71
|
+
end
|
72
|
+
@stdout.puts("done.\n")
|
73
|
+
|
74
|
+
tag_server
|
75
|
+
|
76
|
+
@stdout.print("Waiting for 20 seconds...")
|
77
|
+
Cucumber::Chef.spinner do
|
78
|
+
sleep(20)
|
79
|
+
end
|
80
|
+
@stdout.print("done.\n")
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
if @server
|
85
|
+
@stdout.print("Waiting for SSHD...")
|
86
|
+
Cucumber::Chef.spinner do
|
87
|
+
ZTK::TCPSocketCheck.new(:host => @server.public_ip_address, :port => 22, :wait => 120).wait
|
88
|
+
end
|
89
|
+
@stdout.puts("done.\n")
|
90
|
+
end
|
91
|
+
|
92
|
+
self
|
93
|
+
|
94
|
+
rescue Exception => e
|
95
|
+
Cucumber::Chef.logger.fatal { e.message }
|
96
|
+
Cucumber::Chef.logger.fatal { "Backtrace:\n#{e.backtrace.join("\n")}" }
|
97
|
+
raise AWSError, e.message
|
98
|
+
end
|
99
|
+
|
100
|
+
################################################################################
|
101
|
+
|
102
|
+
def destroy
|
103
|
+
if ((l = labs).count > 0)
|
104
|
+
@stdout.puts("Destroying Servers:")
|
105
|
+
l.each do |server|
|
106
|
+
@stdout.puts(" * #{server.public_ip_address}")
|
107
|
+
server.destroy
|
108
|
+
end
|
109
|
+
else
|
110
|
+
@stdout.puts("There are no cucumber-chef test labs to destroy!")
|
111
|
+
end
|
112
|
+
|
113
|
+
rescue Exception => e
|
114
|
+
Cucumber::Chef.logger.fatal { e.message }
|
115
|
+
Cucumber::Chef.logger.fatal { e.backtrace.join("\n") }
|
116
|
+
raise AWSError, e.message
|
117
|
+
end
|
118
|
+
|
119
|
+
################################################################################
|
120
|
+
|
121
|
+
def up
|
122
|
+
if (lab_exists? && (@server = labs_shutdown.first))
|
123
|
+
if @server.start
|
124
|
+
|
125
|
+
@stdout.print("Waiting for instance...")
|
126
|
+
Cucumber::Chef.spinner do
|
127
|
+
@server.wait_for { ready? }
|
128
|
+
end
|
129
|
+
@stdout.puts("done.\n")
|
130
|
+
|
131
|
+
@stdout.print("Waiting for SSHD...")
|
132
|
+
Cucumber::Chef.spinner do
|
133
|
+
ZTK::TCPSocketCheck.new(:host => @server.public_ip_address, :port => 22, :wait => 120).wait
|
134
|
+
end
|
135
|
+
@stdout.puts("done.\n")
|
136
|
+
|
137
|
+
@stdout.puts("Successfully started up cucumber-chef test lab!")
|
138
|
+
|
139
|
+
info
|
140
|
+
else
|
141
|
+
@stdout.puts("Failed to start up cucumber-chef test lab!")
|
142
|
+
end
|
143
|
+
else
|
144
|
+
@stdout.puts("There are no available cucumber-chef test labs to start up!")
|
145
|
+
end
|
146
|
+
|
147
|
+
rescue Exception => e
|
148
|
+
Cucumber::Chef.logger.fatal { e.message }
|
149
|
+
Cucumber::Chef.logger.fatal { e.backtrace.join("\n") }
|
150
|
+
raise AWSError, e.message
|
151
|
+
end
|
152
|
+
|
153
|
+
################################################################################
|
154
|
+
|
155
|
+
def down
|
156
|
+
if (lab_exists? && (@server = labs_running.first))
|
157
|
+
if @server.stop
|
158
|
+
@stdout.puts("Successfully shutdown cucumber-chef test lab!")
|
159
|
+
else
|
160
|
+
@stdout.puts("Failed to shutdown cucumber-chef test lab!")
|
161
|
+
end
|
162
|
+
else
|
163
|
+
@stdout.puts("There are no available cucumber-chef test labs top shutdown!")
|
164
|
+
end
|
165
|
+
|
166
|
+
rescue Exception => e
|
167
|
+
Cucumber::Chef.logger.fatal { e.message }
|
168
|
+
Cucumber::Chef.logger.fatal { e.backtrace.join("\n") }
|
169
|
+
raise AWSError, e.message
|
170
|
+
end
|
171
|
+
|
172
|
+
################################################################################
|
173
|
+
|
174
|
+
def id
|
175
|
+
labs_running.first.id
|
176
|
+
end
|
177
|
+
|
178
|
+
def state
|
179
|
+
labs_running.first.state
|
180
|
+
end
|
181
|
+
|
182
|
+
def username
|
183
|
+
labs_running.first.username
|
184
|
+
end
|
185
|
+
|
186
|
+
def ip
|
187
|
+
labs_running.first.public_ip_address
|
188
|
+
end
|
189
|
+
|
190
|
+
def port
|
191
|
+
22
|
192
|
+
end
|
193
|
+
|
194
|
+
################################################################################
|
195
|
+
|
196
|
+
def lab_exists?
|
197
|
+
(labs.size > 0)
|
198
|
+
end
|
199
|
+
|
200
|
+
################################################################################
|
201
|
+
|
202
|
+
def labs
|
203
|
+
@servers ||= @connection.servers
|
204
|
+
results = @servers.select do |server|
|
205
|
+
Cucumber::Chef.logger.debug("candidate") { "ID=#{server.id}, state='#{server.state}'" }
|
206
|
+
( server.tags['cucumber-chef-mode'] == Cucumber::Chef::Config[:mode].to_s &&
|
207
|
+
server.tags['cucumber-chef-user'] == Cucumber::Chef::Config[:user].to_s &&
|
208
|
+
VALID_STATES.any?{ |state| state == server.state } )
|
209
|
+
end
|
210
|
+
results.each do |server|
|
211
|
+
Cucumber::Chef.logger.debug("results") { "ID=#{server.id}, state='#{server.state}'" }
|
212
|
+
end
|
213
|
+
results
|
214
|
+
end
|
215
|
+
|
216
|
+
################################################################################
|
217
|
+
|
218
|
+
def labs_running
|
219
|
+
@servers ||= @connection.servers
|
220
|
+
results = @servers.select do |server|
|
221
|
+
Cucumber::Chef.logger.debug("candidate") { "ID=#{server.id}, state='#{server.state}'" }
|
222
|
+
( server.tags['cucumber-chef-mode'] == Cucumber::Chef::Config[:mode].to_s &&
|
223
|
+
server.tags['cucumber-chef-user'] == Cucumber::Chef::Config[:user].to_s &&
|
224
|
+
RUNNING_STATES.any?{ |state| state == server.state } )
|
225
|
+
end
|
226
|
+
results.each do |server|
|
227
|
+
Cucumber::Chef.logger.debug("results") { "ID=#{server.id}, state='#{server.state}'" }
|
228
|
+
end
|
229
|
+
results
|
230
|
+
end
|
231
|
+
|
232
|
+
################################################################################
|
233
|
+
|
234
|
+
def labs_shutdown
|
235
|
+
@servers ||= @connection.servers
|
236
|
+
results = @servers.select do |server|
|
237
|
+
Cucumber::Chef.logger.debug("candidate") { "ID=#{server.id}, state='#{server.state}'" }
|
238
|
+
( server.tags['cucumber-chef-mode'] == Cucumber::Chef::Config[:mode].to_s &&
|
239
|
+
server.tags['cucumber-chef-user'] == Cucumber::Chef::Config[:user].to_s &&
|
240
|
+
SHUTDOWN_STATES.any?{ |state| state == server.state } )
|
241
|
+
end
|
242
|
+
results.each do |server|
|
243
|
+
Cucumber::Chef.logger.debug("results") { "ID=#{server.id}, state='#{server.state}'" }
|
244
|
+
end
|
245
|
+
results
|
246
|
+
end
|
247
|
+
|
248
|
+
|
249
|
+
################################################################################
|
250
|
+
private
|
251
|
+
################################################################################
|
252
|
+
|
253
|
+
def tag_server
|
254
|
+
{
|
255
|
+
"cucumber-chef-mode" => Cucumber::Chef::Config[:mode],
|
256
|
+
"cucumber-chef-user" => Cucumber::Chef::Config[:user],
|
257
|
+
"purpose" => "cucumber-chef"
|
258
|
+
}.each do |k, v|
|
259
|
+
tag = @connection.tags.new
|
260
|
+
tag.resource_id = @server.id
|
261
|
+
tag.key, tag.value = k, v
|
262
|
+
tag.save
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
################################################################################
|
267
|
+
|
268
|
+
def ensure_security_group
|
269
|
+
security_group_name = Cucumber::Chef::Config[:aws][:aws_security_group]
|
270
|
+
if (security_group = @connection.security_groups.get(security_group_name))
|
271
|
+
port_ranges = security_group.ip_permissions.collect{ |entry| entry["fromPort"]..entry["toPort"] }
|
272
|
+
security_group.authorize_port_range(22..22) if port_ranges.none?{ |port_range| port_range === 22 }
|
273
|
+
security_group.authorize_port_range(4000..4000) if port_ranges.none?{ |port_range| port_range === 4000 }
|
274
|
+
security_group.authorize_port_range(4040..4040) if port_ranges.none?{ |port_range| port_range === 4040 }
|
275
|
+
security_group.authorize_port_range(8787..8787) if port_ranges.none?{ |port_range| port_range === 8787 }
|
276
|
+
elsif (security_group = @connection.security_groups.new(:name => security_group_name, :description => "cucumber-chef test lab")).save
|
277
|
+
security_group.authorize_port_range(22..22)
|
278
|
+
security_group.authorize_port_range(4000..4000)
|
279
|
+
security_group.authorize_port_range(4040..4040)
|
280
|
+
security_group.authorize_port_range(8787..8787)
|
281
|
+
else
|
282
|
+
raise AWSError, "Could not find an existing or create a new AWS security group."
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
################################################################################
|
287
|
+
|
288
|
+
end
|
289
|
+
|
290
|
+
end
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
################################################################################
|
@@ -0,0 +1,121 @@
|
|
1
|
+
################################################################################
|
2
|
+
#
|
3
|
+
# Author: Zachary Patten <zachary@jovelabs.com>
|
4
|
+
# Copyright: Copyright (c) 2011-2013 Atalanta Systems Ltd
|
5
|
+
# License: Apache License, Version 2.0
|
6
|
+
#
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
+
# you may not use this file except in compliance with the License.
|
9
|
+
# You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16
|
+
# See the License for the specific language governing permissions and
|
17
|
+
# limitations under the License.
|
18
|
+
#
|
19
|
+
################################################################################
|
20
|
+
|
21
|
+
module Cucumber
|
22
|
+
module Chef
|
23
|
+
class Provider
|
24
|
+
|
25
|
+
class VagrantError < Error; end
|
26
|
+
|
27
|
+
class Vagrant
|
28
|
+
attr_accessor :env, :vm, :stdout, :stderr, :stdin, :logger
|
29
|
+
|
30
|
+
################################################################################
|
31
|
+
|
32
|
+
def initialize(stdout=STDOUT, stderr=STDERR, stdin=STDIN, logger=$logger)
|
33
|
+
@stdout, @stderr, @stdin, @logger = stdout, stderr, stdin, logger
|
34
|
+
@stdout.sync = true if @stdout.respond_to?(:sync=)
|
35
|
+
|
36
|
+
# @env = ::Vagrant::Environment.new
|
37
|
+
@env = ::Vagrant::Environment.new(:ui_class => ::Vagrant::UI::Colored)
|
38
|
+
@vm = @env.primary_vm
|
39
|
+
end
|
40
|
+
|
41
|
+
################################################################################
|
42
|
+
|
43
|
+
def create
|
44
|
+
@stdout.puts("Provisioning cucumber-chef test lab platform.")
|
45
|
+
|
46
|
+
@stdout.print("Waiting for instance...")
|
47
|
+
Cucumber::Chef.spinner do
|
48
|
+
@env.cli("up")
|
49
|
+
end
|
50
|
+
@stdout.puts("done.\n")
|
51
|
+
|
52
|
+
@stdout.print("Waiting for SSHD...")
|
53
|
+
Cucumber::Chef.spinner do
|
54
|
+
ZTK::TCPSocketCheck.new(:host => self.ip, :port => 22, :wait => 120).wait
|
55
|
+
end
|
56
|
+
@stdout.puts("done.\n")
|
57
|
+
|
58
|
+
self
|
59
|
+
end
|
60
|
+
|
61
|
+
def destroy
|
62
|
+
@env.cli("destroy", "--force")
|
63
|
+
end
|
64
|
+
|
65
|
+
def up
|
66
|
+
@env.cli("up")
|
67
|
+
end
|
68
|
+
|
69
|
+
def down
|
70
|
+
@env.cli("halt")
|
71
|
+
end
|
72
|
+
|
73
|
+
################################################################################
|
74
|
+
|
75
|
+
def id
|
76
|
+
@vm.name
|
77
|
+
end
|
78
|
+
|
79
|
+
def state
|
80
|
+
@vm.state
|
81
|
+
end
|
82
|
+
|
83
|
+
def username
|
84
|
+
@vm.config.ssh.username
|
85
|
+
end
|
86
|
+
|
87
|
+
def ip
|
88
|
+
@vm.config.ssh.host
|
89
|
+
end
|
90
|
+
|
91
|
+
def port
|
92
|
+
@vm.config.vm.forwarded_ports.select{ |fwd_port| (fwd_port[:name] == "ssh") }.first[:hostport].to_i
|
93
|
+
end
|
94
|
+
|
95
|
+
################################################################################
|
96
|
+
|
97
|
+
def lab_exists?
|
98
|
+
(@env.vms.count > 0)
|
99
|
+
end
|
100
|
+
|
101
|
+
def labs
|
102
|
+
[@env.primary_vm]
|
103
|
+
end
|
104
|
+
|
105
|
+
def labs_running
|
106
|
+
[@env.primary_vm]
|
107
|
+
end
|
108
|
+
|
109
|
+
def labs_shutdown
|
110
|
+
Array.new # @env.vms
|
111
|
+
end
|
112
|
+
|
113
|
+
################################################################################
|
114
|
+
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
################################################################################
|
@@ -32,26 +32,27 @@ module Cucumber
|
|
32
32
|
|
33
33
|
################################################################################
|
34
34
|
|
35
|
-
def initialize(
|
36
|
-
@
|
35
|
+
def initialize(test_lab, stdout=STDOUT, stderr=STDERR, stdin=STDIN)
|
36
|
+
@test_lab = test_lab
|
37
37
|
@stdout, @stderr, @stdin = stdout, stderr, stdin
|
38
38
|
@stdout.sync = true if @stdout.respond_to?(:sync=)
|
39
39
|
|
40
40
|
@ssh = ZTK::SSH.new(:stdout => @stdout, :stderr => @stderr, :stdin => @stdin)
|
41
|
-
@ssh.config.host_name = @
|
42
|
-
@ssh.config.
|
43
|
-
@ssh.config.
|
41
|
+
@ssh.config.host_name = @test_lab.ip
|
42
|
+
@ssh.config.port = @test_lab.port
|
43
|
+
@ssh.config.user = Cucumber::Chef.lab_user
|
44
|
+
@ssh.config.keys = Cucumber::Chef::Config[Cucumber::Chef::Config[:provider]][:identity_file]
|
44
45
|
|
45
46
|
# @command = Cucumber::Chef::Command.new(@stdout, @stderr, @stdin)
|
46
47
|
|
47
|
-
@cookbooks_path = File.
|
48
|
-
@roles_path = File.
|
48
|
+
@cookbooks_path = File.join(Cucumber::Chef.root_dir, "chef_repo", "cookbooks")
|
49
|
+
@roles_path = File.join(Cucumber::Chef.root_dir, "chef_repo", "roles")
|
49
50
|
end
|
50
51
|
|
51
52
|
################################################################################
|
52
53
|
|
53
54
|
def build
|
54
|
-
template_file = File.
|
55
|
+
template_file = File.join(Cucumber::Chef.root_dir, "lib", "cucumber", "chef", "templates", "bootstrap", "ubuntu-precise-test-lab.erb")
|
55
56
|
|
56
57
|
bootstrap(template_file)
|
57
58
|
wait_for_chef_server
|
@@ -79,21 +80,24 @@ module Cucumber
|
|
79
80
|
def bootstrap(template_file)
|
80
81
|
raise ProvisionerError, "You must have the environment variable 'USER' set." if !Cucumber::Chef::Config[:user]
|
81
82
|
|
82
|
-
@stdout.print("Bootstrapping
|
83
|
+
@stdout.print("Bootstrapping #{Cucumber::Chef::Config[:provider].upcase} instance...")
|
83
84
|
Cucumber::Chef.spinner do
|
84
85
|
attributes = {
|
85
86
|
"run_list" => "role[test_lab]",
|
86
87
|
"cucumber_chef" => {
|
87
88
|
"version" => Cucumber::Chef::VERSION,
|
88
89
|
"prerelease" => Cucumber::Chef::Config[:prerelease]
|
89
|
-
}
|
90
|
+
},
|
91
|
+
"lab_user" => Cucumber::Chef.lab_user,
|
92
|
+
"lxc_user" => Cucumber::Chef.lxc_user
|
90
93
|
}
|
91
94
|
|
92
95
|
bootstrap = Cucumber::Chef::Bootstrap.new(@stdout, @stderr, @stdin)
|
93
|
-
bootstrap.config[:host] = @
|
94
|
-
bootstrap.config[:
|
96
|
+
bootstrap.config[:host] = @test_lab.ip
|
97
|
+
bootstrap.config[:port] = @test_lab.port
|
98
|
+
bootstrap.config[:ssh_user] = Cucumber::Chef.lab_user
|
95
99
|
bootstrap.config[:use_sudo] = true
|
96
|
-
bootstrap.config[:identity_file] = Cucumber::Chef
|
100
|
+
bootstrap.config[:identity_file] = Cucumber::Chef.bootstrap_identity
|
97
101
|
bootstrap.config[:template_file] = template_file
|
98
102
|
bootstrap.config[:context][:hostname] = HOSTNAME
|
99
103
|
bootstrap.config[:context][:chef_server] = HOSTNAME
|
@@ -111,8 +115,8 @@ module Cucumber
|
|
111
115
|
def download_chef_credentials
|
112
116
|
@stdout.print("Downloading chef-server credentials...")
|
113
117
|
Cucumber::Chef.spinner do
|
114
|
-
local_path = Cucumber::Chef.
|
115
|
-
remote_path = File.join(
|
118
|
+
local_path = File.join(Cucumber::Chef.home_dir, Cucumber::Chef::Config[:provider].to_s)
|
119
|
+
remote_path = File.join(Cucumber::Chef.lab_user_home_dir, ".chef")
|
116
120
|
|
117
121
|
files = [ "#{Cucumber::Chef::Config[:user]}.pem", "validation.pem" ]
|
118
122
|
files.each do |file|
|
@@ -127,10 +131,10 @@ module Cucumber
|
|
127
131
|
def download_proxy_ssh_credentials
|
128
132
|
@stdout.print("Downloading container SSH credentials...")
|
129
133
|
Cucumber::Chef.spinner do
|
130
|
-
local_path = Cucumber::Chef.
|
131
|
-
remote_path = File.join(
|
134
|
+
local_path = File.join(Cucumber::Chef.home_dir, Cucumber::Chef::Config[:provider].to_s)
|
135
|
+
remote_path = File.join(Cucumber::Chef.lab_user_home_dir, ".ssh")
|
132
136
|
|
133
|
-
files = { "id_rsa" => "id_rsa-#{
|
137
|
+
files = { "id_rsa" => "id_rsa-#{@ssh.config.user}" }
|
134
138
|
files.each do |remote_file, local_file|
|
135
139
|
local = File.join(local_path, local_file)
|
136
140
|
File.exists?(local) and File.delete(local)
|
@@ -146,16 +150,15 @@ module Cucumber
|
|
146
150
|
def render_knife_rb
|
147
151
|
@stdout.print("Building 'cc-knife' configuration...")
|
148
152
|
Cucumber::Chef.spinner do
|
149
|
-
template_file = File.
|
150
|
-
knife_rb = File.expand_path(File.join(Cucumber::Chef.locate(:directory, ".cucumber-chef"), "knife.rb"))
|
153
|
+
template_file = File.join(Cucumber::Chef.root_dir, "lib", "cucumber", "chef", "templates", "cucumber-chef", "knife-rb.erb")
|
151
154
|
|
152
155
|
context = {
|
153
|
-
:chef_server => @
|
156
|
+
:chef_server => @test_lab.ip,
|
154
157
|
:librarian_chef => Cucumber::Chef::Config[:librarian_chef],
|
155
158
|
:user => Cucumber::Chef::Config[:user]
|
156
159
|
}
|
157
160
|
|
158
|
-
File.open(knife_rb, 'w') do |f|
|
161
|
+
File.open(Cucumber::Chef.knife_rb, 'w') do |f|
|
159
162
|
f.puts(ZTK::Template.render(template_file, context))
|
160
163
|
end
|
161
164
|
end
|
@@ -169,7 +172,7 @@ module Cucumber
|
|
169
172
|
@stdout.print("Uploading cucumber-chef cookbooks...")
|
170
173
|
|
171
174
|
Cucumber::Chef.spinner do
|
172
|
-
Cucumber::Chef.
|
175
|
+
Cucumber::Chef.load_chef_config
|
173
176
|
cookbook_repo = ::Chef::CookbookLoader.new(@cookbooks_path)
|
174
177
|
cookbook_repo.each do |name, cookbook|
|
175
178
|
Cucumber::Chef.logger.debug { "::Chef::CookbookUploader(#{name}) ATTEMPT" }
|
@@ -190,7 +193,7 @@ module Cucumber
|
|
190
193
|
@stdout.print("Uploading cucumber-chef test lab role...")
|
191
194
|
|
192
195
|
Cucumber::Chef.spinner do
|
193
|
-
Cucumber::Chef.
|
196
|
+
Cucumber::Chef.load_chef_config
|
194
197
|
::Chef::Config[:role_path] = @roles_path
|
195
198
|
[ "test_lab" ].each do |name|
|
196
199
|
role = ::Chef::Role.from_disk(name)
|
@@ -210,7 +213,7 @@ module Cucumber
|
|
210
213
|
@stdout.print("Tagging cucumber-chef test lab node...")
|
211
214
|
|
212
215
|
Cucumber::Chef.spinner do
|
213
|
-
Cucumber::Chef.
|
216
|
+
Cucumber::Chef.load_chef_config
|
214
217
|
node = ::Chef::Node.load(HOSTNAME)
|
215
218
|
[ Cucumber::Chef::Config[:mode].to_s, Cucumber::Chef::Config[:user].to_s ].each do |tag|
|
216
219
|
node.tags << tag
|
@@ -230,7 +233,7 @@ module Cucumber
|
|
230
233
|
@stdout.print("Setting up cucumber-chef test lab run list...")
|
231
234
|
|
232
235
|
Cucumber::Chef.spinner do
|
233
|
-
Cucumber::Chef.
|
236
|
+
Cucumber::Chef.load_chef_config
|
234
237
|
node = ::Chef::Node.load(HOSTNAME)
|
235
238
|
[ "role[test_lab]" ].each do |entry|
|
236
239
|
node.run_list << entry
|
@@ -260,13 +263,13 @@ module Cucumber
|
|
260
263
|
def wait_for_chef_server
|
261
264
|
@stdout.print("Waiting for Chef-Server...")
|
262
265
|
Cucumber::Chef.spinner do
|
263
|
-
ZTK::TCPSocketCheck.new(:host => @
|
266
|
+
ZTK::TCPSocketCheck.new(:host => @test_lab.ip, :port => 4000, :data => "GET", :wait => 120).wait
|
264
267
|
end
|
265
268
|
@stdout.puts("done.\n")
|
266
269
|
|
267
270
|
@stdout.print("Waiting for Chef-WebUI...")
|
268
271
|
Cucumber::Chef.spinner do
|
269
|
-
ZTK::TCPSocketCheck.new(:host => @
|
272
|
+
ZTK::TCPSocketCheck.new(:host => @test_lab.ip, :port => 4040, :data => "GET", :wait => 120).wait
|
270
273
|
end
|
271
274
|
@stdout.puts("done.\n")
|
272
275
|
end
|
@@ -284,7 +287,7 @@ module Cucumber
|
|
284
287
|
|
285
288
|
@stdout.print("Waiting for SSHD...")
|
286
289
|
Cucumber::Chef.spinner do
|
287
|
-
ZTK::TCPSocketCheck.new(:host => @
|
290
|
+
ZTK::TCPSocketCheck.new(:host => @test_lab.ip, :port => 22, :wait => 120).wait
|
288
291
|
end
|
289
292
|
@stdout.puts("done.\n")
|
290
293
|
|