test-kitchen 1.7.0 → 1.7.1.dev
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 +8 -8
- data/.gitattributes +3 -0
- data/.github/ISSUE_TEMPLATE.md +55 -55
- data/.gitignore +28 -28
- data/.kitchen.ci.yml +23 -23
- data/.kitchen.proxy.yml +27 -27
- data/.rubocop.yml +3 -3
- data/.travis.yml +70 -70
- data/.yardopts +3 -3
- data/Berksfile +3 -3
- data/CHANGELOG.md +1090 -1083
- data/CONTRIBUTING.md +14 -14
- data/Gemfile +19 -19
- data/Gemfile.proxy_tests +4 -4
- data/Guardfile +42 -42
- data/LICENSE +15 -15
- data/MAINTAINERS.md +23 -23
- data/README.md +135 -135
- data/Rakefile +61 -61
- data/appveyor.yml +44 -44
- data/features/kitchen_action_commands.feature +164 -164
- data/features/kitchen_command.feature +16 -16
- data/features/kitchen_console_command.feature +34 -34
- data/features/kitchen_defaults.feature +38 -38
- data/features/kitchen_diagnose_command.feature +96 -96
- data/features/kitchen_driver_create_command.feature +64 -64
- data/features/kitchen_driver_discover_command.feature +25 -25
- data/features/kitchen_help_command.feature +16 -16
- data/features/kitchen_init_command.feature +274 -274
- data/features/kitchen_list_command.feature +104 -104
- data/features/kitchen_login_command.feature +62 -62
- data/features/kitchen_sink_command.feature +30 -30
- data/features/kitchen_test_command.feature +88 -88
- data/features/step_definitions/gem_steps.rb +36 -36
- data/features/step_definitions/git_steps.rb +5 -5
- data/features/step_definitions/output_steps.rb +5 -5
- data/features/support/env.rb +75 -75
- data/lib/kitchen.rb +150 -150
- data/lib/kitchen/base64_stream.rb +55 -55
- data/lib/kitchen/cli.rb +419 -419
- data/lib/kitchen/collection.rb +55 -55
- data/lib/kitchen/color.rb +65 -65
- data/lib/kitchen/command.rb +185 -185
- data/lib/kitchen/command/action.rb +45 -45
- data/lib/kitchen/command/console.rb +58 -58
- data/lib/kitchen/command/diagnose.rb +92 -92
- data/lib/kitchen/command/driver_discover.rb +105 -105
- data/lib/kitchen/command/exec.rb +41 -41
- data/lib/kitchen/command/list.rb +119 -119
- data/lib/kitchen/command/login.rb +43 -43
- data/lib/kitchen/command/sink.rb +54 -54
- data/lib/kitchen/command/test.rb +51 -51
- data/lib/kitchen/config.rb +322 -322
- data/lib/kitchen/configurable.rb +529 -529
- data/lib/kitchen/data_munger.rb +959 -959
- data/lib/kitchen/diagnostic.rb +141 -141
- data/lib/kitchen/driver.rb +56 -56
- data/lib/kitchen/driver/base.rb +134 -134
- data/lib/kitchen/driver/dummy.rb +108 -108
- data/lib/kitchen/driver/proxy.rb +72 -72
- data/lib/kitchen/driver/ssh_base.rb +357 -357
- data/lib/kitchen/errors.rb +229 -229
- data/lib/kitchen/generator/driver_create.rb +177 -177
- data/lib/kitchen/generator/init.rb +296 -296
- data/lib/kitchen/instance.rb +662 -662
- data/lib/kitchen/lazy_hash.rb +142 -142
- data/lib/kitchen/loader/yaml.rb +349 -349
- data/lib/kitchen/logger.rb +423 -423
- data/lib/kitchen/logging.rb +56 -56
- data/lib/kitchen/login_command.rb +52 -52
- data/lib/kitchen/metadata_chopper.rb +52 -52
- data/lib/kitchen/platform.rb +67 -67
- data/lib/kitchen/provisioner.rb +54 -54
- data/lib/kitchen/provisioner/base.rb +236 -236
- data/lib/kitchen/provisioner/chef/berkshelf.rb +114 -114
- data/lib/kitchen/provisioner/chef/common_sandbox.rb +322 -322
- data/lib/kitchen/provisioner/chef/librarian.rb +112 -112
- data/lib/kitchen/provisioner/chef_apply.rb +124 -124
- data/lib/kitchen/provisioner/chef_base.rb +341 -341
- data/lib/kitchen/provisioner/chef_solo.rb +88 -88
- data/lib/kitchen/provisioner/chef_zero.rb +245 -245
- data/lib/kitchen/provisioner/dummy.rb +79 -79
- data/lib/kitchen/provisioner/shell.rb +138 -138
- data/lib/kitchen/rake_tasks.rb +63 -63
- data/lib/kitchen/shell_out.rb +93 -93
- data/lib/kitchen/ssh.rb +276 -276
- data/lib/kitchen/state_file.rb +120 -120
- data/lib/kitchen/suite.rb +51 -51
- data/lib/kitchen/thor_tasks.rb +66 -66
- data/lib/kitchen/transport.rb +54 -54
- data/lib/kitchen/transport/base.rb +176 -176
- data/lib/kitchen/transport/dummy.rb +79 -79
- data/lib/kitchen/transport/ssh.rb +364 -364
- data/lib/kitchen/transport/winrm.rb +486 -486
- data/lib/kitchen/util.rb +147 -147
- data/lib/kitchen/verifier.rb +55 -55
- data/lib/kitchen/verifier/base.rb +235 -235
- data/lib/kitchen/verifier/busser.rb +277 -277
- data/lib/kitchen/verifier/dummy.rb +79 -79
- data/lib/kitchen/verifier/shell.rb +101 -101
- data/lib/kitchen/version.rb +21 -21
- data/lib/vendor/hash_recursive_merge.rb +82 -82
- data/spec/kitchen/base64_stream_spec.rb +77 -77
- data/spec/kitchen/cli_spec.rb +56 -56
- data/spec/kitchen/collection_spec.rb +80 -80
- data/spec/kitchen/color_spec.rb +54 -54
- data/spec/kitchen/config_spec.rb +408 -408
- data/spec/kitchen/configurable_spec.rb +1095 -1095
- data/spec/kitchen/data_munger_spec.rb +2694 -2694
- data/spec/kitchen/diagnostic_spec.rb +129 -129
- data/spec/kitchen/driver/base_spec.rb +121 -121
- data/spec/kitchen/driver/dummy_spec.rb +199 -199
- data/spec/kitchen/driver/proxy_spec.rb +138 -138
- data/spec/kitchen/driver/ssh_base_spec.rb +1115 -1115
- data/spec/kitchen/driver_spec.rb +112 -112
- data/spec/kitchen/errors_spec.rb +309 -309
- data/spec/kitchen/instance_spec.rb +1419 -1419
- data/spec/kitchen/lazy_hash_spec.rb +117 -117
- data/spec/kitchen/loader/yaml_spec.rb +774 -774
- data/spec/kitchen/logger_spec.rb +429 -429
- data/spec/kitchen/logging_spec.rb +59 -59
- data/spec/kitchen/login_command_spec.rb +68 -68
- data/spec/kitchen/metadata_chopper_spec.rb +82 -82
- data/spec/kitchen/platform_spec.rb +89 -89
- data/spec/kitchen/provisioner/base_spec.rb +386 -386
- data/spec/kitchen/provisioner/chef_apply_spec.rb +136 -136
- data/spec/kitchen/provisioner/chef_base_spec.rb +1161 -1161
- data/spec/kitchen/provisioner/chef_solo_spec.rb +557 -557
- data/spec/kitchen/provisioner/chef_zero_spec.rb +1001 -1001
- data/spec/kitchen/provisioner/dummy_spec.rb +99 -99
- data/spec/kitchen/provisioner/shell_spec.rb +566 -566
- data/spec/kitchen/provisioner_spec.rb +107 -107
- data/spec/kitchen/shell_out_spec.rb +150 -150
- data/spec/kitchen/ssh_spec.rb +693 -693
- data/spec/kitchen/state_file_spec.rb +129 -129
- data/spec/kitchen/suite_spec.rb +62 -62
- data/spec/kitchen/transport/base_spec.rb +89 -89
- data/spec/kitchen/transport/ssh_spec.rb +1255 -1255
- data/spec/kitchen/transport/winrm_spec.rb +1143 -1143
- data/spec/kitchen/transport_spec.rb +112 -112
- data/spec/kitchen/util_spec.rb +165 -165
- data/spec/kitchen/verifier/base_spec.rb +362 -362
- data/spec/kitchen/verifier/busser_spec.rb +610 -610
- data/spec/kitchen/verifier/dummy_spec.rb +99 -99
- data/spec/kitchen/verifier/shell_spec.rb +160 -160
- data/spec/kitchen/verifier_spec.rb +120 -120
- data/spec/kitchen_spec.rb +114 -114
- data/spec/spec_helper.rb +85 -85
- data/spec/support/powershell_max_size_spec.rb +40 -40
- data/support/busser_install_command.ps1 +14 -14
- data/support/busser_install_command.sh +14 -14
- data/support/chef-client-zero.rb +77 -77
- data/support/chef_base_init_command.ps1 +18 -18
- data/support/chef_base_init_command.sh +2 -2
- data/support/chef_base_install_command.ps1 +85 -85
- data/support/chef_base_install_command.sh +229 -229
- data/support/chef_zero_prepare_command_legacy.ps1 +9 -9
- data/support/chef_zero_prepare_command_legacy.sh +10 -10
- data/support/download_helpers.sh +109 -109
- data/support/dummy-validation.pem +27 -27
- data/templates/driver/CHANGELOG.md.erb +3 -3
- data/templates/driver/Gemfile.erb +3 -3
- data/templates/driver/README.md.erb +64 -64
- data/templates/driver/Rakefile.erb +21 -21
- data/templates/driver/driver.rb.erb +23 -23
- data/templates/driver/gemspec.erb +29 -29
- data/templates/driver/gitignore.erb +17 -17
- data/templates/driver/license_apachev2.erb +15 -15
- data/templates/driver/license_lgplv3.erb +16 -16
- data/templates/driver/license_mit.erb +22 -22
- data/templates/driver/license_reserved.erb +5 -5
- data/templates/driver/tailor.erb +4 -4
- data/templates/driver/travis.yml.erb +11 -11
- data/templates/driver/version.rb.erb +12 -12
- data/templates/init/chefignore.erb +1 -1
- data/templates/init/kitchen.yml.erb +18 -18
- data/test-kitchen.gemspec +62 -62
- data/test/integration/default/default_spec.rb +3 -3
- data/testing_windows.md +37 -37
- metadata +5 -4
data/lib/kitchen/collection.rb
CHANGED
|
@@ -1,55 +1,55 @@
|
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
|
2
|
-
#
|
|
3
|
-
# Author:: Fletcher Nichol (<fnichol@nichol.ca>)
|
|
4
|
-
#
|
|
5
|
-
# Copyright (C) 2012, Fletcher Nichol
|
|
6
|
-
#
|
|
7
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
|
-
# you may not use this file except in compliance with the License.
|
|
9
|
-
# You may obtain a copy of the License at
|
|
10
|
-
#
|
|
11
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
-
#
|
|
13
|
-
# Unless required by applicable law or agreed to in writing, software
|
|
14
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
-
# See the License for the specific language governing permissions and
|
|
17
|
-
# limitations under the License.
|
|
18
|
-
|
|
19
|
-
require "delegate"
|
|
20
|
-
|
|
21
|
-
module Kitchen
|
|
22
|
-
|
|
23
|
-
# Delegate class which adds the ability to find single and multiple
|
|
24
|
-
# objects by their #name in an Array. Hey, it's better than monkey-patching
|
|
25
|
-
# Array, right?
|
|
26
|
-
#
|
|
27
|
-
# @author Fletcher Nichol <fnichol@nichol.ca>
|
|
28
|
-
class Collection < SimpleDelegator
|
|
29
|
-
|
|
30
|
-
# Returns a single object by its name, or nil if none are found.
|
|
31
|
-
#
|
|
32
|
-
# @param name [String] name of object
|
|
33
|
-
# @return [Object] first match by name, or nil if none are found
|
|
34
|
-
def get(name)
|
|
35
|
-
__getobj__.find { |i| i.name == name }
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
# Returns a Collection of all objects whose #name is matched by the
|
|
39
|
-
# regular expression.
|
|
40
|
-
#
|
|
41
|
-
# @param regexp [Regexp] a regular expression pattern
|
|
42
|
-
# @return [Kitchen::Config::Collection<Object>] a new collection of
|
|
43
|
-
# matched objects
|
|
44
|
-
def get_all(regexp)
|
|
45
|
-
Kitchen::Collection.new(__getobj__.select { |i| i.name =~ regexp })
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
# Returns an Array of names from the collection as strings.
|
|
49
|
-
#
|
|
50
|
-
# @return [Array<String>] array of name strings
|
|
51
|
-
def as_names
|
|
52
|
-
__getobj__.map(&:name)
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
end
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Author:: Fletcher Nichol (<fnichol@nichol.ca>)
|
|
4
|
+
#
|
|
5
|
+
# Copyright (C) 2012, Fletcher Nichol
|
|
6
|
+
#
|
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
|
+
# you may not use this file except in compliance with the License.
|
|
9
|
+
# You may obtain a copy of the License at
|
|
10
|
+
#
|
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
#
|
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
# See the License for the specific language governing permissions and
|
|
17
|
+
# limitations under the License.
|
|
18
|
+
|
|
19
|
+
require "delegate"
|
|
20
|
+
|
|
21
|
+
module Kitchen
|
|
22
|
+
|
|
23
|
+
# Delegate class which adds the ability to find single and multiple
|
|
24
|
+
# objects by their #name in an Array. Hey, it's better than monkey-patching
|
|
25
|
+
# Array, right?
|
|
26
|
+
#
|
|
27
|
+
# @author Fletcher Nichol <fnichol@nichol.ca>
|
|
28
|
+
class Collection < SimpleDelegator
|
|
29
|
+
|
|
30
|
+
# Returns a single object by its name, or nil if none are found.
|
|
31
|
+
#
|
|
32
|
+
# @param name [String] name of object
|
|
33
|
+
# @return [Object] first match by name, or nil if none are found
|
|
34
|
+
def get(name)
|
|
35
|
+
__getobj__.find { |i| i.name == name }
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Returns a Collection of all objects whose #name is matched by the
|
|
39
|
+
# regular expression.
|
|
40
|
+
#
|
|
41
|
+
# @param regexp [Regexp] a regular expression pattern
|
|
42
|
+
# @return [Kitchen::Config::Collection<Object>] a new collection of
|
|
43
|
+
# matched objects
|
|
44
|
+
def get_all(regexp)
|
|
45
|
+
Kitchen::Collection.new(__getobj__.select { |i| i.name =~ regexp })
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Returns an Array of names from the collection as strings.
|
|
49
|
+
#
|
|
50
|
+
# @return [Array<String>] array of name strings
|
|
51
|
+
def as_names
|
|
52
|
+
__getobj__.map(&:name)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
data/lib/kitchen/color.rb
CHANGED
|
@@ -1,65 +1,65 @@
|
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
|
2
|
-
#
|
|
3
|
-
# Author:: Fletcher Nichol (<fnichol@nichol.ca>)
|
|
4
|
-
#
|
|
5
|
-
# Copyright (C) 2013, Fletcher Nichol
|
|
6
|
-
#
|
|
7
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
|
-
# you may not use this file except in compliance with the License.
|
|
9
|
-
# You may obtain a copy of the License at
|
|
10
|
-
#
|
|
11
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
-
#
|
|
13
|
-
# Unless required by applicable law or agreed to in writing, software
|
|
14
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
-
# See the License for the specific language governing permissions and
|
|
17
|
-
# limitations under the License.
|
|
18
|
-
|
|
19
|
-
module Kitchen
|
|
20
|
-
|
|
21
|
-
# Utility methods to help ouput colorized text in a terminal. The
|
|
22
|
-
# implementation is a compressed mashup of code from the Thor and Foreman
|
|
23
|
-
# projects.
|
|
24
|
-
#
|
|
25
|
-
# @author Fletcher Nichol <fnichol@nichol.ca>
|
|
26
|
-
module Color
|
|
27
|
-
|
|
28
|
-
ANSI = {
|
|
29
|
-
:reset => 0, :black => 30, :red => 31, :green => 32, :yellow => 33,
|
|
30
|
-
:blue => 34, :magenta => 35, :cyan => 36, :white => 37,
|
|
31
|
-
:bright_black => 90, :bright_red => 91, :bright_green => 92,
|
|
32
|
-
:bright_yellow => 93, :bright_blue => 94, :bright_magenta => 95,
|
|
33
|
-
:bright_cyan => 96, :bright_white => 97
|
|
34
|
-
}.freeze
|
|
35
|
-
|
|
36
|
-
COLORS = %w[
|
|
37
|
-
cyan yellow green magenta blue bright_cyan bright_yellow
|
|
38
|
-
bright_green bright_magenta bright_blue
|
|
39
|
-
].freeze
|
|
40
|
-
|
|
41
|
-
# Returns an ansi escaped string representing a color control sequence.
|
|
42
|
-
#
|
|
43
|
-
# @param name [Symbol] a valid color representation, taken from
|
|
44
|
-
# Kitchen::Color::ANSI
|
|
45
|
-
# @return [String] an ansi escaped string if the color is valid and an
|
|
46
|
-
# empty string otherwise
|
|
47
|
-
def self.escape(name)
|
|
48
|
-
return "" if name.nil?
|
|
49
|
-
return "" unless ANSI[name]
|
|
50
|
-
"\e[#{ANSI[name]}m"
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
# Returns a colorized ansi escaped string with the given color.
|
|
54
|
-
#
|
|
55
|
-
# @param str [String] a string to colorize
|
|
56
|
-
# @param name [Symbol] a valid color representation, taken from
|
|
57
|
-
# Kitchen::Color::ANSI
|
|
58
|
-
# @return [String] an ansi escaped string if the color is valid and an
|
|
59
|
-
# unescaped string otherwise
|
|
60
|
-
def self.colorize(str, name)
|
|
61
|
-
color = escape(name)
|
|
62
|
-
color.empty? ? str : "#{color}#{str}#{escape(:reset)}"
|
|
63
|
-
end
|
|
64
|
-
end
|
|
65
|
-
end
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Author:: Fletcher Nichol (<fnichol@nichol.ca>)
|
|
4
|
+
#
|
|
5
|
+
# Copyright (C) 2013, Fletcher Nichol
|
|
6
|
+
#
|
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
|
+
# you may not use this file except in compliance with the License.
|
|
9
|
+
# You may obtain a copy of the License at
|
|
10
|
+
#
|
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
#
|
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
# See the License for the specific language governing permissions and
|
|
17
|
+
# limitations under the License.
|
|
18
|
+
|
|
19
|
+
module Kitchen
|
|
20
|
+
|
|
21
|
+
# Utility methods to help ouput colorized text in a terminal. The
|
|
22
|
+
# implementation is a compressed mashup of code from the Thor and Foreman
|
|
23
|
+
# projects.
|
|
24
|
+
#
|
|
25
|
+
# @author Fletcher Nichol <fnichol@nichol.ca>
|
|
26
|
+
module Color
|
|
27
|
+
|
|
28
|
+
ANSI = {
|
|
29
|
+
:reset => 0, :black => 30, :red => 31, :green => 32, :yellow => 33,
|
|
30
|
+
:blue => 34, :magenta => 35, :cyan => 36, :white => 37,
|
|
31
|
+
:bright_black => 90, :bright_red => 91, :bright_green => 92,
|
|
32
|
+
:bright_yellow => 93, :bright_blue => 94, :bright_magenta => 95,
|
|
33
|
+
:bright_cyan => 96, :bright_white => 97
|
|
34
|
+
}.freeze
|
|
35
|
+
|
|
36
|
+
COLORS = %w[
|
|
37
|
+
cyan yellow green magenta blue bright_cyan bright_yellow
|
|
38
|
+
bright_green bright_magenta bright_blue
|
|
39
|
+
].freeze
|
|
40
|
+
|
|
41
|
+
# Returns an ansi escaped string representing a color control sequence.
|
|
42
|
+
#
|
|
43
|
+
# @param name [Symbol] a valid color representation, taken from
|
|
44
|
+
# Kitchen::Color::ANSI
|
|
45
|
+
# @return [String] an ansi escaped string if the color is valid and an
|
|
46
|
+
# empty string otherwise
|
|
47
|
+
def self.escape(name)
|
|
48
|
+
return "" if name.nil?
|
|
49
|
+
return "" unless ANSI[name]
|
|
50
|
+
"\e[#{ANSI[name]}m"
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Returns a colorized ansi escaped string with the given color.
|
|
54
|
+
#
|
|
55
|
+
# @param str [String] a string to colorize
|
|
56
|
+
# @param name [Symbol] a valid color representation, taken from
|
|
57
|
+
# Kitchen::Color::ANSI
|
|
58
|
+
# @return [String] an ansi escaped string if the color is valid and an
|
|
59
|
+
# unescaped string otherwise
|
|
60
|
+
def self.colorize(str, name)
|
|
61
|
+
color = escape(name)
|
|
62
|
+
color.empty? ? str : "#{color}#{str}#{escape(:reset)}"
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
data/lib/kitchen/command.rb
CHANGED
|
@@ -1,185 +1,185 @@
|
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
|
2
|
-
#
|
|
3
|
-
# Author:: Fletcher Nichol (<fnichol@nichol.ca>)
|
|
4
|
-
#
|
|
5
|
-
# Copyright (C) 2013, Fletcher Nichol
|
|
6
|
-
#
|
|
7
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
|
-
# you may not use this file except in compliance with the License.
|
|
9
|
-
# You may obtain a copy of the License at
|
|
10
|
-
#
|
|
11
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
-
#
|
|
13
|
-
# Unless required by applicable law or agreed to in writing, software
|
|
14
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
-
# See the License for the specific language governing permissions and
|
|
17
|
-
# limitations under the License.
|
|
18
|
-
|
|
19
|
-
require "thread"
|
|
20
|
-
|
|
21
|
-
module Kitchen
|
|
22
|
-
|
|
23
|
-
module Command
|
|
24
|
-
|
|
25
|
-
# Base class for CLI commands.
|
|
26
|
-
#
|
|
27
|
-
# @author Fletcher Nichol <fnichol@nichol.ca>
|
|
28
|
-
class Base
|
|
29
|
-
|
|
30
|
-
include Logging
|
|
31
|
-
|
|
32
|
-
# Contstructs a new Command object.
|
|
33
|
-
#
|
|
34
|
-
# @param cmd_args [Array] remainder of the arguments from processed ARGV
|
|
35
|
-
# @param cmd_options [Hash] hash of Thor options
|
|
36
|
-
# @param options [Hash] configuration options
|
|
37
|
-
# @option options [String] :action action to take, usually corresponding
|
|
38
|
-
# to the subcommand name (default: `nil`)
|
|
39
|
-
# @option options [proc] :help a callable that displays help for the
|
|
40
|
-
# command
|
|
41
|
-
# @option options [Config] :config a Config object (default: `nil`)
|
|
42
|
-
# @option options [Loader] :loader a Loader object (default: `nil`)
|
|
43
|
-
# @option options [String] :shell a Thor shell object
|
|
44
|
-
def initialize(cmd_args, cmd_options, options = {})
|
|
45
|
-
@args = cmd_args
|
|
46
|
-
@options = cmd_options
|
|
47
|
-
@action = options.fetch(:action, nil)
|
|
48
|
-
@help = options.fetch(:help, -> { "No help provided" })
|
|
49
|
-
@config = options.fetch(:config, nil)
|
|
50
|
-
@loader = options.fetch(:loader, nil)
|
|
51
|
-
@shell = options.fetch(:shell)
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
private
|
|
55
|
-
|
|
56
|
-
# @return [Array] remainder of the arguments from processed ARGV
|
|
57
|
-
# @api private
|
|
58
|
-
attr_reader :args
|
|
59
|
-
|
|
60
|
-
# @return [Hash] hash of Thor options
|
|
61
|
-
# @api private
|
|
62
|
-
attr_reader :options
|
|
63
|
-
|
|
64
|
-
# @return [proc] a callable that displays help for the command
|
|
65
|
-
# @api private
|
|
66
|
-
attr_reader :help
|
|
67
|
-
|
|
68
|
-
# @return [Config] a Config object
|
|
69
|
-
# @api private
|
|
70
|
-
attr_reader :config
|
|
71
|
-
|
|
72
|
-
# @return [Thor::Shell] a Thor shell object
|
|
73
|
-
# @api private
|
|
74
|
-
attr_reader :shell
|
|
75
|
-
|
|
76
|
-
# @return [String] the action to perform
|
|
77
|
-
# @api private
|
|
78
|
-
attr_reader :action
|
|
79
|
-
|
|
80
|
-
# Emit an error message, display contextual help and then exit with a
|
|
81
|
-
# non-zero exit code.
|
|
82
|
-
#
|
|
83
|
-
# **Note** This method calls exit and will not return.
|
|
84
|
-
#
|
|
85
|
-
# @param msg [String] error message
|
|
86
|
-
# @api private
|
|
87
|
-
def die(msg)
|
|
88
|
-
error "\n#{msg}\n\n"
|
|
89
|
-
help.call
|
|
90
|
-
exit 1
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
# @return [Array<Instance>] an array of instances
|
|
94
|
-
# @raise [SystemExit] if no instances are returned
|
|
95
|
-
# @api private
|
|
96
|
-
def all_instances
|
|
97
|
-
result = @config.instances
|
|
98
|
-
|
|
99
|
-
if result.empty?
|
|
100
|
-
die "No instances defined"
|
|
101
|
-
else
|
|
102
|
-
result
|
|
103
|
-
end
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
# Return an array on instances whos name matches the regular expression.
|
|
107
|
-
#
|
|
108
|
-
# @param regexp [Regexp] a regular expression matching on instance names
|
|
109
|
-
# @return [Array<Instance>] an array of instances
|
|
110
|
-
# @raise [SystemExit] if no instances are returned or the regular
|
|
111
|
-
# expression is invalid
|
|
112
|
-
# @api private
|
|
113
|
-
def filtered_instances(regexp)
|
|
114
|
-
result = begin
|
|
115
|
-
@config.instances.get(regexp) ||
|
|
116
|
-
@config.instances.get_all(/#{regexp}/)
|
|
117
|
-
rescue RegexpError => e
|
|
118
|
-
die "Invalid Ruby regular expression, " \
|
|
119
|
-
"you may need to single quote the argument. " \
|
|
120
|
-
"Please try again or consult http://rubular.com/ (#{e.message})"
|
|
121
|
-
end
|
|
122
|
-
result = Array(result)
|
|
123
|
-
|
|
124
|
-
if result.empty?
|
|
125
|
-
die "No instances for regex `#{regexp}', try running `kitchen list'"
|
|
126
|
-
else
|
|
127
|
-
result
|
|
128
|
-
end
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
# @return [Logger] the common logger
|
|
132
|
-
# @api private
|
|
133
|
-
def logger
|
|
134
|
-
Kitchen.logger
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
# Return an array on instances whos name matches the regular expression,
|
|
138
|
-
# the full instance name, or the `"all"` literal.
|
|
139
|
-
#
|
|
140
|
-
# @param arg [String] an instance name, a regular expression, the literal
|
|
141
|
-
# `"all"`, or `nil`
|
|
142
|
-
# @return [Array<Instance>] an array of instances
|
|
143
|
-
# @api private
|
|
144
|
-
def parse_subcommand(arg = nil)
|
|
145
|
-
arg == "all" ? all_instances : filtered_instances(arg)
|
|
146
|
-
end
|
|
147
|
-
end
|
|
148
|
-
|
|
149
|
-
# Common module to execute a Kitchen action such as create, converge, etc.
|
|
150
|
-
#
|
|
151
|
-
# @author Fletcher Nichol <fnichol@nichol.ca>
|
|
152
|
-
module RunAction
|
|
153
|
-
|
|
154
|
-
# Run an instance action (create, converge, setup, verify, destroy) on
|
|
155
|
-
# a collection of instances. The instance actions will take place in a
|
|
156
|
-
# seperate thread of execution which may or may not be running
|
|
157
|
-
# concurrently.
|
|
158
|
-
#
|
|
159
|
-
# @param action [String] action to perform
|
|
160
|
-
# @param instances [Array<Instance>] an array of instances
|
|
161
|
-
def run_action(action, instances, *args)
|
|
162
|
-
concurrency = 1
|
|
163
|
-
if options[:concurrency]
|
|
164
|
-
concurrency = options[:concurrency] || instances.size
|
|
165
|
-
concurrency = instances.size if concurrency > instances.size
|
|
166
|
-
end
|
|
167
|
-
|
|
168
|
-
queue = Queue.new
|
|
169
|
-
instances.each { |i| queue << i }
|
|
170
|
-
concurrency.times { queue << nil }
|
|
171
|
-
|
|
172
|
-
threads = []
|
|
173
|
-
concurrency.times do
|
|
174
|
-
threads << Thread.new do
|
|
175
|
-
while instance = queue.pop
|
|
176
|
-
instance.public_send(action, *args)
|
|
177
|
-
instance.cleanup!
|
|
178
|
-
end
|
|
179
|
-
end
|
|
180
|
-
end
|
|
181
|
-
threads.map(&:join)
|
|
182
|
-
end
|
|
183
|
-
end
|
|
184
|
-
end
|
|
185
|
-
end
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Author:: Fletcher Nichol (<fnichol@nichol.ca>)
|
|
4
|
+
#
|
|
5
|
+
# Copyright (C) 2013, Fletcher Nichol
|
|
6
|
+
#
|
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
|
+
# you may not use this file except in compliance with the License.
|
|
9
|
+
# You may obtain a copy of the License at
|
|
10
|
+
#
|
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
#
|
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
# See the License for the specific language governing permissions and
|
|
17
|
+
# limitations under the License.
|
|
18
|
+
|
|
19
|
+
require "thread"
|
|
20
|
+
|
|
21
|
+
module Kitchen
|
|
22
|
+
|
|
23
|
+
module Command
|
|
24
|
+
|
|
25
|
+
# Base class for CLI commands.
|
|
26
|
+
#
|
|
27
|
+
# @author Fletcher Nichol <fnichol@nichol.ca>
|
|
28
|
+
class Base
|
|
29
|
+
|
|
30
|
+
include Logging
|
|
31
|
+
|
|
32
|
+
# Contstructs a new Command object.
|
|
33
|
+
#
|
|
34
|
+
# @param cmd_args [Array] remainder of the arguments from processed ARGV
|
|
35
|
+
# @param cmd_options [Hash] hash of Thor options
|
|
36
|
+
# @param options [Hash] configuration options
|
|
37
|
+
# @option options [String] :action action to take, usually corresponding
|
|
38
|
+
# to the subcommand name (default: `nil`)
|
|
39
|
+
# @option options [proc] :help a callable that displays help for the
|
|
40
|
+
# command
|
|
41
|
+
# @option options [Config] :config a Config object (default: `nil`)
|
|
42
|
+
# @option options [Loader] :loader a Loader object (default: `nil`)
|
|
43
|
+
# @option options [String] :shell a Thor shell object
|
|
44
|
+
def initialize(cmd_args, cmd_options, options = {})
|
|
45
|
+
@args = cmd_args
|
|
46
|
+
@options = cmd_options
|
|
47
|
+
@action = options.fetch(:action, nil)
|
|
48
|
+
@help = options.fetch(:help, -> { "No help provided" })
|
|
49
|
+
@config = options.fetch(:config, nil)
|
|
50
|
+
@loader = options.fetch(:loader, nil)
|
|
51
|
+
@shell = options.fetch(:shell)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
private
|
|
55
|
+
|
|
56
|
+
# @return [Array] remainder of the arguments from processed ARGV
|
|
57
|
+
# @api private
|
|
58
|
+
attr_reader :args
|
|
59
|
+
|
|
60
|
+
# @return [Hash] hash of Thor options
|
|
61
|
+
# @api private
|
|
62
|
+
attr_reader :options
|
|
63
|
+
|
|
64
|
+
# @return [proc] a callable that displays help for the command
|
|
65
|
+
# @api private
|
|
66
|
+
attr_reader :help
|
|
67
|
+
|
|
68
|
+
# @return [Config] a Config object
|
|
69
|
+
# @api private
|
|
70
|
+
attr_reader :config
|
|
71
|
+
|
|
72
|
+
# @return [Thor::Shell] a Thor shell object
|
|
73
|
+
# @api private
|
|
74
|
+
attr_reader :shell
|
|
75
|
+
|
|
76
|
+
# @return [String] the action to perform
|
|
77
|
+
# @api private
|
|
78
|
+
attr_reader :action
|
|
79
|
+
|
|
80
|
+
# Emit an error message, display contextual help and then exit with a
|
|
81
|
+
# non-zero exit code.
|
|
82
|
+
#
|
|
83
|
+
# **Note** This method calls exit and will not return.
|
|
84
|
+
#
|
|
85
|
+
# @param msg [String] error message
|
|
86
|
+
# @api private
|
|
87
|
+
def die(msg)
|
|
88
|
+
error "\n#{msg}\n\n"
|
|
89
|
+
help.call
|
|
90
|
+
exit 1
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# @return [Array<Instance>] an array of instances
|
|
94
|
+
# @raise [SystemExit] if no instances are returned
|
|
95
|
+
# @api private
|
|
96
|
+
def all_instances
|
|
97
|
+
result = @config.instances
|
|
98
|
+
|
|
99
|
+
if result.empty?
|
|
100
|
+
die "No instances defined"
|
|
101
|
+
else
|
|
102
|
+
result
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# Return an array on instances whos name matches the regular expression.
|
|
107
|
+
#
|
|
108
|
+
# @param regexp [Regexp] a regular expression matching on instance names
|
|
109
|
+
# @return [Array<Instance>] an array of instances
|
|
110
|
+
# @raise [SystemExit] if no instances are returned or the regular
|
|
111
|
+
# expression is invalid
|
|
112
|
+
# @api private
|
|
113
|
+
def filtered_instances(regexp)
|
|
114
|
+
result = begin
|
|
115
|
+
@config.instances.get(regexp) ||
|
|
116
|
+
@config.instances.get_all(/#{regexp}/)
|
|
117
|
+
rescue RegexpError => e
|
|
118
|
+
die "Invalid Ruby regular expression, " \
|
|
119
|
+
"you may need to single quote the argument. " \
|
|
120
|
+
"Please try again or consult http://rubular.com/ (#{e.message})"
|
|
121
|
+
end
|
|
122
|
+
result = Array(result)
|
|
123
|
+
|
|
124
|
+
if result.empty?
|
|
125
|
+
die "No instances for regex `#{regexp}', try running `kitchen list'"
|
|
126
|
+
else
|
|
127
|
+
result
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# @return [Logger] the common logger
|
|
132
|
+
# @api private
|
|
133
|
+
def logger
|
|
134
|
+
Kitchen.logger
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
# Return an array on instances whos name matches the regular expression,
|
|
138
|
+
# the full instance name, or the `"all"` literal.
|
|
139
|
+
#
|
|
140
|
+
# @param arg [String] an instance name, a regular expression, the literal
|
|
141
|
+
# `"all"`, or `nil`
|
|
142
|
+
# @return [Array<Instance>] an array of instances
|
|
143
|
+
# @api private
|
|
144
|
+
def parse_subcommand(arg = nil)
|
|
145
|
+
arg == "all" ? all_instances : filtered_instances(arg)
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# Common module to execute a Kitchen action such as create, converge, etc.
|
|
150
|
+
#
|
|
151
|
+
# @author Fletcher Nichol <fnichol@nichol.ca>
|
|
152
|
+
module RunAction
|
|
153
|
+
|
|
154
|
+
# Run an instance action (create, converge, setup, verify, destroy) on
|
|
155
|
+
# a collection of instances. The instance actions will take place in a
|
|
156
|
+
# seperate thread of execution which may or may not be running
|
|
157
|
+
# concurrently.
|
|
158
|
+
#
|
|
159
|
+
# @param action [String] action to perform
|
|
160
|
+
# @param instances [Array<Instance>] an array of instances
|
|
161
|
+
def run_action(action, instances, *args)
|
|
162
|
+
concurrency = 1
|
|
163
|
+
if options[:concurrency]
|
|
164
|
+
concurrency = options[:concurrency] || instances.size
|
|
165
|
+
concurrency = instances.size if concurrency > instances.size
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
queue = Queue.new
|
|
169
|
+
instances.each { |i| queue << i }
|
|
170
|
+
concurrency.times { queue << nil }
|
|
171
|
+
|
|
172
|
+
threads = []
|
|
173
|
+
concurrency.times do
|
|
174
|
+
threads << Thread.new do
|
|
175
|
+
while instance = queue.pop
|
|
176
|
+
instance.public_send(action, *args)
|
|
177
|
+
instance.cleanup!
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
threads.map(&:join)
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
end
|