переключиться на другого пользователя, используя ткань

Недавно я начал искать ткань для удаленного развертывания. Мне нужно переключиться на пользователя diff (от того, под которым я вхожу), и я не могу понять это. Возможно ли это, если да, то как? У моего текущего пользователя нет разрешений sudo.

Я попытался изменить следующие переменные среды

env.sudo_prefix = "su newUser -c "
env.sudo_prompt = "Password:"

Но ткань не ждет ввода пароля для «newUser» и терпит неудачу.

out: Password: 
[[email protected]] out: su: incorrect password

Fatal error: sudo() received nonzero return code 1 while executing!

Requested: touch x
Executed: su newUser -c  -u "root"  /bin/bash -l -c "cd /home/oldUser/upgrade && touch x"

Aborting.
Disconnecting from [email protected]... done.

Обновлять:

Как предположил Дж. Ф. Себастьян, su newUser -c работает, но запрашивает пароль для каждой команды для каждого сервера, что противоречит цели автоматизации. Есть ли способ в Fabric передать одно и то же значение на основе подсказки (в данном случае это всегда Password:)


person shailesh mangal    schedule 28.09.2012    source источник
comment
ты пробовал sudo('su newuser')   -  person jfs    schedule 28.09.2012
comment
Да, я сделал. Проблема в том, что oldUser не является sudoer, поэтому любая команда sudo завершается с ошибкой [out: oldUser отсутствует в файле sudoers. Об этом инциденте будет сообщено.]   -  person shailesh mangal    schedule 28.09.2012
comment
это было бы наиболее логичным вариантом попробовать, но, к сожалению, нет :(   -  person shailesh mangal    schedule 28.09.2012
comment
документы говорят, что он должен работать без какой-либо настройки, т. е. run('su newuser -c command') работает как положено. Какая у вас версия ткани?   -  person jfs    schedule 28.09.2012
comment
Да, единственная проблема с этой командой заключается в том, что она запрашивает пароль для каждой команды запуска на сервере (Fabric не может сохранить это как пароль). Что в некотором смысле противоречит цели сценария.   -  person shailesh mangal    schedule 28.09.2012
comment
вы пробовали env.password в дополнение к env.sudo_*? Хотя ткань использует -S в префиксе sudo по умолчанию, т. е. она передает пароль через стандартный ввод, поэтому su может не работать, если она считывает пароль напрямую с tty.   -  person jfs    schedule 28.09.2012
comment
env.password для первоначального входа в систему. Я использую его в настоящее время.   -  person shailesh mangal    schedule 28.09.2012
comment
документы говорят, что он также используется для sudo   -  person jfs    schedule 28.09.2012
comment
Это правильно, sudo для текущего пользователя, и, следовательно, тот же пароль будет работать. В случае su это пользователь diff и, следовательно, потребуется пароль diff. Для этого нет другого заполнителя.   -  person shailesh mangal    schedule 28.09.2012
comment
не могли бы вы временно изменить env.password: with settings(password=newuser_password): sudo(command)?   -  person jfs    schedule 28.09.2012


Ответы (2)


Спасибо J F Sebastian, было несколько уловов.

  1. Fabric устанавливает соединения лениво, поэтому мне пришлось создать фиктивное соединение перед вызовом su, чтобы избежать переключения контекста.
  2. Pwd необходимо хранить в глобальной области видимости, чтобы его можно было использовать повторно. Fabric не помещает его в кеш для переопределенной команды su.

Вот что в итоге получилось. Это работает.

pwd = None
@hosts('myhost.com')
def test():
    with cd('/home/oldUser/upgrade'):
        run('ls')  #This is to connect aggressively (instead of lazily)
        global pwd  #Change the scope of pwd
        if pwd is None:
            pwd = getpass.getpass('enter password for newUser')

        execute(su, pwd, 'newUser', 'touch x')  
        run ('ls')
        execute(su, pwd, 'newUser', 'rm x') 
        run ('ls')

def su(pwd, user, command):
    with settings(
        password= "%s" % pwd,
        sudo_prefix="su %s -c " % user,
        sudo_prompt="Password:"
        ):
        sudo(command)
person shailesh mangal    schedule 28.09.2012

Если вы не можете использовать ssh как newuser и не можете использовать sudo(command, user='newuser'):

import getpass # just for demonstration
from fabric.api import sudo, settings

def su(user, command):
    with settings(password=getpass.getpass('enter password for %s: ' % user),
                  sudo_prefix="su %s -c " % user,
                  sudo_prompt="Password:"):
        sudo(command)
person jfs    schedule 28.09.2012