有没有办法使用capistrano(或类似)远程与rails控制台交互

时间:2010-12-03 16:49:15

标签: ruby-on-rails console capistrano

我很喜欢capistrano如何简化我的部署工作流程,但是经常推送的更改会遇到我需要登录到服务器以通过控制台进行故障排除的问题。

有没有办法使用capistrano或其他远程管理工具与本地终端服务器上的rails控制台进行交互?

**更新:

cap shell似乎很有希望,但是当你尝试启动控制台时它会挂起:

cap> cd /path/to/application/current
cap> pwd
 ** [out :: application.com] /path/to/application/current
cap> rails c production
 ** [out :: application.com] Loading production environment (Rails 3.0.0)
 ** [out :: application.com] Switch to inspect mode.

如果您知道解决方法,那就太棒了

6 个答案:

答案 0 :(得分:12)

我找到了基于https://github.com/codesnik/rails-recipes/blob/master/lib/rails-recipes/console.rb

的非常好的解决方案
desc "Remote console" 
task :console, :roles => :app do
  env = stage || "production"
  server = find_servers(:roles => [:app]).first
  run_with_tty server, %W( ./script/rails console #{env} )
end

desc "Remote dbconsole" 
task :dbconsole, :roles => :app do
  env = stage || "production"
  server = find_servers(:roles => [:app]).first
  run_with_tty server, %W( ./script/rails dbconsole #{env} )
end

def run_with_tty(server, cmd)
  # looks like total pizdets
  command = []
  command += %W( ssh -t #{gateway} -l #{self[:gateway_user] || self[:user]} ) if     self[:gateway]
  command += %W( ssh -t )
  command += %W( -p #{server.port}) if server.port
  command += %W( -l #{user} #{server.host} )
  command += %W( cd #{current_path} )
  # have to escape this once if running via double ssh
  command += [self[:gateway] ? '\&\&' : '&&']
  command += Array(cmd)
  system *command
end

答案 1 :(得分:1)

如果没有Capistrano,我就是这样做的:https://github.com/mcasimir/remoting(基于rake任务构建的部署工具)。我已经在README中添加了一个任务来打开服务器上的远程控制台:

# remote.rake
namespace :remote do

desc "Open rails console on server"
task :console do
  require 'remoting/task'

  remote('console', config.login, :interactive => true) do
    cd config.dest
    source '$HOME/.rvm/scripts/rvm'
    bundle :exec, "rails c production"
  end
end

end

比我能跑

$ rake remote:console

答案 2 :(得分:1)

我非常喜欢this gist中显示的“只使用现有工具”方法。它只是使用SSH shell命令而不是自己实现交互式SSH shell,这可能会破坏任何时候改变它的默认提示,你需要切换用户或任何其他疯狂的事情发生。

答案 3 :(得分:0)

不一定是最好的选择,但我在项目中一起破解了以下问题:

task :remote_cmd do
  cmd = fetch(:cmd)

  puts `#{current_path}/script/console << EOF\r\n#{cmd}\r\n EOF`
end

要使用它,我只需使用:

cap remote_cmd -s cmd="a = 1; b = 2; puts a+b"

(注意:如果您使用Rails 3,则必须将上面的script/console更改为rails console,但是由于我尚未在项目中使用Rails 3,因此尚未对此进行测试)< / p>

答案 4 :(得分:0)

上限-T

cap invoke                        # Invoke a single command on the remote ser...
cap shell                         # Begin an interactive Capistrano session.

cap -e invoke

------------------------------------------------------------
cap invoke
------------------------------------------------------------
Invoke a single command on the remote servers. This is useful for performing
one-off commands that may not require a full task to be written for them. Simply
specify the command to execute via the COMMAND environment variable. To execute
the command only on certain roles, specify the ROLES environment variable as a
comma-delimited list of role names. Alternatively, you can specify the HOSTS
environment variable as a comma-delimited list of hostnames to execute the task
on those hosts, explicitly. Lastly, if you want to execute the command via sudo,
specify a non-empty value for the SUDO environment variable.

Sample usage:

  $ cap COMMAND=uptime HOSTS=foo.capistano.test invoke
  $ cap ROLES=app,web SUDO=1 COMMAND="tail -f /var/log/messages" invoke

答案 5 :(得分:0)

文章http://errtheblog.com/posts/19-streaming-capistrano为此提供了很好的解决方案。我只做了一个小改动,以便它可以在多个服务器设置中工作。

  desc "open remote console (only on the last machine from the :app roles)"
  task :console, :roles => :app do
    server = find_servers_for_task(current_task).last
    input = ''

    run "cd #{current_path} && ./script/console #{rails_env}", :hosts => server.host do |channel, stream, data|
      next if data.chomp == input.chomp || data.chomp == ''
      print data
      channel.send_data(input = $stdin.gets) if data =~ /^(>|\?)>/
    end
  end

你得到的终端并不是真的很神奇。如果某人有一些改进可以使CTRL-D和CTRL-H或箭头工作,请发布它。