Capistrano 3 Task Argument Error - ruby-on-rails

I'm using a capistrano 3 task that should work, but am getting the error:
> cap staging deploy --trace
** Invoke staging (first_time)
** Invoke use_rvm (first_time)
** Execute use_rvm
** Execute staging
** Invoke load:defaults (first_time)
** Execute load:defaults
cap aborted!
Task Argument Error
/Users/stevenspiel/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/rake-10.4.2/lib/rake/task_manager.rb:109:in `resolve_args_with_dependencies'
/Users/stevenspiel/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/rake-10.4.2/lib/rake/task_manager.rb:75:in `resolve_args'
/Users/stevenspiel/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/rake-10.4.2/lib/rake/task_manager.rb:27:in `define_task'
/Users/stevenspiel/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/rake-10.4.2/lib/rake/task.rb:365:in `define_task'
/Users/stevenspiel/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/rake-10.4.2/lib/rake/dsl_definition.rb:66:in `task'
config/deploy.rb:65:in `<top (required)>'
...
the task is straightforward:
set :backup_to, '/home/deployer/app/db_backups'
desc 'Backup the remote production database'
task :backup_database, roles: :db, only: { primary: true } do
run "mkdir -p #{backup_to}" # create backup folder unless already exists
filename = "#{backup_to}/app_#{Time.now.strftime '%Y%m%d%H%M%S'}.sql.gz"
# Check if we've got database config
database_config = File.join(deploy_to, '/current/config/database.yml')
if remote_file_exists?(database_config)
text = capture("cat #{database_config}")
# `capture` is returning some bad whitespace that YAML::load can't handle.
# This strips out whitespace except for innocuous spaces and newlines.
text.gsub!(/[^\n \S]/, '')
config = YAML::load(text)[rails_env]
on_rollback { run "rm #{filename}" } # if migration rolls back, removes backup
run "pg_dump -U #{config['username']} #{config['database']} -W -h #{config['host']} | gzip --best > #{filename}" do |ch, stream, out|
ch.send_data "#{config['password']}\n" if out =~ /^Password:/
end
else
logger.debug('[BackupDatabase] No configuration file was found.')
end
end
before 'deploy:migrate', :backup_database if rails_env == 'staging'
And the error is coming from the task declaration:
task :backup_database, roles: :db, only: { primary: true } do
What is wrong with it?
EDIT
Thanks to basia's suggestion, I ended up doing this:
task :backup_database do
on roles(:app), except: { primary: true } do
...
end
end

You're using Capistrano 2 syntax and for Capistrano 3 the syntax is different than 2, have a look https://semaphoreapp.com/blog/2013/11/26/capistrano-3-upgrade-guide.html. Your code should look more like that (not tested):
task :backup_database do
roles(:db) do
.....
on
end
Or downgrade to Cap 2 :)

Related

capistrano3: Don't know how to build task 'deploy:create_db'

I use capistrano3 to deploy my rails app.
deploy.rb
namespace :deploy do
after "deploy", "deploy:create_db"
after "deploy", "deploy:migrate"
after "finishing", "deploy:restart"
task :restart do
on roles(:web) do
execute "mkdir -p #{current_path}/tmp"
execute "touch #{current_path}/tmp/restart.txt"
end
end
task :create_db do
on roles(:web) do
execute "cd #{current_path}; bundle exec rake db:create RAILS_ENV=#{rails_env}"
end
end
end
When I run cap -T, the error occurred as below:
(Backtrace restricted to imported tasks)
cap aborted!
Don't know how to build task 'deploy:create_db'
(See full trace by running task with --trace)
cap -T --trace
** Invoke load:defaults (first_time)
** Execute load:defaults
cap aborted!
Don't know how to build task 'deploy:create_db'
/Library/Ruby/Gems/2.0.0/gems/rake-10.4.2/lib/rake/task_manager.rb:62:in `[]'
/Library/Ruby/Gems/2.0.0/gems/rake-10.4.2/lib/rake/task.rb:353:in `[]'
/Library/Ruby/Gems/2.0.0/gems/capistrano-3.3.5/lib/capistrano/dsl/task_enhancements.rb:12:in `after'
/Users/liuxingqi/Public/Spar/config/deploy.rb:53:in `block in <top (required)>'
Hope someone can help me, Thanks in advance!!!
I think you should define tasks first...
Try this:
namespace :deploy do
task :restart do
on roles(:web) do
execute "mkdir -p #{current_path}/tmp"
execute "touch #{current_path}/tmp/restart.txt"
end
end
task :create_db do
on roles(:web) do
execute "cd #{current_path}; bundle exec rake db:create RAILS_ENV=#{rails_env}"
end
end
after "deploy", "deploy:create_db"
after "deploy", "deploy:migrate"
after "finishing", "deploy:restart"
end

When deploying, "undefined local variable or method `branch' for #<SSHKit::Backend::Netssh:>"

I'm in the midst of upgrading my Rails app to Capistrano 3 and I seem to have hit a wall.
When running cap staging deploy, I get this error:
** Invoke staging (first_time)
** Execute staging
** Invoke load:defaults (first_time)
** Execute load:defaults
** Invoke bundler:map_bins (first_time)
** Execute bundler:map_bins
** Invoke deploy:set_rails_env (first_time)
** Execute deploy:set_rails_env
** Invoke deploy:set_rails_env
** Invoke deploy (first_time)
** Execute deploy
** Invoke deploy:starting (first_time)
** Execute deploy:starting
** Invoke deploy:check (first_time)
** Execute deploy:check
** Invoke git:check (first_time)
** Invoke git:wrapper (first_time)
** Execute git:wrapper
** Execute git:check
** Invoke deploy:check:directories (first_time)
** Execute deploy:check:directories
** Invoke deploy:check:linked_dirs (first_time)
** Execute deploy:check:linked_dirs
** Invoke deploy:check:make_linked_dirs (first_time)
** Execute deploy:check:make_linked_dirs
** Invoke deploy:check:linked_files (first_time)
** Execute deploy:check:linked_files
** Invoke deploy:set_previous_revision (first_time)
** Execute deploy:set_previous_revision
** Invoke deploy:started (first_time)
** Execute deploy:started
** Invoke deploy:check_revision (first_time)
** Execute deploy:check_revision
cap aborted!
SSHKit::Runner::ExecuteError: Exception while executing on host %HIDDEN_HOST_NAME%: undefined local variable or method `branch' for #<SSHKit::Backend::Netssh:0x007fe8958826f8>
config/deploy.rb:35:in `block (3 levels) in <top (required)>'
/Users/user/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/sshkit-1.5.1/lib/sshkit/backends/netssh.rb:54:in `instance_exec'
/Users/user/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/sshkit-1.5.1/lib/sshkit/backends/netssh.rb:54:in `run'
/Users/user/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/sshkit-1.5.1/lib/sshkit/runners/parallel.rb:13:in `block (2 levels) in execute'
NameError: undefined local variable or method `branch' for #<SSHKit::Backend::Netssh:0x007fe8958826f8>
config/deploy.rb:35:in `block (3 levels) in <top (required)>'
/Users/user/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/sshkit-1.5.1/lib/sshkit/backends/netssh.rb:54:in `instance_exec'
/Users/user/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/sshkit-1.5.1/lib/sshkit/backends/netssh.rb:54:in `run'
/Users/user/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/sshkit-1.5.1/lib/sshkit/runners/parallel.rb:13:in `block (2 levels) in execute'
Tasks: TOP => deploy:check_revision
The deploy has failed with an error: #<SSHKit::Runner::ExecuteError: Exception while executing on host %HIDDEN_HOST_NAME%: undefined local variable or method `branch' for #<SSHKit::Backend::Netssh:0x007fe8958826f8>>
** Invoke deploy:failed (first_time)
** Execute deploy:failed
Here is my Capfile:
# Load DSL and Setup Up Stages
require 'capistrano/setup'
# Includes default deployment tasks
require 'capistrano/deploy'
require 'capistrano/bundler'
require 'capistrano/rails'
require 'capistrano/rails/migrations'
require 'capistrano/rails/assets'
require 'new_relic/recipes'
# Loads custom tasks from `lib/capistrano/tasks' if you have any defined.
Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r }
Rake.application.options.trace = true
Rake.application.options.backtrace = true
Here is deploy.rb
# config valid only for Capistrano 3.1
lock '3.2.1'
set :application, "%HIDDEN%"
set :repo_url, "%HIDDEN%"
ask :branch, proc { `git rev-parse --abbrev-ref HEAD`.chomp }
# I've also tried simply set :branch, "master" but same result
set :git_enable_submodules, 1
set :bundle_flags, "--deployment --verbose"
set :rails_env, "production"
set :pty, true
set :linked_files, %w{config/database.yml}
set :linked_dirs, %w{bin log tmp vendor/bundle public/system}
set :config_files, %w{database.example.yml}
And staging.rb
location = "%HIDDEN_HOST_NAME%"
role :app, location
role :web, location, no_release: true
role :db, location
server location, roles: %w{web app db}
set :ssh_options, {
user: "deploy",
forward_agent: true,
}
Per http://capistranorb.com/documentation/getting-started/cold-start/, I can run cap staging check_write_permissions and cap staging git:check just fine. No errors there. Running cap production deploy produces the same error.
Any ideas? Thanks in advance!
It turned out I had a task that was referring to #{branch}. This worked in Cap 2 but not Cap 3 apparently.
This was the fix:
desc "Make sure local git is in sync with remote."
task :check_revision do
branch = fetch(:branch) # <--- This line fixed it
on roles(:app) do
unless ENV["IGNORE_GIT_SYNC"]
unless `git rev-parse HEAD` == `git rev-parse origin/#{branch}`
puts "WARNING: HEAD is not the same as origin/#{branch}"
puts "Run `git push` to sync changes."
puts "(set IGNORE_GIT_SYNC=1 to ignore this)"
exit
end
end
end
end

My Capistrano does not set the RAILS_ENV variable

My Capistrano deployment does not set the RAILS_ENV variable when running the bundle command. I don't understand why.
My Gemfile is :
source 'https://rubygems.org'
ruby '2.1.3'
gem 'capistrano', '~> 3.2.1'
gem 'capistrano-rails', '~> 1.1.1'
My deploy.rb :
set :stage, :production
set :rails_env, 'production'
set :bundle_flags, '--deployment'
set :bundle_env_variables, { rails_env: "production" }
namespace :sphinx do
desc "Index Sphinx"
task :index do
on roles(:app) do
within release_path do
execute :rake, "rake ts:index"
end
end
end
When running :
➜ ansible-sharetribe git:(master) ✗ bin/cap production sphinx:index --trace
** Invoke production (first_time)
** Execute production
** Invoke load:defaults (first_time)
** Execute load:defaults
** Invoke bundler:map_bins (first_time)
** Execute bundler:map_bins
** Invoke deploy:set_rails_env (first_time)
** Execute deploy:set_rails_env
** Invoke deploy:set_rails_env
** Invoke sphinx:index (first_time)
** Execute sphinx:index
INFO[3ca70ab5] Running bundle exec rake rake ts:index on www.myapplication.com
cap aborted!
SSHKit::Runner::ExecuteError: Exception while executing on host www.myapplication.com: rake exit status: 1
rake stdout: Nothing written
rake stderr: Digest::Digest is deprecated; use Digest
rake aborted!
NameError: uninitialized constant Annotate
If I write :
execute :rake, "rake ts:index RAILS_ENV=production"
it works. Why is RAILS_ENV=production not set automatically?
You can use this syntax in your task
execute :rake, "rake ts:index", "RAILS_ENV=#{fetch :rails_env}"
I have the same problem.
I ran rake secret and got "NameError: uninitialized constant Annotate" error.
After i set RAILS_ENV=production, it worked like charm.
I dont know why RAILS_ENV wasnt set but BTW thanks so much.
Saved me a lot of time

No such file or directory during cap deploy:update

I noticed in the output from cap deploy:update, that it is triggering "deploy:assets:precompile" as an after callback for deploy:update_code:
triggering after callbacks for `deploy:update_code'
* 2013-05-15 11:32:16 executing `deploy:assets:precompile'
triggering before callbacks for `deploy:assets:precompile'
* 2013-05-15 11:32:16 executing `deploy:assets:update_asset_mtimes'
* executing "[ -e /home/johnmerlino/public_html/store.johnmerlino.com/shared/assets/manifest* ] && cat /home/johnmerlino/public_html/store.johnmerlino.com/shared/assets/manifest* || echo"
servers: ["xxx.xx.xx.xxx"]
[xxx.xx.xx.xxx] executing command
command finished in 314ms
* executing "cd -- /home/johnmerlino/public_html/store.johnmerlino.com/releases/20130515153214 && bundle exec rake RAILS_ENV=production RAILS_GROUPS=assets assets:precompile"
servers: ["xxx.xx.xx.xxx"]
[xxx.xx.xx.xxx] executing command
** [out :: xxx.xx.xx.xxx] rake aborted!
** [out :: xxx.xx.xx.xxx] No such file or directory - /home/johnmerlino/public_html/store.johnmerlino.com/releases/20130515153214/config/config.yml
** [out :: xxx.xx.xx.xxx
Now the problem there is it says that the latest release doesn't have a "config.yml" file.
Actually in my capistrano script, that file is created after "deploy:update_code":
after "deploy:update_code", "deploy:symlink_shared_configs"
namespace :deploy do
desc "Symlink configuration files"
task :symlink_shared_configs, :roles => [:db,:app] do
run "ln -nfs #{shared_path}/config/database.yml #{release_path}/config/database.yml"
run "ln -nfs #{shared_path}/config/config.yml #{release_path}/config/config.yml"
end
task :start do ; end
task :stop do ; end
task :restart, :roles => :app, :except => { :no_release => true } do
run "#{try_sudo} touch #{File.join(current_path,'tmp','restart.txt')}"
end
end
So shouldn't config.yml be created by this time?
If both are being triggered in the list of callbacks for after deploy:update_code then they're essentially part of the same callback group, but the order in which callbacks in the same group are called depends on the implementation of the callback registration and execution.
If you need them to run in a given order then you can explicitly change when assets:precompile is run by moving it later, or moving the config.yml file earlier in order to guarantee that one comes before the other.
As it stands now, since they both run in the after deploy:update_code the order in which they get executed could be either:
...before...
deploy:update_code
...after... | after group
deploy:symlink_shared_configs | after group
deploy:assets:precompile | after group
...OR...
...before...
deploy:update_code
...after... | after group
deploy:assets:precompile | after group
deploy:symlink_shared_configs | after group
...and based on the fact that you've posted this question, it sounds like the latter instance is happening for you.

Capistrano Trouble From Git

I am new to using git and Capistrano. I have setup everything else on my server and pushed my app onto a git repo (http://github.com/tnederlof/daily-trailer). When I go to run cap deploy:cold everything seems to be working until it tries to rake the db. Below is what I get when I run it, this is the last bunch of information I recieve and where the error occurs:
* executing "cd /var/www/dailytrailer.net/releases/20100205052047; rake RAILS_ENV=production db:migrate"
servers: ["173.203.201.168"]
[173.203.201.168] executing command
** [out :: 173.203.201.168] (in /var/www/dailytrailer.net/releases/20100205052047)
command finished
* executing `deploy:start'
[DEPRECATED] `deploy:start` is going to be removed after 2.5.9 - see http://is.gd/2BPeA
* executing "cd /var/www/dailytrailer.net/current && nohup script/spin"
servers: ["173.203.201.168"]
[173.203.201.168] executing command
** [out :: 173.203.201.168] nohup: ignoring input and appending output to `nohup.out'
** [out :: 173.203.201.168] nohup: cannot run command `script/spin': No such file or directory
command finished
failed: "sh -c 'cd /var/www/dailytrailer.net/current && nohup script/spin'" on 173.203.201.168
Can someone please help me figure out what script/spin is all about?
Thank you!
Do you know what you're trying to use for an app server? If it's Passenger, then you've got something screwed up in your deploy.rb. (Post that file if you want more help debugging this.) If it's mongrel, then this should be helpful.
http://www.rubyrobot.org/article/deploying-rails-20-to-mongrel-with-capistrano-21
so I am having the sam problem here
Everything gets executed expect for
executing `deploy:start'
[DEPRECATED] `deploy:start` is going to be removed after 2.5.9 - see http://is.gd/2BPeA
* executing "cd /srv/www/domain.com/domain/current && nohup script/spin"
servers: ["domain.com"]
[domain.com] executing command
** [out :: domain.com] nohup: ignoring input and appending output to `nohup.out'
** [out :: domain.com] nohup: cannot run command `script/spin': No such file or directory
command finished
failed: "sh -c 'cd /srv/www/domain.com/domain/current && nohup script/spin'" on domain.com
here is my deploy file don't see any problems as is
set :application, "domain"
set :repository, "git#git.assembla.com:domain.git"
set :user, "blitz"
set :use_sudo, false
set :scm, :git
# Or: `accurev`, `bzr`, `cvs`, `darcs`, `git`, `mercurial`, `perforce`, `subversion` or `none`
set :deploy_to, "/srv/www/domain.com/#{application}"
#set :git_enable_submodules, 1 # Make sure git submodules are populated
set :port, 3002 # The port you've setup in the SSH setup section
#set :ssh_options, { :forward_agent => true }
default_run_options[:pty] = true
role :web, "domain.com" # Your HTTP server, Apache/etc
role :app, "domain.com" # This may be the same as your `Web` server
role :db, "domain.com", :primary => true # This is where Rails migrations will run
#role :db, "domain.com" # for slave db
# If you are using Passenger mod_rails uncomment this:
# if you're still using the script/reapear helper you will need
# these http://github.com/rails/irs_process_scripts
namespace :deploy do
desc "Restarting mod_rails with restart.txt"
# task :start do ; end
# task :stop do ; end
task :restart, :roles => :app, :except => { :no_release => true } do
run "#{try_sudo} touch #{File.join(current_path,'tmp','restart.txt')}"
end
desc "Make symlink for database.yml"
task :symlink_dbyaml do
run "ln -nfs #{shared_path}/config/database.yml #{release_path}/config/database.yml"
end
desc "Create empty database.yml in shared path"
task :create_dbyaml do
run "mkdir -p #{shared_path}/config"
put '', "#{shared_path}/config/database.yml"
end
end
after 'deploy:setup', 'deploy:create_dbyaml'
after 'deploy:update_code', 'deploy:symlink_dbyaml'
after "deploy", "deploy:cleanup"
edit:
never-mind found the ans
was using passenger and needed this in the deploy.rb
[:start, :stop].each do |t|
desc "ignore #{t} since we are using passenger"
task t do ; end
end

Resources