frontier 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,2 @@
1
+
2
+ You may not use this software. At all.
data/README.md ADDED
@@ -0,0 +1,74 @@
1
+
2
+ Ruby sans frontiers
3
+ -------------------
4
+
5
+ A cross-host ruby bridge. Allows you to create and operate on objects
6
+ created in ruby runtimes on remote hosts. Frontier uses an ssh connection
7
+ and tunnels serializes method calls and replies through it. It's inspired
8
+ by Rush, but without the limitation of needing a server process running on
9
+ the remote host.
10
+
11
+ In its pure form, the shell simply forwards all missing methods to the unix
12
+ shell (bash or whatever you use). But you can extend the shell through
13
+ a system of mixins. There's a few builtin mixins, and you can write your own.
14
+
15
+
16
+ Mixins
17
+ ------
18
+
19
+ * Filesystem: the 'filesystem' mixin provides the method `#[](glob)` which
20
+ returns an array of Pathname objects.
21
+
22
+ * Process: the 'process' mixin provides the method 'process' which uses
23
+ PQL internally to enumerate or find processes.
24
+
25
+
26
+ Limitations
27
+ -----------
28
+
29
+ Frontier uses Marshal internally to serialize objects and Marshal has certain
30
+ limitations which objects it can serialize. For example it can't serialize
31
+ Proc objects, bindings or IO objects. So you need to pay attention where the
32
+ object you created lives, whether on the local or remote host.
33
+
34
+ For example this won't work:
35
+
36
+ server.process.where(:command => /ruby/).each {|p| puts p }
37
+
38
+ But this will
39
+
40
+ server.process.where(:command => /ruby/).all.each {|p| puts p }
41
+
42
+ This is because where() returns a Plucky::Query object which lives on the
43
+ server, so passing a proc to it doesn't work. but where().all() returns an
44
+ Array which is lives in the process space on the local host and you can treat
45
+ it just like any other array.
46
+
47
+
48
+ Example
49
+ -------
50
+
51
+ require 'frontier'
52
+
53
+ server = Frontier::Shell.new('user@server.tld')
54
+
55
+ puts server.uname
56
+ puts server.ls '*.rb'
57
+
58
+ server.load('filesystem')
59
+ puts server['*.rb'].last
60
+
61
+ server.load('process')
62
+ puts local.process.where(:command => /ruby/).fields(:pid, :rss).all
63
+
64
+
65
+ References
66
+ ----------
67
+
68
+ * [Rush](http://rush.heroku.com/)
69
+ * [PQL](http://github.com/wereHamster/process-query-language)
70
+
71
+ License
72
+ -------
73
+
74
+ Copyright (c) 2010 by Tomas "wereHamster" Carnecky (tomas.carnecky@gmail.com)
data/bin/frontier ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'frontier'
5
+
6
+ Frontier::Adapter.new
@@ -0,0 +1,55 @@
1
+
2
+ module Frontier
3
+
4
+ class Adapter
5
+
6
+ def self.wrap(object)
7
+ case object
8
+ when Numeric, String, Exception
9
+ return object
10
+ when Array
11
+ return object.map { |o| wrap(o) }
12
+ when Hash
13
+ return object.merge(object) { |k, v| wrap(v) }
14
+ else
15
+ return Proxy.new(object)
16
+ end
17
+ end
18
+
19
+
20
+ def initialize
21
+ @cache = {}
22
+
23
+ while true do
24
+ begin
25
+ request = Marshal.load($stdin)
26
+
27
+ if request[:object]
28
+ object = ObjectSpace._id2ref(request[:object])
29
+ else
30
+ object = self
31
+ end
32
+
33
+ reply = object.send(request[:name], *request[:args])
34
+ @cache[reply.object_id] = reply
35
+ Marshal.dump(Adapter.wrap(reply), $stdout)
36
+ rescue Exception => e
37
+ Marshal.dump(e, $stdout)
38
+ end
39
+ $stdout.flush
40
+ end
41
+ end
42
+
43
+ def load(*mixins)
44
+ [*mixins].each do |mixin|
45
+ self.class.class_eval("include Frontier::Mixin::#{mixin.capitalize}")
46
+ end
47
+ end
48
+
49
+ def method_missing(name, *args)
50
+ %x[#{name} #{args.join(' ')}]
51
+ end
52
+
53
+ end
54
+
55
+ end
@@ -0,0 +1,29 @@
1
+
2
+ module Frontier
3
+
4
+ class Channel
5
+
6
+ def self.hydrate(channel, object)
7
+ case object
8
+ when Array, Hash
9
+ object.each { |o| Channel.hydrate(channel, o) }
10
+ when Proxy
11
+ object.channel = channel
12
+ end
13
+
14
+ return object
15
+ end
16
+
17
+
18
+ def initialize(host, port)
19
+ @channel = IO.popen("ssh #{host} frontier", "r+")
20
+ end
21
+
22
+ def submit(request)
23
+ Marshal.dump(request, @channel)
24
+ return Channel.hydrate(self, Marshal.load(@channel))
25
+ end
26
+
27
+ end
28
+
29
+ end
@@ -0,0 +1,10 @@
1
+
2
+ require 'pathname'
3
+
4
+ module Frontier::Mixin::Filesystem
5
+
6
+ def [](glob)
7
+ Pathname.glob(glob)
8
+ end
9
+
10
+ end
@@ -0,0 +1,10 @@
1
+
2
+ require 'process-query-language'
3
+
4
+ module Frontier::Mixin::Process
5
+
6
+ def process
7
+ return Process
8
+ end
9
+
10
+ end
@@ -0,0 +1,11 @@
1
+
2
+ module Frontier
3
+
4
+ module Mixin
5
+
6
+ autoload :Filesystem, 'frontier/mixin/filesystem'
7
+ autoload :Process, 'frontier/mixin/process'
8
+
9
+ end
10
+
11
+ end
@@ -0,0 +1,19 @@
1
+
2
+ module Frontier
3
+
4
+ class Proxy
5
+ attr_accessor :channel
6
+
7
+ def initialize(object)
8
+ @typename = object.class.to_s
9
+ @object = object.object_id
10
+ end
11
+
12
+ def method_missing(name, *args)
13
+ request = { :object => @object, :name => name, :args => args }
14
+ return @channel.submit(request)
15
+ end
16
+
17
+ end
18
+
19
+ end
@@ -0,0 +1,18 @@
1
+
2
+ module Frontier
3
+
4
+ class Shell
5
+
6
+ def initialize(host = 'localhost', port = 22)
7
+ @host = host
8
+ @port = port
9
+ end
10
+
11
+ def method_missing(name, *args)
12
+ @channel ||= Channel.new(@host, @port)
13
+ return @channel.submit({ :name => name, :args => args })
14
+ end
15
+
16
+ end
17
+
18
+ end
@@ -0,0 +1,6 @@
1
+
2
+ module Frontier
3
+
4
+ Version = '0.0.1'
5
+
6
+ end
data/lib/frontier.rb ADDED
@@ -0,0 +1,11 @@
1
+
2
+ module Frontier
3
+
4
+ autoload :Adapter, 'frontier/adapter'
5
+ autoload :Channel, 'frontier/channel'
6
+ autoload :Mixin, 'frontier/mixin'
7
+ autoload :Proxy, 'frontier/proxy'
8
+ autoload :Shell, 'frontier/shell'
9
+ autoload :Version, 'frontier/version'
10
+
11
+ end
metadata ADDED
@@ -0,0 +1,79 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: frontier
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Tomas Carnecky
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-10-31 01:00:00 +02:00
19
+ default_executable:
20
+ dependencies: []
21
+
22
+ description:
23
+ email:
24
+ - tomas.carnecky@gmail.com
25
+ executables:
26
+ - frontier
27
+ extensions: []
28
+
29
+ extra_rdoc_files: []
30
+
31
+ files:
32
+ - lib/frontier/adapter.rb
33
+ - lib/frontier/channel.rb
34
+ - lib/frontier/mixin/filesystem.rb
35
+ - lib/frontier/mixin/process.rb
36
+ - lib/frontier/mixin.rb
37
+ - lib/frontier/proxy.rb
38
+ - lib/frontier/shell.rb
39
+ - lib/frontier/version.rb
40
+ - lib/frontier.rb
41
+ - LICENSE
42
+ - README.md
43
+ - bin/frontier
44
+ has_rdoc: true
45
+ homepage: http://github.com/wereHamster/frontier
46
+ licenses: []
47
+
48
+ post_install_message:
49
+ rdoc_options: []
50
+
51
+ require_paths:
52
+ - lib
53
+ required_ruby_version: !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ hash: 3
59
+ segments:
60
+ - 0
61
+ version: "0"
62
+ required_rubygems_version: !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ hash: 3
68
+ segments:
69
+ - 0
70
+ version: "0"
71
+ requirements: []
72
+
73
+ rubyforge_project:
74
+ rubygems_version: 1.3.7
75
+ signing_key:
76
+ specification_version: 3
77
+ summary: Ruby without borders
78
+ test_files: []
79
+