puppet_litmus 0.18.2 → 0.21.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -17,15 +17,15 @@ namespace :litmus do
17
17
  end
18
18
 
19
19
  # Provisions a list of OSes from provision.yaml file e.g. 'bundle exec rake litmus:provision_list[default]'.
20
- # @See https://github.com/puppetlabs/puppet_litmus/wiki/Overview-of-Litmus#provisioning-via-yaml
20
+ # @See https://puppetlabs.github.io/litmus/Litmus-core-commands.html#provisioning-via-yaml
21
21
  #
22
22
  # @param :key [String] key that maps to a value for a provisioner and an image to be used for each OS provisioned.
23
- desc "provision list of machines from provision.yaml file. 'bundle exec rake 'litmus:provision_list[default]'"
23
+ desc 'provision list of machines from provision.yaml file'
24
24
  task :provision_list, [:key] do |_task, args|
25
25
  raise 'Cannot find provision.yaml file' unless File.file?('./provision.yaml')
26
26
 
27
27
  provision_hash = YAML.load_file('./provision.yaml')
28
- raise "No key #{args[:key]} in ./provision.yaml, see https://github.com/puppetlabs/puppet_litmus/wiki/Overview-of-Litmus#provisioning-via-yaml for examples" if provision_hash[args[:key]].nil?
28
+ raise "No key #{args[:key]} in ./provision.yaml, see https://puppetlabs.github.io/litmus/Litmus-core-commands.html#provisioning-via-yaml for examples" if provision_hash[args[:key]].nil?
29
29
 
30
30
  Rake::Task['spec_prep'].invoke
31
31
 
@@ -33,35 +33,35 @@ namespace :litmus do
33
33
  inventory_vars = provision_hash[args[:key]]['vars']
34
34
  # Splat the params into environment variables to pass to the provision task but only in this runspace
35
35
  provision_hash[args[:key]]['params']&.each { |k, value| ENV[k.upcase] = value.to_s }
36
- results = []
37
36
  failed_image_message = ''
38
- provision_hash[args[:key]]['images'].each do |image|
39
- if (ENV['CI'] == 'true') || !ENV['DISTELLI_BUILDNUM'].nil?
40
- progress = Thread.new do
41
- loop do
42
- printf '.'
43
- sleep(10)
44
- end
45
- end
46
- else
47
- require 'tty-spinner'
48
- spinner = TTY::Spinner.new("Provisioning #{image} using #{provisioner} provisioner.[:spinner]")
49
- spinner.auto_spin
50
- end
51
- result = provision(provisioner, image, inventory_vars)
52
-
53
- if (ENV['CI'] == 'true') || !ENV['DISTELLI_BUILDNUM'].nil?
54
- Thread.kill(progress)
55
- else
56
- spinner.success
37
+ if provision_hash[args[:key]]['images'].instance_of?(Hash)
38
+ begin
39
+ spinner = start_spinner("Provisioning multiple images using #{provisioner} provisioner.")
40
+ result = provision(provisioner, provision_hash[args[:key]]['images'], inventory_vars)
41
+ ensure
42
+ stop_spinner(spinner)
57
43
  end
58
44
 
59
45
  if result.first['status'] != 'success'
60
46
  failed_image_message += "=====\n#{result.first['target']}\n#{result.first['value']['_output']}\n#{result.inspect}"
61
47
  else
62
- STDOUT.puts "#{result.first['value']['node_name']}, #{image}"
48
+ $stdout.puts 'Success'
49
+ end
50
+ else
51
+ provision_hash[args[:key]]['images'].each do |image|
52
+ begin
53
+ spinner = start_spinner("Provisioning #{image} using #{provisioner} provisioner.")
54
+ result = provision(provisioner, image, inventory_vars)
55
+ ensure
56
+ stop_spinner(spinner)
57
+ end
58
+
59
+ if result.first['status'] != 'success'
60
+ failed_image_message += "=====\n#{result.first['target']}\n#{result.first['value']['_output']}\n#{result.inspect}"
61
+ else
62
+ $stdout.puts "#{result.first['value']['node_name']}, #{image}"
63
+ end
63
64
  end
64
- results << result
65
65
  end
66
66
 
67
67
  raise "Failed to provision with '#{provisioner}'\n #{failed_image_message}" unless failed_image_message.empty?
@@ -71,31 +71,38 @@ namespace :litmus do
71
71
  #
72
72
  # @param :provisioner [String] provisioner to use in provisioning given platform.
73
73
  # @param :platform [String] OS platform for container or VM to use.
74
- desc "provision container/VM - abs/docker/vagrant/vmpooler eg 'bundle exec rake 'litmus:provision[vmpooler, ubuntu-1604-x86_64]'"
74
+ desc 'provision a test system using the given provisioner and platform name. See the puppetlabs-provision module tasks for more documentation'
75
75
  task :provision, [:provisioner, :platform, :inventory_vars] do |_task, args|
76
76
  Rake::Task['spec_prep'].invoke
77
- if (ENV['CI'] == 'true') || !ENV['DISTELLI_BUILDNUM'].nil?
78
- progress = Thread.new do
79
- loop do
80
- printf '.'
81
- sleep(10)
77
+
78
+ begin
79
+ spinner = start_spinner("Provisioning #{args[:platform]} using #{args[:provisioner]} provisioner.")
80
+
81
+ results = provision(args[:provisioner], args[:platform], args[:inventory_vars])
82
+
83
+ unless results.first['status'] == 'success'
84
+ raise "Failed provisioning #{args[:platform]} using #{args[:provisioner]}\n#{results.first}"
85
+ end
86
+
87
+ puts "Successfully provisioned #{args[:platform]} using #{args[:provisioner]}\n"
88
+
89
+ target_names = if results.first['value']['node']
90
+ [results.first['value']['node']['uri']]
91
+ else
92
+ results.first['value']['target_names'] || [] # provision_service multi-node provisioning
93
+ end
94
+ target_names.each do |target|
95
+ Honeycomb.start_span(name: 'litmus.provision.check_connectivity') do |span|
96
+ span.add_field('target_name', target)
97
+ with_retries do
98
+ check_connectivity?(inventory_hash_from_inventory_file, target)
99
+ end
82
100
  end
83
101
  end
84
- else
85
- require 'tty-spinner'
86
- spinner = TTY::Spinner.new("Provisioning #{args[:platform]} using #{args[:provisioner]} provisioner.[:spinner]")
87
- spinner.auto_spin
88
- end
89
- results = provision(args[:provisioner], args[:platform], args[:inventory_vars])
90
- if results.first['status'] != 'success'
91
- raise "Failed provisioning #{args[:platform]} using #{args[:provisioner]}\n#{results.first}"
102
+ ensure
103
+ stop_spinner(spinner)
92
104
  end
93
105
 
94
- if (ENV['CI'] == 'true') || !ENV['DISTELLI_BUILDNUM'].nil?
95
- Thread.kill(progress)
96
- else
97
- spinner.success
98
- end
99
106
  puts "#{results.first['value']['node_name']}, #{args[:platform]}"
100
107
  end
101
108
 
@@ -103,7 +110,7 @@ namespace :litmus do
103
110
  #
104
111
  # @param :collection [String] parameters to pass to the puppet agent install command.
105
112
  # @param :target_node_name [Array] nodes on which to install puppet agent.
106
- desc 'install puppet agent, [:collection, :target_node_name]'
113
+ desc 'install a puppet agent to all or a specified set of targets'
107
114
  task :install_agent, [:collection, :target_node_name] do |_task, args|
108
115
  inventory_hash = inventory_hash_from_inventory_file
109
116
  targets = find_targets(inventory_hash, args[:target_node_name])
@@ -118,32 +125,46 @@ namespace :litmus do
118
125
 
119
126
  results = install_agent(args[:collection], targets, inventory_hash)
120
127
  results.each do |result|
121
- if result['status'] != 'success'
122
- command_to_run = "bolt task run puppet_agent::install --targets #{result['target']} --inventoryfile inventory.yaml --modulepath #{DEFAULT_CONFIG_DATA['modulepath']}"
123
- raise "Failed on #{result['target']}\n#{result}\ntry running '#{command_to_run}'"
124
- else
125
- # add puppet-agent feature to successful nodes
126
- inventory_hash = add_feature_to_node(inventory_hash, 'puppet-agent', result['target'])
128
+ command_to_run = "bolt task run puppet_agent::install --targets #{result['target']} --inventoryfile inventory.yaml --modulepath #{DEFAULT_CONFIG_DATA['modulepath']}"
129
+ raise "Failed on #{result['target']}\n#{result}\ntry running '#{command_to_run}'" if result['status'] != 'success'
130
+
131
+ # validate successful install
132
+ puts "Successfull install result: #{result.inspect}" if ENV['DEBUG'] == 'true'
133
+ retries = 0
134
+ begin
135
+ responses = run_command('puppet --version', targets, options: {}, config: DEFAULT_CONFIG_DATA, inventory: inventory_hash.clone)
136
+ responses.each do |response|
137
+ raise "Error checking puppet version on #{response.to_json}" if response['status'] != 'success'
138
+ end
139
+ rescue StandardError => e
140
+ puts "ERROR:#{e}" if ENV['DEBUG'] == 'true'
141
+ # fix the path
142
+ path_changes = configure_path(inventory_hash)
143
+ if ENV['DEBUG'] == 'true'
144
+ path_changes.each do |change|
145
+ puts "Configuring puppet path result: #{change.inspect}"
146
+ end
147
+ end
148
+
149
+ retries += 1
150
+ sleep 3
151
+ retry if retries <= 300
152
+ raise 'Failed to detect installed puppet version after 5 minutes'
127
153
  end
154
+
155
+ # add puppet-agent feature to successful nodes
156
+ inventory_hash = add_feature_to_node(inventory_hash, 'puppet-agent', result['target'])
128
157
  end
158
+
129
159
  # update the inventory with the puppet-agent feature set per node
130
160
  write_to_inventory_file(inventory_hash, 'inventory.yaml')
131
-
132
- # fix the path on ssh_nodes
133
- results = configure_path(inventory_hash)
134
-
135
- results.each do |result|
136
- if result['status'] != 'success'
137
- puts "Failed on #{result['target']}\n#{result}"
138
- end
139
- end
140
161
  end
141
162
 
142
163
  # Add a given feature to a selection of nodes
143
164
  #
144
165
  # @param :target_node_name [Array] nodes on which to add the feature.
145
166
  # @param :added_feature [String] the feature which you wish to add.
146
- desc 'add_feature, [:added_feature, :target_node_name]'
167
+ desc 'add a feature tag to a node'
147
168
  task :add_feature, [:added_feature, :target_node_name] do |_task, args|
148
169
  inventory_hash = inventory_hash_from_inventory_file
149
170
  targets = find_targets(inventory_hash, args[:target_node_name])
@@ -166,83 +187,118 @@ namespace :litmus do
166
187
  puts 'Feature added'
167
188
  end
168
189
 
190
+ # Install the puppet module under test on a collection of nodes
191
+ #
192
+ # @param :target_node_name [Array] nodes on which to install a puppet module for testing.
193
+ desc 'build the module under test and install it onto targets'
194
+ task :install_module, [:target_node_name, :module_repository] do |_task, args|
195
+ args.with_defaults(target_node_name: nil, module_repository: nil)
196
+ inventory_hash = inventory_hash_from_inventory_file
197
+ target_nodes = find_targets(inventory_hash, args[:target_node_name])
198
+ if target_nodes.empty?
199
+ puts 'No targets found'
200
+ exit 0
201
+ end
202
+
203
+ module_tar = build_module
204
+ puts "Built '#{module_tar}'"
205
+
206
+ # module_tar = Dir.glob('pkg/*.tar.gz').max_by { |f| File.mtime(f) }
207
+ raise "Unable to find package in 'pkg/*.tar.gz'" if module_tar.nil?
208
+
209
+ install_module(inventory_hash, args[:target_node_name], module_tar, args[:module_repository])
210
+
211
+ puts "Installed '#{module_tar}' on #{args[:target_node_name]}"
212
+ end
213
+
169
214
  # Install the puppet modules from a source directory to nodes. It does not install dependencies.
170
215
  #
171
216
  # @param :source [String] source directory to look in (ignores symlinks) defaults do './spec/fixtures/modules'.
172
217
  # @param :target_node_name [Array] nodes on which to install a puppet module for testing.
173
- desc 'install_module - build and install module'
174
- task :install_modules_from_directory, [:source, :target_node_name, :module_repository] do |_task, args|
175
- args.with_defaults(source: nil, target_node_name: nil, module_repository: 'https://forgeapi.puppetlabs.com')
218
+ desc 'build and install all modules from a directory'
219
+ task :install_modules_from_directory, [:source, :target_node_name, :module_repository, :ignore_dependencies] do |_task, args|
220
+ args.with_defaults(source: nil, target_node_name: nil, module_repository: nil, ignore_dependencies: false)
176
221
  inventory_hash = inventory_hash_from_inventory_file
177
222
  target_nodes = find_targets(inventory_hash, args[:target_node_name])
178
223
  if target_nodes.empty?
179
224
  puts 'No targets found'
180
225
  exit 0
181
226
  end
182
- source_folder = if args[:source].nil?
183
- './spec/fixtures/modules'
184
- else
185
- File.expand_path(args[:source])
186
- end
187
- raise "Source folder doesnt exist #{source_folder}" unless File.directory?(source_folder)
188
-
189
- puts 'Building'
190
- module_tars = build_modules_in_folder(source_folder)
227
+ source_dir = if args[:source].nil?
228
+ './spec/fixtures/modules'
229
+ else
230
+ File.expand_path(args[:source])
231
+ end
232
+ raise "Source directory doesn't exist #{source_dir}" unless File.directory?(source_dir)
233
+
234
+ puts "Building all modules in #{source_dir.inspect}"
235
+ module_tars = build_modules_in_dir(source_dir)
191
236
  require 'bolt_spec/run'
192
237
  include BoltSpec::Run
193
- puts "\nInstalling"
194
238
  module_tars.each do |module_tar|
239
+ puts "Installing '#{module_tar}'"
195
240
  target_nodes.each do |target_node_name|
196
- install_module(inventory_hash, target_node_name, module_tar, args[:module_repository])
241
+ install_module(inventory_hash, target_node_name, module_tar, args[:module_repository], args[:ignore_dependencies])
242
+ puts "Installed '#{module_tar}' on #{target_node_name}"
197
243
  end
198
244
  end
199
245
  end
200
246
 
201
- # Check that the nodes in the inventory are still contactable
247
+ # Uninstall the puppet module under test on a collection of nodes
202
248
  #
203
- # @param :target_node_name [Array] nodes on which to check connnectivity
204
- desc 'check_connectivity - build and install module'
205
- task :check_connectivity, [:target_node_name] do |_task, args|
249
+ # @param :target_node_name [Array] nodes on which to install a puppet module for testing.
250
+ # @param :module_name [String] module name to be uninstalled
251
+ desc 'uninstall a specific module'
252
+ task :uninstall_module, [:target_node_name, :module_name] do |_task, args|
206
253
  inventory_hash = inventory_hash_from_inventory_file
207
254
  target_nodes = find_targets(inventory_hash, args[:target_node_name])
208
255
  if target_nodes.empty?
209
256
  puts 'No targets found'
210
257
  exit 0
211
258
  end
212
- check_connectivity?(inventory_hash, args[:target_node_name])
259
+
260
+ result = uninstall_module(inventory_hash, args[:target_node_name], args[:module_name])
261
+
262
+ raise "Failed trying to run 'puppet module uninstall #{module_name}' against inventory." unless result.is_a?(Array)
263
+
264
+ result.each do |node|
265
+ puts "#{node['target']} failed #{node['value']}" if node['status'] != 'success'
266
+ end
267
+
268
+ puts 'Uninstalled'
213
269
  end
214
270
 
215
- # Install the puppet module under test on a collection of nodes
271
+ # Reinstall the puppet module under test on a collection of nodes
216
272
  #
217
273
  # @param :target_node_name [Array] nodes on which to install a puppet module for testing.
218
- desc 'install_module - build and install module'
219
- task :install_module, [:target_node_name, :module_repository] do |_task, args|
220
- args.with_defaults(target_node_name: nil, module_repository: 'https://forgeapi.puppetlabs.com')
274
+ desc 'reinstall the module under test'
275
+ task :reinstall_module, [:target_node_name, :module_repository] do |_task, args|
276
+ args.with_defaults(target_node_name: nil, module_repository: nil)
277
+ Rake::Task['litmus:uninstall_module'].invoke(args[:target_node_name])
278
+ Rake::Task['litmus:install_module'].invoke(args[:target_node_name], args[:module_repository])
279
+ end
280
+
281
+ # Check that the nodes in the inventory are still contactable
282
+ #
283
+ # @param :target_node_name [Array] nodes on which to check connnectivity
284
+ desc 'check the connectivity to all provisioned targets'
285
+ task :check_connectivity, [:target_node_name] do |_task, args|
221
286
  inventory_hash = inventory_hash_from_inventory_file
222
287
  target_nodes = find_targets(inventory_hash, args[:target_node_name])
223
288
  if target_nodes.empty?
224
289
  puts 'No targets found'
225
290
  exit 0
226
291
  end
227
-
228
- module_tar = build_module
229
- puts 'Built'
230
-
231
- # module_tar = Dir.glob('pkg/*.tar.gz').max_by { |f| File.mtime(f) }
232
- raise "Unable to find package in 'pkg/*.tar.gz'" if module_tar.nil?
233
-
234
- install_module(inventory_hash, args[:target_node_name], module_tar, args[:module_repository])
235
-
236
- puts 'Installed'
292
+ check_connectivity?(inventory_hash, args[:target_node_name])
237
293
  end
238
294
 
239
295
  # Provision a list of machines, install a puppet agent, and install the puppet module under test on a collection of nodes
240
296
  #
241
297
  # @param :key [String] key that maps to a value for a provisioner and an image to be used for each OS provisioned.
242
298
  # @param :collection [String] parameters to pass to the puppet agent install command.
243
- desc 'provision_install - provision a list of machines, install an agent, and the module.'
299
+ desc 'provision a list of machines, install an agent, and the module.'
244
300
  task :provision_install, [:key, :collection, :module_repository] do |_task, args|
245
- args.with_defaults(module_repository: 'https://forgeapi.puppetlabs.com')
301
+ args.with_defaults(module_repository: nil)
246
302
  Rake::Task['spec_prep'].invoke
247
303
  Rake::Task['litmus:provision_list'].invoke(args[:key])
248
304
  Rake::Task['litmus:install_agent'].invoke(args[:collection])
@@ -252,7 +308,7 @@ namespace :litmus do
252
308
  # Decommissions test machines.
253
309
  #
254
310
  # @param :target [Array] nodes to remove from test environemnt and decommission.
255
- desc 'tear-down - decommission machines'
311
+ desc 'destroy provisioned targets'
256
312
  task :tear_down, [:target] do |_task, args|
257
313
  inventory_hash = inventory_hash_from_inventory_file
258
314
  targets = find_targets(inventory_hash, args[:target])
@@ -278,40 +334,6 @@ namespace :litmus do
278
334
  end
279
335
  end
280
336
 
281
- # Uninstall the puppet module under test on a collection of nodes
282
- #
283
- # @param :target_node_name [Array] nodes on which to install a puppet module for testing.
284
- # @param :module_name [String] module name to be uninstalled
285
- desc 'uninstall_module - uninstall module'
286
- task :uninstall_module, [:target_node_name, :module_name] do |_task, args|
287
- inventory_hash = inventory_hash_from_inventory_file
288
- target_nodes = find_targets(inventory_hash, args[:target_node_name])
289
- if target_nodes.empty?
290
- puts 'No targets found'
291
- exit 0
292
- end
293
-
294
- result = uninstall_module(inventory_hash, args[:target_node_name], args[:module_name])
295
-
296
- raise "Failed trying to run 'puppet module uninstall #{module_name}' against inventory." unless result.is_a?(Array)
297
-
298
- result.each do |node|
299
- puts "#{node['target']} failed #{node['value']}" if node['status'] != 'success'
300
- end
301
-
302
- puts 'Uninstalled'
303
- end
304
-
305
- # Reinstall the puppet module under test on a collection of nodes
306
- #
307
- # @param :target_node_name [Array] nodes on which to install a puppet module for testing.
308
- desc 'reinstall_module - reinstall module'
309
- task :reinstall_module, [:target_node_name, :module_repository] do |_task, args|
310
- args.with_defaults(target_node_name: nil, module_repository: 'https://forgeapi.puppetlabs.com')
311
- Rake::Task['litmus:uninstall_module'].invoke(args[:target_node_name])
312
- Rake::Task['litmus:install_module'].invoke(args[:target_node_name], args[:module_repository])
313
- end
314
-
315
337
  namespace :acceptance do
316
338
  require 'rspec/core/rake_task'
317
339
  if File.file?('inventory.yaml')
@@ -320,15 +342,21 @@ namespace :litmus do
320
342
 
321
343
  # Run acceptance tests against all machines in the inventory file in parallel.
322
344
  desc 'Run tests in parallel against all machines in the inventory file'
323
- task :parallel do
345
+ task :parallel, [:tag] do |_task, args|
346
+ args.with_defaults(tag: nil)
324
347
  if targets.empty?
325
348
  puts 'No targets found'
326
349
  exit 0
327
350
  end
351
+ tag_value = if args[:tag].nil?
352
+ nil
353
+ else
354
+ "--tag #{args[:tag]}"
355
+ end
328
356
  payloads = []
329
357
  # Generate list of targets to provision
330
358
  targets.each do |target|
331
- test = 'bundle exec rspec ./spec/acceptance --format progress --require rspec_honeycomb_formatter --format RSpecHoneycombFormatter'
359
+ test = "bundle exec rspec ./spec/acceptance #{tag_value} --format progress --require rspec_honeycomb_formatter --format RSpecHoneycombFormatter"
332
360
  title = "#{target}, #{facts_from_node(inventory_hash, target)['platform']}"
333
361
  options = {
334
362
  env: {
@@ -342,7 +370,7 @@ namespace :litmus do
342
370
  success_list = []
343
371
  failure_list = []
344
372
  # Provision targets depending on what environment we're in
345
- if (ENV['CI'] == 'true') || !ENV['DISTELLI_BUILDNUM'].nil?
373
+ if ENV['CI'] == 'true'
346
374
  # CI systems are strange beasts, we only output a '.' every wee while to keep the terminal alive.
347
375
  puts "Running against #{targets.size} targets.\n"
348
376
  progress = Thread.new do
@@ -359,16 +387,16 @@ namespace :litmus do
359
387
  at_exit { exit! }
360
388
 
361
389
  env = options[:env].nil? ? {} : options[:env]
362
- env['HTTP_X_HONEYCOMB_TRACE'] = Honeycomb.current_span.to_trace_header
390
+ env['HONEYCOMB_TRACE'] = Honeycomb.current_span.to_trace_header
363
391
  stdout, stderr, status = Open3.capture3(env, test)
364
392
  ["\n================\n#{title}\n", stdout, stderr, status]
365
393
  end
366
394
  # because we cannot modify variables inside of Parallel
367
395
  results.each do |result|
368
396
  if result.last.to_i.zero?
369
- success_list.push(result.first.scan(%r{.*})[2])
397
+ success_list.push(result.first.scan(%r{.*})[3])
370
398
  else
371
- failure_list.push(result.first.scan(%r{.*})[2])
399
+ failure_list.push(result.first.scan(%r{.*})[3])
372
400
  end
373
401
  end
374
402
  Thread.kill(progress)
@@ -377,7 +405,7 @@ namespace :litmus do
377
405
  spinners = TTY::Spinner::Multi.new("[:spinner] Running against #{targets.size} targets.")
378
406
  payloads.each do |title, test, options|
379
407
  env = options[:env].nil? ? {} : options[:env]
380
- env['HTTP_X_HONEYCOMB_TRACE'] = Honeycomb.current_span.to_trace_header
408
+ env['HONEYCOMB_TRACE'] = Honeycomb.current_span.to_trace_header
381
409
  spinners.register("[:spinner] #{title}") do |sp|
382
410
  stdout, stderr, status = Open3.capture3(env, test)
383
411
  if status.to_i.zero?
@@ -410,8 +438,9 @@ namespace :litmus do
410
438
  desc "Run serverspec against #{target}"
411
439
  next if target == 'litmus_localhost'
412
440
 
413
- RSpec::Core::RakeTask.new(target.to_sym) do |t|
441
+ RSpec::Core::RakeTask.new(target.to_sym, :tag) do |t, args|
414
442
  t.pattern = 'spec/acceptance/**{,/*/**}/*_spec.rb'
443
+ t.rspec_opts = "--tag #{args[:tag]}" unless args[:tag].nil?
415
444
  ENV['TARGET_HOST'] = target
416
445
  end
417
446
  end
@@ -420,8 +449,9 @@ namespace :litmus do
420
449
  # add localhost separately
421
450
  desc 'Run serverspec against localhost, USE WITH CAUTION, this action can be potentially dangerous.'
422
451
  host = 'localhost'
423
- RSpec::Core::RakeTask.new(host.to_sym) do |t|
452
+ RSpec::Core::RakeTask.new(host.to_sym, :tag) do |t, args|
424
453
  t.pattern = 'spec/acceptance/**{,/*/**}/*_spec.rb'
454
+ t.rspec_opts = "--tag #{args[:tag]}" unless args[:tag].nil?
425
455
  Rake::Task['spec_prep'].invoke
426
456
  ENV['TARGET_HOST'] = host
427
457
  end