test-kitchen-rsync 3.0.0.pre.1
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 +7 -0
- data/Gemfile +21 -0
- data/LICENSE +15 -0
- data/Rakefile +53 -0
- data/bin/zl-kitchen +11 -0
- data/lib/kitchen/base64_stream.rb +48 -0
- data/lib/kitchen/chef_utils_wiring.rb +40 -0
- data/lib/kitchen/cli.rb +413 -0
- data/lib/kitchen/collection.rb +52 -0
- data/lib/kitchen/color.rb +63 -0
- data/lib/kitchen/command/action.rb +41 -0
- data/lib/kitchen/command/console.rb +54 -0
- data/lib/kitchen/command/diagnose.rb +84 -0
- data/lib/kitchen/command/doctor.rb +39 -0
- data/lib/kitchen/command/exec.rb +37 -0
- data/lib/kitchen/command/list.rb +148 -0
- data/lib/kitchen/command/login.rb +39 -0
- data/lib/kitchen/command/package.rb +32 -0
- data/lib/kitchen/command/sink.rb +50 -0
- data/lib/kitchen/command/test.rb +47 -0
- data/lib/kitchen/command.rb +207 -0
- data/lib/kitchen/config.rb +344 -0
- data/lib/kitchen/configurable.rb +616 -0
- data/lib/kitchen/data_munger.rb +1024 -0
- data/lib/kitchen/diagnostic.rb +138 -0
- data/lib/kitchen/driver/base.rb +133 -0
- data/lib/kitchen/driver/dummy.rb +105 -0
- data/lib/kitchen/driver/exec.rb +70 -0
- data/lib/kitchen/driver/proxy.rb +70 -0
- data/lib/kitchen/driver/ssh_base.rb +351 -0
- data/lib/kitchen/driver.rb +40 -0
- data/lib/kitchen/errors.rb +243 -0
- data/lib/kitchen/generator/init.rb +254 -0
- data/lib/kitchen/instance.rb +726 -0
- data/lib/kitchen/lazy_hash.rb +148 -0
- data/lib/kitchen/lifecycle_hook/base.rb +78 -0
- data/lib/kitchen/lifecycle_hook/local.rb +53 -0
- data/lib/kitchen/lifecycle_hook/remote.rb +39 -0
- data/lib/kitchen/lifecycle_hooks.rb +92 -0
- data/lib/kitchen/loader/yaml.rb +377 -0
- data/lib/kitchen/logger.rb +422 -0
- data/lib/kitchen/logging.rb +52 -0
- data/lib/kitchen/login_command.rb +49 -0
- data/lib/kitchen/metadata_chopper.rb +49 -0
- data/lib/kitchen/platform.rb +64 -0
- data/lib/kitchen/plugin.rb +76 -0
- data/lib/kitchen/plugin_base.rb +60 -0
- data/lib/kitchen/provisioner/base.rb +269 -0
- data/lib/kitchen/provisioner/chef/berkshelf.rb +116 -0
- data/lib/kitchen/provisioner/chef/common_sandbox.rb +350 -0
- data/lib/kitchen/provisioner/chef/policyfile.rb +163 -0
- data/lib/kitchen/provisioner/chef_apply.rb +121 -0
- data/lib/kitchen/provisioner/chef_base.rb +705 -0
- data/lib/kitchen/provisioner/chef_infra.rb +167 -0
- data/lib/kitchen/provisioner/chef_solo.rb +82 -0
- data/lib/kitchen/provisioner/chef_zero.rb +12 -0
- data/lib/kitchen/provisioner/dummy.rb +75 -0
- data/lib/kitchen/provisioner/shell.rb +157 -0
- data/lib/kitchen/provisioner.rb +42 -0
- data/lib/kitchen/rake_tasks.rb +80 -0
- data/lib/kitchen/shell_out.rb +90 -0
- data/lib/kitchen/ssh.rb +289 -0
- data/lib/kitchen/state_file.rb +112 -0
- data/lib/kitchen/suite.rb +48 -0
- data/lib/kitchen/thor_tasks.rb +63 -0
- data/lib/kitchen/transport/base.rb +236 -0
- data/lib/kitchen/transport/dummy.rb +78 -0
- data/lib/kitchen/transport/exec.rb +145 -0
- data/lib/kitchen/transport/ssh.rb +579 -0
- data/lib/kitchen/transport/winrm.rb +546 -0
- data/lib/kitchen/transport.rb +40 -0
- data/lib/kitchen/util.rb +229 -0
- data/lib/kitchen/verifier/base.rb +243 -0
- data/lib/kitchen/verifier/busser.rb +275 -0
- data/lib/kitchen/verifier/dummy.rb +75 -0
- data/lib/kitchen/verifier/shell.rb +99 -0
- data/lib/kitchen/verifier.rb +39 -0
- data/lib/kitchen/version.rb +20 -0
- data/lib/kitchen/which.rb +26 -0
- data/lib/kitchen.rb +152 -0
- data/lib/vendor/hash_recursive_merge.rb +79 -0
- data/support/busser_install_command.ps1 +14 -0
- data/support/busser_install_command.sh +21 -0
- data/support/chef-client-fail-if-update-handler.rb +15 -0
- data/support/chef_base_init_command.ps1 +18 -0
- data/support/chef_base_init_command.sh +1 -0
- data/support/chef_base_install_command.ps1 +85 -0
- data/support/chef_base_install_command.sh +229 -0
- data/support/download_helpers.sh +109 -0
- data/support/dummy-validation.pem +27 -0
- data/templates/driver/CHANGELOG.md.erb +3 -0
- data/templates/driver/Gemfile.erb +3 -0
- data/templates/driver/README.md.erb +64 -0
- data/templates/driver/Rakefile.erb +21 -0
- data/templates/driver/driver.rb.erb +23 -0
- data/templates/driver/gemspec.erb +29 -0
- data/templates/driver/gitignore.erb +17 -0
- data/templates/driver/license_apachev2.erb +15 -0
- data/templates/driver/license_lgplv3.erb +16 -0
- data/templates/driver/license_mit.erb +22 -0
- data/templates/driver/license_reserved.erb +5 -0
- data/templates/driver/tailor.erb +4 -0
- data/templates/driver/travis.yml.erb +11 -0
- data/templates/driver/version.rb.erb +12 -0
- data/templates/init/chefignore.erb +2 -0
- data/templates/init/kitchen.yml.erb +18 -0
- data/test-kitchen.gemspec +52 -0
- metadata +528 -0
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Author:: Salim Afiune (<salim@afiunemaya.com.mx>)
|
|
3
|
+
# Author:: Fletcher Nichol (<fnichol@nichol.ca>)
|
|
4
|
+
#
|
|
5
|
+
# Copyright (C) 2014, Salim Afiune
|
|
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_relative "../configurable"
|
|
20
|
+
require_relative "../errors"
|
|
21
|
+
require_relative "../lazy_hash"
|
|
22
|
+
require_relative "../logging"
|
|
23
|
+
require_relative "../login_command"
|
|
24
|
+
require_relative "../plugin_base"
|
|
25
|
+
|
|
26
|
+
module Kitchen
|
|
27
|
+
module Transport
|
|
28
|
+
# Wrapped exception for any internally raised Transport errors.
|
|
29
|
+
#
|
|
30
|
+
# @author Salim Afiune <salim@afiunemaya.com.mx>
|
|
31
|
+
class TransportFailed < TransientFailure
|
|
32
|
+
attr_reader :exit_code
|
|
33
|
+
|
|
34
|
+
def initialize(message, exit_code = nil)
|
|
35
|
+
@exit_code = exit_code
|
|
36
|
+
super(message)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Base class for a transport.
|
|
41
|
+
#
|
|
42
|
+
# @author Salim Afiune <salim@afiunemaya.com.mx>
|
|
43
|
+
# @author Fletcher Nichol <fnichol@nichol.ca>
|
|
44
|
+
class Base < Kitchen::Plugin::Base
|
|
45
|
+
include Configurable
|
|
46
|
+
include Logging
|
|
47
|
+
|
|
48
|
+
# Create a new transport by providing a configuration hash.
|
|
49
|
+
#
|
|
50
|
+
# @param config [Hash] initial provided configuration
|
|
51
|
+
def initialize(config = {})
|
|
52
|
+
@connection = nil
|
|
53
|
+
init_config(config)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Creates a new Connection, configured by a merging of configuration
|
|
57
|
+
# and state data. Depending on the implementation, the Connection could
|
|
58
|
+
# be saved or cached to speed up multiple calls, given the same state
|
|
59
|
+
# hash as input.
|
|
60
|
+
#
|
|
61
|
+
# @param state [Hash] mutable instance state
|
|
62
|
+
# @return [Connection] a connection for this transport
|
|
63
|
+
# @raise [TransportFailed] if a connection could not be returned
|
|
64
|
+
# rubocop:disable Lint/UnusedMethodArgument
|
|
65
|
+
def connection(state)
|
|
66
|
+
raise ClientError, "#{self.class}#connection must be implemented"
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Check system and configuration for common errors.
|
|
70
|
+
#
|
|
71
|
+
# @param state [Hash] mutable instance state
|
|
72
|
+
# @returns [Boolean] Return true if a problem is found.
|
|
73
|
+
def doctor(state)
|
|
74
|
+
false
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Closes the connection, if it is still active.
|
|
78
|
+
#
|
|
79
|
+
# @return [void]
|
|
80
|
+
def cleanup!
|
|
81
|
+
# This method may be left unimplemented if that is applicable
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# A Connection instance can be generated and re-generated, given new
|
|
85
|
+
# connection details such as connection port, hostname, credentials, etc.
|
|
86
|
+
# This object is responsible for carrying out the actions on the remote
|
|
87
|
+
# host such as executing commands, transferring files, etc.
|
|
88
|
+
#
|
|
89
|
+
# @author Fletcher Nichol <fnichol@nichol.ca>
|
|
90
|
+
class Connection
|
|
91
|
+
include Logging
|
|
92
|
+
|
|
93
|
+
# Create a new Connection instance.
|
|
94
|
+
#
|
|
95
|
+
# @param options [Hash] connection options
|
|
96
|
+
# @yield [self] yields itself for block-style invocation
|
|
97
|
+
def initialize(options = {})
|
|
98
|
+
init_options(options)
|
|
99
|
+
|
|
100
|
+
yield self if block_given?
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# Closes the session connection, if it is still active.
|
|
104
|
+
def close
|
|
105
|
+
# this method may be left unimplemented if that is applicable
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# Execute a command on the remote host.
|
|
109
|
+
#
|
|
110
|
+
# @param command [String] command string to execute
|
|
111
|
+
# @raise [TransportFailed] if the command does not exit successfully,
|
|
112
|
+
# which may vary by implementation
|
|
113
|
+
def execute(command)
|
|
114
|
+
raise ClientError, "#{self.class}#execute must be implemented"
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# Execute a command on the remote host and retry
|
|
118
|
+
#
|
|
119
|
+
# @param command [String] command string to execute
|
|
120
|
+
# @param retryable_exit_codes [Array] Array of exit codes to retry against
|
|
121
|
+
# @param max_retries [Fixnum] maximum number of retry attempts
|
|
122
|
+
# @param wait_time [Fixnum] number of seconds to wait before retrying command
|
|
123
|
+
# @raise [TransportFailed] if the command does not exit successfully,
|
|
124
|
+
# which may vary by implementation
|
|
125
|
+
def execute_with_retry(command, retryable_exit_codes = [], max_retries = 1, wait_time = 30)
|
|
126
|
+
tries = 0
|
|
127
|
+
begin
|
|
128
|
+
tries += 1
|
|
129
|
+
debug("Attempting to execute command - try #{tries} of #{max_retries}.")
|
|
130
|
+
execute(command)
|
|
131
|
+
rescue Kitchen::Transport::TransportFailed => e
|
|
132
|
+
if retry?(tries, max_retries, retryable_exit_codes, e.exit_code)
|
|
133
|
+
close
|
|
134
|
+
sleep wait_time
|
|
135
|
+
retry
|
|
136
|
+
else
|
|
137
|
+
raise e
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def retry?(current_try, max_retries, retryable_exit_codes, exit_code)
|
|
143
|
+
current_try <= max_retries &&
|
|
144
|
+
!retryable_exit_codes.nil? &&
|
|
145
|
+
retryable_exit_codes.flatten.include?(exit_code)
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
# Builds a LoginCommand which can be used to open an interactive
|
|
149
|
+
# session on the remote host.
|
|
150
|
+
#
|
|
151
|
+
# @return [LoginCommand] an object containing the array of command line
|
|
152
|
+
# tokens and exec options to be used in a fork/exec
|
|
153
|
+
# @raise [ActionFailed] if the action could not be completed
|
|
154
|
+
def login_command
|
|
155
|
+
raise ActionFailed, "Remote login not supported in #{self.class}."
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
# Uploads local files or directories to remote host.
|
|
159
|
+
#
|
|
160
|
+
# @param locals [Array<String>] paths to local files or directories
|
|
161
|
+
# @param remote [String] path to remote destination
|
|
162
|
+
# @raise [TransportFailed] if the files could not all be uploaded
|
|
163
|
+
# successfully, which may vary by implementation
|
|
164
|
+
def upload(locals, remote) # rubocop:disable Lint/UnusedMethodArgument
|
|
165
|
+
raise ClientError, "#{self.class}#upload must be implemented"
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
# Download remote files or directories to local host.
|
|
169
|
+
#
|
|
170
|
+
# @param remotes [Array<String>] paths to remote files or directories
|
|
171
|
+
# @param local [String] path to local destination. If `local` is an
|
|
172
|
+
# existing directory, `remote` will be downloaded into the directory
|
|
173
|
+
# using its original name
|
|
174
|
+
# @raise [TransportFailed] if the files could not all be downloaded
|
|
175
|
+
# successfully, which may vary by implementation
|
|
176
|
+
def download(remotes, local) # rubocop:disable Lint/UnusedMethodArgument
|
|
177
|
+
raise ClientError, "#{self.class}#download must be implemented"
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
# Block and return only when the remote host is prepared and ready to
|
|
181
|
+
# execute command and upload files. The semantics and details will
|
|
182
|
+
# vary by implementation, but a round trip through the hosted
|
|
183
|
+
# service is preferred to simply waiting on a socket to become
|
|
184
|
+
# available.
|
|
185
|
+
def wait_until_ready
|
|
186
|
+
# this method may be left unimplemented if that is applicable
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
def rsyn_chef_repo(dirs_to_copy, root_path)
|
|
190
|
+
# this method may be left unimplemented if that is applicable
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
private
|
|
194
|
+
|
|
195
|
+
# @return [Kitchen::Logger] a logger
|
|
196
|
+
# @api private
|
|
197
|
+
attr_reader :logger
|
|
198
|
+
|
|
199
|
+
# @return [Hash] connection options
|
|
200
|
+
# @api private
|
|
201
|
+
attr_reader :options
|
|
202
|
+
|
|
203
|
+
# Initialize incoming options for use by the object.
|
|
204
|
+
#
|
|
205
|
+
# @param options [Hash] configuration options
|
|
206
|
+
def init_options(options)
|
|
207
|
+
@options = options.dup
|
|
208
|
+
@logger = @options.delete(:logger) || Kitchen.logger
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
# Sets the API version for this transport. If the transport does not set
|
|
213
|
+
# this value, then `nil` will be used and reported.
|
|
214
|
+
#
|
|
215
|
+
# Sets the API version for this transport
|
|
216
|
+
#
|
|
217
|
+
# @example setting an API version
|
|
218
|
+
#
|
|
219
|
+
# module Kitchen
|
|
220
|
+
# module Transport
|
|
221
|
+
# class NewTransport < Kitchen::Transport::Base
|
|
222
|
+
#
|
|
223
|
+
# kitchen_transport_api_version 2
|
|
224
|
+
#
|
|
225
|
+
# end
|
|
226
|
+
# end
|
|
227
|
+
# end
|
|
228
|
+
#
|
|
229
|
+
# @param version [Integer,String] a version number
|
|
230
|
+
#
|
|
231
|
+
def self.kitchen_transport_api_version(version)
|
|
232
|
+
@api_version = version
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
end
|
|
236
|
+
end
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Author:: Salim Afiune (<salim@afiunemaya.com.mx>)
|
|
3
|
+
#
|
|
4
|
+
# Copyright (C) 2013, Salim Afiune
|
|
5
|
+
#
|
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
# you may not use this file except in compliance with the License.
|
|
8
|
+
# You may obtain a copy of the License at
|
|
9
|
+
#
|
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
#
|
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
# See the License for the specific language governing permissions and
|
|
16
|
+
# limitations under the License.
|
|
17
|
+
|
|
18
|
+
require_relative "../../kitchen"
|
|
19
|
+
|
|
20
|
+
module Kitchen
|
|
21
|
+
module Transport
|
|
22
|
+
# Dummy transport for Kitchen. This transport does nothing but report what would
|
|
23
|
+
# happen if this transport did anything of consequence. As a result it may
|
|
24
|
+
# be a useful transport to use when debugging or developing new features or
|
|
25
|
+
# plugins.
|
|
26
|
+
class Dummy < Kitchen::Transport::Base
|
|
27
|
+
kitchen_transport_api_version 1
|
|
28
|
+
|
|
29
|
+
plugin_version Kitchen::VERSION
|
|
30
|
+
|
|
31
|
+
default_config :sleep, 1
|
|
32
|
+
default_config :random_exit_code, 0
|
|
33
|
+
|
|
34
|
+
def connection(state, &block)
|
|
35
|
+
options = config.to_hash.merge(state)
|
|
36
|
+
Kitchen::Transport::Dummy::Connection.new(options, &block)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# TODO: comment
|
|
40
|
+
class Connection < Kitchen::Transport::Base::Connection
|
|
41
|
+
# (see Base#execute)
|
|
42
|
+
def execute(command)
|
|
43
|
+
report(:execute, command)
|
|
44
|
+
if options[:random_exit_code] != 0
|
|
45
|
+
info("Dummy exited (#{exit_code}) for command: [#{command}]")
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def upload(locals, remote)
|
|
50
|
+
report(:upload, "#{locals.inspect} => #{remote}")
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def download(remotes, local)
|
|
54
|
+
report(:download, "#{remotes.inspect} => #{local}")
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
private
|
|
58
|
+
|
|
59
|
+
# Report what action is taking place, sleeping if so configured, and
|
|
60
|
+
# possibly fail randomly.
|
|
61
|
+
#
|
|
62
|
+
# @param action [Symbol] the action currently taking place
|
|
63
|
+
# @param state [Hash] the state hash
|
|
64
|
+
# @api private
|
|
65
|
+
def report(action, msg = "")
|
|
66
|
+
what = action.capitalize
|
|
67
|
+
info("[Dummy] #{what} #{msg} on Transport=Dummy")
|
|
68
|
+
sleep_if_set
|
|
69
|
+
debug("[Dummy] #{what} #{msg} completed (#{options[:sleep]}s).")
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def sleep_if_set
|
|
73
|
+
sleep(options[:sleep].to_f) if options[:sleep].to_f > 0.0
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
# you may not use this file except in compliance with the License.
|
|
4
|
+
# You may obtain a copy of the License at
|
|
5
|
+
#
|
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
#
|
|
8
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
# See the License for the specific language governing permissions and
|
|
12
|
+
# limitations under the License.
|
|
13
|
+
|
|
14
|
+
require "fileutils" unless defined?(FileUtils)
|
|
15
|
+
|
|
16
|
+
require_relative "../shell_out"
|
|
17
|
+
require_relative "base"
|
|
18
|
+
require_relative "../version"
|
|
19
|
+
|
|
20
|
+
module Kitchen
|
|
21
|
+
module Transport
|
|
22
|
+
# Exec transport for Kitchen. This transport runs all commands locally.
|
|
23
|
+
#
|
|
24
|
+
# @since 1.19
|
|
25
|
+
class Exec < Kitchen::Transport::Base
|
|
26
|
+
kitchen_transport_api_version 1
|
|
27
|
+
|
|
28
|
+
plugin_version Kitchen::VERSION
|
|
29
|
+
|
|
30
|
+
def connection(state, &block)
|
|
31
|
+
options = connection_options(config.to_hash.merge(state))
|
|
32
|
+
Kitchen::Transport::Exec::Connection.new(options, &block)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Fake connection which just does local operations.
|
|
36
|
+
class Connection < Kitchen::Transport::Base::Connection
|
|
37
|
+
include ShellOut
|
|
38
|
+
|
|
39
|
+
# (see Base#execute)
|
|
40
|
+
def execute(command)
|
|
41
|
+
return if command.nil?
|
|
42
|
+
|
|
43
|
+
if host_os_windows?
|
|
44
|
+
run_command(run_from_file_command(command))
|
|
45
|
+
close
|
|
46
|
+
else
|
|
47
|
+
run_command(command)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def close
|
|
52
|
+
if host_os_windows?
|
|
53
|
+
FileUtils.remove(exec_script_file)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# "Upload" the files by copying them locally.
|
|
58
|
+
#
|
|
59
|
+
# @see Base#upload
|
|
60
|
+
def upload(locals, remote)
|
|
61
|
+
# evaluate $env:temp on Windows
|
|
62
|
+
real_remote = remote.to_s == "\$env:TEMP\\kitchen" ? kitchen_temp : remote
|
|
63
|
+
FileUtils.mkdir_p(real_remote)
|
|
64
|
+
Array(locals).each do |local|
|
|
65
|
+
FileUtils.cp_r(local, real_remote)
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# (see Base#init_options)
|
|
70
|
+
def init_options(options)
|
|
71
|
+
super
|
|
72
|
+
@instance_name = @options.delete(:instance_name)
|
|
73
|
+
@kitchen_root = @options.delete(:kitchen_root)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
private
|
|
77
|
+
|
|
78
|
+
# @return [String] display name for the associated instance
|
|
79
|
+
# @api private
|
|
80
|
+
attr_reader :instance_name
|
|
81
|
+
|
|
82
|
+
# @return [String] local path to the root of the project
|
|
83
|
+
# @api private
|
|
84
|
+
attr_reader :kitchen_root
|
|
85
|
+
|
|
86
|
+
# Takes a long command and saves it to a file and uploads it to
|
|
87
|
+
# the test instance. Windows has cli character limits.
|
|
88
|
+
#
|
|
89
|
+
# @param command [String] a long command to be saved and uploaded
|
|
90
|
+
# @return [String] a command that executes the uploaded script
|
|
91
|
+
# @api private
|
|
92
|
+
def run_from_file_command(command)
|
|
93
|
+
if logger.debug?
|
|
94
|
+
debug("Creating exec script for #{instance_name} (#{exec_script_file})")
|
|
95
|
+
debug("Executing #{exec_script_file}")
|
|
96
|
+
end
|
|
97
|
+
File.open(exec_script_file, "wb") { |file| file.write(command) }
|
|
98
|
+
%{powershell -file "#{exec_script_file}"}
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# @return [String] evaluated $env:temp variable
|
|
102
|
+
# @api private
|
|
103
|
+
def kitchen_temp
|
|
104
|
+
"#{ENV["temp"]}/kitchen"
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# @return [String] name of script using instance name
|
|
108
|
+
# @api private
|
|
109
|
+
def exec_script_name
|
|
110
|
+
"#{instance_name}-exec-script.ps1"
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
# @return [String] file path for exec script to be run
|
|
114
|
+
# @api private
|
|
115
|
+
def exec_script_file
|
|
116
|
+
File.join(kitchen_root, ".kitchen", exec_script_name)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def host_os_windows?
|
|
120
|
+
case RbConfig::CONFIG["host_os"]
|
|
121
|
+
when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
|
|
122
|
+
true
|
|
123
|
+
else
|
|
124
|
+
false
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
private
|
|
130
|
+
|
|
131
|
+
# Builds the hash of options needed by the Connection object on construction.
|
|
132
|
+
#
|
|
133
|
+
# @param data [Hash] merged configuration and mutable state data
|
|
134
|
+
# @return [Hash] hash of connection options
|
|
135
|
+
# @api private
|
|
136
|
+
def connection_options(data)
|
|
137
|
+
opts = {
|
|
138
|
+
instance_name: instance.name,
|
|
139
|
+
kitchen_root: Dir.pwd,
|
|
140
|
+
}
|
|
141
|
+
opts
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
end
|