2014-03-31 17 views
0

我這裏所描述的同樣的問題:聲明和使用Capistrano的內紅寶石功能3個任務

How to call a Capistrano's task within another Capistrano's task?

然而回滾到Capistrano的V3.0.1的解決方法解決方案和sshkit 1.0對我不起作用。在使用存儲在LIB/Capistrano的.RB文件decalared功能的lib/Capistrano酒店/任務/

使用this tutorial,我宣佈自定義任務

capfile:

# Load DSL and Setup Up Stages 
require 'capistrano/setup' 

# Includes default deployment tasks 
require 'capistrano/deploy' 

require 'capistrano/rails' 

require 'capistrano/rvm' 

# Loads custom tasks from `lib/capistrano/tasks' if you have any defined. 
Dir.glob('lib/capistrano/tasks/*.cap').each { |r| import r } 

# Loads custom tasks from all folders below `lib/capistrano' if you have any defined. 
Dir.glob('lib/capistrano/**/*.rb').each { |r| import r } 

# because the above didn't quite look right to me, and all the .rbs are in /lib/capistrano 
Dir.glob('lib/capistrano/*.rb').each { |r| import r } 

deploy.rb

set :application, 'hello-rails' 
set :app_shortname, 'hr' 
set :repo_url, '[email protected]:me/myapp.git' #<-substituted fake info here for this post 

# Default value for :linked_files is [] 
set :linked_files, %w{config/database.yml config/application.yml} 

# Default value for linked_dirs is [] 
set :linked_dirs, %w{bin log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system} 

# everything below this comment adapted from the talkingquickly tutorial 
#which config files should be copied by deploy:setup_config 
set(:config_files, %w(
    nginx.conf 
    unicorn.rb 
    unicorn_init.sh 
)) 

# which config files should be made executable after copying 
# by deploy:setup_config 
set(:executable_config_files, %w(unicorn_init.sh)) 

# files which need to be symlinked 
set(:symlinks, [ 
    { 
    source: "nginx.conf", 
    link: "/etc/nginx/sites-enabled/{{full_app_name}}" 
    }, 
    { 
    source: "unicorn_init.sh", 
    link: "/etc/init.d/unicorn_{{full_app_name}}" 
    } 
]) 

#specify my ruby version 
set :rvm_type, :system 

#specify my gemset 
set :rvm_ruby_version, '[email protected]' 

namespace :deploy do 
    # make sure we're deploying what we think we're deploying 
    before :deploy, "deploy:check_revision" 
    # only allow a deploy with passing tests to deployed 
    before :deploy, "deploy:run_tests" 
    # compile assets locally then rsync 
    after 'deploy:symlink:shared', 'deploy:compile_assets_locally' 
    after :finishing, 'deploy:cleanup' 
end 

配置/ staging.rb

set :stage, :staging 
set :branch, "cap-rails" 
set :rails_env, :test 

# used in case we're deploying multiple versions of the same 
# app side by side. Also provides quick sanity checks when looking 
# at filepaths 
set :full_app_name, "#{fetch(:app_shortname)}_#{fetch(:stage)}" 

set :deploy_to, "/srv/#{fetch(:app_shortname)}" 

# number of unicorn workers 
set :unicorn_worker_count, 5 

# For building nginx config file 
set :enable_ssl, false 

# extended properties on the server. 
server 'dev', user: 'deployer', roles: %w{web app} #<-substituted fake info here for this post 

# custom ssh options 
set :ssh_options, { 
    user: 'deployer', #<-substituted fake info here for this post 
    keys: %w(path.to.key), #<-substituted fake info here for this post 
    forward_agent: true, 
    auth_methods: %w(publickey) 
} 

的lib/Capistrano酒店/任務/ setup_config.cap

namespace :deploy do 
    task :setup_config do 
    on roles(:app) do 
     # make the config dir 
     execute :mkdir, "-p #{shared_path}/config" 
     full_app_name = fetch(:full_app_name) 

     # config files to be uploaded to shared/config, see the 
     # definition of smart_template for details of operation. 
     # Essentially looks for #{filename}.erb in deploy/#{full_app_name}/ 
     # and if it isn't there, falls back to deploy/#{shared}. Generally 
     # everything should be in deploy/shared with params which differ 
     # set in the stage files 
     config_files = fetch(:config_files) 
     config_files.each do |file| 
     smart_template file 
     end 

     # which of the above files should be marked as executable 
     executable_files = fetch(:executable_config_files) 
     executable_files.each do |file| 
     execute :chmod, "+x #{shared_path}/config/#{file}" 
     end 

     # symlink stuff which should be... symlinked 
     symlinks = fetch(:symlinks) 

     symlinks.each do |symlink| 
     sudo "ln -nfs #{shared_path}/config/#{symlink[:source]} #{sub_strings(symlink[:link])}" 
     end 
    end 
    end 
end 

的lib/Capistrano的/ template.rb

def smart_template(from, to=nil) 
    to ||= from 
    full_to_path = "#{shared_path}/config/#{to}" 
    if from_erb_path = template_file(from) 
    from_erb = StringIO.new(ERB.new(File.read(from_erb_path)).result(binding)) 
    upload! from_erb, full_to_path 
    info "copying: #{from_erb} to: #{full_to_path}" 
    else 
    error "error #{from} not found" 
    end 
end 

def template_file(name) 
    if File.exist?((file = "config/deploy/#{fetch(:full_app_name)}/#{name}.erb")) 
    return file 
    elsif File.exist?((file = "config/deploy/shared/#{name}.erb")) 
    return file 
    end 
    return nil 
end 

的Gemfile

source 'https://rubygems.org' 

    # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' 
    gem 'rails', '4.0.4' 

    # Use sqlite3 as the database for Active Record 
    gem 'sqlite3' 

    # Use SCSS for stylesheets 
    gem 'sass-rails', '~> 4.0.2' 

    # Use Uglifier as compressor for JavaScript assets 
    gem 'uglifier', '>= 1.3.0' 

    # Use CoffeeScript for .js.coffee assets and views 
    gem 'coffee-rails', '~> 4.0.0' 

    # Use jquery as the JavaScript library 
    gem 'jquery-rails' 

    # Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks 
    gem 'turbolinks' 

    # Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder 
    gem 'jbuilder', '~> 1.2' 

    #because sshkit 1.3 has this bug: https://stackoverflow.com/questions/21401665/how-to-call-a-capistranos-task-within-another-capistranos-task 
    gem 'sshkit', '~> 1.0.0' 
    gem 'capistrano', '~> 3.0.1' 

    gem 'capistrano-rails', '~> 1.1' 
    gem 'capistrano-rvm' 

    group :doc do 
     # bundle exec rake doc:rails generates the API under doc/api. 
     gem 'sdoc', require: false 
    end 

Gemfile.lock的

GEM 
    remote: https://rubygems.org/ 
    specs: 
    actionmailer (4.0.4) 
     actionpack (= 4.0.4) 
     mail (~> 2.5.4) 
    actionpack (4.0.4) 
     activesupport (= 4.0.4) 
     builder (~> 3.1.0) 
     erubis (~> 2.7.0) 
     rack (~> 1.5.2) 
     rack-test (~> 0.6.2) 
    activemodel (4.0.4) 
     activesupport (= 4.0.4) 
     builder (~> 3.1.0) 
    activerecord (4.0.4) 
     activemodel (= 4.0.4) 
     activerecord-deprecated_finders (~> 1.0.2) 
     activesupport (= 4.0.4) 
     arel (~> 4.0.0) 
    activerecord-deprecated_finders (1.0.3) 
    activesupport (4.0.4) 
     i18n (~> 0.6, >= 0.6.9) 
     minitest (~> 4.2) 
     multi_json (~> 1.3) 
     thread_safe (~> 0.1) 
     tzinfo (~> 0.3.37) 
    arel (4.0.2) 
    atomic (1.1.16) 
    builder (3.1.4) 
    capistrano (3.0.1) 
     i18n 
     rake (>= 10.0.0) 
     sshkit (>= 0.0.23) 
    capistrano-bundler (1.0.0) 
     capistrano (>= 3.0.0.pre) 
    capistrano-rails (1.1.0) 
     capistrano (>= 3.0.0) 
     capistrano-bundler (>= 1.0.0) 
    capistrano-rvm (0.0.3) 
     capistrano 
    coffee-rails (4.0.1) 
     coffee-script (>= 2.2.0) 
     railties (>= 4.0.0, < 5.0) 
    coffee-script (2.2.0) 
     coffee-script-source 
     execjs 
    coffee-script-source (1.7.0) 
    erubis (2.7.0) 
    execjs (2.0.2) 
    hike (1.2.3) 
    i18n (0.6.9) 
    jbuilder (1.5.3) 
     activesupport (>= 3.0.0) 
     multi_json (>= 1.2.0) 
    jquery-rails (3.1.0) 
     railties (>= 3.0, < 5.0) 
     thor (>= 0.14, < 2.0) 
    json (1.8.1) 
    mail (2.5.4) 
     mime-types (~> 1.16) 
     treetop (~> 1.4.8) 
    mime-types (1.25.1) 
    minitest (4.7.5) 
    multi_json (1.9.2) 
    net-scp (1.1.2) 
     net-ssh (>= 2.6.5) 
    net-ssh (2.8.0) 
    polyglot (0.3.4) 
    rack (1.5.2) 
    rack-test (0.6.2) 
     rack (>= 1.0) 
    rails (4.0.4) 
     actionmailer (= 4.0.4) 
     actionpack (= 4.0.4) 
     activerecord (= 4.0.4) 
     activesupport (= 4.0.4) 
     bundler (>= 1.3.0, < 2.0) 
     railties (= 4.0.4) 
     sprockets-rails (~> 2.0.0) 
    railties (4.0.4) 
     actionpack (= 4.0.4) 
     activesupport (= 4.0.4) 
     rake (>= 0.8.7) 
     thor (>= 0.18.1, < 2.0) 
    rake (10.2.2) 
    rdoc (4.1.1) 
     json (~> 1.4) 
    sass (3.2.18) 
    sass-rails (4.0.2) 
     railties (>= 4.0.0, < 5.0) 
     sass (~> 3.2.0) 
     sprockets (~> 2.8, <= 2.11.0) 
     sprockets-rails (~> 2.0.0) 
    sdoc (0.4.0) 
     json (~> 1.8) 
     rdoc (~> 4.0, < 5.0) 
    sprockets (2.11.0) 
     hike (~> 1.2) 
     multi_json (~> 1.0) 
     rack (~> 1.0) 
     tilt (~> 1.1, != 1.3.0) 
    sprockets-rails (2.0.1) 
     actionpack (>= 3.0) 
     activesupport (>= 3.0) 
     sprockets (~> 2.8) 
    sqlite3 (1.3.9) 
    sshkit (1.0.0) 
     net-scp 
     net-ssh 
     term-ansicolor 
    term-ansicolor (1.3.0) 
     tins (~> 1.0) 
    thor (0.19.1) 
    thread_safe (0.3.1) 
     atomic (>= 1.1.7, < 2) 
    tilt (1.4.1) 
    tins (1.0.1) 
    treetop (1.4.15) 
     polyglot 
     polyglot (>= 0.3.1) 
    turbolinks (2.2.1) 
     coffee-rails 
    tzinfo (0.3.39) 
    uglifier (2.5.0) 
     execjs (>= 0.3.0) 
     json (>= 1.8.0) 

PLATFORMS 
    ruby 

DEPENDENCIES 
    capistrano (~> 3.0.1) 
    capistrano-rails (~> 1.1) 
    capistrano-rvm 
    coffee-rails (~> 4.0.0) 
    jbuilder (~> 1.2) 
    jquery-rails 
    rails (= 4.0.4) 
    sass-rails (~> 4.0.2) 
    sdoc 
    sqlite3 
    sshkit (~> 1.0.0) 
    turbolinks 
    uglifier (>= 1.3.0) 

當我執行 束EXEC帽分期部署:setup_config

我得到這樣的輸出:

INFO [9e71d728] Running mkdir -p /srv/hr/shared/config on ruby-dev 
DEBUG [9e71d728] Command: mkdir -p /srv/hr/shared/config 
INFO [9e71d728] Finished in 0.738 seconds command successful. 
cap aborted! 
NoMethodError: undefined method `smart_template' for #<SSHKit::Backend::Netssh:0x007f8a4dc04980> 
/Users/nico/DevOps/repo/hello-rails/lib/capistrano/tasks/setup_config.cap:16:in `block (4 levels) in <top (required)>' 
/Users/nico/DevOps/repo/hello-rails/lib/capistrano/tasks/setup_config.cap:15:in `each' 
/Users/nico/DevOps/repo/hello-rails/lib/capistrano/tasks/setup_config.cap:15:in `block (3 levels) in <top (required)>' 
/Users/nico/.rvm/gems/[email protected]/gems/sshkit-1.0.0/lib/sshkit/backends/netssh.rb:42:in `instance_exec' 
/Users/nico/.rvm/gems/[email protected]/gems/sshkit-1.0.0/lib/sshkit/backends/netssh.rb:42:in `run' 

看來,使用Capistrano的V3.0.1和sshkit V1.0不解決我的問題。 deploy:setup_config任務嘗試調用lib/capistrano/template.rb中定義的函數smart_template,並且輸出指示無法找到該函數。我不知道如何正確地工作。歡迎任何關於解決該問題的建議。另外,如果更好的方法來創建nginx和獨角獸的配置和可執行文件存在,我很樂意聽到。

編輯

懷疑從RubyGems的該sshkit寶石仍然包含錯誤之後,我加入

gem 'sshkit', :git => 'https://github.com/capistrano/sshkit.git' 

我Capfile和重建我的本地寶石。然而,這並沒有解決這個問題,並指示我去其他地方看看。從那裏,我能診斷問題因爲涉及到由這些線在我的Capfile定義的Ruby文件的導入:

Dir.glob('lib/capistrano/*.rb').each { |r| import r } 
Dir.glob('lib/capistrano/**/*.rb').each { |r| import r } 

我評論的線條勾勒出並替換爲他們:

require_relative 'lib/capistrano/template.rb' 
require_relative 'lib/capistrano/substitute_strings.rb' 

,現在通過我的deploy:setup_config任務正確調用函數。我導出了有效的gem集,並使用ruby gems中的sshkit創建了一個新的gemset。通過上面列出的require_relative行,來自rubygems的sshkit gem運行良好。所以這個問題從來沒有在sshkit中的錯誤,不管我使用的是哪個源代碼(git或rubygems),但是導入了包含我的cap任務調用的函數的ruby文件。

回答

1

有兩個問題與你的榜樣,正確的線路有:

Dir.glob('lib/capistrano/tasks/*.cap').each { |r| import r }                                  
Dir.glob('lib/capistrano/**/*.rb').each { |r| import r }  

你可以看到完整的示例here

+0

我因爲意識到這是正確的答案,雖然我還在我的自定義任務中開始使用.cap約定。將其改爲已接受的答案 –

0

根據我在原始問題中的編輯,sshkit gem的來源不是我的問題。 相反,問題在於進口報表。

更改線路:

# Loads custom tasks from all folders below `lib/capistrano' if you have any defined. 
Dir.glob('lib/capistrano/*.rb').each { |r| import r } 
Dir.glob('lib/capistrano/**/*.rb').each { |r| import r } 

到:

require_relative 'lib/capistrano/template.rb' 
require_relative 'lib/capistrano/substitute_strings.rb' 

解決這個問題對我來說。

我不知道爲什麼Dir.glob方法不適用於我,我假設操作員錯誤,並期望確定我做錯了什麼將有助於在未來上限部署中推廣導入。