test-kitchen 1.1.1 → 1.2.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.
- checksums.yaml +4 -4
- data/.cane +5 -0
- data/.travis.yml +8 -3
- data/CHANGELOG.md +66 -0
- data/Guardfile +3 -1
- data/README.md +3 -1
- data/Rakefile +1 -16
- data/features/kitchen_command.feature +1 -0
- data/features/kitchen_driver_create_command.feature +1 -0
- data/features/kitchen_driver_discover_command.feature +1 -0
- data/features/kitchen_help_command.feature +16 -0
- data/features/kitchen_init_command.feature +2 -0
- data/features/kitchen_list_command.feature +42 -0
- data/features/support/env.rb +25 -0
- data/lib/kitchen.rb +0 -1
- data/lib/kitchen/busser.rb +2 -2
- data/lib/kitchen/cli.rb +80 -233
- data/lib/kitchen/command.rb +117 -0
- data/lib/kitchen/command/action.rb +44 -0
- data/lib/kitchen/command/console.rb +51 -0
- data/lib/kitchen/command/diagnose.rb +51 -0
- data/lib/kitchen/command/driver_discover.rb +72 -0
- data/lib/kitchen/command/list.rb +86 -0
- data/lib/kitchen/command/login.rb +42 -0
- data/lib/kitchen/command/sink.rb +53 -0
- data/lib/kitchen/command/test.rb +50 -0
- data/lib/kitchen/driver/ssh_base.rb +2 -1
- data/lib/kitchen/loader/yaml.rb +67 -29
- data/lib/kitchen/provisioner/base.rb +67 -4
- data/lib/kitchen/provisioner/chef_base.rb +50 -65
- data/lib/kitchen/provisioner/chef_solo.rb +3 -2
- data/lib/kitchen/provisioner/chef_zero.rb +11 -9
- data/lib/kitchen/provisioner/shell.rb +88 -0
- data/lib/kitchen/state_file.rb +7 -2
- data/lib/kitchen/util.rb +1 -1
- data/lib/kitchen/version.rb +1 -1
- data/spec/kitchen/loader/yaml_spec.rb +327 -13
- data/spec/spec_helper.rb +2 -7
- data/support/chef-client-zero.rb +1 -0
- data/templates/driver/README.md.erb +1 -1
- data/test-kitchen.gemspec +2 -2
- metadata +59 -46
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b3c4db1c478015e6304dfe1664f758171403be58
|
4
|
+
data.tar.gz: 61c4f294a642cf6d300e9388a97919f712875be5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b5b814ee625daaf11b9105476bc1f3c32f8079f22ee19298d787ad1fa41e090253d4a894227f64b10bbaee67775d4e0e755b925f2f3f9199c97d246650584d2a
|
7
|
+
data.tar.gz: 395cd37b2a48b85ee8e2005e27a6038159c2655a920f9d1e466717dd177c9b8adc58a6a0b13063b94d0c70fdc510ecceadc058444be82692b15911d2d9e2159c
|
data/.cane
ADDED
data/.travis.yml
CHANGED
@@ -1,13 +1,16 @@
|
|
1
1
|
language: ruby
|
2
2
|
|
3
3
|
rvm:
|
4
|
-
- 1.
|
4
|
+
- 2.1.0
|
5
5
|
- 2.0.0
|
6
|
-
-
|
6
|
+
- 1.9.3
|
7
|
+
- 1.9.2
|
7
8
|
- ruby-head
|
9
|
+
- jruby-19mode
|
8
10
|
|
9
11
|
env:
|
10
|
-
- RUBYGEMS_VERSION=2.
|
12
|
+
- RUBYGEMS_VERSION=2.1.11
|
13
|
+
- RUBYGEMS_VERSION=2.0.14
|
11
14
|
- RUBYGEMS_VERSION=1.8.25
|
12
15
|
|
13
16
|
before_install:
|
@@ -23,3 +26,5 @@ matrix:
|
|
23
26
|
exclude:
|
24
27
|
- rvm: 2.0.0
|
25
28
|
env: RUBYGEMS_VERSION=1.8.25
|
29
|
+
- rvm: 2.1.0-preview2
|
30
|
+
env: RUBYGEMS_VERSION=1.8.25
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,39 @@
|
|
1
|
+
## 1.2.0 / 2014-02-11
|
2
|
+
|
3
|
+
### Upstream changes
|
4
|
+
|
5
|
+
* Pull request [#288][]: Update omnibus URL to getchef.com. ([@juliandunn][])
|
6
|
+
|
7
|
+
### Bug fixes
|
8
|
+
|
9
|
+
* Pull request [#353][]: Ensure that a chef-client failure returns non-zero exit code for chef-client-zero.rb shim script. ([@kamalim][])
|
10
|
+
* Pull request [#318][]: Upload chef clients data. ([@jtimberman][])
|
11
|
+
* Issue [#282][], issue [#316][]: [CLI] Match a specific instance before trying to find with a regexp. ([@fnichol][])
|
12
|
+
* Issue [#305][]: Ensure that `kitchen help` exits non-zero on failure. ([@fnichol][])
|
13
|
+
* Pull request [#296][]: Fixing error when using more than one helper. ([@jschneiderhan][])
|
14
|
+
* Pull request [#313][]: Allow files in subdirectories in "helpers" directory. ([@mthssdrbrg][])
|
15
|
+
* Pull request [#309][]: Add `/opt/local/bin` to instance path when installing Chef Omnibus package. Smartmachines need this otherwise curl can't find certificates. ([@someara][])
|
16
|
+
* Pull request [#283][], pull request [#287][], pull request [#310][]: Fix failing minitest test on Windows. ([@rarenerd][])
|
17
|
+
* Fix testing regressions for Ruby 1.9.2 around YAML parsing. ([@fnichol][])
|
18
|
+
|
19
|
+
### New features
|
20
|
+
|
21
|
+
* Pull request [#286][]: **Experimental** Basic shell provisioner, first non-Chef addition! Still considered experimental, that is subject to change between releases until APIs stabilize. ([@ChrisLundquist][])
|
22
|
+
* Pull request [#293][], pull request [#277][], issue [#176][]: Add `--concurrency` option to specify number of multiple actions to perform at a time. ([@ryotarai][], [@bkw][])
|
23
|
+
* Support `--concurrency` without value, defaulting to all instances and begin to deprecate `--parallel` flag. ([@fnichol][])
|
24
|
+
* Pull request [#306][], issue [#304][]: Add local & global file locations with environment variables (`KITCHEN_LOCAL_YAML` and `KITCHEN_GLOBAL_YAML`). ([@fnichol][])
|
25
|
+
* Pull request [#298][]: Base provisioner refactoring to start accommodating other provisioners. For more details, see [#298][]. ([@fnichol][])
|
26
|
+
|
27
|
+
### Improvements
|
28
|
+
|
29
|
+
* Pull request [#280][]: Add `json_attributes: true` config option to ChefZero provisioner. This option allows a user to invoke chef-client without passing the generated JSON file in the `--json-attributes` option. ([@fnichol][])
|
30
|
+
* Make `kitchen login` work without args if there is only one instance (thank goodness). ([@fnichol][])
|
31
|
+
* Issue [#285][]: Greatly improved error recovery & reporting in Kitchen::Loader::YAML. ([@fnichol][])
|
32
|
+
* Pull request [#303][]: Use SafeYAML.load to avoid YAML monkeypatch in safe_yaml. This will leave YAML loading in Test Kitchen as implementation detail and avoid polluting other Ruby objects. ([@fnichol][])
|
33
|
+
* Pull request [#302][]: CLI refactoring to remove logic from cli.rb. ([@fnichol][])
|
34
|
+
* Add Ruby 2.1.0 to TravisCI testing matrix. ([@fnichol][])
|
35
|
+
|
36
|
+
|
1
37
|
## 1.1.1 / 2013-12-08
|
2
38
|
|
3
39
|
### Bug fixes
|
@@ -372,6 +408,7 @@ The initial release.
|
|
372
408
|
[#170]: https://github.com/opscode/test-kitchen/issues/170
|
373
409
|
[#171]: https://github.com/opscode/test-kitchen/issues/171
|
374
410
|
[#172]: https://github.com/opscode/test-kitchen/issues/172
|
411
|
+
[#176]: https://github.com/opscode/test-kitchen/issues/176
|
375
412
|
[#178]: https://github.com/opscode/test-kitchen/issues/178
|
376
413
|
[#179]: https://github.com/opscode/test-kitchen/issues/179
|
377
414
|
[#187]: https://github.com/opscode/test-kitchen/issues/187
|
@@ -399,11 +436,34 @@ The initial release.
|
|
399
436
|
[#272]: https://github.com/opscode/test-kitchen/issues/272
|
400
437
|
[#275]: https://github.com/opscode/test-kitchen/issues/275
|
401
438
|
[#276]: https://github.com/opscode/test-kitchen/issues/276
|
439
|
+
[#277]: https://github.com/opscode/test-kitchen/issues/277
|
402
440
|
[#278]: https://github.com/opscode/test-kitchen/issues/278
|
441
|
+
[#280]: https://github.com/opscode/test-kitchen/issues/280
|
442
|
+
[#282]: https://github.com/opscode/test-kitchen/issues/282
|
443
|
+
[#283]: https://github.com/opscode/test-kitchen/issues/283
|
444
|
+
[#285]: https://github.com/opscode/test-kitchen/issues/285
|
445
|
+
[#286]: https://github.com/opscode/test-kitchen/issues/286
|
446
|
+
[#287]: https://github.com/opscode/test-kitchen/issues/287
|
447
|
+
[#288]: https://github.com/opscode/test-kitchen/issues/288
|
448
|
+
[#293]: https://github.com/opscode/test-kitchen/issues/293
|
449
|
+
[#296]: https://github.com/opscode/test-kitchen/issues/296
|
450
|
+
[#298]: https://github.com/opscode/test-kitchen/issues/298
|
451
|
+
[#302]: https://github.com/opscode/test-kitchen/issues/302
|
452
|
+
[#303]: https://github.com/opscode/test-kitchen/issues/303
|
453
|
+
[#304]: https://github.com/opscode/test-kitchen/issues/304
|
454
|
+
[#305]: https://github.com/opscode/test-kitchen/issues/305
|
455
|
+
[#306]: https://github.com/opscode/test-kitchen/issues/306
|
456
|
+
[#309]: https://github.com/opscode/test-kitchen/issues/309
|
457
|
+
[#310]: https://github.com/opscode/test-kitchen/issues/310
|
458
|
+
[#313]: https://github.com/opscode/test-kitchen/issues/313
|
459
|
+
[#316]: https://github.com/opscode/test-kitchen/issues/316
|
460
|
+
[#318]: https://github.com/opscode/test-kitchen/issues/318
|
461
|
+
[#353]: https://github.com/opscode/test-kitchen/issues/353
|
403
462
|
[@ChrisLundquist]: https://github.com/ChrisLundquist
|
404
463
|
[@adamhjk]: https://github.com/adamhjk
|
405
464
|
[@arangamani]: https://github.com/arangamani
|
406
465
|
[@arunthampi]: https://github.com/arunthampi
|
466
|
+
[@bkw]: https://github.com/bkw
|
407
467
|
[@bryanwb]: https://github.com/bryanwb
|
408
468
|
[@calavera]: https://github.com/calavera
|
409
469
|
[@ekrupnik]: https://github.com/ekrupnik
|
@@ -417,24 +477,30 @@ The initial release.
|
|
417
477
|
[@jonsmorrow]: https://github.com/jonsmorrow
|
418
478
|
[@josephholsten]: https://github.com/josephholsten
|
419
479
|
[@jrwesolo]: https://github.com/jrwesolo
|
480
|
+
[@jschneiderhan]: https://github.com/jschneiderhan
|
420
481
|
[@jtimberman]: https://github.com/jtimberman
|
421
482
|
[@juliandunn]: https://github.com/juliandunn
|
483
|
+
[@kamalim]: https://github.com/kamalim
|
422
484
|
[@kisoku]: https://github.com/kisoku
|
423
485
|
[@manul]: https://github.com/manul
|
424
486
|
[@mattray]: https://github.com/mattray
|
425
487
|
[@mconigliaro]: https://github.com/mconigliaro
|
488
|
+
[@mthssdrbrg]: https://github.com/mthssdrbrg
|
426
489
|
[@oferrigni]: https://github.com/oferrigni
|
427
490
|
[@patcon]: https://github.com/patcon
|
428
491
|
[@portertech]: https://github.com/portertech
|
492
|
+
[@rarenerd]: https://github.com/rarenerd
|
429
493
|
[@reset]: https://github.com/reset
|
430
494
|
[@rteabeault]: https://github.com/rteabeault
|
431
495
|
[@ryansouza]: https://github.com/ryansouza
|
496
|
+
[@ryotarai]: https://github.com/ryotarai
|
432
497
|
[@saketoba]: https://github.com/saketoba
|
433
498
|
[@scarolan]: https://github.com/scarolan
|
434
499
|
[@schisamo]: https://github.com/schisamo
|
435
500
|
[@scotthain]: https://github.com/scotthain
|
436
501
|
[@sethvargo]: https://github.com/sethvargo
|
437
502
|
[@smith]: https://github.com/smith
|
503
|
+
[@someara]: https://github.com/someara
|
438
504
|
[@stevendanna]: https://github.com/stevendanna
|
439
505
|
[@thommay]: https://github.com/thommay
|
440
506
|
[@zts]: https://github.com/zts
|
data/Guardfile
CHANGED
@@ -4,7 +4,9 @@ guard 'minitest' do
|
|
4
4
|
watch(%r|^spec/spec_helper\.rb|) { "spec" }
|
5
5
|
end
|
6
6
|
|
7
|
-
|
7
|
+
cucumber_cli = '--no-profile --color --format progress --strict'
|
8
|
+
cucumber_cli += ' --tags ~@spawn' if RUBY_PLATFORM =~ /mswin|mingw|windows/
|
9
|
+
guard 'cucumber', cli: cucumber_cli do
|
8
10
|
watch(%r{^features/.+\.feature$})
|
9
11
|
watch(%r{^features/support/.+$}) { 'features' }
|
10
12
|
watch(%r{^features/step_definitions/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'features' }
|
data/README.md
CHANGED
@@ -9,7 +9,7 @@
|
|
9
9
|
|-------------|-----------------------------------------------|
|
10
10
|
| Website | http://kitchen.ci |
|
11
11
|
| Source Code | http://kitchen.ci/docs/getting-started/ |
|
12
|
-
| IRC | [#kitchenci][irc] channel on Freenode
|
12
|
+
| IRC | [#kitchenci][irc] channel on Freenode, [transcript][irc_log] thanks to [BotBot.me][botbotme] |
|
13
13
|
| Twitter | [@kitchenci][twitter] |
|
14
14
|
|
15
15
|
> **Test Kitchen is an integration tool for developing and testing
|
@@ -111,10 +111,12 @@ a growing community of [contributors][contributors].
|
|
111
111
|
|
112
112
|
Apache License, Version 2.0 (see [LICENSE][license])
|
113
113
|
|
114
|
+
[botbotme]: https://botbot.me/
|
114
115
|
[contributors]: https://github.com/test-kitchen/test-kitchen/graphs/contributors
|
115
116
|
[fnichol]: https://github.com/fnichol
|
116
117
|
[guide]: http://kitchen.ci/docs/getting-started/
|
117
118
|
[irc]: http://webchat.freenode.net/?channels=kitchenci
|
119
|
+
[irc_log]: https://botbot.me/freenode/kitchenci/
|
118
120
|
[issues]: https://github.com/test-kitchen/test-kitchen/issues
|
119
121
|
[license]: https://github.com/test-kitchen/test-kitchen/blob/master/LICENSE
|
120
122
|
[repo]: https://github.com/test-kitchen/test-kitchen
|
data/Rakefile
CHANGED
@@ -30,22 +30,7 @@ unless RUBY_ENGINE == 'jruby'
|
|
30
30
|
|
31
31
|
desc "Run cane to check quality metrics"
|
32
32
|
Cane::RakeTask.new do |cane|
|
33
|
-
cane.
|
34
|
-
cane.abc_exclude = %w(
|
35
|
-
Kitchen::RakeTasks#define
|
36
|
-
Kitchen::ThorTasks#define
|
37
|
-
Kitchen::CLI#pry_prompts
|
38
|
-
Kitchen::CLI#debug_instance
|
39
|
-
Kitchen::Instance#synchronize_or_call
|
40
|
-
Kitchen::Driver::SSHBase#converge
|
41
|
-
)
|
42
|
-
cane.style_exclude = %w(
|
43
|
-
lib/vendor/hash_recursive_merge.rb
|
44
|
-
)
|
45
|
-
cane.doc_exclude = %w(
|
46
|
-
lib/vendor/hash_recursive_merge.rb
|
47
|
-
)
|
48
|
-
cane.style_measure = 160
|
33
|
+
cane.canefile = './.cane'
|
49
34
|
end
|
50
35
|
|
51
36
|
Tailor::RakeTask.new do |task|
|
@@ -3,6 +3,7 @@ Feature: Search RubyGems to discover new Test Kitchen Driver gems
|
|
3
3
|
As a Test Kitchen user
|
4
4
|
I want to run a command which returns candidate Kitchen drivers
|
5
5
|
|
6
|
+
@spawn
|
6
7
|
Scenario: Displaying help
|
7
8
|
When I run `kitchen help driver discover`
|
8
9
|
Then the output should contain:
|
@@ -0,0 +1,16 @@
|
|
1
|
+
Feature: Using Test Kitchen CLI help
|
2
|
+
In order to access the self describing documentation
|
3
|
+
As a user of Test Kitchen
|
4
|
+
I want to run a command help help for kitchen commands
|
5
|
+
|
6
|
+
@spawn
|
7
|
+
Scenario: Printing help
|
8
|
+
When I run `kitchen help`
|
9
|
+
Then the exit status should be 0
|
10
|
+
And the output should contain "kitchen help [COMMAND]"
|
11
|
+
|
12
|
+
@spawn
|
13
|
+
Scenario: Bad arugments should exit nonzero
|
14
|
+
When I run `kitchen help -d always -c`
|
15
|
+
Then the exit status should not be 0
|
16
|
+
And the output should contain "Usage: "
|
@@ -3,6 +3,7 @@ Feature: Add Test Kitchen support to an existing project
|
|
3
3
|
As an operator
|
4
4
|
I want to run a command to initialize my project
|
5
5
|
|
6
|
+
@spawn
|
6
7
|
Scenario: Displaying help
|
7
8
|
When I run `kitchen help init`
|
8
9
|
Then the output should contain:
|
@@ -12,6 +13,7 @@ Feature: Add Test Kitchen support to an existing project
|
|
12
13
|
"""
|
13
14
|
And the exit status should be 0
|
14
15
|
|
16
|
+
@spawn
|
15
17
|
Scenario: Running init with default values
|
16
18
|
Given a sandboxed GEM_HOME directory named "kitchen-init"
|
17
19
|
And I have a git repository
|
@@ -13,6 +13,7 @@ Feature: Listing Test Kitchen instances
|
|
13
13
|
platforms:
|
14
14
|
- name: ubuntu-13.04
|
15
15
|
- name: centos-6.4
|
16
|
+
- name: centos-6.4-with-small-mem
|
16
17
|
|
17
18
|
suites:
|
18
19
|
- name: foobar
|
@@ -31,6 +32,7 @@ Feature: Listing Test Kitchen instances
|
|
31
32
|
"""
|
32
33
|
foobar-ubuntu-1304
|
33
34
|
foobar-centos-64
|
35
|
+
foobar-centos-64-with-small-mem
|
34
36
|
|
35
37
|
"""
|
36
38
|
|
@@ -51,12 +53,52 @@ Feature: Listing Test Kitchen instances
|
|
51
53
|
|
52
54
|
"""
|
53
55
|
|
56
|
+
@spawn
|
54
57
|
Scenario: Listing instances with a regular expression yielding no results
|
55
58
|
When I run `kitchen list freebsd --bare`
|
56
59
|
Then the exit status should not be 0
|
57
60
|
And the output should contain "No instances for regex `freebsd', try running `kitchen list'"
|
58
61
|
|
62
|
+
@spawn
|
59
63
|
Scenario: Listing instances with a bad regular expression
|
60
64
|
When I run `kitchen list *centos* --bare`
|
61
65
|
Then the exit status should not be 0
|
62
66
|
And the output should contain "Invalid Ruby regular expression"
|
67
|
+
|
68
|
+
Scenario: Listing a full instance name returns an exact match, not fuzzy matches
|
69
|
+
When I successfully run `kitchen list foobar-centos-64 --bare`
|
70
|
+
Then the output should contain exactly:
|
71
|
+
"""
|
72
|
+
foobar-centos-64
|
73
|
+
|
74
|
+
"""
|
75
|
+
|
76
|
+
Scenario: Listing a full instance name returns an exact match, not fuzzy matches at start
|
77
|
+
Given a file named ".kitchen.yml" with:
|
78
|
+
"""
|
79
|
+
---
|
80
|
+
driver: dummy
|
81
|
+
provisioner: chef_solo
|
82
|
+
|
83
|
+
platforms:
|
84
|
+
- name: ubuntu-12.04
|
85
|
+
|
86
|
+
suites:
|
87
|
+
- name: gdb01-master
|
88
|
+
- name: logdb01-master
|
89
|
+
"""
|
90
|
+
When I successfully run `kitchen list gdb01-master-ubuntu-1204 --bare`
|
91
|
+
Then the output should contain exactly:
|
92
|
+
"""
|
93
|
+
gdb01-master-ubuntu-1204
|
94
|
+
|
95
|
+
"""
|
96
|
+
|
97
|
+
Scenario: Listing a full instance with regex returns all regex matches
|
98
|
+
When I successfully run `kitchen list 'foobar-centos-64.*' --bare`
|
99
|
+
Then the output should contain exactly:
|
100
|
+
"""
|
101
|
+
foobar-centos-64
|
102
|
+
foobar-centos-64-with-small-mem
|
103
|
+
|
104
|
+
"""
|
data/features/support/env.rb
CHANGED
@@ -1,10 +1,35 @@
|
|
1
1
|
# Set up the environment for testing
|
2
2
|
require 'aruba/cucumber'
|
3
|
+
require 'aruba/in_process'
|
4
|
+
require 'aruba/spawn_process'
|
3
5
|
require 'kitchen'
|
6
|
+
require 'kitchen/cli'
|
7
|
+
|
8
|
+
class ArubaHelper
|
9
|
+
def initialize(argv, stdin=STDIN, stdout=STDOUT, stderr=STDERR, kernel=Kernel)
|
10
|
+
@argv, @stdin, @stdout, @stderr, @kernel = argv, stdin, stdout, stderr, kernel
|
11
|
+
end
|
12
|
+
|
13
|
+
def execute!
|
14
|
+
$stdout = @stdout
|
15
|
+
$stdin = @stdin
|
16
|
+
|
17
|
+
kitchen_cli = Kitchen::CLI
|
18
|
+
kitchen_cli.start(@argv)
|
19
|
+
@kernel.exit(0)
|
20
|
+
end
|
21
|
+
end
|
4
22
|
|
5
23
|
Before do
|
6
24
|
@aruba_timeout_seconds = 15
|
7
25
|
@cleanup_dirs = []
|
26
|
+
|
27
|
+
Aruba::InProcess.main_class = ArubaHelper
|
28
|
+
Aruba.process = Aruba::InProcess
|
29
|
+
end
|
30
|
+
|
31
|
+
Before('@spawn') do
|
32
|
+
Aruba.process = Aruba::SpawnProcess
|
8
33
|
end
|
9
34
|
|
10
35
|
After do |s|
|
data/lib/kitchen.rb
CHANGED
data/lib/kitchen/busser.rb
CHANGED
@@ -128,7 +128,7 @@ module Kitchen
|
|
128
128
|
sync_cmd << busser_setup_env
|
129
129
|
sync_cmd << "#{sudo}#{config[:busser_bin]} suite cleanup"
|
130
130
|
sync_cmd << "#{local_suite_files.map { |f| stream_file(f, remote_file(f, config[:suite_name])) }.join("; ")}"
|
131
|
-
sync_cmd << "#{helper_files.map { |f| stream_file(f, remote_file(f, "helpers")) }.join}"
|
131
|
+
sync_cmd << "#{helper_files.map { |f| stream_file(f, remote_file(f, "helpers")) }.join("; ")}"
|
132
132
|
|
133
133
|
# use Bourne (/bin/sh) as Bash does not exist on all Unix flavors
|
134
134
|
"sh -c '#{sync_cmd.join('; ')}'"
|
@@ -193,7 +193,7 @@ module Kitchen
|
|
193
193
|
end
|
194
194
|
|
195
195
|
def helper_files
|
196
|
-
Dir.glob(File.join(config[:test_base_path], "helpers", "*/**/*"))
|
196
|
+
Dir.glob(File.join(config[:test_base_path], "helpers", "*/**/*")).reject { |f| File.directory?(f) }
|
197
197
|
end
|
198
198
|
|
199
199
|
def remote_file(file, dir)
|
data/lib/kitchen/cli.rb
CHANGED
@@ -16,11 +16,7 @@
|
|
16
16
|
# See the License for the specific language governing permissions and
|
17
17
|
# limitations under the License.
|
18
18
|
|
19
|
-
require 'benchmark'
|
20
|
-
require 'erb'
|
21
|
-
require 'ostruct'
|
22
19
|
require 'thor'
|
23
|
-
require 'thread'
|
24
20
|
|
25
21
|
require 'kitchen'
|
26
22
|
require 'kitchen/generator/driver_create'
|
@@ -33,22 +29,47 @@ module Kitchen
|
|
33
29
|
# @author Fletcher Nichol <fnichol@nichol.ca>
|
34
30
|
class CLI < Thor
|
35
31
|
|
36
|
-
|
32
|
+
# Common module to load and invoke a CLI-implementation agnostic command.
|
33
|
+
module PerformCommand
|
34
|
+
|
35
|
+
def perform(task, command, args = nil, additional_options = {})
|
36
|
+
require "kitchen/command/#{command}"
|
37
|
+
|
38
|
+
command_options = {
|
39
|
+
:action => task,
|
40
|
+
:help => lambda { help(task) },
|
41
|
+
:config => @config,
|
42
|
+
:shell => shell
|
43
|
+
}.merge(additional_options)
|
44
|
+
|
45
|
+
str_const = Thor::Util.camel_case(command)
|
46
|
+
klass = ::Kitchen::Command.const_get(str_const)
|
47
|
+
klass.new(args, options, command_options).call
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
37
51
|
include Logging
|
52
|
+
include PerformCommand
|
53
|
+
|
54
|
+
MAX_CONCURRENCY = 9999
|
38
55
|
|
39
56
|
# Constructs a new instance.
|
40
57
|
def initialize(*args)
|
41
58
|
super
|
42
59
|
$stdout.sync = true
|
43
60
|
Kitchen.logger = Kitchen.default_file_logger
|
44
|
-
@loader = Kitchen::Loader::YAML.new(
|
61
|
+
@loader = Kitchen::Loader::YAML.new(
|
62
|
+
:project_config => ENV['KITCHEN_YAML'],
|
63
|
+
:local_config => ENV['KITCHEN_LOCAL_YAML'],
|
64
|
+
:global_config => ENV['KITCHEN_GLOBAL_YAML']
|
65
|
+
)
|
45
66
|
@config = Kitchen::Config.new(
|
46
67
|
:loader => @loader,
|
47
68
|
:log_level => ENV.fetch('KITCHEN_LOG', "info").downcase.to_sym
|
48
69
|
)
|
49
70
|
end
|
50
71
|
|
51
|
-
desc "list [
|
72
|
+
desc "list [INSTANCE|REGEXP|all]", "Lists one or more instances"
|
52
73
|
method_option :bare, :aliases => "-b", :type => :boolean,
|
53
74
|
:desc => "List the name of each instance only, one per line"
|
54
75
|
method_option :debug, :aliases => "-d", :type => :boolean,
|
@@ -57,18 +78,10 @@ module Kitchen
|
|
57
78
|
:desc => "Set the log level (debug, info, warn, error, fatal)"
|
58
79
|
def list(*args)
|
59
80
|
update_config!
|
60
|
-
|
61
|
-
if options[:debug]
|
62
|
-
die task, "The --debug flag on the list subcommand is deprecated, " +
|
63
|
-
"please use `kitchen diagnose'."
|
64
|
-
elsif options[:bare]
|
65
|
-
say Array(result).map { |i| i.name }.join("\n")
|
66
|
-
else
|
67
|
-
list_table(result)
|
68
|
-
end
|
81
|
+
perform("list", "list", args)
|
69
82
|
end
|
70
83
|
|
71
|
-
desc "diagnose [
|
84
|
+
desc "diagnose [INSTANCE|REGEXP|all]", "Show computed diagnostic configuration"
|
72
85
|
method_option :log_level, :aliases => "-l",
|
73
86
|
:desc => "Set the log level (debug, info, warn, error, fatal)"
|
74
87
|
method_option :loader, :type => :boolean,
|
@@ -79,36 +92,34 @@ module Kitchen
|
|
79
92
|
:desc => "Include all diagnostics"
|
80
93
|
def diagnose(*args)
|
81
94
|
update_config!
|
82
|
-
|
83
|
-
loader = if options[:all] || options[:loader]
|
84
|
-
@loader
|
85
|
-
else
|
86
|
-
nil
|
87
|
-
end
|
88
|
-
instances = if options[:all] || options[:instances]
|
89
|
-
parse_subcommand(args.first)
|
90
|
-
else
|
91
|
-
[]
|
92
|
-
end
|
93
|
-
|
94
|
-
require 'yaml'
|
95
|
-
Kitchen::Diagnostic.new(:loader => loader, :instances => instances).
|
96
|
-
read.to_yaml.each_line { |line| say(line) }
|
95
|
+
perform("diagnose", "diagnose", args, :loader => @loader)
|
97
96
|
end
|
98
97
|
|
99
98
|
[:create, :converge, :setup, :verify, :destroy].each do |action|
|
100
99
|
desc(
|
101
|
-
"#{action} [
|
100
|
+
"#{action} [INSTANCE|REGEXP|all]",
|
102
101
|
"#{action.capitalize} one or more instances"
|
103
102
|
)
|
103
|
+
method_option :concurrency, :aliases => "-c",
|
104
|
+
:type => :numeric, :lazy_default => MAX_CONCURRENCY,
|
105
|
+
:desc => <<-DESC.gsub(/^\s+/, '').gsub(/\n/, ' ')
|
106
|
+
Run a #{action} against all matching instances concurrently. Only N
|
107
|
+
instances will run at the same time if a number is given.
|
108
|
+
DESC
|
104
109
|
method_option :parallel, :aliases => "-p", :type => :boolean,
|
105
|
-
:desc =>
|
110
|
+
:desc => <<-DESC.gsub(/^\s+/, '').gsub(/\n/, ' ')
|
111
|
+
[Future DEPRECATION, use --concurrency]
|
112
|
+
Run a #{action} against all matching instances concurrently.
|
113
|
+
DESC
|
106
114
|
method_option :log_level, :aliases => "-l",
|
107
115
|
:desc => "Set the log level (debug, info, warn, error, fatal)"
|
108
|
-
define_method(action)
|
116
|
+
define_method(action) do |*args|
|
117
|
+
update_config!
|
118
|
+
perform(action, "action", args)
|
119
|
+
end
|
109
120
|
end
|
110
121
|
|
111
|
-
desc "test [all
|
122
|
+
desc "test [INSTANCE|REGEXP|all]", "Test one or more instances"
|
112
123
|
long_desc <<-DESC
|
113
124
|
Test one or more instances
|
114
125
|
|
@@ -119,8 +130,17 @@ module Kitchen
|
|
119
130
|
* always: instances will always be destroyed afterwards.\n
|
120
131
|
* never: instances will never be destroyed afterwards.
|
121
132
|
DESC
|
133
|
+
method_option :concurrency, :aliases => "-c",
|
134
|
+
:type => :numeric, :lazy_default => MAX_CONCURRENCY,
|
135
|
+
:desc => <<-DESC.gsub(/^\s+/, '').gsub(/\n/, ' ')
|
136
|
+
Run a test against all matching instances concurrently. Only N
|
137
|
+
instances will run at the same time if a number is given.
|
138
|
+
DESC
|
122
139
|
method_option :parallel, :aliases => "-p", :type => :boolean,
|
123
|
-
:desc =>
|
140
|
+
:desc => <<-DESC.gsub(/^\s+/, '').gsub(/\n/, ' ')
|
141
|
+
[Future DEPRECATION, use --concurrency]
|
142
|
+
Run a test against all matching instances concurrently.
|
143
|
+
DESC
|
124
144
|
method_option :log_level, :aliases => "-l",
|
125
145
|
:desc => "Set the log level (debug, info, warn, error, fatal)"
|
126
146
|
method_option :destroy, :aliases => "-d", :default => "passing",
|
@@ -128,79 +148,33 @@ module Kitchen
|
|
128
148
|
method_option :auto_init, :type => :boolean, :default => false,
|
129
149
|
:desc => "Invoke init command if .kitchen.yml is missing"
|
130
150
|
def test(*args)
|
131
|
-
if ! %w{passing always never}.include?(options[:destroy])
|
132
|
-
raise ArgumentError, "Destroy mode must be passing, always, or never."
|
133
|
-
end
|
134
|
-
|
135
151
|
update_config!
|
136
|
-
|
137
|
-
|
138
|
-
ensure_initialized
|
139
|
-
destroy_mode = options[:destroy].to_sym
|
140
|
-
@task = :test
|
141
|
-
results = parse_subcommand(args.join('|'))
|
142
|
-
|
143
|
-
if options[:parallel]
|
144
|
-
run_parallel(results, destroy_mode)
|
145
|
-
else
|
146
|
-
run_serial(results, destroy_mode)
|
147
|
-
end
|
148
|
-
end
|
149
|
-
banner "Kitchen is finished. #{Util.duration(elapsed.real)}"
|
152
|
+
ensure_initialized
|
153
|
+
perform("test", "test", args)
|
150
154
|
end
|
151
155
|
|
152
|
-
desc "login
|
156
|
+
desc "login INSTANCE|REGEXP", "Log in to one instance"
|
153
157
|
method_option :log_level, :aliases => "-l",
|
154
158
|
:desc => "Set the log level (debug, info, warn, error, fatal)"
|
155
|
-
def login(
|
159
|
+
def login(*args)
|
156
160
|
update_config!
|
157
|
-
|
158
|
-
if results.size > 1
|
159
|
-
die task, "Argument `#{regexp}' returned multiple results:\n" +
|
160
|
-
results.map { |i| " * #{i.name}" }.join("\n")
|
161
|
-
end
|
162
|
-
instance = results.pop
|
163
|
-
|
164
|
-
instance.login
|
161
|
+
perform("login", "login", args)
|
165
162
|
end
|
166
163
|
|
167
164
|
desc "version", "Print Kitchen's version information"
|
168
165
|
def version
|
169
|
-
|
166
|
+
puts "Test Kitchen version #{Kitchen::VERSION}"
|
170
167
|
end
|
171
168
|
map %w(-v --version) => :version
|
172
169
|
|
173
170
|
desc "sink", "Show the Kitchen sink!", :hide => true
|
174
171
|
def sink
|
175
|
-
|
176
|
-
"",
|
177
|
-
" ___ ",
|
178
|
-
" ' _ '. ",
|
179
|
-
" / /` `\\ \\ ",
|
180
|
-
" | | [__] ",
|
181
|
-
" | | {{ ",
|
182
|
-
" | | }} ",
|
183
|
-
" _ | | _ {{ ",
|
184
|
-
" ___________<_>_| |_<_>}}________ ",
|
185
|
-
" .=======^=(___)=^={{====. ",
|
186
|
-
" / .----------------}}---. \\ ",
|
187
|
-
" / / {{ \\ \\ ",
|
188
|
-
" / / }} \\ \\ ",
|
189
|
-
" ( '=========================' ) ",
|
190
|
-
" '-----------------------------' ",
|
191
|
-
" ", # necessary newline
|
192
|
-
""
|
193
|
-
].map(&:rstrip).join("\n")
|
172
|
+
perform("sink", "sink")
|
194
173
|
end
|
195
174
|
|
196
175
|
desc "console", "Kitchen Console!"
|
197
176
|
def console
|
198
|
-
|
199
|
-
Pry.start(@config, :prompt => pry_prompts)
|
200
|
-
rescue LoadError => e
|
201
|
-
warn %{Make sure you have the pry gem installed. You can install it with:}
|
202
|
-
warn %{`gem install pry` or including 'gem "pry"' in your Gemfile.}
|
203
|
-
exit 1
|
177
|
+
perform("console", "console")
|
204
178
|
end
|
205
179
|
|
206
180
|
register Kitchen::Generator::Init, "init",
|
@@ -218,6 +192,8 @@ module Kitchen
|
|
218
192
|
# @author Fletcher Nichol <fnichol@nichol.ca>
|
219
193
|
class Driver < Thor
|
220
194
|
|
195
|
+
include PerformCommand
|
196
|
+
|
221
197
|
register Kitchen::Generator::DriverCreate, "create",
|
222
198
|
"create [NAME]", "Create a new Kitchen Driver gem project"
|
223
199
|
long_desc <<-D, :for => "create"
|
@@ -238,43 +214,12 @@ module Kitchen
|
|
238
214
|
relevant drivers will be returned.
|
239
215
|
D
|
240
216
|
def discover
|
241
|
-
|
242
|
-
specs = specs[0, 49].push(["...", "..."]) if specs.size > 49
|
243
|
-
specs = specs.unshift(["Gem Name", "Latest Stable Release"])
|
244
|
-
print_table(specs, :indent => 4)
|
217
|
+
perform("discover", "driver_discover", args)
|
245
218
|
end
|
246
219
|
|
247
220
|
def self.basename
|
248
221
|
super + " driver"
|
249
222
|
end
|
250
|
-
|
251
|
-
private
|
252
|
-
|
253
|
-
def fetch_gem_specs
|
254
|
-
require 'rubygems/spec_fetcher'
|
255
|
-
SafeYAML::OPTIONS[:suppress_warnings] = true
|
256
|
-
req = Gem::Requirement.default
|
257
|
-
dep = Gem::Deprecate.skip_during do
|
258
|
-
Gem::Dependency.new(/kitchen-/i, req)
|
259
|
-
end
|
260
|
-
fetcher = Gem::SpecFetcher.fetcher
|
261
|
-
|
262
|
-
specs = if fetcher.respond_to?(:find_matching)
|
263
|
-
fetch_gem_specs_pre_rubygems_2(fetcher, dep)
|
264
|
-
else
|
265
|
-
fetch_gem_specs_post_rubygems_2(fetcher, dep)
|
266
|
-
end
|
267
|
-
end
|
268
|
-
|
269
|
-
def fetch_gem_specs_pre_rubygems_2(fetcher, dep)
|
270
|
-
specs = fetcher.find_matching(dep, false, false, false)
|
271
|
-
specs.map { |t| t.first }.map { |t| t[0, 2] }
|
272
|
-
end
|
273
|
-
|
274
|
-
def fetch_gem_specs_post_rubygems_2(fetcher, dep)
|
275
|
-
specs = fetcher.spec_for_dependency(dep, false)
|
276
|
-
specs.first.map { |t| [t.first.name, t.first.version] }
|
277
|
-
end
|
278
223
|
end
|
279
224
|
|
280
225
|
register Kitchen::CLI::Driver, "driver",
|
@@ -293,111 +238,30 @@ module Kitchen
|
|
293
238
|
|
294
239
|
private
|
295
240
|
|
296
|
-
|
241
|
+
def self.exit_on_failure?
|
242
|
+
true
|
243
|
+
end
|
297
244
|
|
298
245
|
def logger
|
299
246
|
Kitchen.logger
|
300
247
|
end
|
301
248
|
|
302
|
-
def exec_action(action)
|
303
|
-
update_config!
|
304
|
-
banner "Starting Kitchen (v#{Kitchen::VERSION})"
|
305
|
-
elapsed = Benchmark.measure do
|
306
|
-
@task = action
|
307
|
-
results = parse_subcommand(args.first)
|
308
|
-
options[:parallel] ? run_parallel(results) : run_serial(results)
|
309
|
-
end
|
310
|
-
banner "Kitchen is finished. #{Util.duration(elapsed.real)}"
|
311
|
-
end
|
312
|
-
|
313
|
-
def run_serial(instances, *args)
|
314
|
-
Array(instances).map { |i| i.public_send(task, *args) }
|
315
|
-
end
|
316
|
-
|
317
|
-
def run_parallel(instances, *args)
|
318
|
-
threads = Array(instances).map do |i|
|
319
|
-
Thread.new do
|
320
|
-
i.public_send(task, *args)
|
321
|
-
end
|
322
|
-
end
|
323
|
-
threads.map { |i| i.join }
|
324
|
-
end
|
325
|
-
|
326
|
-
def parse_subcommand(arg = nil)
|
327
|
-
arg == "all" ? get_all_instances : get_filtered_instances(arg)
|
328
|
-
end
|
329
|
-
|
330
|
-
def get_all_instances
|
331
|
-
result = @config.instances
|
332
|
-
|
333
|
-
if result.empty?
|
334
|
-
die task, "No instances defined"
|
335
|
-
else
|
336
|
-
result
|
337
|
-
end
|
338
|
-
end
|
339
|
-
|
340
|
-
def get_filtered_instances(regexp)
|
341
|
-
result = begin
|
342
|
-
@config.instances.get_all(/#{regexp}/)
|
343
|
-
rescue RegexpError => e
|
344
|
-
die task, "Invalid Ruby regular expression, " +
|
345
|
-
"you may need to single quote the argument. " +
|
346
|
-
"Please try again or consult http://rubular.com/ (#{e.message})"
|
347
|
-
end
|
348
|
-
|
349
|
-
if result.empty?
|
350
|
-
die task, "No instances for regex `#{regexp}', try running `kitchen list'"
|
351
|
-
else
|
352
|
-
result
|
353
|
-
end
|
354
|
-
end
|
355
|
-
|
356
|
-
def list_table(result)
|
357
|
-
table = [
|
358
|
-
[set_color("Instance", :green), set_color("Driver", :green),
|
359
|
-
set_color("Provisioner", :green), set_color("Last Action", :green)]
|
360
|
-
]
|
361
|
-
table += Array(result).map { |i| display_instance(i) }
|
362
|
-
print_table(table)
|
363
|
-
end
|
364
|
-
|
365
|
-
def display_instance(instance)
|
366
|
-
[
|
367
|
-
color_pad(instance.name),
|
368
|
-
color_pad(instance.driver.name),
|
369
|
-
color_pad(instance.provisioner.name),
|
370
|
-
format_last_action(instance.last_action)
|
371
|
-
]
|
372
|
-
end
|
373
|
-
|
374
|
-
def color_pad(string)
|
375
|
-
string + set_color("", :white)
|
376
|
-
end
|
377
|
-
|
378
|
-
def format_last_action(last_action)
|
379
|
-
case last_action
|
380
|
-
when 'create' then set_color("Created", :cyan)
|
381
|
-
when 'converge' then set_color("Converged", :magenta)
|
382
|
-
when 'setup' then set_color("Set Up", :blue)
|
383
|
-
when 'verify' then set_color("Verified", :yellow)
|
384
|
-
when nil then set_color("<Not Created>", :red)
|
385
|
-
else set_color("<Unknown>", :white)
|
386
|
-
end
|
387
|
-
end
|
388
|
-
|
389
249
|
def update_config!
|
390
250
|
if options[:log_level]
|
391
251
|
level = options[:log_level].downcase.to_sym
|
392
252
|
@config.log_level = level
|
393
253
|
Kitchen.logger.level = Util.to_logger_level(level)
|
394
254
|
end
|
395
|
-
end
|
396
255
|
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
256
|
+
if options[:parallel]
|
257
|
+
# warn here in a future release when option is used
|
258
|
+
@options = Thor::CoreExt::HashWithIndifferentAccess.new(options.to_hash)
|
259
|
+
if options[:parallel] && !options[:concurrency]
|
260
|
+
options[:concurrency] = MAX_CONCURRENCY
|
261
|
+
end
|
262
|
+
options.delete(:parallel)
|
263
|
+
options.freeze
|
264
|
+
end
|
401
265
|
end
|
402
266
|
|
403
267
|
def ensure_initialized
|
@@ -408,22 +272,5 @@ module Kitchen
|
|
408
272
|
invoke "init"
|
409
273
|
end
|
410
274
|
end
|
411
|
-
|
412
|
-
def pry_prompts
|
413
|
-
[
|
414
|
-
proc { |target_self, nest_level, pry|
|
415
|
-
["[#{pry.input_array.size}] ",
|
416
|
-
"kc(#{Pry.view_clip(target_self.class)})",
|
417
|
-
"#{":#{nest_level}" unless nest_level.zero?}> "
|
418
|
-
].join
|
419
|
-
},
|
420
|
-
proc { |target_self, nest_level, pry|
|
421
|
-
["[#{pry.input_array.size}] ",
|
422
|
-
"kc(#{Pry.view_clip(target_self.class)})",
|
423
|
-
"#{":#{nest_level}" unless nest_level.zero?}* "
|
424
|
-
].join
|
425
|
-
},
|
426
|
-
]
|
427
|
-
end
|
428
275
|
end
|
429
276
|
end
|