zoukankan      html  css  js  c++  java
  • farbic plugin fexpect,bravo!

    Fexpect: Dealing with prompts in fabric with pexpect

    Fexpect: Dealing with prompts in fabric with pexpect

    Tuesday 06 March 2012

    Update: Fexpect has been improved and is now on pypi and github (new blogpost)

    Fabric is a popular python library for executing commands on a remote computer over ssh. It is commonly used for deployment or provisioning tasks. Often however, these tasks ask for user feedback through a prompt (“Continue? Y/N”). Fabric has no built-in way to code how to deal with such a prompt, which means that execution of the script will pause until the user provides the answer to the prompt.

    There are several other tools available to ‘expect’ such a prompt and answer with a scripted response. Among those are the unix tools ‘yes’ and ‘expect’ [1]. Others have suggested to use these for situations that require prompt interaction in fabric scripts. One common use case is for an OS-upgrade, which usually includes several prompts.

    A more elegant solution would be an extension of fabric. I recently suggested such a plugin on the fabric mailing list [2], and will describe my solution in more details here. It involves using the python version of ‘expect’, pexpect [3].

    In short, it entails compiling a short fexpect script, sending it along with the fexpect library to the target machine using put(), and executing it.

    Fabric scripts have to formulate expectations, i.e. prompts, and the corresponding answer (‘y’):
    from fexpect import expect
    expectation = expect("Continue \[yN\]",'y')
    
    Notice that we escape the brackets, since the expectation is formulated as a regular expression to match the prompt.

    We can combine expectations in a list, since often a command prompts multiple questions:
    prompts = []
    prompts += expect(‘What is your name?’,'Jasper')
    prompts += expect('Where do you live?','Frankfurt')
    
    And then we run the command with a context manager for the expectations:
    from fexpect import expecting, run #or import ‘as erun’ not to confuse with fabric.api.run
    
    with expecting(prompts):
        run(‘command’)
    
    Here are some extracts from the code to see what’s going on:

    The context manager just stores the expectations in the fabric state:
    class ExpectationContext(object):
        def __init__(self,expectations):
            self.expectations = expectations
        def __enter__(self):
            env.expectations = self.expectations
        def __exit__(self, type, value, tb):
            env.expectations = []
    
    A custom run function (sudo also available):
    def run(cmd):
        #sudo wrapper
        wrappedCmd = wrapExpectations(cmd,env)
        return fabric.api.run(wrappedCmd)
    
    Which calls the actual ‘magic’:
    def wrapExpectations(cmd,env):
        script = createScript(cmd,env)
        remoteScript = '/tmp/fexpect_'+shortuuid.uuid()
        fabric.api.put(resource('pexpect.py'),'/tmp/')
        fabric.api.put(StringIO(script),remoteScript)
        wrappedCmd = 'python '+remoteScript
        return wrappedCmd
    
    Which in turn calls a simple function which creates the pexpect script.

    Get the complete module and some tests at github: fexpect


    Links:

    Comments? Write me an email or discuss on facebook, google+ or twitter.

  • 相关阅读:
    Cocos2dx开发(3)——Cocos2dx打包成APK,ANT环境搭建
    Cocos2dx开发(2)——Win8.1下Cocod2dx 3.2环境搭建
    Cocos2dx开发(1)——Win8.1下 NDK r10 环境搭建
    设计模式备忘录(1):适配器模式、依赖注入依赖倒置、空对象模式
    使用latencytop深度了解你的系统的延迟(转)
    操作系统基础
    计算机基础
    说明exit()函数作用的程序
    变量的引用类型和非引用类型的区别
    二进制转16进制JAVA代码
  • 原文地址:https://www.cnblogs.com/lexus/p/2465831.html
Copyright © 2011-2022 走看看