Я хочу использовать Fabric для развертывания кода моего веб-приложения на серверах разработки, тестирования и производства. Мой fabfile:
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». По моим наблюдениям, это просто неправда.
Кто-нибудь может объяснить, что здесь происходит? Как я могу настроить хост для развертывания?
Ответы:
Я делаю это, объявляя фактическую функцию для каждой среды. Например:
Используя вышеуказанные функции, я бы набрал следующее для развертывания в моей тестовой среде:
... и следующее для развертывания в производственной среде:
Хорошая вещь о делать это таким образом, что
test
иprod
функции могут быть использована до любой потрясающей функции, а не просто развернуть. Это невероятно полезно.источник
code.fabfile.org
домену есть такие ответы.fab A B C
стиле, если они не определены как задачи.Использовать ролевые определения
Выберите роль с помощью -R:
источник
roledef
?'password': 'some_password'
Кажется, что следующая словарная запись игнорируется и приводит к запросу во время выполнения.Вот более простая версия ответа serverhorror :
источник
env
переменных, а не для их первоначальной установки. Я думаю, что использование roledefs , как предположил Томи, более подходит для определения хостов, таких как stage, dev и test.На этом застрял сам, но наконец разобрался. Вы просто не можете установить конфигурацию env.hosts из внутри задачи. Каждая задача выполняется N раз, по одному разу для каждого указанного хоста, поэтому настройка принципиально выходит за рамки задачи.
Глядя на свой код выше, вы можете просто сделать это:
Кажется, это будет делать то, что вы собираетесь.
Или вы можете написать некоторый собственный код в глобальной области видимости, который анализирует аргументы вручную и устанавливает env.hosts до определения вашей функции задачи. По нескольким причинам я собственно так и настроил свою.
источник
from fabric.api import env
:;env.host_string = "dev"
Начиная с fab 1.5 это документированный способ динамической установки хостов.
http://docs.fabfile.org/en/1.7/usage/execution.html#dynamic-hosts
Цитата из документа ниже.
источник
В отличие от некоторых других ответов, то есть можно изменить
env
переменные среды в рамках задачи. Однако этоenv
будет использоваться только для последующих задач, выполняемых с помощьюfabric.tasks.execute
функции.Без упаковки подзадач будут использоваться настройки
execute(...)
уровня вашего модуляenv
или все, что передается изfab
интерфейса командной строки.источник
Вам нужно
host_string
подать пример:источник
Чтобы объяснить, почему это вообще проблема. Команда fab использует структуру библиотеки для выполнения задач в списках хостов. Если вы пытаетесь изменить список хостов внутри задачи, вы, по сути, пытаетесь изменить список во время итерации по нему. Или в случае, если у вас не определены хосты, переберите пустой список, где код, в котором вы устанавливаете цикл для перебора, никогда не выполняется.
Использование env.host_string позволяет обойти такое поведение только в том смысле, что он указывает непосредственно функциям, с какими хостами подключаться. Это вызывает некоторые проблемы, поскольку вы будете переделывать цикл выполнения, если хотите, чтобы для выполнения было несколько хостов.
Самый простой способ, которым люди могут установить хосты во время выполнения, - это сохранить заполнение env в виде отдельной задачи, которая устанавливает все строки хоста, пользователей и т. Д. Затем они запускают задачу развертывания. Выглядит это так:
или
Где постановка и производство похожи на задачи, которые вы дали, но сами они не вызывают следующую задачу. Причина, по которой он должен работать так, заключается в том, что задача должна завершиться и выйти из цикла (хостов, в случае env None, но в этот момент это цикл из одного), а затем цикл должен быть завершен хосты (теперь определенные предыдущей задачей) заново.
источник
Вам нужно изменить env.hosts на уровне модуля, а не в функции задачи. Я совершил ту же ошибку.
источник
Все очень просто. Просто инициализируйте переменную env.host_string, и все следующие команды будут выполнены на этом хосте.
источник
Я новичок в фабрике, но чтобы заставить фабрику запускать одни и те же команды на нескольких хостах (например, для развертывания на нескольких серверах одной командой), вы можете запустить:
где staging-server и production-server - это 2 сервера, на которых вы хотите запустить действие развертывания. Вот простой файл fabfile.py, который отображает имя ОС. Обратите внимание, что файл fabfile.py должен находиться в том же каталоге, где вы запускаете команду fab.
Это работает по крайней мере с тканью 1.8.1.
источник
Итак, чтобы установить хосты и запустить команды на всех хостах, вам нужно начать с:
Как только они будут определены, запустите команду в командной строке:
Что будет запускать задачу развертывания на всех серверах, перечисленных в функции PROD, поскольку она устанавливает env.hosts перед запуском задачи.
источник
Вы можете назначить
env.hoststring
перед выполнением подзадачи. Назначьте эту глобальную переменную в цикле, если вы хотите перебрать несколько хостов.К сожалению для вас и меня, ткань не предназначена для этого варианта использования. Ознакомьтесь с
main
функцией на http://github.com/bitprophet/fabric/blob/master/fabric/main.py, чтобы узнать, как она работает.источник
Вот еще один паттерн «саммерсальта», который позволяет
fab my_env_1 my_command
использовать:С помощью этого шаблона нам нужно только один раз определить среду, используя словарь.
env_factory
создает функции на основе имёнENVS
. Я помещаюENVS
в отдельный каталог и файл,secrets.config.py
чтобы отделить конфигурацию от кода фабрики.Недостатком является то, что, как написано, добавление
@task
декоратора сломает его .Примечания: мы используем
def func(k=k):
вместоdef func():
на заводе из-за позднего связывания . Мы получаем работающий модуль с этим решением и исправляем его, чтобы определить функцию.secretts.config.py
fabfile.py
источник
Использование ролей в настоящее время считается «правильным» и «правильным» способом сделать это, и это то, что вам «следует» делать.
Тем не менее, если вы похожи на большую часть того, что вы «хотели» или «желаете», так это возможность выполнять «сложную систему» или переключать целевые системы на лету.
Таким образом, исключительно в развлекательных целях (!) Следующий пример иллюстрирует то, что многие могут посчитать рискованным, но в то же время вполне удовлетворительным маневром, который выглядит примерно так:
Затем запускаем:
источник