test-kitchen 1.2.1 → 1.3.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 +1 -1
- data/.rubocop.yml +3 -0
- data/.travis.yml +20 -9
- data/CHANGELOG.md +219 -108
- data/Gemfile +10 -6
- data/Guardfile +38 -9
- data/README.md +11 -1
- data/Rakefile +21 -37
- data/bin/kitchen +4 -4
- data/features/kitchen_action_commands.feature +161 -0
- data/features/kitchen_console_command.feature +34 -0
- data/features/kitchen_diagnose_command.feature +64 -0
- data/features/kitchen_init_command.feature +29 -17
- data/features/kitchen_list_command.feature +2 -2
- data/features/kitchen_login_command.feature +56 -0
- data/features/{sink_command.feature → kitchen_sink_command.feature} +0 -0
- data/features/kitchen_test_command.feature +88 -0
- data/features/step_definitions/gem_steps.rb +8 -6
- data/features/step_definitions/git_steps.rb +4 -2
- data/features/step_definitions/output_steps.rb +5 -0
- data/features/support/env.rb +12 -9
- data/lib/kitchen.rb +60 -38
- data/lib/kitchen/base64_stream.rb +55 -0
- data/lib/kitchen/busser.rb +124 -58
- data/lib/kitchen/cli.rb +121 -38
- data/lib/kitchen/collection.rb +3 -3
- data/lib/kitchen/color.rb +4 -4
- data/lib/kitchen/command.rb +78 -11
- data/lib/kitchen/command/action.rb +3 -2
- data/lib/kitchen/command/console.rb +12 -5
- data/lib/kitchen/command/diagnose.rb +17 -3
- data/lib/kitchen/command/driver_discover.rb +26 -7
- data/lib/kitchen/command/exec.rb +41 -0
- data/lib/kitchen/command/list.rb +44 -14
- data/lib/kitchen/command/login.rb +2 -1
- data/lib/kitchen/command/sink.rb +2 -1
- data/lib/kitchen/command/test.rb +5 -4
- data/lib/kitchen/config.rb +146 -14
- data/lib/kitchen/configurable.rb +314 -0
- data/lib/kitchen/data_munger.rb +522 -18
- data/lib/kitchen/diagnostic.rb +43 -4
- data/lib/kitchen/driver.rb +4 -4
- data/lib/kitchen/driver/base.rb +80 -115
- data/lib/kitchen/driver/dummy.rb +34 -6
- data/lib/kitchen/driver/proxy.rb +14 -3
- data/lib/kitchen/driver/ssh_base.rb +61 -7
- data/lib/kitchen/errors.rb +109 -9
- data/lib/kitchen/generator/driver_create.rb +39 -5
- data/lib/kitchen/generator/init.rb +130 -45
- data/lib/kitchen/instance.rb +162 -28
- data/lib/kitchen/lazy_hash.rb +79 -7
- data/lib/kitchen/loader/yaml.rb +159 -27
- data/lib/kitchen/logger.rb +267 -21
- data/lib/kitchen/logging.rb +30 -3
- data/lib/kitchen/login_command.rb +11 -2
- data/lib/kitchen/metadata_chopper.rb +2 -2
- data/lib/kitchen/provisioner.rb +4 -4
- data/lib/kitchen/provisioner/base.rb +107 -103
- data/lib/kitchen/provisioner/chef/berkshelf.rb +36 -8
- data/lib/kitchen/provisioner/chef/librarian.rb +40 -11
- data/lib/kitchen/provisioner/chef_base.rb +206 -167
- data/lib/kitchen/provisioner/chef_solo.rb +25 -7
- data/lib/kitchen/provisioner/chef_zero.rb +105 -29
- data/lib/kitchen/provisioner/dummy.rb +1 -1
- data/lib/kitchen/provisioner/shell.rb +21 -6
- data/lib/kitchen/rake_tasks.rb +8 -3
- data/lib/kitchen/shell_out.rb +15 -18
- data/lib/kitchen/ssh.rb +122 -27
- data/lib/kitchen/state_file.rb +24 -7
- data/lib/kitchen/thor_tasks.rb +9 -4
- data/lib/kitchen/util.rb +43 -118
- data/lib/kitchen/version.rb +1 -1
- data/lib/vendor/hash_recursive_merge.rb +10 -2
- data/spec/kitchen/base64_stream_spec.rb +77 -0
- data/spec/kitchen/busser_spec.rb +490 -0
- data/spec/kitchen/collection_spec.rb +10 -10
- data/spec/kitchen/color_spec.rb +2 -2
- data/spec/kitchen/config_spec.rb +234 -62
- data/spec/kitchen/configurable_spec.rb +490 -0
- data/spec/kitchen/data_munger_spec.rb +1070 -862
- data/spec/kitchen/diagnostic_spec.rb +79 -0
- data/spec/kitchen/driver/base_spec.rb +80 -85
- data/spec/kitchen/driver/dummy_spec.rb +43 -14
- data/spec/kitchen/driver/proxy_spec.rb +134 -0
- data/spec/kitchen/driver/ssh_base_spec.rb +644 -0
- data/spec/kitchen/driver_spec.rb +15 -15
- data/spec/kitchen/errors_spec.rb +309 -0
- data/spec/kitchen/instance_spec.rb +143 -46
- data/spec/kitchen/lazy_hash_spec.rb +36 -9
- data/spec/kitchen/loader/yaml_spec.rb +237 -226
- data/spec/kitchen/logger_spec.rb +419 -0
- data/spec/kitchen/logging_spec.rb +59 -0
- data/spec/kitchen/login_command_spec.rb +49 -0
- data/spec/kitchen/metadata_chopper_spec.rb +82 -0
- data/spec/kitchen/platform_spec.rb +4 -4
- data/spec/kitchen/provisioner/base_spec.rb +65 -125
- data/spec/kitchen/provisioner/chef_base_spec.rb +798 -0
- data/spec/kitchen/provisioner/chef_solo_spec.rb +316 -0
- data/spec/kitchen/provisioner/chef_zero_spec.rb +624 -0
- data/spec/kitchen/provisioner/shell_spec.rb +269 -0
- data/spec/kitchen/provisioner_spec.rb +6 -6
- data/spec/kitchen/shell_out_spec.rb +143 -0
- data/spec/kitchen/ssh_spec.rb +683 -0
- data/spec/kitchen/state_file_spec.rb +28 -21
- data/spec/kitchen/suite_spec.rb +7 -7
- data/spec/kitchen/util_spec.rb +68 -10
- data/spec/kitchen_spec.rb +107 -0
- data/spec/spec_helper.rb +18 -13
- data/support/chef-client-zero.rb +10 -9
- data/support/chef_helpers.sh +16 -0
- data/support/download_helpers.sh +109 -0
- data/test-kitchen.gemspec +42 -33
- metadata +107 -33
data/lib/kitchen/collection.rb
CHANGED
@@ -16,7 +16,7 @@
|
|
16
16
|
# See the License for the specific language governing permissions and
|
17
17
|
# limitations under the License.
|
18
18
|
|
19
|
-
require
|
19
|
+
require "delegate"
|
20
20
|
|
21
21
|
module Kitchen
|
22
22
|
|
@@ -42,14 +42,14 @@ module Kitchen
|
|
42
42
|
# @return [Kitchen::Config::Collection<Object>] a new collection of
|
43
43
|
# matched objects
|
44
44
|
def get_all(regexp)
|
45
|
-
Kitchen::Collection.new(__getobj__.
|
45
|
+
Kitchen::Collection.new(__getobj__.select { |i| i.name =~ regexp })
|
46
46
|
end
|
47
47
|
|
48
48
|
# Returns an Array of names from the collection as strings.
|
49
49
|
#
|
50
50
|
# @return [Array<String>] array of name strings
|
51
51
|
def as_names
|
52
|
-
__getobj__.map
|
52
|
+
__getobj__.map(&:name)
|
53
53
|
end
|
54
54
|
end
|
55
55
|
end
|
data/lib/kitchen/color.rb
CHANGED
@@ -33,10 +33,10 @@ module Kitchen
|
|
33
33
|
:bright_cyan => 96, :bright_white => 97
|
34
34
|
}.freeze
|
35
35
|
|
36
|
-
COLORS = %w
|
36
|
+
COLORS = %w[
|
37
37
|
cyan yellow green magenta blue bright_cyan bright_yellow
|
38
38
|
bright_green bright_magenta bright_blue
|
39
|
-
|
39
|
+
].freeze
|
40
40
|
|
41
41
|
# Returns an ansi escaped string representing a color control sequence.
|
42
42
|
#
|
@@ -46,8 +46,8 @@ module Kitchen
|
|
46
46
|
# empty string otherwise
|
47
47
|
def self.escape(name)
|
48
48
|
return "" if name.nil?
|
49
|
-
return "" unless
|
50
|
-
"\e[#{
|
49
|
+
return "" unless ANSI[name]
|
50
|
+
"\e[#{ANSI[name]}m"
|
51
51
|
end
|
52
52
|
|
53
53
|
# Returns a colorized ansi escaped string with the given color.
|
data/lib/kitchen/command.rb
CHANGED
@@ -16,7 +16,7 @@
|
|
16
16
|
# See the License for the specific language governing permissions and
|
17
17
|
# limitations under the License.
|
18
18
|
|
19
|
-
require
|
19
|
+
require "thread"
|
20
20
|
|
21
21
|
module Kitchen
|
22
22
|
|
@@ -29,27 +29,71 @@ module Kitchen
|
|
29
29
|
|
30
30
|
include Logging
|
31
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
|
32
44
|
def initialize(cmd_args, cmd_options, options = {})
|
33
45
|
@args = cmd_args
|
34
46
|
@options = cmd_options
|
35
47
|
@action = options.fetch(:action, nil)
|
36
|
-
@help = options.fetch(:help,
|
48
|
+
@help = options.fetch(:help, -> { "No help provided" })
|
37
49
|
@config = options.fetch(:config, nil)
|
38
50
|
@loader = options.fetch(:loader, nil)
|
39
51
|
@shell = options.fetch(:shell)
|
40
52
|
end
|
41
53
|
|
42
|
-
|
54
|
+
private
|
43
55
|
|
44
|
-
|
56
|
+
# @return [Array] remainder of the arguments from processed ARGV
|
57
|
+
# @api private
|
58
|
+
attr_reader :args
|
45
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
|
46
87
|
def die(msg)
|
47
88
|
error "\n#{msg}\n\n"
|
48
89
|
help.call
|
49
90
|
exit 1
|
50
91
|
end
|
51
92
|
|
52
|
-
|
93
|
+
# @return [Array<Instance>] an array of instances
|
94
|
+
# @raise [SystemExit] if no instances are returned
|
95
|
+
# @api private
|
96
|
+
def all_instances
|
53
97
|
result = @config.instances
|
54
98
|
|
55
99
|
if result.empty?
|
@@ -59,13 +103,20 @@ module Kitchen
|
|
59
103
|
end
|
60
104
|
end
|
61
105
|
|
62
|
-
|
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)
|
63
114
|
result = begin
|
64
115
|
@config.instances.get(regexp) ||
|
65
116
|
@config.instances.get_all(/#{regexp}/)
|
66
117
|
rescue RegexpError => e
|
67
|
-
die "Invalid Ruby regular expression, "
|
68
|
-
"you may need to single quote the argument. "
|
118
|
+
die "Invalid Ruby regular expression, " \
|
119
|
+
"you may need to single quote the argument. " \
|
69
120
|
"Please try again or consult http://rubular.com/ (#{e.message})"
|
70
121
|
end
|
71
122
|
result = Array(result)
|
@@ -77,12 +128,21 @@ module Kitchen
|
|
77
128
|
end
|
78
129
|
end
|
79
130
|
|
131
|
+
# @return [Logger] the common logger
|
132
|
+
# @api private
|
80
133
|
def logger
|
81
134
|
Kitchen.logger
|
82
135
|
end
|
83
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
|
84
144
|
def parse_subcommand(arg = nil)
|
85
|
-
arg == "all" ?
|
145
|
+
arg == "all" ? all_instances : filtered_instances(arg)
|
86
146
|
end
|
87
147
|
end
|
88
148
|
|
@@ -91,6 +151,13 @@ module Kitchen
|
|
91
151
|
# @author Fletcher Nichol <fnichol@nichol.ca>
|
92
152
|
module RunAction
|
93
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
|
94
161
|
def run_action(action, instances, *args)
|
95
162
|
concurrency = 1
|
96
163
|
if options[:concurrency]
|
@@ -99,7 +166,7 @@ module Kitchen
|
|
99
166
|
end
|
100
167
|
|
101
168
|
queue = Queue.new
|
102
|
-
instances.each {|i| queue << i }
|
169
|
+
instances.each { |i| queue << i }
|
103
170
|
concurrency.times { queue << nil }
|
104
171
|
|
105
172
|
threads = []
|
@@ -110,7 +177,7 @@ module Kitchen
|
|
110
177
|
end
|
111
178
|
end
|
112
179
|
end
|
113
|
-
threads.map
|
180
|
+
threads.map(&:join)
|
114
181
|
end
|
115
182
|
end
|
116
183
|
end
|
@@ -16,9 +16,9 @@
|
|
16
16
|
# See the License for the specific language governing permissions and
|
17
17
|
# limitations under the License.
|
18
18
|
|
19
|
-
require
|
19
|
+
require "kitchen/command"
|
20
20
|
|
21
|
-
require
|
21
|
+
require "benchmark"
|
22
22
|
|
23
23
|
module Kitchen
|
24
24
|
|
@@ -31,6 +31,7 @@ module Kitchen
|
|
31
31
|
|
32
32
|
include RunAction
|
33
33
|
|
34
|
+
# Invoke the command.
|
34
35
|
def call
|
35
36
|
banner "Starting Kitchen (v#{Kitchen::VERSION})"
|
36
37
|
elapsed = Benchmark.measure do
|
@@ -16,7 +16,7 @@
|
|
16
16
|
# See the License for the specific language governing permissions and
|
17
17
|
# limitations under the License.
|
18
18
|
|
19
|
-
require
|
19
|
+
require "kitchen/command"
|
20
20
|
|
21
21
|
module Kitchen
|
22
22
|
|
@@ -27,20 +27,27 @@ module Kitchen
|
|
27
27
|
# @author Fletcher Nichol <fnichol@nichol.ca>
|
28
28
|
class Console < Kitchen::Command::Base
|
29
29
|
|
30
|
+
# Invoke the command.
|
30
31
|
def call
|
31
|
-
require
|
32
|
+
require "pry"
|
32
33
|
Pry.start(@config, :prompt => [prompt(">"), prompt("*")])
|
33
|
-
rescue LoadError
|
34
|
+
rescue LoadError
|
34
35
|
warn %{Make sure you have the pry gem installed. You can install it with:}
|
35
36
|
warn %{`gem install pry` or including 'gem "pry"' in your Gemfile.}
|
36
37
|
exit 1
|
37
38
|
end
|
38
39
|
|
39
|
-
|
40
|
+
private
|
40
41
|
|
42
|
+
# Construct a custom Pry prompt proc.
|
43
|
+
#
|
44
|
+
# @param char [String] prompt character
|
45
|
+
# @return [proc] a prompt proc
|
46
|
+
# @api private
|
41
47
|
def prompt(char)
|
42
48
|
proc { |target_self, nest_level, pry|
|
43
|
-
[
|
49
|
+
[
|
50
|
+
"[#{pry.input_array.size}] ",
|
44
51
|
"kc(#{Pry.view_clip(target_self.class)})",
|
45
52
|
"#{":#{nest_level}" unless nest_level.zero?}#{char} "
|
46
53
|
].join
|
@@ -16,10 +16,10 @@
|
|
16
16
|
# See the License for the specific language governing permissions and
|
17
17
|
# limitations under the License.
|
18
18
|
|
19
|
-
require
|
20
|
-
require
|
19
|
+
require "kitchen/command"
|
20
|
+
require "kitchen/diagnostic"
|
21
21
|
|
22
|
-
require
|
22
|
+
require "yaml"
|
23
23
|
|
24
24
|
module Kitchen
|
25
25
|
|
@@ -30,6 +30,7 @@ module Kitchen
|
|
30
30
|
# @author Fletcher Nichol <fnichol@nichol.ca>
|
31
31
|
class Diagnose < Kitchen::Command::Base
|
32
32
|
|
33
|
+
# Invoke the command.
|
33
34
|
def call
|
34
35
|
instances = record_failure { load_instances }
|
35
36
|
|
@@ -41,6 +42,10 @@ module Kitchen
|
|
41
42
|
|
42
43
|
private
|
43
44
|
|
45
|
+
# Loads and returns instances if they are requested.
|
46
|
+
#
|
47
|
+
# @return [Array<Instance>] an array of instances or an empty array
|
48
|
+
# @api private
|
44
49
|
def load_instances
|
45
50
|
if options[:all] || options[:instances]
|
46
51
|
parse_subcommand(args.first)
|
@@ -49,6 +54,10 @@ module Kitchen
|
|
49
54
|
end
|
50
55
|
end
|
51
56
|
|
57
|
+
# Loads and returns loader configuration if it is requested.
|
58
|
+
#
|
59
|
+
# @return [Hash,nil] a hash or nil
|
60
|
+
# @api private
|
52
61
|
def load_loader
|
53
62
|
if options[:all] || options[:loader]
|
54
63
|
@loader
|
@@ -57,6 +66,11 @@ module Kitchen
|
|
57
66
|
end
|
58
67
|
end
|
59
68
|
|
69
|
+
# Returns a hash with exception detail if an exception is raised in the
|
70
|
+
# yielded block.
|
71
|
+
#
|
72
|
+
# @return [yield,Hash] the result of the yielded block or an error hash
|
73
|
+
# @api private
|
60
74
|
def record_failure
|
61
75
|
yield
|
62
76
|
rescue => e
|
@@ -16,10 +16,9 @@
|
|
16
16
|
# See the License for the specific language governing permissions and
|
17
17
|
# limitations under the License.
|
18
18
|
|
19
|
-
require
|
19
|
+
require "kitchen/command"
|
20
20
|
|
21
|
-
require
|
22
|
-
require 'safe_yaml'
|
21
|
+
require "rubygems/spec_fetcher"
|
23
22
|
|
24
23
|
module Kitchen
|
25
24
|
|
@@ -30,6 +29,7 @@ module Kitchen
|
|
30
29
|
# @author Fletcher Nichol <fnichol@nichol.ca>
|
31
30
|
class DriverDiscover < Kitchen::Command::Base
|
32
31
|
|
32
|
+
# Invoke the command.
|
33
33
|
def call
|
34
34
|
specs = fetch_gem_specs.sort { |x, y| x[0] <=> y[0] }
|
35
35
|
specs = specs[0, 49].push(["...", "..."]) if specs.size > 49
|
@@ -37,33 +37,52 @@ module Kitchen
|
|
37
37
|
print_table(specs, :indent => 4)
|
38
38
|
end
|
39
39
|
|
40
|
-
|
40
|
+
private
|
41
41
|
|
42
|
+
# Fetches Kitchen-related RubyGems and returns an array of name/version
|
43
|
+
# tuples.
|
44
|
+
#
|
45
|
+
# @return [Array<Array>] an array of name/version tuples
|
46
|
+
# @api private
|
42
47
|
def fetch_gem_specs
|
43
|
-
SafeYAML::OPTIONS[:suppress_warnings] = true
|
44
48
|
req = Gem::Requirement.default
|
45
49
|
dep = Gem::Deprecate.skip_during do
|
46
50
|
Gem::Dependency.new(/kitchen-/i, req)
|
47
51
|
end
|
48
52
|
fetcher = Gem::SpecFetcher.fetcher
|
49
53
|
|
50
|
-
|
54
|
+
if fetcher.respond_to?(:find_matching)
|
51
55
|
fetch_gem_specs_pre_rubygems_2(fetcher, dep)
|
52
56
|
else
|
53
57
|
fetch_gem_specs_post_rubygems_2(fetcher, dep)
|
54
58
|
end
|
55
59
|
end
|
56
60
|
|
61
|
+
# Fetches gem specs for RubyGems 2 and later.
|
62
|
+
#
|
63
|
+
# @param fetcher [Gem::SpecFetcher] a gemspec fetcher
|
64
|
+
# @param dep [Gem::Dependency] a gem dependency object
|
65
|
+
# @return [Array<Array>] an array of name/version tuples
|
66
|
+
# @api private
|
57
67
|
def fetch_gem_specs_post_rubygems_2(fetcher, dep)
|
58
68
|
specs = fetcher.spec_for_dependency(dep, false)
|
59
69
|
specs.first.map { |t| [t.first.name, t.first.version] }
|
60
70
|
end
|
61
71
|
|
72
|
+
# Fetches gem specs for pre-RubyGems 2.
|
73
|
+
#
|
74
|
+
# @param fetcher [Gem::SpecFetcher] a gemspec fetcher
|
75
|
+
# @param dep [Gem::Dependency] a gem dependency object
|
76
|
+
# @return [Array<Array>] an array of name/version tuples
|
77
|
+
# @api private
|
62
78
|
def fetch_gem_specs_pre_rubygems_2(fetcher, dep)
|
63
79
|
specs = fetcher.find_matching(dep, false, false, false)
|
64
|
-
specs.map
|
80
|
+
specs.map(&:first).map { |t| t[0, 2] }
|
65
81
|
end
|
66
82
|
|
83
|
+
# Print out a display table.
|
84
|
+
#
|
85
|
+
# @api private
|
67
86
|
def print_table(*args)
|
68
87
|
shell.print_table(*args)
|
69
88
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
#
|
3
|
+
# Author:: SAWANOBORI Yukihiko (<sawanoboriyu@higanworks.com>)
|
4
|
+
#
|
5
|
+
# Copyright (C) 2014, HiganWorks LLC
|
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 "kitchen/command"
|
20
|
+
|
21
|
+
module Kitchen
|
22
|
+
|
23
|
+
module Command
|
24
|
+
|
25
|
+
# Execute command on remote instance.
|
26
|
+
#
|
27
|
+
# @author SAWANOBORI Yukihiko (<sawanoboriyu@higanworks.com>)
|
28
|
+
class Exec < Kitchen::Command::Base
|
29
|
+
|
30
|
+
# Invoke the command.
|
31
|
+
def call
|
32
|
+
results = parse_subcommand(args.first)
|
33
|
+
|
34
|
+
results.each do |instance|
|
35
|
+
banner "Execute command on #{instance.name}."
|
36
|
+
instance.remote_exec(options[:command])
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/kitchen/command/list.rb
CHANGED
@@ -16,7 +16,7 @@
|
|
16
16
|
# See the License for the specific language governing permissions and
|
17
17
|
# limitations under the License.
|
18
18
|
|
19
|
-
require
|
19
|
+
require "kitchen/command"
|
20
20
|
|
21
21
|
module Kitchen
|
22
22
|
|
@@ -27,24 +27,36 @@ module Kitchen
|
|
27
27
|
# @author Fletcher Nichol <fnichol@nichol.ca>
|
28
28
|
class List < Kitchen::Command::Base
|
29
29
|
|
30
|
+
# Invoke the command.
|
30
31
|
def call
|
31
32
|
result = parse_subcommand(args.first)
|
32
33
|
if options[:debug]
|
33
|
-
die "The --debug flag on the list subcommand is deprecated, "
|
34
|
+
die "The --debug flag on the list subcommand is deprecated, " \
|
34
35
|
"please use `kitchen diagnose'."
|
35
36
|
elsif options[:bare]
|
36
|
-
puts Array(result).map
|
37
|
+
puts Array(result).map(&:name).join("\n")
|
37
38
|
else
|
38
39
|
list_table(result)
|
39
40
|
end
|
40
41
|
end
|
41
42
|
|
42
|
-
|
43
|
+
private
|
43
44
|
|
45
|
+
# Add a trailing ansi color escape code to line up columns of colored
|
46
|
+
# output.
|
47
|
+
#
|
48
|
+
# @param string [String] a string
|
49
|
+
# @return [String]
|
50
|
+
# @api private
|
44
51
|
def color_pad(string)
|
45
|
-
string +
|
52
|
+
string + colorize("", :white)
|
46
53
|
end
|
47
54
|
|
55
|
+
# Generate the display rows for an instance.
|
56
|
+
#
|
57
|
+
# @param instance [Instance] an instance
|
58
|
+
# @return [Array<String>]
|
59
|
+
# @api private
|
48
60
|
def display_instance(instance)
|
49
61
|
[
|
50
62
|
color_pad(instance.name),
|
@@ -54,31 +66,49 @@ module Kitchen
|
|
54
66
|
]
|
55
67
|
end
|
56
68
|
|
69
|
+
# Format and color the given last action.
|
70
|
+
#
|
71
|
+
# @param [String] the last action
|
72
|
+
# @return [String] formated last action
|
73
|
+
# @api private
|
57
74
|
def format_last_action(last_action)
|
58
75
|
case last_action
|
59
|
-
when
|
60
|
-
when
|
61
|
-
when
|
62
|
-
when
|
63
|
-
when nil then
|
64
|
-
else
|
76
|
+
when "create" then colorize("Created", :cyan)
|
77
|
+
when "converge" then colorize("Converged", :magenta)
|
78
|
+
when "setup" then colorize("Set Up", :blue)
|
79
|
+
when "verify" then colorize("Verified", :yellow)
|
80
|
+
when nil then colorize("<Not Created>", :red)
|
81
|
+
else colorize("<Unknown>", :white)
|
65
82
|
end
|
66
83
|
end
|
67
84
|
|
85
|
+
# Constructs a list display table and output it to the screen.
|
86
|
+
#
|
87
|
+
# @param result [Array<Instance>] an array of instances
|
88
|
+
# @api private
|
68
89
|
def list_table(result)
|
69
90
|
table = [
|
70
|
-
[
|
71
|
-
|
91
|
+
[
|
92
|
+
colorize("Instance", :green), colorize("Driver", :green),
|
93
|
+
colorize("Provisioner", :green), colorize("Last Action", :green)
|
94
|
+
]
|
72
95
|
]
|
73
96
|
table += Array(result).map { |i| display_instance(i) }
|
74
97
|
print_table(table)
|
75
98
|
end
|
76
99
|
|
100
|
+
# Outputs a formatted display table.
|
101
|
+
#
|
102
|
+
# @api private
|
77
103
|
def print_table(*args)
|
78
104
|
shell.print_table(*args)
|
79
105
|
end
|
80
106
|
|
81
|
-
|
107
|
+
# Colorize a string.
|
108
|
+
#
|
109
|
+
# @return [String] a colorized string
|
110
|
+
# @api private
|
111
|
+
def colorize(*args)
|
82
112
|
shell.set_color(*args)
|
83
113
|
end
|
84
114
|
end
|