kitchen-ssh 0.0.10 → 0.0.11

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 05bc5e6294e6f5689135c56ff96384cc819f7220
4
- data.tar.gz: aa64f3bcce9afbe859c07fc59d4c3ed7459293e8
3
+ metadata.gz: c5cac5019b09aeac0fb2ffe4f784d78a0f25f3c8
4
+ data.tar.gz: 4f7a0a2df1d7371c3ab021608d1365798ae64860
5
5
  SHA512:
6
- metadata.gz: 26a8743b008abdff35f2fe61016631ad398b2e0fb8fe317b747b62ab9db40216524135c3bd02fcf3146ec2d450c43f668e35c9628500c8b360ec9365d0b22f8e
7
- data.tar.gz: 6aac7f1c9b1dc71eb44a494d48754084ffe795cb6ce2fb7110afbb341d347949a10516962338c9c94593fcfb153cd3ffca997340fb18dd99d3d948d88b5b4ada
6
+ metadata.gz: 869f95c057d6110409689d5d7795e9c431b50f25972f2024a89d491caaf8f83548e16ac26d0bf59fb1a4b5ba3e133d22c607d4c4439960059efa3e0681a506e9
7
+ data.tar.gz: e4692e8ff4c1a84060dc7b5375a8e3e97f8e43333b0fde890eda875ad4bdf697e5d592db45b14363ef73e509b00cd644cbde7ca253b648ab33d87dabce4e8ba8
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in kitchen-sshgzip.gemspec
4
+ gemspec
data/README.md CHANGED
@@ -1,62 +1,62 @@
1
- # kitchen-ssh
2
-
3
- ssh and ssh_gzip driver for test-kitchen for any running server with an ip address.
4
-
5
- As well as ssh it supports a second driver called ssh_gzip that will also gzip file before transfer which can provide
6
- a big performance improvement when alot of files are transfered.
7
-
8
- server must be created and destroyed natively (e.g. via cloudformation, heat, or cloud or virtualization console).
9
- specify driver parameters
10
- * hostname
11
- * port
12
- * username
13
- * password
14
- * sudo
15
- * ssh_key
16
- * forward_agent
17
-
18
- NOTE: ssh driver is compatibile with test-kitchen 1.4 while ssh_gzip has legacy driver compatiability
19
- with test-kitchen 1.4
20
-
21
-
22
- ## Installation
23
-
24
- Add this line to your application's Gemfile:
25
-
26
- gem 'kitchen-ssh', group: :integration
27
-
28
- And then execute:
29
-
30
- $ bundle
31
-
32
- Or install it yourself as:
33
-
34
- $ gem install kitchen-ssh
35
-
36
- ## Usage
37
-
38
- In your .kitchen.yml file set driver to be 'ssh' or 'ssh_gzip'.
39
-
40
- ##Example
41
-
42
- ```yaml
43
- ---
44
- driver:
45
- name: ssh
46
- hostname: your-ip
47
- port: 22
48
- username: username
49
- ssh_key: /path/to/id_rsa
50
- ```
51
-
52
- or
53
-
54
- ```yaml
55
- ---
56
- driver:
57
- name: ssh_gzip
58
- hostname: your-ip
59
- port: 22
60
- username: username
61
- ssh_key: /path/to/id_rsa
62
- ```
1
+ # kitchen-ssh
2
+
3
+ ssh and ssh_gzip driver for test-kitchen for any running server with an ip address.
4
+
5
+ As well as ssh it supports a second driver called ssh_gzip that will also gzip file before transfer which can provide
6
+ a big performance improvement when alot of files are transfered.
7
+
8
+ server must be created and destroyed natively (e.g. via cloudformation, heat, or cloud or virtualization console).
9
+ specify driver parameters
10
+ * hostname
11
+ * port
12
+ * username
13
+ * password
14
+ * sudo
15
+ * ssh_key
16
+ * forward_agent
17
+
18
+ NOTE: ssh driver is compatibile with test-kitchen 1.4 while ssh_gzip has legacy driver compatiability
19
+ with test-kitchen 1.4
20
+
21
+
22
+ ## Installation
23
+
24
+ Add this line to your application's Gemfile:
25
+
26
+ gem 'kitchen-ssh', group: :integration
27
+
28
+ And then execute:
29
+
30
+ $ bundle
31
+
32
+ Or install it yourself as:
33
+
34
+ $ gem install kitchen-ssh
35
+
36
+ ## Usage
37
+
38
+ In your .kitchen.yml file set driver to be 'ssh' or 'ssh_gzip'.
39
+
40
+ ##Example
41
+
42
+ ```yaml
43
+ ---
44
+ driver:
45
+ name: ssh
46
+ hostname: your-ip
47
+ port: 22
48
+ username: username
49
+ ssh_key: /path/to/id_rsa
50
+ ```
51
+
52
+ or
53
+
54
+ ```yaml
55
+ ---
56
+ driver:
57
+ name: ssh_gzip
58
+ hostname: your-ip
59
+ port: 22
60
+ username: username
61
+ ssh_key: /path/to/id_rsa
62
+ ```
@@ -1,27 +1,28 @@
1
- # encoding: utf-8
2
-
3
- $:.unshift File.expand_path('../lib', __FILE__)
4
- require 'kitchen/ssh/version'
5
-
6
- Gem::Specification.new do |s|
7
- s.name = "kitchen-ssh"
8
- s.version = Kitchen::Ssh::VERSION
9
- s.authors = ["Neill Turner"]
10
- s.email = ["neillwturner@gmail.com"]
11
- s.homepage = "https://github.com/neillturner/kitchen-ssh"
12
- s.add_dependency('minitar', '~> 0.5')
13
- s.summary = "ssh and ssh_gzip driver for test-kitchen for any running server with an ip address"
14
- candidates = Dir.glob("{lib}/**/*") + ['README.md', 'LICENSE.txt', 'kitchen-ssh.gemspec']
15
- s.files = candidates.sort
16
- s.platform = Gem::Platform::RUBY
17
- s.require_paths = ['lib']
18
- s.rubyforge_project = '[none]'
19
- s.description = <<-EOF
20
- ssh and ssh_gzip driver for test-kitchen for any running server with an ip address
21
-
22
- *** As well as ssh it supports a second driver called ssh_gzip that will also gzip file before transfer which can provide
23
- a big performance improvement when alot of files are transfered. ****
24
-
25
- EOF
26
-
27
- end
1
+ # encoding: utf-8
2
+
3
+ $:.unshift File.expand_path('../lib', __FILE__)
4
+ require 'kitchen/ssh/version'
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "kitchen-ssh"
8
+ s.license = 'Apache-2.0'
9
+ s.version = Kitchen::Ssh::VERSION
10
+ s.authors = ["Neill Turner"]
11
+ s.email = ["neillwturner@gmail.com"]
12
+ s.homepage = "https://github.com/neillturner/kitchen-ssh"
13
+ s.add_dependency('minitar', '~> 0.5')
14
+ s.summary = "ssh and ssh_gzip driver for test-kitchen for any running server with an ip address"
15
+ candidates = Dir.glob("{lib}/**/*") + ['README.md', 'LICENSE.txt', 'kitchen-ssh.gemspec', 'Gemfile']
16
+ s.files = candidates.sort
17
+ s.platform = Gem::Platform::RUBY
18
+ s.require_paths = ['lib']
19
+ s.rubyforge_project = '[none]'
20
+ s.description = <<-EOF
21
+ ssh and ssh_gzip driver for test-kitchen for any running server with an ip address
22
+
23
+ *** As well as ssh it supports a second driver called ssh_gzip that will also gzip file before transfer which can provide
24
+ a big performance improvement when alot of files are transfered. ****
25
+
26
+ EOF
27
+
28
+ end
@@ -1,30 +1,30 @@
1
- require 'kitchen'
2
- require 'kitchen/driver/ssh_base'
3
-
4
- module Kitchen
5
- module Driver
6
- class Ssh < SSHBase
7
- def create(state)
8
- state[:sudo] = config[:sudo]
9
- state[:port] = config[:port]
10
- state[:ssh_key] = config[:ssh_key]
11
- state[:forward_agent] = config[:forward_agent]
12
- state[:username] = config[:username]
13
- state[:hostname] = config[:hostname]
14
- state[:password] = config[:password]
15
- print "Kitchen-ssh does not start your server '#{state[:hostname]}' but will look for an ssh connection with user '#{state[:username]}'"
16
- wait_for_sshd(state[:hostname], state[:username], {:port => state[:port]})
17
- print "Kitchen-ssh found ssh ready on host '#{state[:hostname]}' with user '#{state[:username]}'\n"
18
- debug("ssh:create '#{state[:hostname]}'")
19
- end
20
-
21
- def destroy(state)
22
- print "Kitchen-ssh does not destroy your server '#{state[:hostname]}' by shutting it down..."
23
- print "Shutdown your server '#{state[:hostname]}' natively with user '#{state[:username]}'"
24
- print 'in your cloud or virtualisation console etc.\n'
25
- debug("ssh:destroy '#{state[:hostname]}'")
26
- end
27
-
28
- end
29
- end
30
- end
1
+ require 'kitchen'
2
+ require 'kitchen/driver/ssh_base'
3
+
4
+ module Kitchen
5
+ module Driver
6
+ class Ssh < SSHBase
7
+ def create(state)
8
+ state[:sudo] = config[:sudo]
9
+ state[:port] = config[:port]
10
+ state[:ssh_key] = config[:ssh_key]
11
+ state[:forward_agent] = config[:forward_agent]
12
+ state[:username] = config[:username]
13
+ state[:hostname] = config[:hostname]
14
+ state[:password] = config[:password]
15
+ print "Kitchen-ssh does not start your server '#{state[:hostname]}' but will look for an ssh connection with user '#{state[:username]}'"
16
+ wait_for_sshd(state[:hostname], state[:username], {:port => state[:port]})
17
+ print "Kitchen-ssh found ssh ready on host '#{state[:hostname]}' with user '#{state[:username]}'\n"
18
+ debug("ssh:create '#{state[:hostname]}'")
19
+ end
20
+
21
+ def destroy(state)
22
+ print "Kitchen-ssh does not destroy your server '#{state[:hostname]}' by shutting it down..."
23
+ print "Shutdown your server '#{state[:hostname]}' natively with user '#{state[:username]}'"
24
+ print 'in your cloud or virtualisation console etc.\n'
25
+ debug("ssh:destroy '#{state[:hostname]}'")
26
+ end
27
+
28
+ end
29
+ end
30
+ end
@@ -1,251 +1,251 @@
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 'archive/tar/minitar'
20
-
21
- module Kitchen
22
-
23
- module Driver
24
-
25
- # Base class for a driver that uses SSH to communication with an instance.
26
- # A subclass must implement the following methods:
27
- # * #create(state)
28
- # * #destroy(state)
29
- #
30
- # @author Fletcher Nichol <fnichol@nichol.ca>
31
- class SSHBaseGzip < Kitchen::Driver::SSHBase
32
-
33
- default_config :sudo, true
34
- default_config :port, 22
35
- default_config :sandbox_archive, 'testkitchen-sandbox.tar.gz'
36
-
37
- # (see Base#create)
38
- def create(state) # rubocop:disable Lint/UnusedMethodArgument
39
- raise ClientError, "#{self.class}#create must be implemented"
40
- end
41
-
42
- # (see Base#converge)
43
- def converge(state)
44
- provisioner = instance.provisioner
45
- provisioner.create_sandbox
46
-
47
- Kitchen::SSH.new(*build_ssh_args(state)) do |conn|
48
- run_remote(provisioner.install_command, conn)
49
- run_remote(provisioner.init_command, conn)
50
- do_sandbox_transfer provisioner, conn
51
- run_remote(provisioner.prepare_command, conn)
52
- run_remote(provisioner.run_command, conn)
53
- end
54
- ensure
55
- provisioner && provisioner.cleanup_sandbox
56
- end
57
-
58
- # (see Base#setup)
59
- def setup(state)
60
- Kitchen::SSH.new(*build_ssh_args(state)) do |conn|
61
- run_remote(busser.setup_cmd, conn)
62
- end
63
- end
64
-
65
- # (see Base#verify) - changed in kitchen >=1.4
66
- #def verify(state)
67
- # Kitchen::SSH.new(*build_ssh_args(state)) do |conn|
68
- # run_remote(busser.sync_cmd, conn)
69
- # run_remote(busser.run_cmd, conn)
70
- # end
71
- #end
72
-
73
- # (see Base#destroy)
74
- def destroy(state) # rubocop:disable Lint/UnusedMethodArgument
75
- raise ClientError, "#{self.class}#destroy must be implemented"
76
- end
77
-
78
- # (see Base#login_command)
79
- def login_command(state)
80
- SSH.new(*build_ssh_args(state)).login_command
81
- end
82
-
83
- # Executes an arbitrary command on an instance over an SSH connection.
84
- #
85
- # @param state [Hash] mutable instance and driver state
86
- # @param command [String] the command to be executed
87
- # @raise [ActionFailed] if the command could not be successfully completed
88
- def remote_command(state, command)
89
- Kitchen::SSH.new(*build_ssh_args(state)) do |conn|
90
- run_remote(command, conn)
91
- end
92
- end
93
-
94
- # **(Deprecated)** Executes a remote command over SSH.
95
- #
96
- # @param ssh_args [Array] ssh arguments
97
- # @param command [String] remote command to invoke
98
- # @deprecated This method should no longer be called directly and exists
99
- # to support very old drivers. This will be removed in the future.
100
- def ssh(ssh_args, command)
101
- Kitchen::SSH.new(*ssh_args) do |conn|
102
- run_remote(command, conn)
103
- end
104
- end
105
-
106
- private
107
-
108
- # Builds arguments for constructing a `Kitchen::SSH` instance.
109
- #
110
- # @param state [Hash] state hash
111
- # @return [Array] SSH constructor arguments
112
- # @api private
113
- def build_ssh_args(state)
114
- combined = config.to_hash.merge(state)
115
-
116
- opts = Hash.new
117
- opts[:user_known_hosts_file] = "/dev/null"
118
- opts[:paranoid] = false
119
- opts[:keys_only] = true if combined[:ssh_key]
120
- opts[:password] = combined[:password] if combined[:password]
121
- opts[:forward_agent] = combined[:forward_agent] if combined.key? :forward_agent
122
- opts[:port] = combined[:port] if combined[:port]
123
- opts[:keys] = Array(combined[:ssh_key]) if combined[:ssh_key]
124
- opts[:logger] = logger
125
-
126
- [combined[:hostname], combined[:username], opts]
127
- end
128
-
129
- # Adds http and https proxy environment variables to a command, if set
130
- # in configuration data.
131
- #
132
- # @param cmd [String] command string
133
- # @return [String] command string
134
- # @api private
135
- def env_cmd(cmd)
136
- env = "env"
137
- env << " http_proxy=#{config[:http_proxy]}" if config[:http_proxy]
138
- env << " https_proxy=#{config[:https_proxy]}" if config[:https_proxy]
139
-
140
- env == "env" ? cmd : "#{env} #{cmd}"
141
- end
142
-
143
- # Executes a remote command over SSH.
144
- #
145
- # @param command [String] remove command to run
146
- # @param connection [Kitchen::SSH] an SSH connection
147
- # @raise [ActionFailed] if an exception occurs
148
- # @api private
149
- def run_remote(command, connection)
150
- return if command.nil?
151
-
152
- connection.exec(env_cmd(command))
153
- rescue SSHFailed, Net::SSH::Exception => ex
154
- raise ActionFailed, ex.message
155
- end
156
-
157
- # Transfers one or more local paths over SSH.
158
- #
159
- # @param locals [Array<String>] array of local paths
160
- # @param remote [String] remote destination path
161
- # @param connection [Kitchen::SSH] an SSH connection
162
- # @raise [ActionFailed] if an exception occurs
163
- # @api private
164
- def transfer_path(locals, remote, connection)
165
- return if locals.nil? || Array(locals).empty?
166
-
167
- info("Transferring files to #{instance.to_str}")
168
- locals.each { |local| connection.upload_path!(local, remote) }
169
- debug("Transfer complete")
170
- rescue SSHFailed, Net::SSH::Exception => ex
171
- raise ActionFailed, ex.message
172
- end
173
-
174
- # Blocks until a TCP socket is available where a remote SSH server
175
- # should be listening.
176
- #
177
- # @param hostname [String] remote SSH server host
178
- # @param username [String] SSH username (default: `nil`)
179
- # @param options [Hash] configuration hash (default: `{}`)
180
- # @api private
181
- def wait_for_sshd(hostname, username = nil, options = {})
182
- SSH.new(hostname, username, { :logger => logger }.merge(options)).wait
183
- end
184
-
185
-
186
- # Creates a temporary folder containing an archive of the current
187
- # TestKitchen sandbox.
188
- #
189
- # @param sandbox_path [String]
190
- def archive_sandbox(sandbox_path)
191
- archive_dir = Dir.mktmpdir("#{instance.name}-sandbox-archive-")
192
- archive_file = "#{archive_dir}/#{self[:sandbox_archive]}"
193
-
194
- Dir.chdir(sandbox_path) do |dir|
195
- tgz = Zlib::GzipWriter.new(File.open(archive_file, 'wb'), Zlib::DEFAULT_COMPRESSION, Zlib::DEFAULT_STRATEGY)
196
- Archive::Tar::Minitar.pack('.', tgz)
197
- end
198
-
199
- archive_dir
200
- end
201
-
202
- # Transfers the local sandbox to the instance.
203
- # - Archives/extracts if the tar command is available remotely.
204
- #
205
- # @param provisioner [Kitchen::Provisioner::Base] the provisioner
206
- # @param connection [Kitchen:SSH] an SSH connection
207
- def do_sandbox_transfer(provisioner, connection)
208
- root_path = provisioner[:root_path]
209
- sandbox_path = provisioner.sandbox_path
210
- archive_file = self[:sandbox_archive]
211
- archive_path = false
212
- do_archive = remote_supports_tar? connection
213
-
214
- begin
215
- # Archive sandbox if enabled (We keep a copy of the archive path so that we do not)
216
- # delete the sandbox if an exception is thrown
217
- if do_archive
218
- info 'Creating sandbox archive'
219
- archive_path = archive_sandbox sandbox_path
220
- sandbox_path = archive_path
221
- end
222
-
223
- # Initiate transfer
224
- transfer_path(Dir.glob("#{sandbox_path}/*"), root_path, connection)
225
-
226
- # Extract archive if enabled (and cleanup locally)
227
- if do_archive
228
- info 'Extracting sandbox archive remotely'
229
- run_remote("tar xf #{root_path}/#{archive_file} -C #{root_path}", connection)
230
- end
231
- ensure
232
- # Ensure archive temporary directory is removed, if used.
233
- FileUtils.rmtree(archive_path) if archive_path
234
- end
235
- end
236
-
237
- # Checks whether the remote instance supports archive extraction using
238
- # the `tar` command.
239
- #
240
- # @param connection [Kitchen::SSH] an SSH connection
241
- def remote_supports_tar?(connection)
242
- begin
243
- run_remote('tar --version > /dev/null 2>&1', connection)
244
- return true
245
- rescue ActionFailed => ex
246
- return false
247
- end
248
- end
249
- end
250
- end
251
- 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 'archive/tar/minitar'
20
+
21
+ module Kitchen
22
+
23
+ module Driver
24
+
25
+ # Base class for a driver that uses SSH to communication with an instance.
26
+ # A subclass must implement the following methods:
27
+ # * #create(state)
28
+ # * #destroy(state)
29
+ #
30
+ # @author Fletcher Nichol <fnichol@nichol.ca>
31
+ class SSHBaseGzip < Kitchen::Driver::SSHBase
32
+
33
+ default_config :sudo, true
34
+ default_config :port, 22
35
+ default_config :sandbox_archive, 'testkitchen-sandbox.tar.gz'
36
+
37
+ # (see Base#create)
38
+ def create(state) # rubocop:disable Lint/UnusedMethodArgument
39
+ raise ClientError, "#{self.class}#create must be implemented"
40
+ end
41
+
42
+ # (see Base#converge)
43
+ def converge(state)
44
+ provisioner = instance.provisioner
45
+ provisioner.create_sandbox
46
+
47
+ Kitchen::SSH.new(*build_ssh_args(state)) do |conn|
48
+ run_remote(provisioner.install_command, conn)
49
+ run_remote(provisioner.init_command, conn)
50
+ do_sandbox_transfer provisioner, conn
51
+ run_remote(provisioner.prepare_command, conn)
52
+ run_remote(provisioner.run_command, conn)
53
+ end
54
+ ensure
55
+ provisioner && provisioner.cleanup_sandbox
56
+ end
57
+
58
+ # (see Base#setup)
59
+ def setup(state)
60
+ Kitchen::SSH.new(*build_ssh_args(state)) do |conn|
61
+ run_remote(busser.setup_cmd, conn)
62
+ end
63
+ end
64
+
65
+ # (see Base#verify) - changed in kitchen >=1.4
66
+ #def verify(state)
67
+ # Kitchen::SSH.new(*build_ssh_args(state)) do |conn|
68
+ # run_remote(busser.sync_cmd, conn)
69
+ # run_remote(busser.run_cmd, conn)
70
+ # end
71
+ #end
72
+
73
+ # (see Base#destroy)
74
+ def destroy(state) # rubocop:disable Lint/UnusedMethodArgument
75
+ raise ClientError, "#{self.class}#destroy must be implemented"
76
+ end
77
+
78
+ # (see Base#login_command)
79
+ def login_command(state)
80
+ SSH.new(*build_ssh_args(state)).login_command
81
+ end
82
+
83
+ # Executes an arbitrary command on an instance over an SSH connection.
84
+ #
85
+ # @param state [Hash] mutable instance and driver state
86
+ # @param command [String] the command to be executed
87
+ # @raise [ActionFailed] if the command could not be successfully completed
88
+ def remote_command(state, command)
89
+ Kitchen::SSH.new(*build_ssh_args(state)) do |conn|
90
+ run_remote(command, conn)
91
+ end
92
+ end
93
+
94
+ # **(Deprecated)** Executes a remote command over SSH.
95
+ #
96
+ # @param ssh_args [Array] ssh arguments
97
+ # @param command [String] remote command to invoke
98
+ # @deprecated This method should no longer be called directly and exists
99
+ # to support very old drivers. This will be removed in the future.
100
+ def ssh(ssh_args, command)
101
+ Kitchen::SSH.new(*ssh_args) do |conn|
102
+ run_remote(command, conn)
103
+ end
104
+ end
105
+
106
+ private
107
+
108
+ # Builds arguments for constructing a `Kitchen::SSH` instance.
109
+ #
110
+ # @param state [Hash] state hash
111
+ # @return [Array] SSH constructor arguments
112
+ # @api private
113
+ def build_ssh_args(state)
114
+ combined = config.to_hash.merge(state)
115
+
116
+ opts = Hash.new
117
+ opts[:user_known_hosts_file] = "/dev/null"
118
+ opts[:paranoid] = false
119
+ opts[:keys_only] = true if combined[:ssh_key]
120
+ opts[:password] = combined[:password] if combined[:password]
121
+ opts[:forward_agent] = combined[:forward_agent] if combined.key? :forward_agent
122
+ opts[:port] = combined[:port] if combined[:port]
123
+ opts[:keys] = Array(combined[:ssh_key]) if combined[:ssh_key]
124
+ opts[:logger] = logger
125
+
126
+ [combined[:hostname], combined[:username], opts]
127
+ end
128
+
129
+ # Adds http and https proxy environment variables to a command, if set
130
+ # in configuration data.
131
+ #
132
+ # @param cmd [String] command string
133
+ # @return [String] command string
134
+ # @api private
135
+ def env_cmd(cmd)
136
+ env = "env"
137
+ env << " http_proxy=#{config[:http_proxy]}" if config[:http_proxy]
138
+ env << " https_proxy=#{config[:https_proxy]}" if config[:https_proxy]
139
+
140
+ env == "env" ? cmd : "#{env} #{cmd}"
141
+ end
142
+
143
+ # Executes a remote command over SSH.
144
+ #
145
+ # @param command [String] remove command to run
146
+ # @param connection [Kitchen::SSH] an SSH connection
147
+ # @raise [ActionFailed] if an exception occurs
148
+ # @api private
149
+ def run_remote(command, connection)
150
+ return if command.nil?
151
+
152
+ connection.exec(env_cmd(command))
153
+ rescue SSHFailed, Net::SSH::Exception => ex
154
+ raise ActionFailed, ex.message
155
+ end
156
+
157
+ # Transfers one or more local paths over SSH.
158
+ #
159
+ # @param locals [Array<String>] array of local paths
160
+ # @param remote [String] remote destination path
161
+ # @param connection [Kitchen::SSH] an SSH connection
162
+ # @raise [ActionFailed] if an exception occurs
163
+ # @api private
164
+ def transfer_path(locals, remote, connection)
165
+ return if locals.nil? || Array(locals).empty?
166
+
167
+ info("Transferring files to #{instance.to_str}")
168
+ locals.each { |local| connection.upload_path!(local, remote) }
169
+ debug("Transfer complete")
170
+ rescue SSHFailed, Net::SSH::Exception => ex
171
+ raise ActionFailed, ex.message
172
+ end
173
+
174
+ # Blocks until a TCP socket is available where a remote SSH server
175
+ # should be listening.
176
+ #
177
+ # @param hostname [String] remote SSH server host
178
+ # @param username [String] SSH username (default: `nil`)
179
+ # @param options [Hash] configuration hash (default: `{}`)
180
+ # @api private
181
+ def wait_for_sshd(hostname, username = nil, options = {})
182
+ SSH.new(hostname, username, { :logger => logger }.merge(options)).wait
183
+ end
184
+
185
+
186
+ # Creates a temporary folder containing an archive of the current
187
+ # TestKitchen sandbox.
188
+ #
189
+ # @param sandbox_path [String]
190
+ def archive_sandbox(sandbox_path)
191
+ archive_dir = Dir.mktmpdir("#{instance.name}-sandbox-archive-")
192
+ archive_file = "#{archive_dir}/#{self[:sandbox_archive]}"
193
+
194
+ Dir.chdir(sandbox_path) do |dir|
195
+ tgz = Zlib::GzipWriter.new(File.open(archive_file, 'wb'), Zlib::DEFAULT_COMPRESSION, Zlib::DEFAULT_STRATEGY)
196
+ Archive::Tar::Minitar.pack('.', tgz)
197
+ end
198
+
199
+ archive_dir
200
+ end
201
+
202
+ # Transfers the local sandbox to the instance.
203
+ # - Archives/extracts if the tar command is available remotely.
204
+ #
205
+ # @param provisioner [Kitchen::Provisioner::Base] the provisioner
206
+ # @param connection [Kitchen:SSH] an SSH connection
207
+ def do_sandbox_transfer(provisioner, connection)
208
+ root_path = provisioner[:root_path]
209
+ sandbox_path = provisioner.sandbox_path
210
+ archive_file = self[:sandbox_archive]
211
+ archive_path = false
212
+ do_archive = remote_supports_tar? connection
213
+
214
+ begin
215
+ # Archive sandbox if enabled (We keep a copy of the archive path so that we do not)
216
+ # delete the sandbox if an exception is thrown
217
+ if do_archive
218
+ info 'Creating sandbox archive'
219
+ archive_path = archive_sandbox sandbox_path
220
+ sandbox_path = archive_path
221
+ end
222
+
223
+ # Initiate transfer
224
+ transfer_path(Dir.glob("#{sandbox_path}/*"), root_path, connection)
225
+
226
+ # Extract archive if enabled (and cleanup locally)
227
+ if do_archive
228
+ info 'Extracting sandbox archive remotely'
229
+ run_remote("tar xf #{root_path}/#{archive_file} -C #{root_path}", connection)
230
+ end
231
+ ensure
232
+ # Ensure archive temporary directory is removed, if used.
233
+ FileUtils.rmtree(archive_path) if archive_path
234
+ end
235
+ end
236
+
237
+ # Checks whether the remote instance supports archive extraction using
238
+ # the `tar` command.
239
+ #
240
+ # @param connection [Kitchen::SSH] an SSH connection
241
+ def remote_supports_tar?(connection)
242
+ begin
243
+ run_remote('tar --version > /dev/null 2>&1', connection)
244
+ return true
245
+ rescue ActionFailed => ex
246
+ return false
247
+ end
248
+ end
249
+ end
250
+ end
251
+ end
@@ -1,30 +1,30 @@
1
- require 'kitchen'
2
- require 'kitchen/driver/ssh_base_gzip'
3
-
4
- module Kitchen
5
- module Driver
6
- class SshGzip < SSHBaseGzip
7
- def create(state)
8
- state[:sudo] = config[:sudo]
9
- state[:port] = config[:port]
10
- state[:ssh_key] = config[:ssh_key]
11
- state[:forward_agent] = config[:forward_agent]
12
- state[:username] = config[:username]
13
- state[:hostname] = config[:hostname]
14
- state[:password] = config[:password]
15
- print "Kitchen-sshGzip does not start your server '#{state[:hostname]}' but will look for an ssh connection with user '#{state[:username]}'"
16
- wait_for_sshd(state[:hostname], state[:username], {:port => state[:port]})
17
- print "Kitchen-sshGzip found ssh ready on host '#{state[:hostname]}' with user '#{state[:username]}'\n"
18
- debug("ssh:create '#{state[:hostname]}'")
19
- end
20
-
21
- def destroy(state)
22
- print "Kitchen-sshGzip does not destroy your server '#{state[:hostname]}' by shutting it down..."
23
- print "Shutdown your server '#{state[:hostname]}' natively with user '#{state[:username]}'"
24
- print 'in your cloud or virtualisation console etc.\n'
25
- debug("ssh:destroy '#{state[:hostname]}'")
26
- end
27
-
28
- end
29
- end
30
- end
1
+ require 'kitchen'
2
+ require 'kitchen/driver/ssh_base_gzip'
3
+
4
+ module Kitchen
5
+ module Driver
6
+ class SshGzip < SSHBaseGzip
7
+ def create(state)
8
+ state[:sudo] = config[:sudo]
9
+ state[:port] = config[:port]
10
+ state[:ssh_key] = config[:ssh_key]
11
+ state[:forward_agent] = config[:forward_agent]
12
+ state[:username] = config[:username]
13
+ state[:hostname] = config[:hostname]
14
+ state[:password] = config[:password]
15
+ print "Kitchen-sshGzip does not start your server '#{state[:hostname]}' but will look for an ssh connection with user '#{state[:username]}'"
16
+ wait_for_sshd(state[:hostname], state[:username], {:port => state[:port]})
17
+ print "Kitchen-sshGzip found ssh ready on host '#{state[:hostname]}' with user '#{state[:username]}'\n"
18
+ debug("ssh:create '#{state[:hostname]}'")
19
+ end
20
+
21
+ def destroy(state)
22
+ print "Kitchen-sshGzip does not destroy your server '#{state[:hostname]}' by shutting it down..."
23
+ print "Shutdown your server '#{state[:hostname]}' natively with user '#{state[:username]}'"
24
+ print 'in your cloud or virtualisation console etc.\n'
25
+ debug("ssh:destroy '#{state[:hostname]}'")
26
+ end
27
+
28
+ end
29
+ end
30
+ end
@@ -1,5 +1,5 @@
1
- module Kitchen
2
- module Ssh
3
- VERSION = "0.0.10"
4
- end
5
- end
1
+ module Kitchen
2
+ module Ssh
3
+ VERSION = "0.0.11"
4
+ end
5
+ end
metadata CHANGED
@@ -1,39 +1,42 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kitchen-ssh
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.10
4
+ version: 0.0.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Neill Turner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-02-10 00:00:00.000000000 Z
11
+ date: 2016-08-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitar
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0.5'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ~>
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0.5'
27
- description: "ssh and ssh_gzip driver for test-kitchen for any running server with
28
- an ip address\n\n*** As well as ssh it supports a second driver called ssh_gzip
29
- that will also gzip file before transfer which can provide \na big performance improvement
30
- when alot of files are transfered. ****\n\n"
27
+ description: |+
28
+ ssh and ssh_gzip driver for test-kitchen for any running server with an ip address
29
+
30
+ *** As well as ssh it supports a second driver called ssh_gzip that will also gzip file before transfer which can provide
31
+ a big performance improvement when alot of files are transfered. ****
32
+
31
33
  email:
32
34
  - neillwturner@gmail.com
33
35
  executables: []
34
36
  extensions: []
35
37
  extra_rdoc_files: []
36
38
  files:
39
+ - Gemfile
37
40
  - LICENSE.txt
38
41
  - README.md
39
42
  - kitchen-ssh.gemspec
@@ -42,7 +45,8 @@ files:
42
45
  - lib/kitchen/driver/ssh_gzip.rb
43
46
  - lib/kitchen/ssh/version.rb
44
47
  homepage: https://github.com/neillturner/kitchen-ssh
45
- licenses: []
48
+ licenses:
49
+ - Apache-2.0
46
50
  metadata: {}
47
51
  post_install_message:
48
52
  rdoc_options: []
@@ -50,17 +54,17 @@ require_paths:
50
54
  - lib
51
55
  required_ruby_version: !ruby/object:Gem::Requirement
52
56
  requirements:
53
- - - '>='
57
+ - - ">="
54
58
  - !ruby/object:Gem::Version
55
59
  version: '0'
56
60
  required_rubygems_version: !ruby/object:Gem::Requirement
57
61
  requirements:
58
- - - '>='
62
+ - - ">="
59
63
  - !ruby/object:Gem::Version
60
64
  version: '0'
61
65
  requirements: []
62
- rubyforge_project: '[none]'
63
- rubygems_version: 2.0.14
66
+ rubyforge_project: "[none]"
67
+ rubygems_version: 2.2.2
64
68
  signing_key:
65
69
  specification_version: 4
66
70
  summary: ssh and ssh_gzip driver for test-kitchen for any running server with an ip