easy-serve 0.6 → 0.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/examples/remote-eval.rb +10 -3
- data/examples/remote-multi-server.rb +112 -0
- data/examples/remote-run.rb +9 -3
- data/lib/easy-serve.rb +1 -1
- data/lib/easy-serve/accessible-servers.rb +29 -0
- data/lib/easy-serve/remote-eval-mgr.rb +2 -2
- data/lib/easy-serve/remote-eval.rb +6 -4
- data/lib/easy-serve/remote-run-mgr.rb +3 -2
- data/lib/easy-serve/remote-run.rb +5 -4
- metadata +23 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: df13d8d57aa30fecfea71c7f1c0b3415e3384aaf
|
4
|
+
data.tar.gz: fad37a85f05878d484889783e6c49387380300fe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 65b1b16bb7305ef869cc00ad481f621a104c680d0940e1ca2351e5b0ec19fbb6cc423dea5037d57f87f4ab7ccadf228ba526fb6188723be4062f3c67d3506e75
|
7
|
+
data.tar.gz: 820382890ef5249a837f5a1c71faf2650c1925c3d4f282a5cc24ee70a9d37f7091d7579adbcd63f4d4dea551ad32b69731e45b0aa29f5b16e0966ad345125d64
|
data/examples/remote-eval.rb
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
require 'easy-serve/remote'
|
2
2
|
|
3
|
+
tunnel = ARGV.delete("--tunnel")
|
3
4
|
addr_there = ARGV.shift
|
4
5
|
|
5
6
|
unless addr_there
|
6
7
|
abort <<-END
|
7
8
|
|
8
|
-
Usage: #$0 addr_there
|
9
|
+
Usage: #$0 addr_there [--tunnel]
|
9
10
|
|
10
11
|
The 'addr_there' is the remote address on which client code will run.
|
11
12
|
It must be a destination accepted by ssh, optionally including a user name:
|
@@ -14,6 +15,10 @@ unless addr_there
|
|
14
15
|
|
15
16
|
The 'hostname' may by any valid hostname or ssh alias.
|
16
17
|
|
18
|
+
If --tunnel is specified, use the ssh connection to tunnel the tupelo
|
19
|
+
traffic. Otherwise, just use tcp. (Always use ssh to start the remote
|
20
|
+
process.)
|
21
|
+
|
17
22
|
END
|
18
23
|
end
|
19
24
|
|
@@ -23,7 +28,8 @@ EasyServe.start do |ez|
|
|
23
28
|
log.formatter = nil if $VERBOSE
|
24
29
|
|
25
30
|
ez.start_servers do
|
26
|
-
|
31
|
+
host = tunnel ? "localhost" : nil # no need to expose port if tunnelled
|
32
|
+
ez.server "simple-server", :tcp, host, 0 do |svr|
|
27
33
|
Thread.new do
|
28
34
|
loop do
|
29
35
|
Thread.new(svr.accept) do |conn|
|
@@ -40,7 +46,8 @@ EasyServe.start do |ez|
|
|
40
46
|
end
|
41
47
|
end
|
42
48
|
|
43
|
-
ez.remote "simple-server", host: addr_there,
|
49
|
+
ez.remote "simple-server", host: addr_there, tunnel: tunnel, log: true,
|
50
|
+
eval: %{
|
44
51
|
conn = conns[0]
|
45
52
|
# this code is executed on the remote host, connected by conn, not drb
|
46
53
|
log.progname = "eval remote on \#{host}"
|
@@ -0,0 +1,112 @@
|
|
1
|
+
require 'easy-serve/remote'
|
2
|
+
|
3
|
+
tunnel = ARGV.delete("--tunnel")
|
4
|
+
address_there = ARGV.shift
|
5
|
+
|
6
|
+
unless address_there
|
7
|
+
abort <<-END
|
8
|
+
|
9
|
+
Usage: #$0 address_there [--tunnel]
|
10
|
+
|
11
|
+
The 'address_there' is the remote address on which client code will run.
|
12
|
+
It must be a destination accepted by ssh, optionally including a user name:
|
13
|
+
|
14
|
+
[user@]hostname
|
15
|
+
|
16
|
+
The 'hostname' may by any valid hostname or ssh alias.
|
17
|
+
|
18
|
+
If --tunnel is specified, use the ssh connection to tunnel the tupelo
|
19
|
+
traffic. Otherwise, just use tcp. (Always use ssh to start the remote
|
20
|
+
process.)
|
21
|
+
|
22
|
+
END
|
23
|
+
end
|
24
|
+
|
25
|
+
EasyServe.start do |ez|
|
26
|
+
log = ez.log
|
27
|
+
log.level = Logger::INFO
|
28
|
+
log.formatter = nil if $VERBOSE
|
29
|
+
|
30
|
+
ez.start_servers do
|
31
|
+
host = tunnel ? "localhost" : nil # no need to expose port if tunnelled
|
32
|
+
|
33
|
+
ez.server "adder", :tcp, host, 0 do |svr|
|
34
|
+
Thread.new do
|
35
|
+
loop do
|
36
|
+
Thread.new(svr.accept) do |conn|
|
37
|
+
begin
|
38
|
+
log.info "accepted connection from #{conn.inspect}"
|
39
|
+
sum = 0
|
40
|
+
while input = conn.gets and not input.empty?
|
41
|
+
log.info "read input: #{input.inspect}"
|
42
|
+
begin
|
43
|
+
sum += Integer(input)
|
44
|
+
rescue
|
45
|
+
log.error "bad input: #{input}"
|
46
|
+
raise
|
47
|
+
end
|
48
|
+
end
|
49
|
+
conn.puts sum
|
50
|
+
log.info "wrote sum: #{sum}"
|
51
|
+
ensure
|
52
|
+
conn.close
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
ez.server "multiplier", :tcp, host, 0 do |svr|
|
60
|
+
Thread.new do
|
61
|
+
loop do
|
62
|
+
Thread.new(svr.accept) do |conn|
|
63
|
+
begin
|
64
|
+
log.info "accepted connection from #{conn.inspect}"
|
65
|
+
prod = 1
|
66
|
+
while input = conn.gets and not input.empty?
|
67
|
+
log.info "read input: #{input.inspect}"
|
68
|
+
begin
|
69
|
+
prod *= Integer(input)
|
70
|
+
rescue
|
71
|
+
log.error "bad input: #{input}"
|
72
|
+
raise
|
73
|
+
end
|
74
|
+
end
|
75
|
+
conn.puts prod
|
76
|
+
log.info "wrote product: #{prod}"
|
77
|
+
ensure
|
78
|
+
conn.close
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
ez.remote "adder", "multiplier",
|
87
|
+
host: address_there, tunnel: tunnel, log: true, eval: %{
|
88
|
+
log.progname = "client on \#{host}"
|
89
|
+
adder, multiplier = conns
|
90
|
+
|
91
|
+
adder.puts 5
|
92
|
+
adder.puts 6
|
93
|
+
adder.puts 7
|
94
|
+
adder.close_write
|
95
|
+
log.info "reading from \#{adder.inspect}"
|
96
|
+
sum = Integer(adder.read)
|
97
|
+
log.info "sum = \#{sum}"
|
98
|
+
adder.close
|
99
|
+
|
100
|
+
multiplier.puts sum
|
101
|
+
multiplier.puts 10
|
102
|
+
multiplier.close_write
|
103
|
+
log.info "reading from \#{multiplier.inspect}"
|
104
|
+
prod = Integer(multiplier.read)
|
105
|
+
log.info "prod = \#{prod}"
|
106
|
+
multiplier.close
|
107
|
+
}
|
108
|
+
# Note use of \#{} to interpolate variables that are only available
|
109
|
+
# in the binding where the code is eval-ed. Alternately, use
|
110
|
+
# eval: %Q{...}
|
111
|
+
# but then interpolation from this script is not posssible.
|
112
|
+
end
|
data/examples/remote-run.rb
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
require 'easy-serve/remote'
|
2
2
|
|
3
|
+
tunnel = ARGV.delete("--tunnel")
|
3
4
|
addr_there = ARGV.shift
|
4
5
|
|
5
6
|
unless addr_there
|
6
7
|
abort <<-END
|
7
8
|
|
8
|
-
Usage: #$0 addr_there
|
9
|
+
Usage: #$0 addr_there [--tunnel]
|
9
10
|
|
10
11
|
The 'addr_there' is the remote address on which client code will run.
|
11
12
|
It must be a destination accepted by ssh, optionally including a user name:
|
@@ -14,6 +15,10 @@ unless addr_there
|
|
14
15
|
|
15
16
|
The 'hostname' may by any valid hostname or ssh alias.
|
16
17
|
|
18
|
+
If --tunnel is specified, use the ssh connection to tunnel the tupelo
|
19
|
+
traffic. Otherwise, just use tcp. (Always use ssh to start the remote
|
20
|
+
process.)
|
21
|
+
|
17
22
|
Note: you must set up the remote by doing
|
18
23
|
|
19
24
|
scp examples/remote-run-script.rb addr_there:/tmp/
|
@@ -27,7 +32,8 @@ EasyServe.start do |ez|
|
|
27
32
|
log.formatter = nil if $VERBOSE
|
28
33
|
|
29
34
|
ez.start_servers do
|
30
|
-
|
35
|
+
host = tunnel ? "localhost" : nil # no need to expose port if tunnelled
|
36
|
+
ez.server "simple-server", :tcp, host, 0 do |svr|
|
31
37
|
Thread.new do
|
32
38
|
loop do
|
33
39
|
Thread.new(svr.accept) do |conn|
|
@@ -44,7 +50,7 @@ EasyServe.start do |ez|
|
|
44
50
|
end
|
45
51
|
end
|
46
52
|
|
47
|
-
ez.remote "simple-server", host: addr_there,
|
53
|
+
ez.remote "simple-server", host: addr_there, tunnel: tunnel,
|
48
54
|
dir: "/tmp",
|
49
55
|
file: "remote-run-script.rb",
|
50
56
|
# 'file' passed to load, so can be rel to dir or ruby's $LOAD_PATH
|
data/lib/easy-serve.rb
CHANGED
@@ -0,0 +1,29 @@
|
|
1
|
+
class EasyServe
|
2
|
+
# Returns list of [name, pid, addr] that are accessible from host, setting
|
3
|
+
# up ssh tunnel if specified. Note that OpenSSH 6.0 or later is required
|
4
|
+
# for the tunnel option.
|
5
|
+
def accessible_servers host, tunnel: false
|
6
|
+
if tunnel and host != "localhost" and host != "127.0.0.1"
|
7
|
+
servers.map do |n, s|
|
8
|
+
_, local_port = s.addr
|
9
|
+
fwd = "0:localhost:#{local_port}"
|
10
|
+
out = `ssh -O forward -R #{fwd} #{host}`
|
11
|
+
|
12
|
+
begin
|
13
|
+
remote_port = Integer(out)
|
14
|
+
rescue
|
15
|
+
log.error "Unable to set up dynamic ssh port forwarding. " +
|
16
|
+
"Please check if ssh -v is at least 6.0."
|
17
|
+
raise
|
18
|
+
end
|
19
|
+
|
20
|
+
at_exit {system "ssh -O cancel -R #{fwd} #{host}"}
|
21
|
+
|
22
|
+
[s.name, s.pid, ["localhost", remote_port]]
|
23
|
+
end
|
24
|
+
|
25
|
+
else
|
26
|
+
servers.map {|n, s| [s.name, s.pid, s.addr]}
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'msgpack'
|
2
2
|
require 'easy-serve'
|
3
3
|
|
4
|
-
def manage_remote_eval_client msg
|
4
|
+
def EasyServe.manage_remote_eval_client msg
|
5
5
|
$VERBOSE = msg["verbose"]
|
6
6
|
server_names, servers_list, log_level, eval_string, host =
|
7
7
|
msg.values_at(*%w{server_names servers_list log_level eval_string host})
|
@@ -44,7 +44,7 @@ end
|
|
44
44
|
|
45
45
|
$stdout.sync = true
|
46
46
|
|
47
|
-
def handle_remote_eval_messages
|
47
|
+
def EasyServe.handle_remote_eval_messages
|
48
48
|
unpacker = MessagePack::Unpacker.new($stdin)
|
49
49
|
unpacker.each do |msg|
|
50
50
|
case
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'msgpack'
|
2
|
+
require 'easy-serve/accessible-servers'
|
2
3
|
|
3
4
|
class EasyServe
|
4
5
|
# useful simple cases in testing and in production, but long eval strings
|
@@ -6,26 +7,27 @@ class EasyServe
|
|
6
7
|
# the ssh connection.
|
7
8
|
#
|
8
9
|
# Note, unlike #local and #child, by default logging goes to the null logger.
|
9
|
-
# If you want
|
10
|
+
# If you want to see logs from the remote, you need to choose:
|
10
11
|
#
|
11
12
|
# 1. Log to remote file: pass log: [args...] with args as in Logger.new
|
12
13
|
#
|
13
14
|
# 2. Log back over ssh: pass log: true.
|
14
15
|
#
|
15
|
-
def remote_eval *server_names,
|
16
|
+
def remote_eval *server_names,
|
17
|
+
host: nil, passive: false, tunnel: false, **opts
|
16
18
|
child_pid = fork do
|
17
19
|
log.progname = "remote_eval #{host}"
|
18
20
|
|
19
21
|
IO.popen [
|
20
22
|
"ssh", host, "ruby",
|
21
23
|
"-r", "easy-serve/remote-eval-mgr",
|
22
|
-
"-e", "handle_remote_eval_messages"
|
24
|
+
"-e", "EasyServe.handle_remote_eval_messages"
|
23
25
|
],
|
24
26
|
"w+" do |ssh|
|
25
27
|
|
26
28
|
ssh.sync = true
|
29
|
+
servers_list = accessible_servers(host, tunnel: tunnel)
|
27
30
|
|
28
|
-
servers_list = servers.map {|n, s| [s.name, s.pid, s.addr]}
|
29
31
|
MessagePack.pack(
|
30
32
|
{
|
31
33
|
verbose: $VERBOSE,
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'msgpack'
|
2
2
|
require 'easy-serve'
|
3
3
|
|
4
|
-
def manage_remote_run_client msg
|
4
|
+
def EasyServe.manage_remote_run_client msg
|
5
5
|
$VERBOSE = msg["verbose"]
|
6
6
|
server_names, servers_list, log_level, host, dir, file, class_name, args =
|
7
7
|
msg.values_at(*%w{
|
@@ -14,6 +14,7 @@ def manage_remote_run_client msg
|
|
14
14
|
servers[name] = EasyServe::Server.new(name, pid, addr)
|
15
15
|
end
|
16
16
|
|
17
|
+
### opt for tmpdir and send files to it via ssh
|
17
18
|
Dir.chdir(dir) if dir
|
18
19
|
load file
|
19
20
|
|
@@ -51,7 +52,7 @@ end
|
|
51
52
|
|
52
53
|
$stdout.sync = true
|
53
54
|
|
54
|
-
def handle_remote_run_messages
|
55
|
+
def EasyServe.handle_remote_run_messages
|
55
56
|
unpacker = MessagePack::Unpacker.new($stdin)
|
56
57
|
unpacker.each do |msg|
|
57
58
|
case
|
@@ -1,30 +1,31 @@
|
|
1
1
|
require 'msgpack'
|
2
|
+
require 'easy-serve/accessible-servers'
|
2
3
|
|
3
4
|
class EasyServe
|
4
5
|
# useful in production, though it requires remote lib files to be set up.
|
5
6
|
# Returns pid of child managing the ssh connection.
|
6
7
|
#
|
7
8
|
# Note, unlike #local and #child, by default logging goes to the null logger.
|
8
|
-
# If you want
|
9
|
+
# If you want to see logs from the remote, you need to choose:
|
9
10
|
#
|
10
11
|
# 1. Log to remote file: pass log: [args...] with args as in Logger.new
|
11
12
|
#
|
12
13
|
# 2. Log back over ssh: pass log: true.
|
13
14
|
#
|
14
|
-
def remote_run *server_names, host: nil, passive: false, **opts
|
15
|
+
def remote_run *server_names, host: nil, passive: false, tunnel: false, **opts
|
15
16
|
child_pid = fork do
|
16
17
|
log.progname = "remote_run #{host}"
|
17
18
|
|
18
19
|
IO.popen [
|
19
20
|
"ssh", host, "ruby",
|
20
21
|
"-r", "easy-serve/remote-run-mgr",
|
21
|
-
"-e", "handle_remote_run_messages"
|
22
|
+
"-e", "EasyServe.handle_remote_run_messages"
|
22
23
|
],
|
23
24
|
"w+" do |ssh|
|
24
25
|
|
25
26
|
ssh.sync = true
|
27
|
+
servers_list = accessible_servers(host, tunnel: tunnel)
|
26
28
|
|
27
|
-
servers_list = servers.map {|n, s| [s.name, s.pid, s.addr]}
|
28
29
|
MessagePack.pack(
|
29
30
|
{
|
30
31
|
verbose: $VERBOSE,
|
metadata
CHANGED
@@ -1,27 +1,27 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: easy-serve
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.7'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joel VanderWerf
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-12-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: msgpack
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
description: Framework for starting tcp/unix servers and connected clients under one
|
@@ -35,50 +35,52 @@ extra_rdoc_files:
|
|
35
35
|
files:
|
36
36
|
- README.md
|
37
37
|
- COPYING
|
38
|
-
- lib/easy-serve.rb
|
39
|
-
- lib/easy-serve/remote-eval-mgr.rb
|
38
|
+
- lib/easy-serve/remote.rb
|
40
39
|
- lib/easy-serve/remote-run.rb
|
41
40
|
- lib/easy-serve/remote-drb.rb
|
42
|
-
- lib/easy-serve/
|
43
|
-
- lib/easy-serve/remote-eval.rb
|
41
|
+
- lib/easy-serve/accessible-servers.rb
|
44
42
|
- lib/easy-serve/remote-run-mgr.rb
|
45
|
-
-
|
46
|
-
-
|
47
|
-
-
|
48
|
-
- examples/remote-eval-passive.rb
|
43
|
+
- lib/easy-serve/remote-eval-mgr.rb
|
44
|
+
- lib/easy-serve/remote-eval.rb
|
45
|
+
- lib/easy-serve.rb
|
49
46
|
- examples/remote-run.rb
|
47
|
+
- examples/remote-multi-server.rb
|
48
|
+
- examples/passive.rb
|
49
|
+
- examples/remote-eval-passive.rb
|
50
50
|
- examples/remote-drb.rb
|
51
51
|
- examples/remote-run-script.rb
|
52
|
+
- examples/multi.rb
|
53
|
+
- examples/remote-manual.rb
|
54
|
+
- examples/simple.rb
|
52
55
|
- examples/remote-eval.rb
|
53
|
-
- examples/passive.rb
|
54
56
|
homepage: https://github.com/vjoel/easy-serve
|
55
57
|
licenses:
|
56
58
|
- BSD
|
57
59
|
metadata: {}
|
58
60
|
post_install_message:
|
59
61
|
rdoc_options:
|
60
|
-
- --quiet
|
61
|
-
- --line-numbers
|
62
|
-
- --inline-source
|
63
|
-
- --title
|
62
|
+
- "--quiet"
|
63
|
+
- "--line-numbers"
|
64
|
+
- "--inline-source"
|
65
|
+
- "--title"
|
64
66
|
- easy-serve
|
65
|
-
- --main
|
67
|
+
- "--main"
|
66
68
|
- README.md
|
67
69
|
require_paths:
|
68
70
|
- lib
|
69
71
|
required_ruby_version: !ruby/object:Gem::Requirement
|
70
72
|
requirements:
|
71
|
-
- -
|
73
|
+
- - ">="
|
72
74
|
- !ruby/object:Gem::Version
|
73
75
|
version: '0'
|
74
76
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
75
77
|
requirements:
|
76
|
-
- -
|
78
|
+
- - ">="
|
77
79
|
- !ruby/object:Gem::Version
|
78
80
|
version: '0'
|
79
81
|
requirements: []
|
80
82
|
rubyforge_project:
|
81
|
-
rubygems_version: 2.
|
83
|
+
rubygems_version: 2.1.11
|
82
84
|
signing_key:
|
83
85
|
specification_version: 4
|
84
86
|
summary: Framework for starting tcp/unix servers and connected clients under one parent
|