ztk 1.1.2 → 1.2.0

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