Задача обновления кода Capistrano 2 без использования sudo

Я использую Capistrano 2(.15.4) для развертывания приложений rails (я знаю, пытаюсь добраться до 3, но пока не совсем). У нас настраивается новая серверная среда, в которой ИТ-специалисты предпочитают доступ через нашего собственного пользователя и предоставляют пользователю возможность развертывания.

Я тестировал с помощью:

set :use_sudo, true
set :sudo, "sudo -u <user>"

Мне кажется, что sudo работает для заданных вручную задач, которые используют команду 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"]
...

Обратите внимание, что функциональность deploy: restart определяется вручную как:

cmd = "touch #{current_path}/tmp/restart.txt"
sudo cmd

но это не похоже на то, что sudo запускает автоматическую задачу update_code при развертывании:

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
...

Любое руководство о том, почему sudo не применяется к задаче update_code, будет высоко оценено, спасибо!

2 ответа

Решение

Capistrano не реализован для поддержки описанного вами варианта использования. Вы можете попытаться установить переменную git для включения sudo (set:git, 'sudo git'), однако вы, вероятно, столкнетесь с проблемой того, что ваш перенаправленный ключ аутентификации недоступен для команды sudo'ed git.

Возможно, более плодотворная стратегия предполагает добавление вашего пользователя в группу владельца папки, в которую пытается извлечь cap, а затем установка разрешения на запись в группу для этой папки.

Попробуйте определить ваши удаленные команды sudo, как рекомендовано в последней документации 2.x или точно в версии2.14.5

обратите особое внимание на часть, которая описывает синтаксис вызова sudo от имени другого пользователя:
#{sudo :as => 'bob'} + ссылаясь на run вместо cmd

Копайтесь глубже в рубиновых источниках, чтобы понять, как вызывается sudo: https://github.com/capistrano/capistrano/blob/legacy-v2/lib/capistrano/shell.rb

Тупая копировальная паста из документации:

Определение

sudo(options={}) sudo(command, options={}, &block)

модуль

Capistrano:: Конфигурация:: Действия:: Призвание
Действие sudo используется для выполнения команд через [ http://en.wikipedia.org/wiki/Sudo sudo]. Его можно использовать любым из двух способов (хотя один не рекомендуется). Хотя вы можете использовать sudo непосредственно в вызовах run(), этот помощник позволяет 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

Укажите пароль ''prompt'' (не сам пароль!), Который должен использовать sudo при запросе пароля. Вам не нужно когда-либо изменять это (по умолчанию это "пароль sudo: "), поскольку это необходимо только для того, чтобы Capistrano мог распознать приглашение sudo и передать его пользователю. Установка значения этой переменной в пустую строку приведет к тому, что Capistrano не будет запрашивать какой-либо конкретный запрос пароля.

sudo(command, options={}, &block)

Такое использование sudo устарело и включено только для обратной совместимости с некоторыми рецептами Capistrano. Он по сути идентичен run(), за исключением того, что он будет добавлять к команде префикс sudo (см. Первое использование sudo()).

sudo "apachectl restart" sudo "crontab -l", :as => "bob"

Обратите внимание, что этот синтаксис не позволяет выполнять сложные команды сценария оболочки или объединять команды в один вызов. Смотрите первый синтаксис для этого.

Другие вопросы по тегам