2014-03-31 3 views
0

나는 같은 문제가 여기에 설명이 있습니다선언과 카피 스트라 노에서 루비 기능을 사용하여 3 작업

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

해결 방법 백 카피 스트라 노의 V3.0.1에 롤링의 솔루션과 1.0 sshkit 나를 위해 작동하지 않습니다하지만. lib 디렉토리/카피 스트라 노에 저장 .rb 파일에 decalared 기능을 사용할 lib 디렉토리/카피 스트라 노/작업에

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 디렉토리/카피 스트라 노/작업/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 디렉토리/카피 스트라 노/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) 
내가 번들 간부 캡 준비 배포 실행하면 3,691,363,210

는 :

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' 

카피 스트라 노의 V3.0.1 및 sshkit v1.0을를 사용하여 내 문제를 해결하지 않는 것으로 나타납니다 setup_config

을 나는이 출력을 얻을. deploy : setup_config 태스크가 lib/capistrano/template.rb에 정의 된대로 smart_template 함수를 호출하려고 시도하고 출력에 함수를 찾을 수 없음이 표시됩니다. 내가 제대로 작동하는 방법에 대한 손실에있어. 이 문제를 해결하기위한 조언은 언제나 환영합니다. 또한 nginx와 unicorn에 대한 설정 파일과 실행 파일을 만드는 더 나은 방법이 있다면 그것에 대해 듣고 싶습니다.

편집은 젬에서 sshkit 보석은 여전히 ​​버그가 포함 된 것으로 의심 후에, 나는 내 Capfile에

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

을 추가하고 내 로컬 gemset 재건. 그러나이 문제를 해결하지 못했고 다른 곳을 보도록 지시했습니다. 거기에서 나는 나의 Capfile에이 라인에 의해 정의 된 루비 파일의 가져 오기에 관련된 것으로 문제를 진단 할 수 있었다 : 나는 아웃 라인을 주석

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 작업에 의해 올바르게 호출됩니다.나는 작업 보석 세트를 수출하고 루비 보석에서 sshkit을 사용하여 새로운 보석 세트를 만들었습니다. 위에 나열된 require_relative 행을 사용하면 rubygems의 sshkit gem이 정상적으로 작동합니다. 그래서 문제는 sshkit의 버그가 아니 었습니다. 소스 (git이나 rubygems)를 사용하고 있었는지에 관계없이 내 모자 태스크가 호출했던 함수를 포함하는 루비 파일을 가져 왔습니다.

답변

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 보석 소스가 내 문제가 아니 었습니다. 오히려 가져 오기 문과 관련된 문제입니다.

변경 라인 :

# 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 메서드가 저에게 효과적이지 않은지 잘 모르겠습니다. 내가 잘못한 것을 계산하면 나중에 캡 배포에서 가져 오기를 일반화하는 데 유용 할 것이라는 기대로 연산자 오류가 있다고 가정합니다.