在另一个环境中调用capistrano任务

时间:2014-09-20 20:38:06

标签: ruby capistrano

我正在尝试创建从我的生产/登台环境同步到本地流浪者框的任务。

我希望得到这样的命令:cap vagrant sync_production_database,它将在远程服务器上执行数据库转储,下载它,然后将其导入到vagrant框中。不幸的是,我找不到在另一个环境中执行capistrano任务的方法。

我的环境设置如下:

config
├── deploy
│   ├── production.rb
│   ├── staging.rb
│   └── vagrant.rb
└── deploy.rb

以下是我要完成的一个例子:

desc 'sync database'
task :sync_production_database do
  # executed on remote server
  # this is obviously not working
  on(:production) do |host|
    # dump database and download it
  end

  # executed on vagrant box
  on roles(:web) do |host|

  end
end

1 个答案:

答案 0 :(得分:2)

首先,我认为最好使用cap命令的stage参数来指定远程阶段服务器而不是本地阶段服务器。这意味着您的命令假设:vagrant始终是本地阶段。

如果vagrant阶段服务器具有远程服务器不具备的角色,您可以通过以下方式在每个阶段执行不同的任务:

# Assuming the following stage definitions in deploy/production.rb and deploy/vagrant.rb respectively
server 'production.example.com', roles: %w{web app}
server 'vagrant.local', roles: %w{web localhost}

# the following will execute tasks on each host
desc 'sync database'
task :sync_database do
  # executed on remote server(s)
  on roles(:app) do |host|
    # dump database and download it
  end
  # Load the servers in deploy/vagrant.rb
  invoke(:vagrant)

  # executed on vagrant box server(s)
  on roles(:localhost) do |host|
    # Create database and load dump from remote
  end
end

这是有效的,因为roles(...)返回加载了给定角色的所有服务器,并且由于每个阶段都有唯一的角色,因此您可以通过指定各自的角色来检索所需的服务器。

通常,如果没有invoke(:vagrant),上面示例中的roles(:localhost)将不会返回任何内容,因为Capistrano默认只加载在给定阶段中定义的服务器。要解决此问题,您可以使用vagrant强制在invoke(:vagrant)阶段加载服务器。那么,roles(:app)返回给定阶段的服务器,roles(:localhost)返回您的流浪服务器。