Equivalent to "ask" in capistrano 2.x - capistrano

I'm trying to write a Capistrano task and would like to ask the user for some input. In Capistrano > 3.2 there's ask:
set :database_password, ask('Enter the database password:', 'default', echo: false)
(from http://capistranorb.com/documentation/getting-started/user-input/)
Is there an equivalent in Capistrano 2.x? If not, what's the preferred way of doing this?

Related

How to reconfigure rails 4 to use mongodb

I want to configure my existing rails application to use mongoid instead of a sql database. Ideally, I would have used "rails new --skip-active-record name_here." How do I do this after I've already made an application? I haven't done anything with the model or database yet so there are no files that i created relating to the database aside from what was made when I created the rails project.
You can start by manually removing references to ActiveRecord::Base in your model files and replace them by include Mongoid::Document
You might also need to comment every line starting by config.active_record in your environment configuration files.
You'll find these files in /config/environments/
Then you can use the rails g mongoid:config command to generate the mongoid.yml configuration file.
PS : When using rake you'll have to use rake db:mongoid:* commands.
EDIT:
Also remove require rails/all
You'll have to require each framework separately, for example :
require "action_controller/railtie"
require "action_mailer/railtie"
require "sprockets/railtie"
require "rails/test_unit/railtie"
The complete list of frameworks included in rails/all is here :
active_record
action_controller
action_view
action_mailer
active_job
rails/test_unit
sprockets
You can also disable all migration check in test/test_helper.rb

capistrano doesn't call deploy:start when executing deploy:cold

I'm using capistrano 2 to deploy my application. According to the documentation, the deploy:cold task will call deploy:update followed by deploy:migrate and finally call deploy:start.
In my application I don't have a migration step, and when I run cap deploy:cold, it does the update but then shows this:
* 2014-04-09 14:57:45 executing `deploy:migrate'
`deploy:migrate' is only run for servers matching {:roles=>:db, :only=>{:primary=>true}}, but no servers matched
and deploy:start is not being called. If I call it manually, it works fine - but never through deploy:cold. What am I missing?
The problem is that Capistrano 2 defines a default task called deploy:migrate that is specified to run only for the role :db. If you don't have that role in your application (which most do not), then when deploy:migrate runs it will error out on the missing role, and that kind of error normally terminates the deployment scenario.
This can happen for other tasks, if you have a complex setup where some tasks are only run for specific servers. This behavior is not documented at all at Capistrano's site, which is a shame.
Starting with Capistrano 2.7 there is a way to circumvent the "is only run for servers matching role" error, by specifying a task property that tells Capistrano to skip tasks if no servers matches any of its specified roles:
For example:
namespace :deploy do
task :stuff, :roles => :somerole, :on_no_matching_servers => :continue do
# stuff
end
end
Now this works well for custom tasks, but how to set this for the default task migrate ? you have to override the task with your own setting and add the :on_no_matching_servers option. I've added this to the global.rb file:
namespace :deploy do
task :migrate, :on_no_matching_servers => :continue do end
end

Capistrano in Open Source Projects and different environments

I consider to use Capistrano to deploy my rails app on my server. Currently I'm using a script, which does all the work for me. But Capistrano looks pretty nice and I want to give it a try.
My first problem/question now is: How to use Capistrano properly in open source projects? I don't want to publish my deploy.rb for several reasons:
It contains sensible informations about my server. I don't want to publish them :)
It contains the config for MY server. For other people, which deploy that open source project to their own server, the configuration may differ. So it's pretty senseless to publish my configuration, because it's useless for other people.
Second problem/question: How do I manage different environments?
Background: On my server I provide two different environments for my application: The stable system using the current stable release branch and located under www.domain.com. And a integration environment for the develop team under dev.domain.com running the master branch.
How do I tell Capistrano to deploy the stable system or the dev system?
The way I handle sensitive information (passwords etc.) in Capistrano is the same way I handle them in general: I use an APP_CONFIG hash that comes from a YAML file that isn't checked into version control. This is a classic technique that's covered e.g. in RailsCast #226, or see this StackOverflow question.
There are a few things you have to do a little differently when using this approach with Capistrano:
Normally APP_CONFIG is loaded from your config/application.rb (so it happens early enough to be usable everywhere else); but Capistrano cap tasks won't load that file. But you can just load it from config/deploy.rb too; here's the top of a contrived config/deploy.rb file using an HTTP repository that requires a username/password.
require 'bundler/capistrano'
APP_CONFIG = YAML.load_file("config/app_config.yml")
set :repo_user, APP_CONFIG['repo_user']
set :repo_password, APP_CONFIG['repo_password']
set :repository, "http://#{repo_user}:#{repo_password}#hostname/repositoryname.git/"
set :scm, :git
# ...
The config/app_config.yml file is not checked into version control (put that path in your .gitignore or similar); I normally check in a config/app_config.yml.sample that shows the parameters that need to be configured:
repo_user: 'usernamehere'
repo_password: 'passwordhere'
If you're using the APP_CONFIG for your application, it probably needs to have different values on your different deploy hosts. So have your Capistrano setup make a symlink from the shared/ directory to each release after it's checked out. You want to do this early in the deploy process, because applying migrations might need a database password. So in your config/deploy.rb put this:
after 'deploy:update_code', 'deploy:symlink_app_config'
namespace :deploy do
desc "Symlinks the app_config.yml"
task :symlink_app_config, :roles => [:web, :app, :db] do
run "ln -nfs #{deploy_to}/shared/config/app_config.yml #{release_path}/config/app_config.yml"
end
end
Now, for the second part of your question (about deploying to multiple hosts), you should configure separate Capistrano "stages" for each host. You put everything that's common across all stages in your config/deploy.rb file, and then you put everything that's unique to each stage into config/deploy/[stagename].rb files. You'll have a section in config/deploy.rb that defines the stages:
# Capistrano settings
require 'bundler/capistrano'
require 'capistrano/ext/multistage'
set :stages, %w(preproduction production)
set :default_stage, 'preproduction'
(You can call the stages whatever you want; the Capistrano stage name is separate from the Rails environment name, so the stage doesn't have to be called "production".) Now when you use the cap command, insert the stage name between cap and the target name, e.g.:
$ cap preproduction deploy #deploys to the 'preproduction' environment
$ cap production deploy #deploys to the 'production' environment
$ cap deploy #deploys to whatever you defined as the default

Capistrano deploy how to use use_sudo and admin_runner

I'm trying to configure Capistrano so that it works for our server setup. We are deploying symfony projects so i'm also using capifony. I'm still experiencing some problems with permissions.
On our server every project runs as a project user, so every project has it's own user. So i configured use_sudo and set it to true and i configured the admin_runner to be the user of the project. But it still didn't work so i modified the capifony to start using try_sudo in stead of the regular run. Which made it work a little bit better. But i'm a bit confused about what to use in which case. You have try_sudo, sudo and run. But which is needed for which use-case?
When you use run i think it'll always be your local user
try_sudo i think will check if the use_sudo flag is true if so it will use the sudo command if not it will use the local user. If you have admin_runner configured it will sudo to the user configured as admin_runner
sudo will always try to sudo
Now my problem is the deploy:symlink method this is also just a regular run command so it executes as the local user, which gives permission problems when i try to view the website.
So can anyone tell me if my description of the 3 commands is correct? and also does anyone know how the admin_runner and use_sudo is suposed to be used, so that the symlink is also being done correctly (and also all other commands done by capistrano)?
kind regards,
Daan
Apologies for such a tardy answer Daan. Your understanding of Capistrano is correct. Note also that the :use_sudo flag defaults to true.
In Capistrano 2.11.2, you'll find lib/capistrano/configuration/variables.rb:
_cset(:run_method) { fetch(:use_sudo, true) ? :sudo : :run }
and lib/capistrano/recipes/deploy.rb:
def try_sudo(*args)
options = args.last.is_a?(Hash) ? args.pop : {}
command = args.shift
raise ArgumentError, "too many arguments" if args.any?
as = options.fetch(:as, fetch(:admin_runner, nil))
via = fetch(:run_method, :sudo)
if command
invoke_command(command, :via => via, :as => as)
elsif via == :sudo
sudo(:as => as)
else
""
end
end
Perhaps your permissions problem involves your server, running as a normal user, not being able to read the contents of the release directory that your current symlink is pointing to?

How to deploy to multiple redundant production servers with "cap deploy"?

Capistrano is working great to deploy to a single server. However, I have multiple production API servers for my web application. When I deploy, my code needs to get deployed to every API server at once. Specifying each server manually is NOT the solution I am looking for (e.g. I don't want to do "cap api1 deploy; cap api2 deploy").
Is there a way, using Capistrano, to deploy to all servers at once, with just a simple "cap deploy"? I'm wondering what changes I would need to make to a typical deploy.rb file, whether I'd need to create a separate file for each server, and whether and how the Capfile would need to be changed. Also, I need to be able to specify a different deploy_to path for each server. And ideally, I wouldn't have to repeat things in different config files for different servers (eg. wouldn't have to specify :repository, :application, etc. multiple times).
I have spent hours searching Google on this and looking through tutorials, but I have found nothing helpful.
Here is a snippet from my current deploy.rb file:
set :application, "testapplication"
set :repository, "ssh://domain.com//srv/hg/#{application}"
set :scm, :mercurial
set :deploy_to, "/srv/www/#{application}"
role :web, "domain.com"
role :app, "domain.com"
role :db, "domain.com", :primary => true, :norelease => true
Should I just use the multistage extension and do this?
task :deploy_everything do
system "cap api1 deploy"
system "cap api2 deploy"
system "cap api2 deploy"
end
That could work, but I feel like this isn't what this extension is meant for...
It seems like you might be interested in the "Multiple Servers" heading on the Getting Started page. Is that what you're after?