drb over pipes

R

Reto Schuettel

Hi

I'd like to establish a drb connection over ssh, preferably over the
stdin/stdout channels which are provided by ssh itself. Is there a
drb protocol which uses pipes? If not, is it easy to implement?

I've seen that the tcpprotocol uses two connections, this could be
problem, as pipes/stdin/stdout only provide one stream.

At the end of the day I'd like to do something like that:
# ruby client.rb | ssh host 'ruby agent.rb'

Unfortunately using drb's tcp protocol directly isn't really an option in
our environment.

Does anybody have a good idea?=20

Thanks!

Cheers,
Reto Sch=FCttel
 
Y

Yoann Guillot

Hi
=20
I'd like to establish a drb connection over ssh, preferably over the
stdin/stdout channels which are provided by ssh itself. Is there a
drb protocol which uses pipes? If not, is it easy to implement?
=20
I've seen that the tcpprotocol uses two connections, this could be
problem, as pipes/stdin/stdout only provide one stream.
=20
At the end of the day I'd like to do something like that:
# ruby client.rb | ssh host 'ruby agent.rb'
=20

With drb, the client needs to talk to the agent and vice-versa, so this
command line will never work (the client will talk to the agent, but not =
the
other way around).
Unfortunately using drb's tcp protocol directly isn't really an option = in
our environment.
=20
Does anybody have a good idea?=20

As suggested, tunelling is probably the best/simpler choice.
=20
Thanks!
=20
Cheers,
Reto Sch=FCttel
=20

--=20
Yoann Guillot
 
R

Reto Schuettel

Hi=20

=20
With drb, the client needs to talk to the agent and vice-versa, so this
command line will never work (the client will talk to the agent, but no= t the
other way around).

A pipe provides two streams (in & out), and tcp does the same. The
question is now if drb really needs two connections (-> 4 streams)?
=20
As suggested, tunelling is probably the best/simpler choice.

Tunneling may be a solution, although I'd prefer the pipe. Otherwise
there would be a daemon, somewhere listening on localhost:port.=20

Regards,
Reto Sch=FCttel
 
R

Robert Klemme

Jonathan said:
I implemented a quick hack to do this. Hopefully the code below will help

The code didn't make it into the newsgroup. I can't detect something
strange about your original message - it's all there on my email
account. This is strange...

Cheers

robert
 
R

Reto Schuettel

Hi Jonathan

I implemented a quick hack to do this. Hopefully the code below will help.
It's a bit of a mess, but allows you to use a DRb scheme like
'drbfd://0,1' which means uses file descriptors 0 and 1 (stdin/stdout) for
communication.

module DRb

That's great! exactly what I needed.

For the record: My statement in the first mail wasn't completely
correct, the pipe I used in my example is only a 'one-way' thing. But
ssh actually transports three streams/pipes: stdin, stdout and stderr, so this
isn't really a problem.

There's one small problem with your fdsocket, it seems like the drb
server/thread doesn't always terminate itself when the streams get
closed. But I will try to investigate this by myself tomorrow :).

I've appended an example which uses your library. It creates two pipes,
forks, connects the pipes to the stdin/stdout of the child and then execs
the ssh client. The same technique could also be used to communicate
with a child (instead of a unix/tcp socket or a simple plain pipe). IMHO
that's really nice, great work Jonathan!

require 'drb'
require 'fdsocket'

ctprd, ctpwr = IO.pipe
ptcrd, ptcwr = IO.pipe

pid = fork

unless pid
# child
ctprd.close
ptcwr.close

$stdin.reopen( ptcrd )
$stdout.reopen( ctpwr )

exec("ssh", "hostname", "./agent.rb")

exit # child shounld't reach this point
end

# parent
ctpwr.close
ptcrd.close

fd_read = ctprd.fileno
fd_write = ptcwr.fileno

# The URI to connect to
SERVER_URI="drbfd://#{fd_read},#{fd_write}"
DRb.start_service

obj = DRbObject.new_with_uri(SERVER_URI)

[...]


Regards,
Reto Schuettel
 
A

ara.t.howard

I've appended an example which uses your library. It creates two pipes,
forks, connects the pipes to the stdin/stdout of the child and then execs
the ssh client. The same technique could also be used to communicate with a
child (instead of a unix/tcp socket or a simple plain pipe). IMHO that's
really nice, great work Jonathan!

require 'drb'
require 'fdsocket'

ctprd, ctpwr = IO.pipe
ptcrd, ptcwr = IO.pipe

pid = fork

unless pid
# child
ctprd.close
ptcwr.close

$stdin.reopen( ptcrd )
$stdout.reopen( ctpwr )

exec("ssh", "hostname", "./agent.rb")

exit # child shounld't reach this point
end

# parent
ctpwr.close
ptcrd.close

fd_read = ctprd.fileno
fd_write = ptcwr.fileno

# The URI to connect to
SERVER_URI="drbfd://#{fd_read},#{fd_write}"
DRb.start_service

obj = DRbObject.new_with_uri(SERVER_URI)

[...]

i think this will fail with calls that use 'yield' or that return
'DrbUndumped' objects because they will attempt to open a connection __from__
'hostname' to 'localhost'.

this doccument details this in the ssh section

http://www.rubygarden.org/ruby?DrbTutorial

fyi.


-a
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,202
Messages
2,571,057
Members
47,666
Latest member
selsetu

Latest Threads

Top