【问题标题】:Stand-alone fabfile for fabric?织物的独立fabfile?
【发布时间】:2015-10-01 16:34:32
【问题描述】:

是否可以使 fabfile 独立?
我不太喜欢运行外部工具“fab”。如果我设法获得独立的 fabfile,我可以从(Eclipse / Pydev)IDE 中运行该文件,轻松调试它,使用项目配置和路径等。
为什么这不起作用:

from fabric.api import run

def host_type():
    run('uname -s')

if __name__ == '__main__':
    host_type()    

【问题讨论】:

    标签: python fabric


    【解决方案1】:

    我最终找到了解决方案(而且非常简单!)。
    在我的 fabfile 中,我添加了:

    from fabric.main import main
    
    if __name__ == '__main__':
        import sys
        sys.argv = ['fab', '-f', __file__, 'update_server']
        main()
    

    我希望这对人们有所帮助......

    【讨论】:

    • 这会产生像 muksie 的解决方案这样的子进程吗?我探索这个问题的主要原因是我们想要消除额外的子流程。
    • 如果您更改 sys.argv 分配,它将适用于任何命令集。 sys.argv[0] 已经是脚本名称,所以: sys.argv = ['fab', '-f'] + sys.argv
    • 只要文件具有.py 扩展名,它就可以工作。我还没有找到使它适用于任何扩展的方法。
    【解决方案2】:

    如果我没记错的话,我也无法让 Fabric API 做我想做的事。我决定完全放弃额外的层,直接使用Paramiko(Fabric 使用的底层 SSH 库):

    import os
    import paramiko
    
    ssh = paramiko.SSHClient()
    ssh.load_system_host_keys()
    ssh.load_host_keys(os.path.expanduser('~/.ssh/known_hosts'))
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh.connect('hostname.example.com', 22, 'username', 'password')
    ssh.save_host_keys(os.path.expanduser('~/.ssh/known_hosts'))
    stdin, stdout, stderr = ssh.exec_command('uname -s')
    print stdout.read()
    

    虽然涉及更多步骤,但这样做可以让您直接利用 SSH 层,而不是使用 subprocess 来生成另一个 Python 实例,或者找出 Fabric API。我有几个项目,包括 web 和控制台,都以这种方式使用 Paramiko,我没有遇到太多麻烦。

    帕拉米科是extensively documented

    【讨论】:

    • 遗憾的是,这对我来说是最好的答案。谢谢!
    【解决方案3】:

    这不是一个很好的解决方案,但会起作用:

    import subprocess
    
    def hello():
        print 'Hello'
    
    if __name__ == '__main__':
        subprocess.call(['fab', '-f', __file__, 'hello'])
    

    【讨论】:

    • 是的,不是很好(但非常原始+1!)。此外,不涉及 stdio(例如,交互式密码提示(我认为这是可解决的))。
    • 劫持顶部评论说在最新版本的fabric中你可以使用execute命令而不是subprocess.callfabric.readthedocs.org/en/1.4.3/usage/execution.html#execute
    【解决方案4】:

    我对上面的示例进行了微调,以通过 argv 参数传递给本地命令,并指定一个可选的 default_commands 列表而不是硬编码的命令名称。请注意,文件名必须具有 .py 扩展名,否则 fab 不会将其检测为 fab 文件!

    #!/usr/bin/env python
    from fabric.api import local
    
    default_commands = ['hello', ]
    
    def hello():
        print ('hello world')
    
    def hostname():
        local('hostname')
    
    if __name__ == '__main__':
       import sys
       from fabric.main import main
       sys.argv = ['fab', '-f', __file__,] +  default_commands + sys.argv[1:]
       main()
    

    【讨论】:

      【解决方案5】:

      docs.fabfile.org/en/1.4.0/usage/library.html

      “正如那部分提到的,关键是运行,sudo 和其他 连接时操作只在一个地方查看: env.host_string 。所有的 设置主机的其他机制由 fab 工具解释 当它运行时,作为库运行时无关紧要。”

      当我发现这个时,我正在寻找同样的问题。另外,在查看时我记得提到在 fabfile 中使用时,env 更改不应与 run、sudo 位于相同的 def 中。谁知道这在“图书馆”模式下是否仍然适用。

      编辑:这是上述实现的示例

      from fabric.api import env, run
      
      def main():
          run("uname -a")
      
      def setup():
          env.host_string = "me@remoteHost"
      
      if __name__ == '__main__':
          setup()
          main()
      

      【讨论】:

        【解决方案6】:
        # thanks to aaron, extending his code a little more
        # here is a little bit more of a graceful solution than running subprocess.call, and specifying multiple hosts
        
        from fabric.api import env, run
        
        def main():
            run("uname -a")
        
        def setup():
            env.hosts = ['host0','host1']
        
        if __name__ == '__main__':
            setup()
            for host in env.hosts:
                env.host_string = host
                main()
        

        【讨论】:

          【解决方案7】:

          自从1.5.0 以来,有一种比搞乱 argv 更好的方法。

          import fabric.main
          
          def main():
              fabric.main.main(fabfile_locations=[__file__])
          
          if __name__ == "__main__":
              main()
          

          这也可以用作 setup.py 中的控制台脚本

          【讨论】:

            【解决方案8】:

            将此添加到您的 fab 文件的底部。

            if __name__ == '__main__':
              from fabric.main import main
              import sys
            
              sys.argv = ['fab', '-f', __file__] + sys.argv[1:]
            
              main()
            

            【讨论】:

              【解决方案9】:

              这是我对Greg's answer 的修改版本,它更改了默认行为以显示可用命令,而不是列出大量的结构选项。

              if __name__ == '__main__':
                  # imports for standalone mode only
                  import sys, fabric.main
              
                  # show available commands by default
                  if not sys.argv[1:]:
                      sys.argv.append('--list')
              
                  fabric.main.main(fabfile_locations=[__file__])
              

              【讨论】:

                【解决方案10】:

                我在run fabric file renamed other than fabfile.py and password-less ssh间接找到了解决方案

                def deploy():
                    ...
                
                if __name__ == '__main__':
                    from fabric import execute
                    execute(deploy)
                

                如果您的文件没有.py 扩展名,这种方法也可以使用。

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2014-03-03
                  • 1970-01-01
                  • 2020-05-12
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多