rye 0.3

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -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
+