【问题标题】:Is there a way to use capistrano (or similar) to remotely interact with rails console有没有办法使用 capistrano (或类似的)与 rails 控制台远程交互
【发布时间】:2011-05-19 20:50:44
【问题描述】:

我很喜欢 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.

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

【问题讨论】:

  • Rails 控制台是一个交互式提示,如果您只是想运行一段代码来快速修复,您可以通过script/runnerrails runner for rails3 来完成。如果您不知道,runner 将加载您的整个环境,就像 console 或依赖于 :environmentrake 任务一样
  • 感谢 Swanand...问题是我需要交互性来诊断应用程序逻辑在生产数据或生产环境中遇到的我无法在本地重现的问题。
  • 你可以试试“cap -v shell”还是在capfile中添加“default_run_options[:shell] = false”?

标签: ruby-on-rails console capistrano


【解决方案1】:

不一定是最好的选择,但我在我们的项目中针对这个问题一起破解了以下内容:

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,因此尚未对此进行测试)

【讨论】:

    【解决方案2】:

    上限-T

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

    cap -e 调用

    ------------------------------------------------------------
    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
    

    【讨论】:

    • 谢谢,invoke 的问题是你没有得到你需要的交互式会话。 shell 更有希望,问题是当你调用控制台时它挂起,我在上面添加了它。
    【解决方案3】:

    文章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 或箭头工作,请发布。

    【讨论】:

      【解决方案4】:

      我找到了基于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
      

      【讨论】:

      • 太棒了!谁需要heroku?现在,如果只有墨西哥的互联网不是一个无赖。一切都很顺利,除了我没有“舞台”环境,只需要删除它,它就像一个魅力。
      • 只是一个注释,需要一个带有 readline 的特殊版本的 ruby​​:`require': libreadline.so.5: cannot open shared object file: No such file or directory`
      【解决方案5】:

      这就是我在没有 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
      

      【讨论】:

        【解决方案6】:

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

        【讨论】:

          猜你喜欢
          • 2011-10-20
          • 2010-10-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-07-28
          • 2013-05-16
          • 1970-01-01
          相关资源
          最近更新 更多