test-kitchen 1.2.1 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|