在 ruby 中创建后台 ssh 隧道
create a background ssh tunnel in ruby
我的 oracle 数据库只能通过跳转服务器访问并且是负载平衡的。结果,我 运行 在 bash 中使用了以下后台隧道命令:
ssh ${jumpoffUser}@${jumpoffIp} -L1521:ont-db01-vip:1521 -L1522:ont-db02-vip:1521 -fN
在我 运行 之前,我使用 sqlplus 在数据库上的命令如下:
sqlplus #{@sqlUsername}/#{@sqlPassword}@'#{@sqlUrl}' @scripts/populateASDB.sql
一切正常。
现在我想对这个程序进行 rubisize。
在查找有关 ruby 的文档时,我找不到如何将隧道置于后台(这是我的偏好),但我找到了有关本地端口转发的文档,我认为它可以模拟上述内容隧道和随后的 sqlplus 命令。
这是我的代码:
Net::SSH.start( @jumpoffIp, @jumpoffUser ) do |session|
session.forward.local( 1521, 'ont-db01-vip', 1521 )
session.forward.local( 1522, 'ont-db02-vip', 1521 )
puts "About to populateDB"
res = %x[sqlplus #{@sqlUsername}/#{@sqlPassword}@'#{@sqlUrl}' @scripts/populateASDB.sql > output.txt]
puts "populateDb output #{res}"
session.loop
end
当我 运行 以上时,我得到行 "About to populateDB" 但它挂在 sqlplus 命令的实际 运行ning 上。我的端口转发代码有问题吗?或者我该如何输入以下内容:
ssh ${jumpoffUser}@${jumpoffIp} -L1521:ont-db01-vip:1521 -L1522:ont-db02-vip:1521 -fN
变成ruby代码?
一个
尝试使用这个 gem:https://github.com/net-ssh/net-ssh-gateway/
require 'net/ssh/gateway'
gateway = Net::SSH::Gateway.new(@jumpoffIp, @jumpoffUser)
gateway.open('ont-db01-vip', 1521, 1521)
gateway.open('ont-db02-vip', 1521, 1521)
res = %x[sqlplus #{@sqlUsername}/#{@sqlPassword}@'#{@sqlUrl}' @scripts/populateASDB.sql > output.txt]
puts "populateDb output #{res}"
gateway.shutdown!
你有两个问题。
1) 您需要使用 'session.loop { true }' 以便会话实际循环
2) 在 sqlplus 命令完成之前,您不会开始循环会话,但是 sqlplus 需要会话循环(转发启动)。
所以我建议使用 Thread.new 创建一个后台线程,然后在 sqlplus 完成后终止线程。
感谢 David 的回答,我得出以下结论:
Net::SSH.start(ip_addr, 'user') do |session|
session.forward.local( 9090, 'localhost', 9090 )
# Need to run the event loop in the background for SSH callbacks to work
t = Thread.new {
session.loop { true }
}
commands.each do | command |
command.call(9090)
end
Thread.kill(t)
end
我的 oracle 数据库只能通过跳转服务器访问并且是负载平衡的。结果,我 运行 在 bash 中使用了以下后台隧道命令:
ssh ${jumpoffUser}@${jumpoffIp} -L1521:ont-db01-vip:1521 -L1522:ont-db02-vip:1521 -fN
在我 运行 之前,我使用 sqlplus 在数据库上的命令如下:
sqlplus #{@sqlUsername}/#{@sqlPassword}@'#{@sqlUrl}' @scripts/populateASDB.sql
一切正常。
现在我想对这个程序进行 rubisize。
在查找有关 ruby 的文档时,我找不到如何将隧道置于后台(这是我的偏好),但我找到了有关本地端口转发的文档,我认为它可以模拟上述内容隧道和随后的 sqlplus 命令。
这是我的代码:
Net::SSH.start( @jumpoffIp, @jumpoffUser ) do |session|
session.forward.local( 1521, 'ont-db01-vip', 1521 )
session.forward.local( 1522, 'ont-db02-vip', 1521 )
puts "About to populateDB"
res = %x[sqlplus #{@sqlUsername}/#{@sqlPassword}@'#{@sqlUrl}' @scripts/populateASDB.sql > output.txt]
puts "populateDb output #{res}"
session.loop
end
当我 运行 以上时,我得到行 "About to populateDB" 但它挂在 sqlplus 命令的实际 运行ning 上。我的端口转发代码有问题吗?或者我该如何输入以下内容:
ssh ${jumpoffUser}@${jumpoffIp} -L1521:ont-db01-vip:1521 -L1522:ont-db02-vip:1521 -fN
变成ruby代码?
一个
尝试使用这个 gem:https://github.com/net-ssh/net-ssh-gateway/
require 'net/ssh/gateway'
gateway = Net::SSH::Gateway.new(@jumpoffIp, @jumpoffUser)
gateway.open('ont-db01-vip', 1521, 1521)
gateway.open('ont-db02-vip', 1521, 1521)
res = %x[sqlplus #{@sqlUsername}/#{@sqlPassword}@'#{@sqlUrl}' @scripts/populateASDB.sql > output.txt]
puts "populateDb output #{res}"
gateway.shutdown!
你有两个问题。
1) 您需要使用 'session.loop { true }' 以便会话实际循环
2) 在 sqlplus 命令完成之前,您不会开始循环会话,但是 sqlplus 需要会话循环(转发启动)。
所以我建议使用 Thread.new 创建一个后台线程,然后在 sqlplus 完成后终止线程。
感谢 David 的回答,我得出以下结论:
Net::SSH.start(ip_addr, 'user') do |session|
session.forward.local( 9090, 'localhost', 9090 )
# Need to run the event loop in the background for SSH callbacks to work
t = Thread.new {
session.loop { true }
}
commands.each do | command |
command.call(9090)
end
Thread.kill(t)
end