Python Fabric: Как обработать произвольную подсказку удаленной оболочки для ввода?
Это связано с этим вопросом здесь, но с небольшим поворотом: вместо того, чтобы просто передавать "да" или "нет", мне нужна Fabric, чтобы передать произвольную строку в удаленную оболочку.
Например, если удаленная оболочка запрашивает "как вас зовут?" тогда мне нужно кормить его "первым, последним".
Пояснение: я знаю, что сказал произвольный ввод, но я действительно пытался использовать его для приглашения SSH-ключа passwd, когда я пытаюсь сделать git pull.
Обновление № 1: Получил ответ от Джеффа Форсье @bitprophet
5 ответов
Взаимодействие с удаленными серверами наконец поддерживается в Fabric 1.0. Смотрите эту страницу для деталей.
Я предложил API для этой функции в ткани в списке рассылки и в итоге написал что-то сам:
from fexpect import expect, expecting, run
prompts = []
prompts += expect('What is your name?','John')
prompts += expect('Where do you live?','New York')
with expecting(prompts):
run('command')
Смотрите мой пост на тему ожидающих подсказок в ткани с fexpect
Один из способов пропустить запрос подтверждения хоста:
run('ssh-keyscan github.com > ~/.ssh/known_hosts')
Также я использую py-github для установки ключей развертывания:
run('ssh-keygen -q -t rsa -f /home/%(user)s/.ssh/id_rsa -N ""' % env)
key = run('cat /home/%(user)s/.ssh/id_rsa.pub' % env)
gh.repos.addDeployKey(repo, env.host, key)
Я установил репозиторий git origin под названием project_name/.git.
ssh to the server, (entering ssh passwords or passphrases as I go)
mkdir project_name
cd project_name
git init
touch fabfile.py
git add fabfile.py
git commit -a -m "almost empty"
git checkout -b web
Я оставляю сеть филиалов проверенной. Вернуться к локальной машине.
Я вытаскиваю информацию с сервера через клон и добавляю содержимое моего каталога проекта в мастер-ветку локального репо. Я не использую fabric, а просто настраиваю, хотя эти шаги тоже можно автоматизировать, и ни один из них не нуждается в другой ssh-фразе.
cd /path/to/project_name/..
git clone ssh://joe@some_server.com/var/web/project_name/.git
cd project_name
gvim fabfile.py
git add fabfile.py
git commit -a -m "fabfile edits"
Теперь я начинаю использовать ткань. Ниже приведен фрагмент моего фаб-файла для управления тегами и ветками git:
#Usage: fab committag brpush | fab committag push | fab push | fab tag
def committag():
"""commit chgs, tag new commit, push tags to server."""
prompt('commit descr: ', 'COM_MSG', default='new stuff')
prompt('commit name: ', 'COM_NAME', default='0.0.1')
local('git commit -a -m "%(COM_MSG)s"' % env)
local('sleep 1')
local('git tag -u "John Griessen" -m "%(COM_MSG)s" %(COM_NAME)s' % env)
local('sleep 1')
local('git push origin --tags') #pushes local tags
def brpush():
"""create a new branch, default COM_NAME, then push to server."""
prompt('new branch name: ', 'BR_NAME', default= '%(COM_NAME)s' % env)
local('git checkout -b %(BR_NAME)s' % env)
local('sleep 2')
local('git checkout master')
local('git push origin --tags') #pushes local tags
local('git push --all origin') #pushes local master and branches
def push():
"""Push existing tags and changes to server."""
local('git push origin --tags') #pushes local tags
local('git push --all origin') #pushes local master and branches
def tag(): #Call this from committag()
"""create a gpg signed tag on the local git repo tag from prompted name ."""
prompt('tag descr: ', 'TAG_MSG', default='0.0.1')
prompt('tag name: ', 'TAG_NAME', default='0.0.1')
local('git tag -u "John Griessen" -m "%(TAG_MSG)s" %(TAG_NAME)s' % env)
Чтобы использовать описанные выше определения fabfile, я просто делаю некоторые изменения в директории моего проекта, думаю о соответствующем сообщении о них и делаю:
$fab committag
и у меня есть изменения, помеченные и обновленные на сервере. Или же:
$fab committag brpush
и я создал новую ветку и обновил сервер.