Capistrano 3 change ssh_options inside task

戏子无情 提交于 2020-01-10 03:03:26

问题


I trying to run capistrano v.3 task in same stage with diferent ssh_options.

my production.rb say:

set :stage, :production

set :user, 'deploy'
set :ssh_options, { user: 'deploy' }

With this configuration capistrano connect with user deploy which is correct for the rest of taks. But I need connect it for one specific task with an_other_user wich is well configured in server. Then my recipe say:

...
tasks with original user
...

task :my_task_with_an_other_user do
  set :user, 'an_other_user'
  set :ssh_options, { user: 'an_other_user' }

  on roles(:all) do |host|
    execute :mkdir, '-p', 'mydir'
  end
end

...
other tasks with original user
...

When execute:

cap production namespace:my_task_with_an_other_user

capistrano make ssh conexion with original :user "deploy" (the user declared in production.rb).

How can I change the user and/or ssh_options it inside task?


回答1:


Capistrano 3

I had hard time finding out a solution. But the solution is much nicer than version 2. Cap team has done a great job. Make sure you have updated Capistrano to 3.2.x+ Here's the trick:

# in config/deploy/production.rb, or config/deploy/staging.rb
# These roles are used for deployment that works with Cap hooks
role :app, %w{deploy@myserver.com}
role :web, %w{deploy@myserver.com}
role :db,  %w{deploy@myserver.com}

# Use additional roles to run side job out side Capistrano hooks
# 'foo' is another ssh user for none-release purpose tasks (mostly root tasks).
# e.g. user 'deploy' does not have root permission, but 'foo' has root permission.
# 'no_release' flag is important to flag this user will skip some standard hooks
# (e.g. scm/git/svn checkout )
role :foo_role, %w{foo@myserver.com}, no_release: true

Make sure both 'deploy' & 'foo' user can ssh into the box. Within your tasks, use the on keyword:

task :restart do
  on roles(:foo_role) do
    sudo "service nginx restart"
  end
end

task :other_standard_deployment_tasks do
  on release_roles(:all) do
     # ...
  end
end

Other gotchas:

Make sure some Capistrano tasks skips the additional no release role you added. Otherwise, it might cause file permission issues during deployment. E.g. capistrano/bundler extension need to override the default bundler_roles

set :bundler_roles, %w(web app db)  # excludes the no release role.
  • Read more about no_release flag: related Github issue.

Capistrano 2

I used to have a custom functions to close and reconnect ssh sessions.

  • Reference Paul Gross's Blog

Place the following methods in deploy.rb. Call with_user to switch ssh session. Slightly simplified version:

def with_user(new_user, &block)
  old_user = user
  set :user, new_user
  close_sessions
  yield
  set :user, old_user
  close_sessions
end

def close_sessions
  sessions.values.each { |session| session.close }
  sessions.clear
end

Usage:

task :update_nginx_config, :roles => :app do
  with_user "root" do
    sudo "nginx -s reload"
  end
end



回答2:


Answer of @activars didn't work for me. Because when I defined several roles for one environment - only one was deployed :(

So my solution was to create several enviroments, e.g. production.rb and productionroot.rb.

productionroot has content with no_release=true flag - just as you've specified:

server '146.120.89.81', user: 'root', roles: %w{foo_role}, no_release: true

After that I've created sh script which runs

#/usr/bin/env bash
bundle exec cap production deploy
bundle exec cap productionroot deploy


来源:https://stackoverflow.com/questions/22054076/capistrano-3-change-ssh-options-inside-task

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!