ztk 1.1.2 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -20,7 +20,7 @@ Issues:
20
20
 
21
21
  Documentation:
22
22
 
23
- * http://zpatten.github.com/ztk/
23
+ * http://zpatten.github.io/ztk/
24
24
 
25
25
  # LICENSE
26
26
 
@@ -0,0 +1,48 @@
1
+ ################################################################################
2
+ #
3
+ # Author: Zachary Patten <zachary@jovelabs.net>
4
+ # Copyright: Copyright (c) Zachary Patten
5
+ # License: Apache License, Version 2.0
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
+ ################################################################################
20
+ module ZTK
21
+ class SSH
22
+
23
+ module Bootstrap
24
+ require 'tempfile'
25
+
26
+ def bootstrap(content, use_sudo=true)
27
+ tempfile = Tempfile.new("bootstrap")
28
+
29
+ File.open(tempfile, 'w') do |file|
30
+ file.puts(content)
31
+ file.respond_to?(:flush) and file.flush
32
+ end
33
+
34
+ self.upload(tempfile.path, tempfile.path)
35
+
36
+ command = Array.new
37
+ command << %(sudo) if (use_sudo == true)
38
+ command << %(/bin/bash)
39
+ command << tempfile.path
40
+ command = command.join(' ')
41
+
42
+ self.exec(command, :silence => true)
43
+ end
44
+
45
+ end
46
+
47
+ end
48
+ end
@@ -0,0 +1,73 @@
1
+ ################################################################################
2
+ #
3
+ # Author: Zachary Patten <zachary@jovelabs.net>
4
+ # Copyright: Copyright (c) Zachary Patten
5
+ # License: Apache License, Version 2.0
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
+ ################################################################################
20
+ module ZTK
21
+ class SSH
22
+
23
+ module Command
24
+
25
+ # Builds our SSH console command.
26
+ def console_command
27
+ verbosity = ((ENV['LOG_LEVEL'].upcase == "DEBUG") ? '-vv' : '-q')
28
+
29
+ command = [ "/usr/bin/env ssh" ]
30
+ command << [ verbosity ]
31
+ command << [ "-x" ]
32
+ command << [ "-a" ]
33
+ command << [ "-o", "UserKnownHostsFile=/dev/null" ]
34
+ command << [ "-o", "StrictHostKeyChecking=no" ]
35
+ command << [ "-o", "KeepAlive=yes" ]
36
+ command << [ "-o", "ServerAliveInterval=60" ]
37
+ command << [ "-o", %(ProxyCommand="#{proxy_command}") ] if config.proxy_host_name
38
+ command << [ "-i", config.keys ] if config.keys
39
+ command << [ "-p", config.port ] if config.port
40
+ command << "#{config.user}@#{config.host_name}"
41
+ command = command.flatten.compact.join(' ')
42
+ config.ui.logger.debug { "console_command(#{command.inspect})" }
43
+ command
44
+ end
45
+
46
+ # Builds our SSH proxy command.
47
+ def proxy_command
48
+ !config.proxy_user and log_and_raise(SSHError, "You must specify an proxy user in order to SSH proxy.")
49
+ !config.proxy_host_name and log_and_raise(SSHError, "You must specify an proxy host_name in order to SSH proxy.")
50
+
51
+ verbosity = ((ENV['LOG_LEVEL'].upcase == "DEBUG") ? '-vv' : '-q')
52
+
53
+ command = ["/usr/bin/env ssh"]
54
+ command << [ verbosity ]
55
+ command << [ "-x" ]
56
+ command << [ "-a" ]
57
+ command << [ "-o", "UserKnownHostsFile=/dev/null" ]
58
+ command << [ "-o", "StrictHostKeyChecking=no" ]
59
+ command << [ "-o", "KeepAlive=yes" ]
60
+ command << [ "-o", "ServerAliveInterval=60" ]
61
+ command << [ "-i", config.proxy_keys ] if config.proxy_keys
62
+ command << [ "-p", config.proxy_port ] if config.proxy_port
63
+ command << "#{config.proxy_user}@#{config.proxy_host_name}"
64
+ command << "'/usr/bin/env nc %h %p'"
65
+ command = command.flatten.compact.join(' ')
66
+ config.ui.logger.debug { "proxy_command(#{command.inspect})" }
67
+ command
68
+ end
69
+
70
+ end
71
+
72
+ end
73
+ end
@@ -0,0 +1,68 @@
1
+ ################################################################################
2
+ #
3
+ # Author: Zachary Patten <zachary@jovelabs.net>
4
+ # Copyright: Copyright (c) Zachary Patten
5
+ # License: Apache License, Version 2.0
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
+ ################################################################################
20
+ module ZTK
21
+ class SSH
22
+
23
+ module Download
24
+
25
+ # Downloads a remote file to the local host.
26
+ #
27
+ # @param [String] remote The remote file/path you with to download from.
28
+ # @param [String] local The local file/path you wish to download to.
29
+ #
30
+ # @example Download a file:
31
+ # $logger = ZTK::Logger.new(STDOUT)
32
+ # ssh = ZTK::SSH.new
33
+ # ssh.config do |config|
34
+ # config.user = ENV["USER"]
35
+ # config.host_name = "127.0.0.1"
36
+ # end
37
+ # local = File.expand_path(File.join("/tmp", "id_rsa.pub"))
38
+ # remote = File.expand_path(File.join(ENV["HOME"], ".ssh", "id_rsa.pub"))
39
+ # ssh.download(remote, local)
40
+ def download(remote, local)
41
+ config.ui.logger.debug { "config=#{config.send(:table).inspect}" }
42
+ config.ui.logger.info { "download(#{remote.inspect}, #{local.inspect})" }
43
+
44
+ ZTK::RescueRetry.try(:tries => 3, :on => EOFError) do
45
+ @sftp = Net::SFTP.start(config.host_name, config.user, ssh_options)
46
+ sftp.download!(remote.to_s, local.to_s) do |event, downloader, *args|
47
+ case event
48
+ when :open
49
+ config.ui.logger.debug { "download(#{args[0].remote} -> #{args[0].local})" }
50
+ when :close
51
+ config.ui.logger.debug { "close(#{args[0].local})" }
52
+ when :mkdir
53
+ config.ui.logger.debug { "mkdir(#{args[0]})" }
54
+ when :get
55
+ config.ui.logger.debug { "get(#{args[0].remote}, size #{args[2].size} bytes, offset #{args[1]})" }
56
+ when :finish
57
+ config.ui.logger.debug { "finish" }
58
+ end
59
+ end
60
+ end
61
+
62
+ true
63
+ end
64
+
65
+ end
66
+
67
+ end
68
+ end
@@ -0,0 +1,148 @@
1
+ ################################################################################
2
+ #
3
+ # Author: Zachary Patten <zachary@jovelabs.net>
4
+ # Copyright: Copyright (c) Zachary Patten
5
+ # License: Apache License, Version 2.0
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
+ ################################################################################
20
+ module ZTK
21
+ class SSH
22
+
23
+ module Exec
24
+
25
+ # Executes a command on the remote host.
26
+ #
27
+ # @param [String] command The command to execute.
28
+ # @param [Hash] options The options hash for executing the command.
29
+ # @option options [Boolean] :silence Squelch output to STDOUT and STDERR.
30
+ # If the log level is :debug, STDOUT and STDERR will go to the log file
31
+ # regardless of this setting. STDOUT and STDERR are always returned in
32
+ # the output return value regardless of this setting.
33
+ #
34
+ # @return [OpenStruct#output] The output of the command, both STDOUT and
35
+ # STDERR.
36
+ # @return [OpenStruct#exit] The exit status (i.e. $?).
37
+ #
38
+ # @example Execute a command:
39
+ #
40
+ # ssh = ZTK::SSH.new
41
+ # ssh.config do |config|
42
+ # config.user = ENV["USER"]
43
+ # config.host_name = "127.0.0.1"
44
+ # end
45
+ # puts ssh.exec("hostname").inspect
46
+ def exec(command, options={})
47
+ options = OpenStruct.new({ :exit_code => 0, :silence => false }.merge(config.send(:table)).merge(options))
48
+
49
+ options.ui.logger.debug { "config=#{options.send(:table).inspect}" }
50
+ options.ui.logger.debug { "options=#{options.send(:table).inspect}" }
51
+ options.ui.logger.info { "exec(#{command.inspect})" }
52
+
53
+ output = ""
54
+ exit_code = -1
55
+ exit_signal = nil
56
+ stdout_header = false
57
+ stderr_header = false
58
+
59
+ begin
60
+ Timeout.timeout(options.timeout) do
61
+ ZTK::RescueRetry.try(:tries => 3, :on => EOFError) do
62
+ @ssh = Net::SSH.start(options.host_name, options.user, ssh_options)
63
+
64
+ channel = ssh.open_channel do |chan|
65
+ options.ui.logger.debug { "Channel opened." }
66
+
67
+ (options.request_pty == true) and chan.request_pty do |ch, success|
68
+ if success
69
+ options.ui.logger.debug { "PTY obtained." }
70
+ else
71
+ options.ui.logger.warn { "Could not obtain PTY." }
72
+ end
73
+ end
74
+
75
+ direct_log(:info) { log_header("COMMAND") }
76
+ direct_log(:info) { "#{command}\n" }
77
+ direct_log(:info) { log_header("OPENED") }
78
+
79
+ chan.exec(command) do |ch, success|
80
+ success or log_and_raise(SSHError, "Could not execute '#{command}'.")
81
+
82
+ ch.on_data do |c, data|
83
+ if !stdout_header
84
+ direct_log(:info) { log_header("STDOUT") }
85
+ stdout_header = true
86
+ stderr_header = false
87
+ end
88
+ direct_log(:info) { data }
89
+
90
+ options.ui.stdout.print(data) unless options.silence
91
+ output += data
92
+ end
93
+
94
+ ch.on_extended_data do |c, type, data|
95
+ if !stderr_header
96
+ direct_log(:warn) { log_header("STDERR") }
97
+ stderr_header = true
98
+ stdout_header = false
99
+ end
100
+ direct_log(:warn) { data }
101
+
102
+ options.ui.stderr.print(data) unless options.silence
103
+ output += data
104
+ end
105
+
106
+ ch.on_request("exit-status") do |ch, data|
107
+ exit_code = data.read_long
108
+ end
109
+
110
+ ch.on_request("exit-signal") do |ch, data|
111
+ exit_signal = data.read_long
112
+ end
113
+
114
+ ch.on_open_failed do |c, code, desc|
115
+ options.ui.logger.fatal { "Open failed! (#{code.inspect} - #{desc.inspect})" }
116
+ end
117
+
118
+ end
119
+ end
120
+ channel.wait
121
+
122
+ direct_log(:info) { log_header("CLOSED") }
123
+ options.ui.logger.debug { "Channel closed." }
124
+ end
125
+ end
126
+
127
+ rescue Timeout::Error => e
128
+ direct_log(:fatal) { log_header("TIMEOUT") }
129
+ log_and_raise(SSHError, "Session timed out after #{options.timeout} seconds!")
130
+ end
131
+
132
+ message = [
133
+ "exit_code=#{exit_code}",
134
+ (exit_signal.nil? ? nil : "exit_signal=#{exit_signal} (#{EXIT_SIGNALS[exit_signal]})")
135
+ ].compact.join(", ")
136
+
137
+ options.ui.logger.debug { message }
138
+
139
+ if !options.ignore_exit_status && (exit_code != options.exit_code)
140
+ log_and_raise(SSHError, message)
141
+ end
142
+ OpenStruct.new(:command => command, :output => output, :exit_code => exit_code, :exit_signal => exit_signal)
143
+ end
144
+
145
+ end
146
+
147
+ end
148
+ end
@@ -0,0 +1,68 @@
1
+ ################################################################################
2
+ #
3
+ # Author: Zachary Patten <zachary@jovelabs.net>
4
+ # Copyright: Copyright (c) Zachary Patten
5
+ # License: Apache License, Version 2.0
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
+ ################################################################################
20
+ module ZTK
21
+ class SSH
22
+
23
+ module Upload
24
+
25
+ # Uploads a local file to a remote host.
26
+ #
27
+ # @param [String] local The local file/path you wish to upload from.
28
+ # @param [String] remote The remote file/path you with to upload to.
29
+ #
30
+ # @example Upload a file:
31
+ # $logger = ZTK::Logger.new(STDOUT)
32
+ # ssh = ZTK::SSH.new
33
+ # ssh.config do |config|
34
+ # config.user = ENV["USER"]
35
+ # config.host_name = "127.0.0.1"
36
+ # end
37
+ # local = File.expand_path(File.join(ENV["HOME"], ".ssh", "id_rsa.pub"))
38
+ # remote = File.expand_path(File.join("/tmp", "id_rsa.pub"))
39
+ # ssh.upload(local, remote)
40
+ def upload(local, remote)
41
+ config.ui.logger.debug { "config=#{config.send(:table).inspect}" }
42
+ config.ui.logger.info { "upload(#{local.inspect}, #{remote.inspect})" }
43
+
44
+ ZTK::RescueRetry.try(:tries => 3, :on => EOFError) do
45
+ @sftp = Net::SFTP.start(config.host_name, config.user, ssh_options)
46
+ sftp.upload!(local.to_s, remote.to_s) do |event, uploader, *args|
47
+ case event
48
+ when :open
49
+ config.ui.logger.debug { "upload(#{args[0].local} -> #{args[0].remote})" }
50
+ when :close
51
+ config.ui.logger.debug { "close(#{args[0].remote})" }
52
+ when :mkdir
53
+ config.ui.logger.debug { "mkdir(#{args[0]})" }
54
+ when :put
55
+ config.ui.logger.debug { "put(#{args[0].remote}, size #{args[2].size} bytes, offset #{args[1]})" }
56
+ when :finish
57
+ config.ui.logger.debug { "finish" }
58
+ end
59
+ end
60
+ end
61
+
62
+ true
63
+ end
64
+
65
+ end
66
+
67
+ end
68
+ end
data/lib/ztk/ssh.rb CHANGED
@@ -84,7 +84,6 @@ module ZTK
84
84
  #
85
85
  # @author Zachary Patten <zachary@jovelabs.net>
86
86
  class SSH < ZTK::Base
87
-
88
87
  # Exit Signal Mappings
89
88
  EXIT_SIGNALS = {
90
89
  1 => "SIGHUP",
@@ -116,6 +115,18 @@ module ZTK
116
115
  27 => "SIGPROF"
117
116
  }
118
117
 
118
+ autoload :Bootstrap, 'ztk/ssh/bootstrap'
119
+ autoload :Command, 'ztk/ssh/command'
120
+ autoload :Download, 'ztk/ssh/download'
121
+ autoload :Exec, 'ztk/ssh/exec'
122
+ autoload :Upload, 'ztk/ssh/upload'
123
+
124
+ include ZTK::SSH::Bootstrap
125
+ include ZTK::SSH::Command
126
+ include ZTK::SSH::Download
127
+ include ZTK::SSH::Exec
128
+ include ZTK::SSH::Upload
129
+
119
130
  # @param [Hash] configuration Configuration options hash.
120
131
  # @option config [String] :host_name Server hostname to connect to.
121
132
  # @option config [String] :user Username to use for authentication.
@@ -185,254 +196,9 @@ module ZTK
185
196
  Kernel.exec(console_command)
186
197
  end
187
198
 
188
- # Executes a command on the remote host.
189
- #
190
- # @param [String] command The command to execute.
191
- # @param [Hash] options The options hash for executing the command.
192
- # @option options [Boolean] :silence Squelch output to STDOUT and STDERR.
193
- # If the log level is :debug, STDOUT and STDERR will go to the log file
194
- # regardless of this setting. STDOUT and STDERR are always returned in
195
- # the output return value regardless of this setting.
196
- #
197
- # @return [OpenStruct#output] The output of the command, both STDOUT and
198
- # STDERR.
199
- # @return [OpenStruct#exit] The exit status (i.e. $?).
200
- #
201
- # @example Execute a command:
202
- #
203
- # ssh = ZTK::SSH.new
204
- # ssh.config do |config|
205
- # config.user = ENV["USER"]
206
- # config.host_name = "127.0.0.1"
207
- # end
208
- # puts ssh.exec("hostname").inspect
209
- def exec(command, options={})
210
- options = OpenStruct.new({ :exit_code => 0, :silence => false }.merge(config.send(:table)).merge(options))
211
-
212
- options.ui.logger.debug { "config=#{options.send(:table).inspect}" }
213
- options.ui.logger.debug { "options=#{options.send(:table).inspect}" }
214
- options.ui.logger.info { "exec(#{command.inspect})" }
215
-
216
- output = ""
217
- exit_code = -1
218
- exit_signal = nil
219
- stdout_header = false
220
- stderr_header = false
221
-
222
- begin
223
- Timeout.timeout(options.timeout) do
224
- ZTK::RescueRetry.try(:tries => 3, :on => EOFError) do
225
- @ssh = Net::SSH.start(options.host_name, options.user, ssh_options)
226
-
227
- channel = ssh.open_channel do |chan|
228
- options.ui.logger.debug { "Channel opened." }
229
-
230
- (options.request_pty == true) and chan.request_pty do |ch, success|
231
- if success
232
- options.ui.logger.debug { "PTY obtained." }
233
- else
234
- options.ui.logger.warn { "Could not obtain PTY." }
235
- end
236
- end
237
-
238
- direct_log(:info) { log_header("COMMAND") }
239
- direct_log(:info) { "#{command}\n" }
240
- direct_log(:info) { log_header("OPENED") }
241
-
242
- chan.exec(command) do |ch, success|
243
- success or log_and_raise(SSHError, "Could not execute '#{command}'.")
244
-
245
- ch.on_data do |c, data|
246
- if !stdout_header
247
- direct_log(:info) { log_header("STDOUT") }
248
- stdout_header = true
249
- stderr_header = false
250
- end
251
- direct_log(:info) { data }
252
-
253
- options.ui.stdout.print(data) unless options.silence
254
- output += data
255
- end
256
-
257
- ch.on_extended_data do |c, type, data|
258
- if !stderr_header
259
- direct_log(:warn) { log_header("STDERR") }
260
- stderr_header = true
261
- stdout_header = false
262
- end
263
- direct_log(:warn) { data }
264
-
265
- options.ui.stderr.print(data) unless options.silence
266
- output += data
267
- end
268
-
269
- ch.on_request("exit-status") do |ch, data|
270
- exit_code = data.read_long
271
- end
272
-
273
- ch.on_request("exit-signal") do |ch, data|
274
- exit_signal = data.read_long
275
- end
276
-
277
- ch.on_open_failed do |c, code, desc|
278
- options.ui.logger.fatal { "Open failed! (#{code.inspect} - #{desc.inspect})" }
279
- end
280
-
281
- end
282
- end
283
- channel.wait
284
-
285
- direct_log(:info) { log_header("CLOSED") }
286
- options.ui.logger.debug { "Channel closed." }
287
- end
288
- end
289
-
290
- rescue Timeout::Error => e
291
- direct_log(:fatal) { log_header("TIMEOUT") }
292
- log_and_raise(SSHError, "Session timed out after #{options.timeout} seconds!")
293
- end
294
-
295
- message = [
296
- "exit_code=#{exit_code}",
297
- (exit_signal.nil? ? nil : "exit_signal=#{exit_signal} (#{EXIT_SIGNALS[exit_signal]})")
298
- ].compact.join(", ")
299
-
300
- options.ui.logger.debug { message }
301
-
302
- if !options.ignore_exit_status && (exit_code != options.exit_code)
303
- log_and_raise(SSHError, message)
304
- end
305
- OpenStruct.new(:command => command, :output => output, :exit_code => exit_code, :exit_signal => exit_signal)
306
- end
307
-
308
- # Uploads a local file to a remote host.
309
- #
310
- # @param [String] local The local file/path you wish to upload from.
311
- # @param [String] remote The remote file/path you with to upload to.
312
- #
313
- # @example Upload a file:
314
- # $logger = ZTK::Logger.new(STDOUT)
315
- # ssh = ZTK::SSH.new
316
- # ssh.config do |config|
317
- # config.user = ENV["USER"]
318
- # config.host_name = "127.0.0.1"
319
- # end
320
- # local = File.expand_path(File.join(ENV["HOME"], ".ssh", "id_rsa.pub"))
321
- # remote = File.expand_path(File.join("/tmp", "id_rsa.pub"))
322
- # ssh.upload(local, remote)
323
- def upload(local, remote)
324
- config.ui.logger.debug { "config=#{config.send(:table).inspect}" }
325
- config.ui.logger.info { "upload(#{local.inspect}, #{remote.inspect})" }
326
-
327
- ZTK::RescueRetry.try(:tries => 3, :on => EOFError) do
328
- @sftp = Net::SFTP.start(config.host_name, config.user, ssh_options)
329
- sftp.upload!(local.to_s, remote.to_s) do |event, uploader, *args|
330
- case event
331
- when :open
332
- config.ui.logger.debug { "upload(#{args[0].local} -> #{args[0].remote})" }
333
- when :close
334
- config.ui.logger.debug { "close(#{args[0].remote})" }
335
- when :mkdir
336
- config.ui.logger.debug { "mkdir(#{args[0]})" }
337
- when :put
338
- config.ui.logger.debug { "put(#{args[0].remote}, size #{args[2].size} bytes, offset #{args[1]})" }
339
- when :finish
340
- config.ui.logger.debug { "finish" }
341
- end
342
- end
343
- end
344
-
345
- true
346
- end
347
-
348
- # Downloads a remote file to the local host.
349
- #
350
- # @param [String] remote The remote file/path you with to download from.
351
- # @param [String] local The local file/path you wish to download to.
352
- #
353
- # @example Download a file:
354
- # $logger = ZTK::Logger.new(STDOUT)
355
- # ssh = ZTK::SSH.new
356
- # ssh.config do |config|
357
- # config.user = ENV["USER"]
358
- # config.host_name = "127.0.0.1"
359
- # end
360
- # local = File.expand_path(File.join("/tmp", "id_rsa.pub"))
361
- # remote = File.expand_path(File.join(ENV["HOME"], ".ssh", "id_rsa.pub"))
362
- # ssh.download(remote, local)
363
- def download(remote, local)
364
- config.ui.logger.debug { "config=#{config.send(:table).inspect}" }
365
- config.ui.logger.info { "download(#{remote.inspect}, #{local.inspect})" }
366
-
367
- ZTK::RescueRetry.try(:tries => 3, :on => EOFError) do
368
- @sftp = Net::SFTP.start(config.host_name, config.user, ssh_options)
369
- sftp.download!(remote.to_s, local.to_s) do |event, downloader, *args|
370
- case event
371
- when :open
372
- config.ui.logger.debug { "download(#{args[0].remote} -> #{args[0].local})" }
373
- when :close
374
- config.ui.logger.debug { "close(#{args[0].local})" }
375
- when :mkdir
376
- config.ui.logger.debug { "mkdir(#{args[0]})" }
377
- when :get
378
- config.ui.logger.debug { "get(#{args[0].remote}, size #{args[2].size} bytes, offset #{args[1]})" }
379
- when :finish
380
- config.ui.logger.debug { "finish" }
381
- end
382
- end
383
- end
384
-
385
- true
386
- end
387
-
388
199
 
389
200
  private
390
201
 
391
- # Builds our SSH console command.
392
- def console_command
393
- command = [ "/usr/bin/env ssh" ]
394
- command << [ "-q" ]
395
- command << [ "-4" ]
396
- command << [ "-x" ]
397
- command << [ "-a" ]
398
- command << [ "-o", "UserKnownHostsFile=/dev/null" ]
399
- command << [ "-o", "StrictHostKeyChecking=no" ]
400
- command << [ "-o", "KeepAlive=yes" ]
401
- command << [ "-o", "ServerAliveInterval=60" ]
402
- command << [ "-o", %(ProxyCommand="#{proxy_command}") ] if config.proxy_host_name
403
- command << [ "-i", config.keys ] if config.keys
404
- command << [ "-p", config.port ] if config.port
405
- # command << [ "-vv" ]
406
- command << "#{config.user}@#{config.host_name}"
407
- command = command.flatten.compact.join(' ')
408
- config.ui.logger.debug { "console_command(#{command.inspect})" }
409
- command
410
- end
411
-
412
- # Builds our SSH proxy command.
413
- def proxy_command
414
- !config.proxy_user and log_and_raise(SSHError, "You must specify an proxy user in order to SSH proxy.")
415
- !config.proxy_host_name and log_and_raise(SSHError, "You must specify an proxy host_name in order to SSH proxy.")
416
-
417
- command = ["/usr/bin/env ssh"]
418
- command << [ "-q" ]
419
- command << [ "-4" ]
420
- command << [ "-x" ]
421
- command << [ "-a" ]
422
- command << [ "-o", "UserKnownHostsFile=/dev/null" ]
423
- command << [ "-o", "StrictHostKeyChecking=no" ]
424
- command << [ "-o", "KeepAlive=yes" ]
425
- command << [ "-o", "ServerAliveInterval=60" ]
426
- command << [ "-i", config.proxy_keys ] if config.proxy_keys
427
- command << [ "-p", config.proxy_port ] if config.proxy_port
428
- # command << [ "-vv" ]
429
- command << "#{config.proxy_user}@#{config.proxy_host_name}"
430
- command << "'/usr/bin/env nc %h %p'"
431
- command = command.flatten.compact.join(' ')
432
- config.ui.logger.debug { "proxy_command(#{command.inspect})" }
433
- command
434
- end
435
-
436
202
  # Builds our SSH options hash.
437
203
  def ssh_options
438
204
  options = {}
data/lib/ztk/template.rb CHANGED
@@ -57,6 +57,29 @@ module ZTK
57
57
  render_template(load_template(template), context)
58
58
  end
59
59
 
60
+ # Renders a "DO NOT EDIT" notice for placement in generated files.
61
+ #
62
+ # @param [Hash] options Options hash.
63
+ # @option options [String] :message An optional message to display in the notice.
64
+ # @option options [String] :char The comment character; defaults to '#'.
65
+ #
66
+ # @return [String] The rendered noticed.
67
+ def do_not_edit_notice(options={})
68
+ message = options[:message]
69
+ char = (options[:char] || '#')
70
+ notice = Array.new
71
+
72
+ notice << char
73
+ notice << "#{char} WARNING: AUTOMATICALLY GENERATED FILE; DO NOT EDIT!"
74
+ notice << char
75
+ notice << "#{char} #{message}" if !message.nil?
76
+ notice << char
77
+ notice << "#{char} Generated @ #{Time.now.utc}"
78
+ notice << char
79
+
80
+ notice.join("\n")
81
+ end
82
+
60
83
 
61
84
  private
62
85
 
data/lib/ztk/version.rb CHANGED
@@ -21,6 +21,6 @@
21
21
  module ZTK
22
22
 
23
23
  # ZTK Version String
24
- VERSION = "1.1.2"
24
+ VERSION = "1.2.0"
25
25
 
26
26
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ztk
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.2
4
+ version: 1.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-04-25 00:00:00.000000000 Z
12
+ date: 2013-04-27 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: erubis
@@ -200,6 +200,11 @@ files:
200
200
  - lib/ztk/rescue_retry.rb
201
201
  - lib/ztk/spinner.rb
202
202
  - lib/ztk/ssh.rb
203
+ - lib/ztk/ssh/bootstrap.rb
204
+ - lib/ztk/ssh/command.rb
205
+ - lib/ztk/ssh/download.rb
206
+ - lib/ztk/ssh/exec.rb
207
+ - lib/ztk/ssh/upload.rb
203
208
  - lib/ztk/tcp_socket_check.rb
204
209
  - lib/ztk/template.rb
205
210
  - lib/ztk/ui.rb
@@ -240,7 +245,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
240
245
  version: '0'
241
246
  segments:
242
247
  - 0
243
- hash: -647383041021827862
248
+ hash: 1781664085234422223
244
249
  required_rubygems_version: !ruby/object:Gem::Requirement
245
250
  none: false
246
251
  requirements:
@@ -249,7 +254,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
249
254
  version: '0'
250
255
  segments:
251
256
  - 0
252
- hash: -647383041021827862
257
+ hash: 1781664085234422223
253
258
  requirements: []
254
259
  rubyforge_project:
255
260
  rubygems_version: 1.8.25