puppet_litmus 0.18.2 → 0.21.0

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.
@@ -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