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/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
+