easy-serve 0.6 → 0.7
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.
- 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
|