scutil 0.1.2 → 0.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/CHANGELOG +5 -0
- data/README +4 -4
- data/lib/scutil.rb +47 -32
- metadata +4 -22
data/CHANGELOG
CHANGED
data/README
CHANGED
@@ -27,10 +27,10 @@ PTYs is beyond the scope of this documentation.
|
|
27
27
|
|
28
28
|
The "_automatic_" part of PTY requests comes from a regex in
|
29
29
|
Scutil.exec_command. Basically, if _sudo_ is at the start of the
|
30
|
-
command to be executed, scutil will request a PTY.
|
31
|
-
|
32
|
-
can force a PTY request by specifying
|
33
|
-
various _options_ arguments.
|
30
|
+
command to be executed, scutil will request a PTY. This regex is
|
31
|
+
configurable through +:scutil_pty_regex+. In a near future release it
|
32
|
+
will be. You can force a PTY request by specifying
|
33
|
+
+:scutil_force_pty+ in the various _options_ arguments.
|
34
34
|
|
35
35
|
All of this syntactic sugar can be used as a simple class method with
|
36
36
|
Scutil.exec_command, as an instantiable class with Scutil::Exec, or as
|
data/lib/scutil.rb
CHANGED
@@ -23,12 +23,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
23
23
|
THE SOFTWARE.
|
24
24
|
=end
|
25
25
|
|
26
|
-
#begin
|
27
|
-
# require 'rubygems'
|
28
|
-
# gem 'net-ssh', ">= 2.1.0"
|
29
|
-
#rescue LoadError, NameError
|
30
|
-
#end
|
31
|
-
|
32
26
|
require 'net/ssh'
|
33
27
|
|
34
28
|
module Scutil
|
@@ -71,11 +65,13 @@ module Scutil
|
|
71
65
|
end
|
72
66
|
end
|
73
67
|
|
68
|
+
SCUTIL_VERSION = '0.2.0'
|
74
69
|
# By default, buffer 10M of data before writing.
|
75
|
-
|
76
|
-
|
70
|
+
DEFAULT_OUTPUT_BUFFER_SIZE = 0xA00000
|
71
|
+
# Checks for a command starting with _sudo_ by default.
|
72
|
+
DEFAULT_PTY_REGEX = /^\s*sudo/
|
77
73
|
@connection_cache = ConnectionCache.new
|
78
|
-
@
|
74
|
+
@output_buffer_size = DEFAULT_OUTPUT_BUFFER_SIZE
|
79
75
|
|
80
76
|
class << self
|
81
77
|
# All successfully established connections end up here for reuse
|
@@ -83,7 +79,7 @@ module Scutil
|
|
83
79
|
attr_accessor :connection_cache
|
84
80
|
# Set to 10M by default, this can be adjusted to tell scutil when
|
85
81
|
# to write command output to _output_.
|
86
|
-
attr_accessor :
|
82
|
+
attr_accessor :output_buffer_size
|
87
83
|
end
|
88
84
|
|
89
85
|
# Wrapper for each connection to a system. Capabile of holding a
|
@@ -107,7 +103,7 @@ module Scutil
|
|
107
103
|
@options.merge!(options)
|
108
104
|
|
109
105
|
scrub_options @options
|
110
|
-
|
106
|
+
|
111
107
|
if (pty_needed)
|
112
108
|
if !@pty_connection.nil?
|
113
109
|
# Existing PTY connection
|
@@ -139,6 +135,7 @@ module Scutil
|
|
139
135
|
def scrub_options(options)
|
140
136
|
options.delete(:scutil_verbose) if (options.has_key?(:scutil_verbose))
|
141
137
|
options.delete(:scutil_force_pty) if (options.has_key?(:scutil_force_pty))
|
138
|
+
options.delete(:scutil_pty_regex) if (options.has_key?(:scutil_pty_regex))
|
142
139
|
end
|
143
140
|
|
144
141
|
def to_s
|
@@ -182,6 +179,27 @@ module Scutil
|
|
182
179
|
end
|
183
180
|
|
184
181
|
class << self
|
182
|
+
|
183
|
+
# Should we request a PTY? Uses custom regex if defined in
|
184
|
+
# +:scutil_pty_regex+.
|
185
|
+
#
|
186
|
+
def check_pty_needed?(cmd, options, hostname)
|
187
|
+
regex = DEFAULT_PTY_REGEX
|
188
|
+
if (options[:scutil_force_pty].nil?)
|
189
|
+
# If a custom regex has been defined, use it.
|
190
|
+
if (!options[:scutil_regex].nil?)
|
191
|
+
if options[:scutil_regex].kind_of? Regexp
|
192
|
+
regex = options[:scutil_regex]
|
193
|
+
else
|
194
|
+
raise Scutil::Error.new("Error: :scutil_regex must be a kind of Regexp", hostname)
|
195
|
+
end
|
196
|
+
else
|
197
|
+
return (cmd =~ regex) ? true : false
|
198
|
+
end
|
199
|
+
else
|
200
|
+
return options[:scutil_force_pty] ? true : false
|
201
|
+
end
|
202
|
+
end
|
185
203
|
|
186
204
|
# Scutil.exec_command is used to execute a command, specified in
|
187
205
|
# _cmd_, on a remote system. The return value and any ouput of
|
@@ -195,10 +213,10 @@ module Scutil
|
|
195
213
|
#
|
196
214
|
# <em>**NB:* This isn't actually true. The only check made is to
|
197
215
|
# see if _output_ responds to +:write+. The idea being that not
|
198
|
-
# only will a file handle have a +write+ method but also
|
199
|
-
# like +StringIO+. Using +StringIO+ here makes it easy
|
200
|
-
# the command's output in a string. Suggestions on a
|
201
|
-
# to do this are definitely welcome.</em>
|
216
|
+
# only will a file handle have a +write+ method, but also
|
217
|
+
# something like +StringIO+. Using +StringIO+ here makes it easy
|
218
|
+
# to capture the command's output in a string. Suggestions on a
|
219
|
+
# better way to do this are definitely welcome.</em>
|
202
220
|
#
|
203
221
|
# Scutil will automatically request a PTY if _sudo_ is at the
|
204
222
|
# start of _cmd_. Right now the regex that drives this isn't
|
@@ -209,7 +227,9 @@ module Scutil
|
|
209
227
|
# Scutil.exec_command takes the following options:
|
210
228
|
#
|
211
229
|
# * :scutil_verbose => Extra output.
|
212
|
-
# * :scutil_force_pty =>
|
230
|
+
# * :scutil_force_pty => Force a PTY request (or not) for every channel.
|
231
|
+
# * :scutil_pty_regex => Specific a custom regex here for use when
|
232
|
+
# scutil decides whether or not to request a PTY.
|
213
233
|
#
|
214
234
|
# In addition, any other options passed Scutil.exec_command will
|
215
235
|
# be passed on to Net::SSH, _except_ those prefixed with
|
@@ -223,13 +243,8 @@ module Scutil
|
|
223
243
|
#
|
224
244
|
def exec_command(hostname, username, cmd, output=nil, options={})
|
225
245
|
# Do we need a PTY?
|
226
|
-
|
227
|
-
|
228
|
-
pty_needed = (cmd =~ /^\s*sudo/) ? true : false
|
229
|
-
else
|
230
|
-
pty_needed = options[:scutil_force_pty] ? true : false
|
231
|
-
end
|
232
|
-
|
246
|
+
pty_needed = check_pty_needed? cmd, options, hostname
|
247
|
+
|
233
248
|
# Check for an existing connection in the cache based on the hostname. If the
|
234
249
|
# hostname exists find a suitable connection.
|
235
250
|
conn = nil
|
@@ -251,7 +266,7 @@ module Scutil
|
|
251
266
|
fh = $stdout
|
252
267
|
if (output.nil?)
|
253
268
|
fh = $stdout
|
254
|
-
elsif (output.respond_to?
|
269
|
+
elsif (output.respond_to? :write)
|
255
270
|
# XXX: This may not be a safe assumuption...
|
256
271
|
fh = output
|
257
272
|
elsif (output.class == String)
|
@@ -264,22 +279,22 @@ module Scutil
|
|
264
279
|
odata = ""
|
265
280
|
edata = ""
|
266
281
|
exit_status = 0
|
267
|
-
|
282
|
+
chan = conn.open_channel do |channel|
|
268
283
|
$stderr.print "[#{conn.host}:#{channel.local_id}] Setting up callbacks...\n" if options[:scutil_verbose]
|
269
284
|
if (pty_needed)
|
270
285
|
$stderr.print "[#{conn.host}:#{channel.local_id}] Requesting PTY...\n" if options[:scutil_verbose]
|
271
|
-
# OPOST
|
286
|
+
# OPOST is necessary, CS8 makes sense. Revisit after broader testing.
|
272
287
|
channel.request_pty(:modes => { Net::SSH::Connection::Term::CS8 => 1, Net::SSH::Connection::Term::OPOST => 0 } ) do |ch, success|
|
273
288
|
raise Scutil::Error.new("Failed to get a PTY", hostname) if !success
|
274
289
|
end
|
275
290
|
end
|
276
|
-
|
291
|
+
|
277
292
|
channel.on_data do |ch, data|
|
278
293
|
# $stderr.print "on_data: #{data.size}\n" if options[:scutil_verbose]
|
279
294
|
odata += data
|
280
295
|
|
281
|
-
# Only buffer some of the output before writing to disk.
|
282
|
-
if (odata.size >=
|
296
|
+
# Only buffer some of the output before writing to disk (10M by default).
|
297
|
+
if (odata.size >= Scutil.output_buffer_size)
|
283
298
|
fh.write odata
|
284
299
|
odata = ""
|
285
300
|
end
|
@@ -318,9 +333,9 @@ module Scutil
|
|
318
333
|
end
|
319
334
|
end
|
320
335
|
|
321
|
-
# def xfer_file(hostname, username, src, dst, direction=:to, command=nil, options={})
|
322
|
-
|
323
|
-
# end
|
336
|
+
# def xfer_file(hostname, username, src, dst, direction=:to, command=nil, options={})
|
337
|
+
|
338
|
+
# end
|
324
339
|
end
|
325
340
|
|
326
341
|
# Exception class for scutil. The system, error message, and return
|
metadata
CHANGED
@@ -1,13 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: scutil
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 1
|
9
|
-
- 2
|
10
|
-
version: 0.1.2
|
4
|
+
prerelease:
|
5
|
+
version: 0.2.0
|
11
6
|
platform: ruby
|
12
7
|
authors:
|
13
8
|
- Marc Soda
|
@@ -15,8 +10,7 @@ autorequire:
|
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
12
|
|
18
|
-
date: 2011-09-
|
19
|
-
default_executable:
|
13
|
+
date: 2011-09-20 00:00:00 Z
|
20
14
|
dependencies:
|
21
15
|
- !ruby/object:Gem::Dependency
|
22
16
|
name: net-ssh
|
@@ -26,11 +20,6 @@ dependencies:
|
|
26
20
|
requirements:
|
27
21
|
- - ">="
|
28
22
|
- !ruby/object:Gem::Version
|
29
|
-
hash: 11
|
30
|
-
segments:
|
31
|
-
- 2
|
32
|
-
- 1
|
33
|
-
- 0
|
34
23
|
version: 2.1.0
|
35
24
|
type: :runtime
|
36
25
|
version_requirements: *id001
|
@@ -49,7 +38,6 @@ files:
|
|
49
38
|
- README
|
50
39
|
- THANKS
|
51
40
|
- CHANGELOG
|
52
|
-
has_rdoc: true
|
53
41
|
homepage: http://marcantonio.github.com/scutil
|
54
42
|
licenses:
|
55
43
|
- MIT
|
@@ -64,23 +52,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
64
52
|
requirements:
|
65
53
|
- - ">="
|
66
54
|
- !ruby/object:Gem::Version
|
67
|
-
hash: 3
|
68
|
-
segments:
|
69
|
-
- 0
|
70
55
|
version: "0"
|
71
56
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
72
57
|
none: false
|
73
58
|
requirements:
|
74
59
|
- - ">="
|
75
60
|
- !ruby/object:Gem::Version
|
76
|
-
hash: 3
|
77
|
-
segments:
|
78
|
-
- 0
|
79
61
|
version: "0"
|
80
62
|
requirements: []
|
81
63
|
|
82
64
|
rubyforge_project:
|
83
|
-
rubygems_version: 1.
|
65
|
+
rubygems_version: 1.8.10
|
84
66
|
signing_key:
|
85
67
|
specification_version: 3
|
86
68
|
summary: SSH Command UTILity
|