开发者

Python Fabric: How to handle arbitrary remote shell prompt for input?

This is related to this question here, but with a slight twist: instead of just passing 'yes' or 'no', I need Fabric to pass an arbitrary string to the remote shell.

For instance, if the remote shell prompts for 'what is your name?' then I need to feed it 'first,last'.

Clarification: I know I said arbitrary input, but I was rea开发者_开发技巧lly trying to use it for the SSH key passwd prompt when I try to do a git pull.

Update #1: Got a response from Jeff Forcier @bitprophet

  • that’s like the #1 wart right now :( Either tunnelling to send a key agent out-of-band, or remote prompting, is needed.

  • I meant adding support for those things in Fabric, is what we need to do to get network-borne git ops working

  • Adding an easy way to kick off an OOB ssh agent-friendly tunnel is going to be easier/faster, most likely. Soon probably


I have proposed an API for this feature in fabric on the mailinglist, and ended up writing something myself:

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')

See my blogpost on expecting prompts in fabric with fexpect


Interaction with remote servers is finally supported in Fabric 1.0. See this page for details.


Maybe look into pexpect


I've set up a git origin repository called 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

I leave branch web checked out. Back to the local machine.

I pull from the server via clone and added my project dir contents in branch master on the local repo. Stll not using fabric, just setting things up, although these steps could be automated too, I suppose, and none of them need another ssh passphrase.

   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"

Now I start using fabric. Below is excerpted from my fabfile for managing git tags and branches:

  #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)

To use the above fabfile defs, I just make some changes to my project dir, think of an apporpriate message about them, and do:

$fab committag

and I have changes tagged and updated on the server. Or:

$fab committag brpush

and I have a new branch created and the server updated.


One way of skipping the host verification prompt is:

run('ssh-keyscan github.com > ~/.ssh/known_hosts')

Also, I'm using py-github to install the deploy keys:

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)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜