Автономный фабфайл для ткани? - PullRequest
8 голосов
/ 19 июля 2010

Можно ли сделать fabfile автономным?
Я не очень люблю запускать внешний инструмент 'fab'. Если мне удастся получить автономный файл fabfile, я смогу запустить файл из (Eclipse / Pydev) IDE, легко отладить его, использовать конфигурации проекта и пути и т. Д. Почему это не работает:

from fabric.api import run

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

if __name__ == '__main__':
    host_type()    

Ответы [ 10 ]

13 голосов
/ 19 июня 2011

В конце концов я нашел решение (и оно действительно простое!).
В своем фабфиле я добавил:

from fabric.main import main

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

Надеюсь, это поможет людям ...

3 голосов
/ 19 июля 2010

Если я правильно помню, я не мог заставить Fabric API делать то, что хотел.Я решил полностью отказаться от дополнительного слоя и напрямую использовать Paramiko (базовая библиотека SSH, используемая в Fabric):

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.У меня есть несколько проектов, как веб-, так и консольных, использующих таким образом Paramiko, и у меня не было особых проблем.

Paramiko тщательно документировано .

2 голосов
/ 22 августа 2013

Поскольку 1.5.0 , есть лучший способ сделать это, чем возиться с argv.

import fabric.main

def main():
    fabric.main.main(fabfile_locations=[__file__])

if __name__ == "__main__":
    main()

Это также можно использовать как консольный скрипт в setup.py

2 голосов
/ 26 мая 2012
# 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()
2 голосов
/ 23 февраля 2012

docs.fabfile.org / ы / 1.4.0 / использование / library.html

"Как упоминается в этом разделе, ключ просто в том, что run, sudo и другие при подключении операции выглядят только в одном месте: env.host_string. Все другие механизмы настройки хостов интерпретируются с помощью потрясающего инструмента когда он запускается, и не имеет значения при работе в качестве библиотеки. "

Я смотрел на ту же проблему, когда нашел это. Кроме того, при просмотре я вспоминаю упоминание о том, что при использовании в fabfile изменения env не должны совпадать с def, sudo Кто знает, применяется ли это по-прежнему при использовании в режиме «библиотеки».

РЕДАКТИРОВАТЬ: Вот пример указанной реализации

from fabric.api import env, run

def main():
    run("uname -a")

def setup():
    env.host_string = "me@remoteHost"

if __name__ == '__main__':
    setup()
    main()
2 голосов
/ 12 января 2012

Я хорошо настроил приведенный выше пример, чтобы пропустить аргументы 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()
2 голосов
/ 19 июля 2010

Это не очень хорошее решение, но оно будет работать:

import subprocess

def hello():
    print 'Hello'

if __name__ == '__main__':
    subprocess.call(['fab', '-f', __file__, 'hello'])
1 голос
/ 12 января 2013

Добавьте это в конец вашего потрясающего файла.

if __name__ == '__main__':
  from fabric.main import main
  import sys

  sys.argv = ['fab', '-f', __file__] + sys.argv[1:]

  main()
0 голосов
/ 01 октября 2015

Я нашел решение косвенно для запуска файла фабрики, переименованного в отличное от fabfile.py и без пароля ssh

def deploy():
    ...

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

Этот способ также работает, если в вашем файле нет .py расширение.

0 голосов
/ 21 апреля 2014

Это моя измененная версия ответа Грега , который изменяет поведение по умолчанию, отображая доступные команды вместо перечисления тонн параметров ткани.

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__])
...