Как установить целевые хосты в файле Fabric - PullRequest
107 голосов
/ 24 февраля 2010

Я хочу использовать Fabric для развертывания кода моего веб-приложения на серверах разработки, подготовки и производства. Мой файл:

def deploy_2_dev():
  deploy('dev')

def deploy_2_staging():
  deploy('staging')

def deploy_2_prod():
  deploy('prod')

def deploy(server):
  print 'env.hosts:', env.hosts
  env.hosts = [server]
  print 'env.hosts:', env.hosts

Пример вывода:

host:folder user$ fab deploy_2_dev
env.hosts: []
env.hosts: ['dev']
No hosts found. Please specify (single) host string for connection:

Когда я создаю задачу set_hosts(), как показано в документах Fabric , env.hosts устанавливается правильно. Тем не менее, это не жизнеспособный вариант, а также не декоратор. Передача хостов в командной строке в конечном итоге приведет к некоторому сценарию оболочки, который вызывает fabfile, я бы предпочел, чтобы один инструмент выполнял эту работу правильно.

В документе Fabric говорится, что «env.hosts - это просто объект списка Python». По моим наблюдениям, это просто неправда.

Может кто-нибудь объяснить, что здесь происходит? Как настроить хост для развертывания?

Ответы [ 15 ]

3 голосов
/ 28 ноября 2011

Это очень просто. Просто инициализируйте переменную env.host_string, и все следующие команды будут выполнены на этом хосте.

from fabric.api import env, run

env.host_string = 'user@exmaple.com'

def foo:
    run("hostname -f")
3 голосов
/ 10 августа 2010

Вам необходимо изменить env.hosts на уровне модуля, а не в функции задачи. Я сделал ту же ошибку.

from fabric.api import *

def _get_hosts():
    hosts = []
    ... populate 'hosts' list ...
    return hosts

env.hosts = _get_hosts()

def your_task():
    ... your task ...
2 голосов
/ 26 марта 2017

Вот еще один шаблон "summersault", который позволяет использовать fab my_env_1 my_command:

С этим шаблоном нам нужно только определить среду один раз, используя словарь. env_factory создает функции на основе имен ключей ENVS. Я помещаю ENVS в его собственную директорию и файл secrets.config.py, чтобы отделить конфигурацию от кода фабрики.

Недостаток в том, что, как написано, добавление декоратора @task сломает его .

Примечания: Мы используем def func(k=k): вместо def func(): на фабрике из-за поздней привязки . Мы получаем работающий модуль с этим решением и исправляем его для определения функции.

secrets.config.py

ENVS = {
    'my_env_1': {
        'HOSTS': [
            'host_1',
            'host_2',
        ],
        'MY_OTHER_SETTING': 'value_1',
    },
    'my_env_2': {
        'HOSTS': ['host_3'],
        'MY_OTHER_SETTING': 'value_2'
    }
}

fabfile.py

import sys
from fabric.api import env
from secrets import config


def _set_env(env_name):
    # can easily customize for various use cases
    selected_config = config.ENVS[env_name]
    for k, v in selected_config.items():
        setattr(env, k, v)


def _env_factory(env_dict):
    for k in env_dict:
        def func(k=k):
            _set_env(k)
        setattr(sys.modules[__name__], k, func)


_env_factory(config.ENVS)

def my_command():
    # do work
2 голосов
/ 12 мая 2010

Вы можете присвоить env.hoststring перед выполнением подзадачи. Присвойте эту глобальную переменную в цикле, если вы хотите перебрать несколько хостов.

К сожалению, для нас с вами, ткань не предназначена для этого случая использования. Проверьте функцию main на http://github.com/bitprophet/fabric/blob/master/fabric/main.py, чтобы увидеть, как она работает.

0 голосов
/ 31 января 2012

Использование ролей в настоящее время считается «правильным» и «правильным» способом сделать это, и это то, что вам «следует» сделать.

Тем не менее, если вы похожи на большинство из того, что вы «хотели бы» или «хотели», так это способность выполнять «витую систерию» или переключать целевые системы на лету.

Таким образом, только для развлекательных целей (!) Следующий пример иллюстрирует то, что многие могут счесть рискованным, и в то же время каким-то образом полностью удовлетворяющим маневром, который выглядит примерно так:

env.remote_hosts       = env.hosts = ['10.0.1.6']
env.remote_user        = env.user = 'bob'
env.remote_password    = env.password = 'password1'
env.remote_host_string = env.host_string

env.local_hosts        = ['127.0.0.1']
env.local_user         = 'mark'
env.local_password     = 'password2'

def perform_sumersault():
    env_local_host_string = env.host_string = env.local_user + '@' + env.local_hosts[0]
    env.password = env.local_password
    run("hostname -f")
    env.host_string = env.remote_host_string
    env.remote_password = env.password
    run("hostname -f")

Затем работает:

fab perform_sumersault
...