kitchen-ssh 0.0.10 → 0.0.11

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 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