rye 0.3
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/CHANGES.txt +26 -0
- data/LICENSE.txt +19 -0
- data/README.rdoc +176 -0
- data/Rakefile +83 -0
- data/bin/try +148 -0
- data/lib/esc.rb +301 -0
- data/lib/rye.rb +155 -0
- data/lib/rye/box.rb +312 -0
- data/lib/rye/cmd.rb +47 -0
- data/lib/rye/rap.rb +83 -0
- data/lib/rye/set.rb +145 -0
- data/lib/sys.rb +274 -0
- data/rye.gemspec +56 -0
- data/test/10_rye_test.rb +63 -0
- metadata +90 -0
data/lib/sys.rb
ADDED
@@ -0,0 +1,274 @@
|
|
1
|
+
require 'socket'
|
2
|
+
|
3
|
+
# SystemInfo
|
4
|
+
#
|
5
|
+
# A container for the platform specific system information.
|
6
|
+
# Portions of this code were originally from Amazon's EC2 AMI tools,
|
7
|
+
# specifically lib/platform.rb.
|
8
|
+
class SystemInfo #:nodoc:all
|
9
|
+
VERSION = 2
|
10
|
+
IMPLEMENTATIONS = [
|
11
|
+
|
12
|
+
# These are for JRuby, System.getproperty('os.name').
|
13
|
+
# For a list of all values, see: http://lopica.sourceforge.net/os.html
|
14
|
+
[/mac\s*os\s*x/i, :unix, :osx ],
|
15
|
+
[/sunos/i, :unix, :solaris ],
|
16
|
+
[/windows\s*ce/i, :win32, :windows ],
|
17
|
+
[/windows/i, :win32, :windows ],
|
18
|
+
[/osx/i, :unix, :osx ],
|
19
|
+
|
20
|
+
# TODO: implement other windows matches: # /djgpp|(cyg|ms|bcc)win|mingw/ (from mongrel)
|
21
|
+
|
22
|
+
# These are for RUBY_PLATFORM and JRuby
|
23
|
+
[/java/i, :java, :java ],
|
24
|
+
[/darwin/i, :unix, :osx ],
|
25
|
+
[/linux/i, :unix, :linux ],
|
26
|
+
[/freebsd/i, :unix, :freebsd ],
|
27
|
+
[/netbsd/i, :unix, :netbsd ],
|
28
|
+
[/solaris/i, :unix, :solaris ],
|
29
|
+
[/irix/i, :unix, :irix ],
|
30
|
+
[/cygwin/i, :unix, :cygwin ],
|
31
|
+
[/mswin/i, :win32, :windows ],
|
32
|
+
[/mingw/i, :win32, :mingw ],
|
33
|
+
[/bccwin/i, :win32, :bccwin ],
|
34
|
+
[/wince/i, :win32, :wince ],
|
35
|
+
[/vms/i, :vms, :vms ],
|
36
|
+
[/os2/i, :os2, :os2 ],
|
37
|
+
[nil, :unknown, :unknown ],
|
38
|
+
|
39
|
+
]
|
40
|
+
|
41
|
+
ARCHITECTURES = [
|
42
|
+
[/(i\d86)/i, :i386 ],
|
43
|
+
[/x86_64/i, :x86_64 ],
|
44
|
+
[/x86/i, :i386 ], # JRuby
|
45
|
+
[/ia64/i, :ia64 ],
|
46
|
+
[/alpha/i, :alpha ],
|
47
|
+
[/sparc/i, :sparc ],
|
48
|
+
[/mips/i, :mips ],
|
49
|
+
[/powerpc/i, :powerpc ],
|
50
|
+
[/universal/i,:universal ],
|
51
|
+
[nil, :unknown ],
|
52
|
+
]
|
53
|
+
|
54
|
+
|
55
|
+
|
56
|
+
attr_reader :os
|
57
|
+
attr_reader :implementation
|
58
|
+
attr_reader :architecture
|
59
|
+
attr_reader :hostname
|
60
|
+
attr_reader :ipaddress
|
61
|
+
attr_reader :uptime
|
62
|
+
|
63
|
+
|
64
|
+
alias :impl :implementation
|
65
|
+
alias :arch :architecture
|
66
|
+
|
67
|
+
|
68
|
+
def initialize
|
69
|
+
@os, @implementation, @architecture = guess
|
70
|
+
@hostname, @ipaddress, @uptime = get_info
|
71
|
+
end
|
72
|
+
|
73
|
+
# guess
|
74
|
+
#
|
75
|
+
# This is called at require-time in stella.rb. It guesses
|
76
|
+
# the current operating system, implementation, architecture.
|
77
|
+
# Returns [os, impl, arch]
|
78
|
+
def guess
|
79
|
+
os = :unknown
|
80
|
+
impl = :unknown
|
81
|
+
arch = :unknown
|
82
|
+
IMPLEMENTATIONS.each do |r, o, i|
|
83
|
+
if r and RUBY_PLATFORM =~ r
|
84
|
+
os, impl = [o, i]
|
85
|
+
break
|
86
|
+
end
|
87
|
+
end
|
88
|
+
ARCHITECTURES.each do |r, a|
|
89
|
+
if r and RUBY_PLATFORM =~ r
|
90
|
+
arch = a
|
91
|
+
break
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
#
|
96
|
+
if os == :win32
|
97
|
+
#require 'Win32API'
|
98
|
+
|
99
|
+
# If we're running in java, we'll need to look elsewhere
|
100
|
+
# for the implementation and architecture.
|
101
|
+
# We'll replace IMPL and ARCH with what we find.
|
102
|
+
elsif os == :java
|
103
|
+
require 'java'
|
104
|
+
include_class java.lang.System
|
105
|
+
|
106
|
+
osname = System.getProperty("os.name")
|
107
|
+
IMPLEMENTATIONS.each do |r, o, i|
|
108
|
+
if r and osname =~ r
|
109
|
+
impl = i
|
110
|
+
break
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
osarch = System.getProperty("os.arch")
|
115
|
+
ARCHITECTURES.each do |r, a|
|
116
|
+
if r and osarch =~ r
|
117
|
+
arch = a
|
118
|
+
break
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
123
|
+
|
124
|
+
[os, impl, arch]
|
125
|
+
end
|
126
|
+
|
127
|
+
# get_info
|
128
|
+
#
|
129
|
+
# Returns [hostname, ipaddr, uptime] for the local machine
|
130
|
+
def get_info
|
131
|
+
hostname = :unknown
|
132
|
+
ipaddr = :unknown
|
133
|
+
uptime = :unknown
|
134
|
+
|
135
|
+
begin
|
136
|
+
hostname = local_hostname
|
137
|
+
ipaddr = local_ip_address
|
138
|
+
uptime = local_uptime
|
139
|
+
rescue => ex
|
140
|
+
# Be silent!
|
141
|
+
end
|
142
|
+
|
143
|
+
[hostname, ipaddr, uptime]
|
144
|
+
end
|
145
|
+
|
146
|
+
# local_hostname
|
147
|
+
#
|
148
|
+
# Return the hostname for the local machine
|
149
|
+
def local_hostname
|
150
|
+
Socket.gethostname
|
151
|
+
end
|
152
|
+
|
153
|
+
# local_uptime
|
154
|
+
#
|
155
|
+
# Returns the local uptime in hours. Use Win32API in Windows,
|
156
|
+
# 'sysctl -b kern.boottime' os osx, and 'who -b' on unix.
|
157
|
+
# Based on Ruby Quiz solutions by: Matthias Reitinger
|
158
|
+
# On Windows, see also: net statistics server
|
159
|
+
def local_uptime
|
160
|
+
|
161
|
+
# Each method must return uptime in seconds
|
162
|
+
methods = {
|
163
|
+
|
164
|
+
:win32_windows => lambda {
|
165
|
+
# Win32API is required in self.guess
|
166
|
+
getTickCount = Win32API.new("kernel32", "GetTickCount", nil, 'L')
|
167
|
+
((getTickCount.call()).to_f / 1000).to_f
|
168
|
+
},
|
169
|
+
|
170
|
+
# Ya, this is kinda wack. Ruby -> Java -> Kernel32. See:
|
171
|
+
# http://www.oreillynet.com/ruby/blog/2008/01/jruby_meets_the_windows_api_1.html
|
172
|
+
# http://msdn.microsoft.com/en-us/library/ms724408(VS.85).aspx
|
173
|
+
# Ruby 1.9.1: Win32API is now deprecated in favor of using the DL library.
|
174
|
+
:java_windows => lambda {
|
175
|
+
kernel32 = com.sun.jna.NativeLibrary.getInstance('kernel32')
|
176
|
+
buf = java.nio.ByteBuffer.allocate(256)
|
177
|
+
(kernel32.getFunction('GetTickCount').invokeInt([256, buf].to_java).to_f / 1000).to_f
|
178
|
+
},
|
179
|
+
|
180
|
+
:unix_osx => lambda {
|
181
|
+
# This is faster than who and could work on BSD also.
|
182
|
+
(Time.now.to_f - Time.at(`sysctl -b kern.boottime 2>/dev/null`.unpack('L').first).to_f).to_f
|
183
|
+
},
|
184
|
+
# This should work for most unix flavours.
|
185
|
+
:unix => lambda {
|
186
|
+
# who is sloooooow. Use File.read('/proc/uptime')
|
187
|
+
(Time.now.to_f - Time.parse(`who -b 2>/dev/null`).to_f)
|
188
|
+
}
|
189
|
+
}
|
190
|
+
|
191
|
+
hours = 0
|
192
|
+
|
193
|
+
begin
|
194
|
+
key = platform
|
195
|
+
method = (methods.has_key? key) ? methods[key] : methods[:unix]
|
196
|
+
hours = (method.call) / 3600 # seconds to hours
|
197
|
+
rescue => ex
|
198
|
+
end
|
199
|
+
hours
|
200
|
+
end
|
201
|
+
|
202
|
+
|
203
|
+
#
|
204
|
+
# Return the local IP address which receives external traffic
|
205
|
+
# from: http://coderrr.wordpress.com/2008/05/28/get-your-local-ip-address/
|
206
|
+
# NOTE: This <em>does not</em> open a connection to the IP address.
|
207
|
+
def local_ip_address
|
208
|
+
# turn off reverse DNS resolution temporarily
|
209
|
+
orig, Socket.do_not_reverse_lookup = Socket.do_not_reverse_lookup, true
|
210
|
+
UDPSocket.open {|s| s.connect('75.101.137.7', 1); s.addr.last } # Solutious IP
|
211
|
+
ensure
|
212
|
+
Socket.do_not_reverse_lookup = orig
|
213
|
+
end
|
214
|
+
|
215
|
+
#
|
216
|
+
# Returns the local IP address based on the hostname.
|
217
|
+
# According to coderrr (see comments on blog link above), this implementation
|
218
|
+
# doesn't guarantee that it will return the address for the interface external
|
219
|
+
# traffic goes through. It's also possible the hostname isn't resolvable to the
|
220
|
+
# local IP.
|
221
|
+
def local_ip_address_alt
|
222
|
+
ipaddr = :unknown
|
223
|
+
begin
|
224
|
+
saddr = Socket.getaddrinfo( Socket.gethostname, nil, Socket::AF_UNSPEC, Socket::SOCK_STREAM, nil, Socket::AI_CANONNAME)
|
225
|
+
ipaddr = saddr.select{|type| type[0] == 'AF_INET' }[0][3]
|
226
|
+
rescue => ex
|
227
|
+
end
|
228
|
+
ipaddr
|
229
|
+
end
|
230
|
+
|
231
|
+
# returns a symbol in the form: os_implementation. This is used throughout Stella
|
232
|
+
# for platform specific support.
|
233
|
+
def platform
|
234
|
+
"#{@os}_#{@implementation}".to_sym
|
235
|
+
end
|
236
|
+
|
237
|
+
# Returns Ruby version as an array
|
238
|
+
def ruby
|
239
|
+
RUBY_VERSION.split('.').map { |v| v.to_i }
|
240
|
+
end
|
241
|
+
|
242
|
+
# Returns the environment PATH as an Array
|
243
|
+
def paths
|
244
|
+
if @os == :unix
|
245
|
+
(ENV['PATH'] || '').split(':')
|
246
|
+
elsif
|
247
|
+
(ENV['PATH'] || '').split(';') # Note tested!
|
248
|
+
else
|
249
|
+
raise "paths not implemented for: #{@os}"
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
def user
|
254
|
+
ENV['USER']
|
255
|
+
end
|
256
|
+
|
257
|
+
def home
|
258
|
+
if @os == :unix
|
259
|
+
File.expand_path(ENV['HOME'])
|
260
|
+
elsif @os == :win32
|
261
|
+
File.expand_path(ENV['USERPROFILE'])
|
262
|
+
else
|
263
|
+
raise "paths not implemented for: #{@os}"
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
# Print friendly system information.
|
268
|
+
def to_s
|
269
|
+
sprintf("Hostname: %s#{$/}IP Address: %s#{$/}System: %s#{$/}Uptime: %.2f (hours)#{$/}Ruby: #{ruby.join('.')}",
|
270
|
+
@hostname, @ipaddress, "#{@os}-#{@implementation}-#{@architecture}", @uptime)
|
271
|
+
end
|
272
|
+
|
273
|
+
|
274
|
+
end
|
data/rye.gemspec
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
@spec = Gem::Specification.new do |s|
|
2
|
+
s.name = "rye"
|
3
|
+
s.rubyforge_project = "rye"
|
4
|
+
s.version = "0.3"
|
5
|
+
s.summary = "Rye: Run system commands via SSH locally and remotely in a Ruby way."
|
6
|
+
s.description = s.summary
|
7
|
+
s.author = "Delano Mandelbaum"
|
8
|
+
s.email = "delano@solutious.com"
|
9
|
+
s.homepage = "http://solutious.com/"
|
10
|
+
|
11
|
+
# = DEPENDENCIES =
|
12
|
+
# Add all gem dependencies
|
13
|
+
s.add_dependency 'net-ssh'
|
14
|
+
s.add_dependency 'highline'
|
15
|
+
|
16
|
+
# = MANIFEST =
|
17
|
+
# The complete list of files to be included in the release. When GitHub packages your gem,
|
18
|
+
# it doesn't allow you to run any command that accesses the filesystem. You will get an
|
19
|
+
# error. You can ask your VCS for the list of versioned files:
|
20
|
+
# git ls-files
|
21
|
+
# svn list -R
|
22
|
+
s.files = %w(
|
23
|
+
CHANGES.txt
|
24
|
+
LICENSE.txt
|
25
|
+
README.rdoc
|
26
|
+
Rakefile
|
27
|
+
bin/try
|
28
|
+
lib/esc.rb
|
29
|
+
lib/rye.rb
|
30
|
+
lib/rye/box.rb
|
31
|
+
lib/rye/cmd.rb
|
32
|
+
lib/rye/rap.rb
|
33
|
+
lib/rye/set.rb
|
34
|
+
lib/sys.rb
|
35
|
+
rye.gemspec
|
36
|
+
test/10_rye_test.rb
|
37
|
+
)
|
38
|
+
|
39
|
+
# = EXECUTABLES =
|
40
|
+
# The list of executables in your project (if any). Don't include the path,
|
41
|
+
# just the base filename.
|
42
|
+
s.executables = %w[try]
|
43
|
+
|
44
|
+
|
45
|
+
s.extra_rdoc_files = %w[README.rdoc LICENSE.txt]
|
46
|
+
s.has_rdoc = true
|
47
|
+
s.rdoc_options = ["--line-numbers", "--title", s.summary, "--main", "README.rdoc"]
|
48
|
+
s.require_paths = %w[lib]
|
49
|
+
s.rubygems_version = '1.3.0'
|
50
|
+
|
51
|
+
if s.respond_to? :specification_version then
|
52
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
53
|
+
s.specification_version = 2
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
data/test/10_rye_test.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
#
|
4
|
+
# Usage: test/10_rye_test.rb
|
5
|
+
#
|
6
|
+
|
7
|
+
$:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
|
8
|
+
|
9
|
+
require 'benchmark'
|
10
|
+
require 'rubygems'
|
11
|
+
require 'stringio'
|
12
|
+
require 'yaml'
|
13
|
+
require 'rye'
|
14
|
+
|
15
|
+
|
16
|
+
machine_key = {
|
17
|
+
:host => 'ryehost',
|
18
|
+
:user => "root",
|
19
|
+
:key => '/proj/git/rudy/.rudy/key-test-app.private'
|
20
|
+
}
|
21
|
+
|
22
|
+
machine_pass = {
|
23
|
+
:host => 'ryehost',
|
24
|
+
:user => 'pablo',
|
25
|
+
:pass => 'pablo9001'
|
26
|
+
}
|
27
|
+
|
28
|
+
machine_local = {
|
29
|
+
:host => "localhost"
|
30
|
+
}
|
31
|
+
|
32
|
+
rbox_key = Rye::Box.new(machine_key[:host], :user => machine_key[:user], :keys => machine_key[:key])
|
33
|
+
rbox_pass = Rye::Box.new(machine_pass[:host], :user => machine_pass[:user], :password=> machine_pass[:pass])
|
34
|
+
rbox_local = Rye::Box.new(machine_local[:host], :safe => false)
|
35
|
+
|
36
|
+
|
37
|
+
rset_serial = Rye::Set.new("example", :parallel => false) #, :debug => STDOUT
|
38
|
+
rset_parallel = Rye::Set.new("example", :parallel => true)
|
39
|
+
rset_serial.add_boxes(rbox_key, rbox_local, rbox_pass)
|
40
|
+
rset_parallel.add_boxes(rbox_key, rbox_local, rbox_pass)
|
41
|
+
|
42
|
+
# The Rehersal will be slower because they'll include the connection time
|
43
|
+
Benchmark.bmbm do |x|
|
44
|
+
x.report('rbox: ') { puts "%10s:%s:%s" % [rbox_key.uname, rbox_local.uname, rbox_pass.uname] }
|
45
|
+
x.report('rset-S:') { puts "%10s:%s:%s" % rset_serial.uname }
|
46
|
+
x.report('rset-P:') { puts "%10s:%s:%s" % rset_parallel.uname }
|
47
|
+
end
|
48
|
+
|
49
|
+
__END__
|
50
|
+
|
51
|
+
#p rset.sleep(1)
|
52
|
+
|
53
|
+
p rbox_remote.echo('$HOME')
|
54
|
+
|
55
|
+
local_files = rbox_local['/tmp/ssh-test'].ls
|
56
|
+
remote_files = rbox_remote['/etc/ssh'].ls
|
57
|
+
diff = remote_files - local_files
|
58
|
+
|
59
|
+
puts "ETC DIFF:"
|
60
|
+
puts diff
|
61
|
+
|
62
|
+
rbox_remote = Rye::Box.new('ec2-75-101-255-188.compute-1.amazonaws.com', :user => 'root', :debug => STDOUT, :safe => false, :keys => '/proj/git/rudy/.rudy/key-test-app.private')
|
63
|
+
|
metadata
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rye
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: "0.3"
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Delano Mandelbaum
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-04-04 00:00:00 -04:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: net-ssh
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: highline
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: "0"
|
34
|
+
version:
|
35
|
+
description: "Rye: Run system commands via SSH locally and remotely in a Ruby way."
|
36
|
+
email: delano@solutious.com
|
37
|
+
executables:
|
38
|
+
- try
|
39
|
+
extensions: []
|
40
|
+
|
41
|
+
extra_rdoc_files:
|
42
|
+
- README.rdoc
|
43
|
+
- LICENSE.txt
|
44
|
+
files:
|
45
|
+
- CHANGES.txt
|
46
|
+
- LICENSE.txt
|
47
|
+
- README.rdoc
|
48
|
+
- Rakefile
|
49
|
+
- bin/try
|
50
|
+
- lib/esc.rb
|
51
|
+
- lib/rye.rb
|
52
|
+
- lib/rye/box.rb
|
53
|
+
- lib/rye/cmd.rb
|
54
|
+
- lib/rye/rap.rb
|
55
|
+
- lib/rye/set.rb
|
56
|
+
- lib/sys.rb
|
57
|
+
- rye.gemspec
|
58
|
+
- test/10_rye_test.rb
|
59
|
+
has_rdoc: true
|
60
|
+
homepage: http://solutious.com/
|
61
|
+
post_install_message:
|
62
|
+
rdoc_options:
|
63
|
+
- --line-numbers
|
64
|
+
- --title
|
65
|
+
- "Rye: Run system commands via SSH locally and remotely in a Ruby way."
|
66
|
+
- --main
|
67
|
+
- README.rdoc
|
68
|
+
require_paths:
|
69
|
+
- lib
|
70
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: "0"
|
75
|
+
version:
|
76
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: "0"
|
81
|
+
version:
|
82
|
+
requirements: []
|
83
|
+
|
84
|
+
rubyforge_project: rye
|
85
|
+
rubygems_version: 1.3.1
|
86
|
+
signing_key:
|
87
|
+
specification_version: 2
|
88
|
+
summary: "Rye: Run system commands via SSH locally and remotely in a Ruby way."
|
89
|
+
test_files: []
|
90
|
+
|