如何通过Capistrano 3运行自定义的rake任务?

12

我可以通过Capistrano在远程服务器上运行rake命令。

例如,我有一个包含一些方法的lib/task/reparse.rake文件。

desc "it's take csv file, makes some changes and fill db with this info"
task :example1 => :environment do
  require 'csv'
  rows_to_insert = []
  # some actions
  # ...
end

在本地服务器上一切正常 - 我只需运行rake reparse:example1,它就能正常工作(正确地填充数据库)。所以问题是 - 在部署后如何在实际托管环境中运行此命令?
我使用的是rails 4.1 + capistrano 3。
P.S. 网站上的示例对我无效。 如何从Capistrano运行rake任务? 如果我尝试cap production rake:invoke task=reparse:land, 它会失败并显示以下内容:
cap aborted!
Don't know how to build task 'rake:invoke'

一些修复

namespace :somenamespace do
  task :runrake do  
    on roles(:all), in: :sequence, wait: 5 do      
      within release_path do
        execute :rake, ENV['task'], "RAILS_ENV=production"
      end 
    end
  end
end

使用这种方式,它开始通过执行。
cap production somenamespace:runrake task=custom_task_file:custom_method1

1
抱歉,我没有仔细阅读回复 :P - 你尝试过添加一个 Capistrano 任务 execute :rake, ENV['task'] 吗? - Uri Agassi
@UriAgassi 感谢您的评论,我进行了一些修复并将其添加到问题中) - kpblc
可能是重复的问题:如何从Capistrano运行rake任务? - Uri Agassi
@UriAgassi 是的,它可以工作,但只有一种方式,就像我上面描述的那样。 - kpblc
https://dev59.com/uHVC5IYBdhLWcg3wYQAp#20506207 - Uri Agassi
5个回答

7

谢谢!您能添加一个示例命令行,展示如何运行它吗? - gmcnaughton

3

我一直在研究这个,似乎效果不错。然而,你需要一个格式化程序来充分利用这段代码。

如果您不想使用格式化程序,只需将日志级别设置为调试模式即可。

SSHKit.config.output_verbosity = Logger::DEBUG

容量问题

namespace :invoke do
  desc 'Run a bash task on a remote server. cap environment invoke:bash[\'ls -la\'] '
  task :bash, :execute do |_task, args|
    on primary :app do
      within deploy_to do
        with rails_env: fetch(:rails_env) do
          SSHKit.config.format = :supersimple
          execute args[:execute]
        end
      end
    end
  end

  desc 'Run a rake task on a remote server. cap environment invoke:rake[\'db:migrate\'] '
  task :rake, :task do |_task, args|
    on primary :app do
      within current_path do
        with rails_env: fetch(:rails_env) do
          SSHKit.config.format = :supersimple
          rake args[:task]
        end
      end
    end
  end
end

这是我为上述代码构建的格式化程序。它基于sshkit中的:textsimple,但调用自定义任务的方式并不差。但是这可能不适用于最新版本的sshkit gem。我知道它能与1.7.1一起使用。我之所以这样说是因为主分支更改了可用的SSHKit :: Command方法。
module SSHKit
  module Formatter
    class SuperSimple < SSHKit::Formatter::Abstract
      def write(obj)
        case obj
        when SSHKit::Command    then write_command(obj)
        when SSHKit::LogMessage then write_log_message(obj)
        end
      end
      alias :<< :write

      private

      def write_command(command)
        unless command.started? && SSHKit.config.output_verbosity == Logger::DEBUG
          original_output << "Running #{String(command)} #{command.host.user ? "as #{command.host.user}@" : "on "}#{command.host}\n"
          if SSHKit.config.output_verbosity == Logger::DEBUG
            original_output << "Command: #{command.to_command}" + "\n"
          end
        end

        unless command.stdout.empty?
          command.stdout.lines.each do |line|
            original_output << line
            original_output << "\n" unless line[-1] == "\n"
          end
        end

        unless command.stderr.empty?
          command.stderr.lines.each do |line|
            original_output << line
            original_output << "\n" unless line[-1] == "\n"
          end
        end

      end

      def write_log_message(log_message)
        original_output << log_message.to_s + "\n"
      end
    end
  end
end

1
不支持 capistrano 的 3.5.0 版本。他们转向了 airbrussh。 - User128848244
1
在 deploy.rb 中: 设置 :format, :airbrussh 更多信息请参见 https://github.com/mattbrictson/airbrussh - shakaran

3
您可以创建一个相应的 Capistrano 任务来运行特定的 rake 任务,就像这样:
namespace :guests do
  desc 'Remove guest users older than 7 days'
  task :clean do
    on roles(:app) do
      within release_path do
        with rails_env: fetch(:rails_env) do
          execute :rake, 'guests:delete_old_guest_users'
        end
      end
    end
  end
end

2

您需要在Capistrano配置中加载自定义rake任务:

# config/deploy.rb || config/deploy/production.rb
load 'lib/task/reparse.rake'

在控制台中检查新任务 cap -T


0

试试 capistrano-rake

无需操心自定义 capistrano 任务或深入了解细节,你只需要安装这个 gem,就可以像这样在远程服务器上执行 rake 任务:

$ cap production invoke:rake TASK=some:rake_task

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接