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

Sign up to get free protection for your applications and to get access to all the features.
@@ -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