cucumber-chef 2.1.0.rc.2 → 2.1.0.rc.3

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.
@@ -27,87 +27,143 @@ module Cucumber
27
27
  class Vagrant
28
28
  attr_accessor :env, :vm, :stdout, :stderr, :stdin, :logger
29
29
 
30
+ INVALID_STATES = %w(not_created aborted).map(&:to_sym)
31
+ RUNNING_STATES = %w(running).map(&:to_sym)
32
+ SHUTDOWN_STATES = %w(paused saved poweroff).map(&:to_sym)
33
+ VALID_STATES = RUNNING_STATES+SHUTDOWN_STATES
34
+
30
35
  ################################################################################
31
36
 
32
37
  def initialize(stdout=STDOUT, stderr=STDERR, stdin=STDIN, logger=$logger)
33
38
  @stdout, @stderr, @stdin, @logger = stdout, stderr, stdin, logger
34
39
  @stdout.sync = true if @stdout.respond_to?(:sync=)
35
40
 
36
- # @env = ::Vagrant::Environment.new
37
- @env = ::Vagrant::Environment.new(:ui_class => ::Vagrant::UI::Colored)
41
+ @env = ::Vagrant::Environment.new
42
+ # @env = ::Vagrant::Environment.new(:ui_class => ::Vagrant::UI::Colored)
38
43
  @vm = @env.primary_vm
39
44
  end
40
45
 
46
+ ################################################################################
47
+ # CREATE
41
48
  ################################################################################
42
49
 
43
50
  def create
44
- @stdout.puts("Provisioning cucumber-chef test lab platform.")
45
-
46
- @stdout.print("Waiting for instance...")
47
- Cucumber::Chef.spinner do
51
+ ZTK::Benchmark.bench(:message => "Creating #{Cucumber::Chef::Config.provider.upcase} instance", :mark => "completed in %0.4f seconds.", :stdout => @stdout) do
48
52
  @env.cli("up")
53
+ ZTK::TCPSocketCheck.new(:host => self.ip, :port => self.port, :wait => 120).wait
49
54
  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
55
 
58
56
  self
57
+
58
+ rescue Exception => e
59
+ Cucumber::Chef.logger.fatal { e.message }
60
+ Cucumber::Chef.logger.fatal { e.backtrace.join("\n") }
61
+ raise VagrantError, e.message
59
62
  end
60
63
 
64
+ ################################################################################
65
+ # DESTROY
66
+ ################################################################################
67
+
61
68
  def destroy
62
- @env.cli("destroy", "--force")
69
+ if exists?
70
+ @env.cli("destroy", "--force")
71
+ else
72
+ raise VagrantError, "We could not find a test lab!"
73
+ end
74
+
75
+ rescue Exception => e
76
+ Cucumber::Chef.logger.fatal { e.message }
77
+ Cucumber::Chef.logger.fatal { e.backtrace.join("\n") }
78
+ raise VagrantError, e.message
63
79
  end
64
80
 
81
+ ################################################################################
82
+ # UP
83
+ ################################################################################
84
+
65
85
  def up
66
- @env.cli("up")
67
- end
86
+ if (exists? && dead?)
87
+ @env.cli("up")
88
+ ZTK::TCPSocketCheck.new(:host => self.ip, :port => self.port, :wait => 120).wait
89
+ else
90
+ raise VagrantError, "We could not find a powered off test lab."
91
+ end
68
92
 
69
- def down
70
- @env.cli("halt")
93
+ rescue Exception => e
94
+ Cucumber::Chef.logger.fatal { e.message }
95
+ Cucumber::Chef.logger.fatal { e.backtrace.join("\n") }
96
+ raise VagrantError, e.message
71
97
  end
72
98
 
99
+ ################################################################################
100
+ # HALT
73
101
  ################################################################################
74
102
 
75
- def id
76
- @vm.name
103
+ def halt
104
+ if (exists? && alive?)
105
+ @env.cli("halt")
106
+ else
107
+ raise AWSError, "We could not find a running test lab."
108
+ end
109
+
110
+ rescue Exception => e
111
+ Cucumber::Chef.logger.fatal { e.message }
112
+ Cucumber::Chef.logger.fatal { e.backtrace.join("\n") }
113
+ raise VagrantError, e.message
77
114
  end
78
115
 
79
- def state
80
- @vm.state
116
+ ################################################################################
117
+ # RELOAD
118
+ ################################################################################
119
+
120
+ def reload
121
+ if (exists? && alive?)
122
+ @env.cli("reload")
123
+ else
124
+ raise AWSError, "We could not find a running test lab."
125
+ end
126
+
127
+ rescue Exception => e
128
+ Cucumber::Chef.logger.fatal { e.message }
129
+ Cucumber::Chef.logger.fatal { e.backtrace.join("\n") }
130
+ raise VagrantError, e.message
81
131
  end
82
132
 
83
- def username
84
- @vm.config.ssh.username
133
+ ################################################################################
134
+
135
+ def exists?
136
+ (@env.vms.count > 0)
85
137
  end
86
138
 
87
- def ip
88
- @vm.config.ssh.host
139
+ def alive?
140
+ (RUNNING_STATES.include?(self.state) rescue false)
89
141
  end
90
142
 
91
- def port
92
- @vm.config.vm.forwarded_ports.select{ |fwd_port| (fwd_port[:name] == "ssh") }.first[:hostport].to_i
143
+ def dead?
144
+ (SHUTDOWN_STATES.include?(self.state) rescue true)
93
145
  end
94
146
 
95
147
  ################################################################################
96
148
 
97
- def lab_exists?
98
- (@env.vms.count > 0)
149
+ def id
150
+ @vm.name
151
+ end
152
+
153
+ def state
154
+ @vm.state.to_sym
99
155
  end
100
156
 
101
- def labs
102
- [@env.primary_vm]
157
+ def username
158
+ @vm.config.ssh.username
103
159
  end
104
160
 
105
- def labs_running
106
- [@env.primary_vm]
161
+ def ip
162
+ @vm.config.ssh.host
107
163
  end
108
164
 
109
- def labs_shutdown
110
- Array.new # @env.vms
165
+ def port
166
+ @vm.config.vm.forwarded_ports.select{ |fwd_port| (fwd_port[:name] == "ssh") }.first[:hostport].to_i
111
167
  end
112
168
 
113
169
  ################################################################################
@@ -25,7 +25,7 @@ module Cucumber
25
25
  class ProvisionerError < Error; end
26
26
 
27
27
  class Provisioner
28
- attr_accessor :stdout, :stderr, :stdin
28
+ attr_accessor :test_lab, :stdout, :stderr, :stdin
29
29
 
30
30
  HOSTNAME = "cucumber-chef.test-lab"
31
31
  PASSWORD = "p@ssw0rd1"
@@ -33,28 +33,20 @@ module Cucumber
33
33
  ################################################################################
34
34
 
35
35
  def initialize(test_lab, stdout=STDOUT, stderr=STDERR, stdin=STDIN)
36
- @test_lab = test_lab
37
36
  @stdout, @stderr, @stdin = stdout, stderr, stdin
38
37
  @stdout.sync = true if @stdout.respond_to?(:sync=)
39
38
 
40
- @ssh = ZTK::SSH.new(:stdout => @stdout, :stderr => @stderr, :stdin => @stdin)
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]
45
-
46
- # @command = Cucumber::Chef::Command.new(@stdout, @stderr, @stdin)
39
+ @test_lab = test_lab
47
40
 
48
41
  @cookbooks_path = File.join(Cucumber::Chef.root_dir, "chef_repo", "cookbooks")
49
42
  @roles_path = File.join(Cucumber::Chef.root_dir, "chef_repo", "roles")
43
+ @bootstrap_template = File.join(Cucumber::Chef.root_dir, "lib", "cucumber", "chef", "templates", "bootstrap", "ubuntu-precise-test-lab.erb")
50
44
  end
51
45
 
52
46
  ################################################################################
53
47
 
54
48
  def build
55
- template_file = File.join(Cucumber::Chef.root_dir, "lib", "cucumber", "chef", "templates", "bootstrap", "ubuntu-precise-test-lab.erb")
56
-
57
- bootstrap(template_file)
49
+ bootstrap
58
50
  wait_for_chef_server
59
51
 
60
52
  download_chef_credentials
@@ -77,101 +69,99 @@ module Cucumber
77
69
  private
78
70
  ################################################################################
79
71
 
80
- def bootstrap(template_file)
81
- raise ProvisionerError, "You must have the environment variable 'USER' set." if !Cucumber::Chef::Config[:user]
72
+ def bootstrap
73
+ raise ProvisionerError, "You must have the environment variable 'USER' set." if !Cucumber::Chef::Config.user
82
74
 
83
- @stdout.print("Bootstrapping #{Cucumber::Chef::Config[:provider].upcase} instance...")
84
- Cucumber::Chef.spinner do
85
- attributes = {
75
+ ZTK::Benchmark.bench(:message => "Bootstrapping #{Cucumber::Chef::Config.provider.upcase} instance", :mark => "completed in %0.4f seconds.", :stdout => @stdout) do
76
+ chef_client_attributes = {
86
77
  "run_list" => "role[test_lab]",
87
78
  "cucumber_chef" => {
88
79
  "version" => Cucumber::Chef::VERSION,
89
- "prerelease" => Cucumber::Chef::Config[:prerelease]
80
+ "prerelease" => Cucumber::Chef::Config.prerelease
90
81
  },
91
82
  "lab_user" => Cucumber::Chef.lab_user,
92
83
  "lxc_user" => Cucumber::Chef.lxc_user
93
84
  }
94
85
 
95
- bootstrap = Cucumber::Chef::Bootstrap.new(@stdout, @stderr, @stdin)
96
- bootstrap.config[:host] = @test_lab.ip
97
- bootstrap.config[:port] = @test_lab.port
98
- bootstrap.config[:ssh_user] = Cucumber::Chef.lab_user
99
- bootstrap.config[:use_sudo] = true
100
- bootstrap.config[:identity_file] = Cucumber::Chef.bootstrap_identity
101
- bootstrap.config[:template_file] = template_file
102
- bootstrap.config[:context][:hostname] = HOSTNAME
103
- bootstrap.config[:context][:chef_server] = HOSTNAME
104
- bootstrap.config[:context][:amqp_password] = PASSWORD
105
- bootstrap.config[:context][:admin_password] = PASSWORD
106
- bootstrap.config[:context][:user] = Cucumber::Chef::Config[:user]
107
- bootstrap.config[:context][:attributes] = attributes
108
- bootstrap.run
86
+ context = {
87
+ :chef_client_attributes => chef_client_attributes,
88
+ :amqp_password => Cucumber::Chef::Config.chef[:amqp_password],
89
+ :admin_password => Cucumber::Chef::Config.chef[:admin_password],
90
+ :user => Cucumber::Chef::Config.user,
91
+ :hostname_short => Cucumber::Chef.lab_hostname_short,
92
+ :hostname_full => Cucumber::Chef.lab_hostname_full
93
+ }
94
+
95
+ local_bootstrap_file = Tempfile.new("bootstrap")
96
+ local_bootstrap_filename = local_bootstrap_file.path
97
+ local_bootstrap_file.write(::ZTK::Template.render(@bootstrap_template, context))
98
+ local_bootstrap_file.close
99
+
100
+ remote_bootstrap_filename = File.join(Cucumber::Chef.lab_user_home_dir, "cucumber-chef-bootstrap.sh")
101
+
102
+ @test_lab.bootstrap_ssh.upload(local_bootstrap_filename, remote_bootstrap_filename)
103
+
104
+ local_bootstrap_file.unlink
105
+
106
+ command = "sudo /bin/bash #{remote_bootstrap_filename}"
107
+ @test_lab.bootstrap_ssh.exec(command, :silence => true)
109
108
  end
110
- @stdout.print("done.\n")
111
109
  end
112
110
 
113
111
  ################################################################################
114
112
 
115
113
  def download_chef_credentials
116
- @stdout.print("Downloading chef-server credentials...")
117
- Cucumber::Chef.spinner do
118
- local_path = File.join(Cucumber::Chef.home_dir, Cucumber::Chef::Config[:provider].to_s)
114
+ ZTK::Benchmark.bench(:message => "Downloading chef-server credentials", :mark => "completed in %0.4f seconds.", :stdout => @stdout) do
115
+ local_path = File.join(Cucumber::Chef.home_dir, Cucumber::Chef::Config.provider.to_s)
119
116
  remote_path = File.join(Cucumber::Chef.lab_user_home_dir, ".chef")
120
117
 
121
118
  files = [ "#{Cucumber::Chef::Config[:user]}.pem", "validation.pem" ]
122
119
  files.each do |file|
123
- @ssh.download(File.join(remote_path, file), File.join(local_path, file))
120
+ @test_lab.bootstrap_ssh.download(File.join(remote_path, file), File.join(local_path, file))
124
121
  end
125
122
  end
126
- @stdout.print("done.\n")
127
123
  end
128
124
 
129
125
  ################################################################################
130
126
 
131
127
  def download_proxy_ssh_credentials
132
- @stdout.print("Downloading container SSH credentials...")
133
- Cucumber::Chef.spinner do
134
- local_path = File.join(Cucumber::Chef.home_dir, Cucumber::Chef::Config[:provider].to_s)
128
+ ZTK::Benchmark.bench(:message => "Downloading proxy SSH credentials", :mark => "completed in %0.4f seconds.", :stdout => @stdout) do
129
+ local_path = File.join(Cucumber::Chef.home_dir, Cucumber::Chef::Config.provider.to_s)
135
130
  remote_path = File.join(Cucumber::Chef.lab_user_home_dir, ".ssh")
136
131
 
137
- files = { "id_rsa" => "id_rsa-#{@ssh.config.user}" }
132
+ files = { "id_rsa" => "id_rsa-#{@test_lab.bootstrap_ssh.config.user}" }
138
133
  files.each do |remote_file, local_file|
139
134
  local = File.join(local_path, local_file)
140
135
  File.exists?(local) and File.delete(local)
141
- @ssh.download(File.join(remote_path, remote_file), local)
136
+ @test_lab.bootstrap_ssh.download(File.join(remote_path, remote_file), local)
142
137
  File.chmod(0600, local)
143
138
  end
144
139
  end
145
- @stdout.print("done.\n")
146
140
  end
147
141
 
148
142
  ################################################################################
149
143
 
150
144
  def render_knife_rb
151
- @stdout.print("Building 'cc-knife' configuration...")
152
- Cucumber::Chef.spinner do
145
+ ZTK::Benchmark.bench(:message => "Building 'cc-knife' configuration", :mark => "completed in %0.4f seconds.", :stdout => @stdout) do
153
146
  template_file = File.join(Cucumber::Chef.root_dir, "lib", "cucumber", "chef", "templates", "cucumber-chef", "knife-rb.erb")
154
147
 
155
148
  context = {
156
149
  :chef_server => @test_lab.ip,
157
- :librarian_chef => Cucumber::Chef::Config[:librarian_chef],
158
- :user => Cucumber::Chef::Config[:user]
150
+ :librarian_chef => Cucumber::Chef::Config.librarian_chef,
151
+ :user => Cucumber::Chef::Config.user
159
152
  }
160
153
 
161
154
  File.open(Cucumber::Chef.knife_rb, 'w') do |f|
162
155
  f.puts(ZTK::Template.render(template_file, context))
163
156
  end
164
157
  end
165
- @stdout.print("done.\n")
166
158
  end
167
159
 
168
160
  ################################################################################
169
161
 
170
162
  def upload_cookbook
171
163
  Cucumber::Chef.logger.debug { "Uploading cucumber-chef cookbooks..." }
172
- @stdout.print("Uploading cucumber-chef cookbooks...")
173
-
174
- Cucumber::Chef.spinner do
164
+ ZTK::Benchmark.bench(:message => "Uploading 'cucumber-chef' cookbooks", :mark => "completed in %0.4f seconds.", :stdout => @stdout) do
175
165
  Cucumber::Chef.load_chef_config
176
166
  cookbook_repo = ::Chef::CookbookLoader.new(@cookbooks_path)
177
167
  cookbook_repo.each do |name, cookbook|
@@ -181,18 +171,13 @@ module Cucumber
181
171
  end
182
172
  #@command.knife([ "cookbook upload cucumber-chef", "-o", @cookbooks_path ], :silence => true)
183
173
  end
184
-
185
- @stdout.print("done.\n")
186
- Cucumber::Chef.logger.debug { "Successfully uploaded cucumber-chef test lab cookbooks." }
187
174
  end
188
175
 
189
176
  ################################################################################
190
177
 
191
178
  def upload_role
192
179
  Cucumber::Chef.logger.debug { "Uploading cucumber-chef test lab role..." }
193
- @stdout.print("Uploading cucumber-chef test lab role...")
194
-
195
- Cucumber::Chef.spinner do
180
+ ZTK::Benchmark.bench(:message => "Uploading 'cucumber-chef' roles", :mark => "completed in %0.4f seconds.", :stdout => @stdout) do
196
181
  Cucumber::Chef.load_chef_config
197
182
  ::Chef::Config[:role_path] = @roles_path
198
183
  [ "test_lab" ].each do |name|
@@ -201,18 +186,13 @@ module Cucumber
201
186
  end
202
187
  #@command.knife([ "role from file", File.join(@roles_path, "test_lab.rb") ], :silence => true)
203
188
  end
204
-
205
- @stdout.print("done.\n")
206
- Cucumber::Chef.logger.debug { "Successfully uploaded cucumber-chef test lab roles."}
207
189
  end
208
190
 
209
191
  ################################################################################
210
192
 
211
193
  def tag_node
212
194
  Cucumber::Chef.logger.debug { "Tagging cucumber-chef test lab node..." }
213
- @stdout.print("Tagging cucumber-chef test lab node...")
214
-
215
- Cucumber::Chef.spinner do
195
+ ZTK::Benchmark.bench(:message => "Tagging 'cucumber-chef' node", :mark => "completed in %0.4f seconds.", :stdout => @stdout) do
216
196
  Cucumber::Chef.load_chef_config
217
197
  node = ::Chef::Node.load(HOSTNAME)
218
198
  [ Cucumber::Chef::Config[:mode].to_s, Cucumber::Chef::Config[:user].to_s ].each do |tag|
@@ -221,18 +201,13 @@ module Cucumber
221
201
  end
222
202
  #@command.knife([ "tag create", HOSTNAME, Cucumber::Chef::Config[:mode] ], :silence => true)
223
203
  end
224
-
225
- @stdout.print("done.\n")
226
- Cucumber::Chef.logger.debug { "Successfully tagged cucumber-chef test lab node."}
227
204
  end
228
205
 
229
206
  ################################################################################
230
207
 
231
208
  def add_node_role
232
209
  Cucumber::Chef.logger.debug { "Setting up cucumber-chef test lab run list..." }
233
- @stdout.print("Setting up cucumber-chef test lab run list...")
234
-
235
- Cucumber::Chef.spinner do
210
+ ZTK::Benchmark.bench(:message => "Setting 'cucumber-chef' run list", :mark => "completed in %0.4f seconds.", :stdout => @stdout) do
236
211
  Cucumber::Chef.load_chef_config
237
212
  node = ::Chef::Node.load(HOSTNAME)
238
213
  [ "role[test_lab]" ].each do |entry|
@@ -241,55 +216,38 @@ module Cucumber
241
216
  node.save
242
217
  #@command.knife([ "node run_list add", HOSTNAME, "\"role[test_lab]\"" ], :silence => true)
243
218
  end
244
-
245
- Cucumber::Chef.logger.debug { "Successfully added roles to cucumber-chef test lab."}
246
- @stdout.print("done.\n")
247
219
  end
248
220
 
249
221
  ################################################################################
250
222
 
251
223
  def chef_first_run
252
- @stdout.print("Performing chef-client run to setup and configure the cucumber-chef test lab...")
253
- Cucumber::Chef.spinner do
224
+ ZTK::Benchmark.bench(:message => "Performing chef-client run", :mark => "completed in %0.4f seconds.", :stdout => @stdout) do
254
225
  command = "/usr/bin/chef-client -j /etc/chef/first-boot.json -l debug"
255
226
  command = "sudo #{command}"
256
- @ssh.exec(command, :silence => true)
227
+ @test_lab.bootstrap_ssh.exec(command, :silence => true)
257
228
  end
258
- @stdout.print("done.\n")
259
229
  end
260
230
 
261
231
  ################################################################################
262
232
 
263
233
  def wait_for_chef_server
264
- @stdout.print("Waiting for Chef-Server...")
265
- Cucumber::Chef.spinner do
234
+ ZTK::Benchmark.bench(:message => "Waiting for the chef-server", :mark => "completed in %0.4f seconds.", :stdout => @stdout) do
266
235
  ZTK::TCPSocketCheck.new(:host => @test_lab.ip, :port => 4000, :data => "GET", :wait => 120).wait
267
236
  end
268
- @stdout.puts("done.\n")
269
237
 
270
- @stdout.print("Waiting for Chef-WebUI...")
271
- Cucumber::Chef.spinner do
238
+ ZTK::Benchmark.bench(:message => "Waiting for the chef-server-webui", :mark => "completed in %0.4f seconds.", :stdout => @stdout) do
272
239
  ZTK::TCPSocketCheck.new(:host => @test_lab.ip, :port => 4040, :data => "GET", :wait => 120).wait
273
240
  end
274
- @stdout.puts("done.\n")
275
241
  end
276
242
 
277
243
  ################################################################################
278
244
 
279
245
  def reboot_test_lab
280
- @stdout.print("Rebooting test lab; please wait...")
281
- Cucumber::Chef.spinner do
246
+ ZTK::Benchmark.bench(:message => "Rebooting the test lab", :mark => "completed in %0.4f seconds.", :stdout => @stdout) do
282
247
  command = "sudo reboot"
283
- @ssh.exec(command, :silence => true)
284
- sleep(10)
285
- end
286
- @stdout.print("done.\n")
287
-
288
- @stdout.print("Waiting for SSHD...")
289
- Cucumber::Chef.spinner do
290
- ZTK::TCPSocketCheck.new(:host => @test_lab.ip, :port => 22, :wait => 120).wait
248
+ @test_lab.bootstrap_ssh.exec(command, :silence => true)
249
+ ZTK::TCPSocketCheck.new(:host => @test_lab.ip, :port => @test_lab.port, :wait => 120).wait
291
250
  end
292
- @stdout.puts("done.\n")
293
251
 
294
252
  wait_for_chef_server
295
253
  end