我正在使用 Capistrano 2(.15.4) 来部署 rails 应用程序(我知道,正在尝试升级到 3,但还没有完全实现)。我们正在设置一个新的服务器环境,IT 更喜欢通过我们自己的用户进行访问,并使用 sudo 来部署用户。
我一直在测试使用:
set :use_sudo, true
set :sudo, "sudo -u <user>"
在我看来,sudo 适用于使用须藤命令:
cap deploy:restart
...
triggering load callbacks
* 2014-09-01 11:34:28 executing `deploy:restart'
* executing "sudo -u <user> touch /path/to/deploy/current/tmp/restart.txt"
servers: ["hostname.com"]
...
请注意部署:重启功能手动定义为:
cmd = "touch #{current_path}/tmp/restart.txt"
sudo cmd
但确实如此不是看起来 sudo 会自动执行更新代码部署时的任务:
cap deploy
...
triggering load callbacks
* 2014-09-01 10:14:32 executing `deploy'
* 2014-09-01 10:14:32 executing `deploy:update'
** transaction: start
* 2014-09-01 10:14:32 executing `deploy:update_code'
updating the cached checkout on all servers
...
copying the cached version to /path/to/deploy/20140901171450
* executing "cp -RPp /path/to/deploy/shared/cached-copy /path/to/deploy/releases/20140901171450 && (echo 690 > /path/to/deploy/releases/20140901171450/REVISION)"
servers: ["hostname.com"]
[hostname.com] executing command
** [out :: hostname] cp: cannot create directory `/path/to/deploy/releases/20140901171450': Permission denied
command finished in 918ms
*** [deploy:update_code] rolling back
* executing "rm -rf /path/to/deploy/releases/20140901171450; true"
servers: ["hostname.com"]
[hostname.com] executing command
command finished in 922ms
...
任何关于原因的指导须藤不适用于更新代码这项任务将不胜感激,谢谢!
答案1
Capistrano 并未实现以支持您描述的用例。您可以尝试设置 git 变量以包含 sudo(set :git, 'sudo git'),但随后您可能会遇到转发的身份验证密钥无法用于 sudo 的 git 命令的问题。
也许更有成效的策略是将您的用户添加到 cap 尝试签出的文件夹所有者的组中,然后设置该文件夹的组可写权限。
答案2
尝试按照最新 2.x 中的建议定义 sudo 远程命令文档或者正好是 2.14.5版本
请特别注意描述以其他用户身份调用 sudo 的语法的部分:
#{sudo :as => 'bob'}
+ 调用run
而不是cmd
深入研究 ruby 源代码以了解如何调用 sudo: https://github.com/capistrano/capistrano/blob/legacy-v2/lib/capistrano/shell.rb
以下是从文档中直接复制粘贴的内容:
定义
sudo(options={}) sudo(command, options={}, &block)
模块
Capistrano::Configuration::Actions::Invocation
sudo 操作用于通过 [http://en.wikipedia.org/wiki/Sudosudo]。它有两种使用方式(尽管其中一种已被弃用)。虽然您可以在 run() 调用中直接使用 sudo,但此帮助程序使 Capistrano 能够在远程服务器提示输入 sudo 密码时提示您输入。
sudo(options={})
这种使用 sudo 的方式实际上并不执行任何操作。相反,它返回一个包含要执行的 sudo 命令的字符串。这样您就可以将其嵌入通过 run 调用的命令中,从而允许您构建使用 sudo 的任意复杂命令。
run "#{sudo} apachectl restart" run "#{sudo :as => 'bob'} crontab -l" run "cd /u/apps/social && #{sudo} script/restart" run "if [ ! -d /u/apps ]; then #{sudo} mkdir -p /u/apps; fi"
参数
选项
:as
指定要以 sudo 身份使用的用户。默认值为 nil,这通常与指定“root”作为用户相同。
变量
:sudo
指定服务器上 sudo 的路径。默认为“sudo”,但如果服务器上的 sudo 位于非标准位置或名称不是“sudo”,则可以相应地设置此变量。
:sudo_password
指定 sudo 在要求输入密码时应使用的密码“prompt”(而不是密码本身!)。您永远不需要更改它(默认值为“sudo password:”),因为这只是为了让 Capistrano 能够识别 sudo 提示并将提示传递给用户。将此变量的值设置为空字符串将导致 Capistrano 不请求任何特定的密码提示。
sudo(command, options={}, &block)
这种 sudo 用法已弃用,仅用于与某些 Capistrano 配方向后兼容。它本质上与 run() 相同,只是它会在命令前加上 sudo(请参阅 sudo() 的第一次使用)。
sudo "apachectl restart" sudo "crontab -l", :as => "bob"
请注意,此语法不允许使用复杂的 shell 脚本命令,也不允许在一次调用中将命令链接在一起。请参阅第一个语法。