Chcę używać Fabric do wdrażania kodu mojej aplikacji internetowej na serwerach deweloperskich, pomostowych i produkcyjnych. Mój plik fab:
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
Przykładowe dane wyjściowe:
host:folder user$ fab deploy_2_dev
env.hosts: []
env.hosts: ['dev']
No hosts found. Please specify (single) host string for connection:
Kiedy tworzę set_hosts()
zadanie, jak pokazano w dokumentacji Fabric , env.hosts jest ustawiany poprawnie. Jednak nie jest to opłacalna opcja, podobnie jak dekorator. Przekazywanie hostów w wierszu poleceń ostatecznie doprowadziłoby do powstania jakiegoś skryptu powłoki, który wywołuje plik fabfile, wolałbym, aby jedno narzędzie wykonało zadanie poprawnie.
W dokumentacji Fabric jest napisane, że „env.hosts jest po prostu obiektem listy Pythona”. Z moich obserwacji wynika, że to po prostu nieprawda.
Czy ktoś może wyjaśnić, co się tutaj dzieje? Jak ustawić hosta do wdrożenia?
Odpowiedzi:
Robię to, deklarując rzeczywistą funkcję dla każdego środowiska. Na przykład:
Korzystając z powyższych funkcji, wpisałbym następujące polecenie, aby wdrożyć w moim środowisku testowym:
... i następujące elementy do wdrożenia do produkcji:
Zaletą robienia tego w ten sposób jest to, że funkcji
test
iprod
można używać przed każdą funkcją fab, a nie tylko wdrażaniem. Jest niesamowicie przydatny.źródło
code.fabfile.org
domeny mają podobne odpowiedzi.fab A B C
stylu bez zdefiniowania ich jako zadań.Użyj roledefs
Wybierz rolę za pomocą -R:
źródło
roledef
? Kolejny wpis w słowniku'password': 'some_password'
wydaje się być ignorowany i prowadzi do zachęty w czasie wykonywania.Oto prostsza wersja odpowiedzi serverhorror :
źródło
env
zmiennych, a nie do ich początkowego ustawiania. Myślę, że używanie roledefs , jak sugeruje thomie, jest bardziej odpowiednie do definiowania hostów, takich jak stage, dev i test.Utknąłem na tym sam, ale w końcu to rozgryzłem. Po prostu nie możesz ustawić konfiguracji env.hosts z poziomu zadania. Każde zadanie jest wykonywane N razy, raz dla każdego określonego hosta, więc ustawienie zasadniczo wykracza poza zakres zadania.
Patrząc na swój kod powyżej, możesz po prostu zrobić to:
Co wydaje się, że zrobi to, co zamierzasz.
Możesz też napisać niestandardowy kod w zakresie globalnym, który ręcznie analizuje argumenty i ustawia env.hosts przed zdefiniowaniem funkcji zadania. Z kilku powodów tak właśnie skonfigurowałem mój.
źródło
from fabric.api import env
:;env.host_string = "dev"
Od fab 1.5 jest to udokumentowany sposób na dynamiczne ustawianie hostów.
http://docs.fabfile.org/en/1.7/usage/execution.html#dynamic-hosts
Cytat z poniższego dokumentu.
źródło
W przeciwieństwie do niektórych innych odpowiedzi, to jest możliwe, aby zmodyfikować
env
zmienne środowiskowe w ramach zadania. Jednakenv
będzie to używane tylko do kolejnych zadań wykonywanych przy użyciufabric.tasks.execute
funkcji.Bez zawijania pod-zadań
execute(...)
, zostaną użyteenv
ustawienia na poziomie modułu lub cokolwiek zostanie przekazane zfab
CLI.źródło
Musisz
host_string
podać przykład:źródło
Aby wyjaśnić, dlaczego to w ogóle problem. Polecenie fab wykorzystuje strukturę biblioteki do wykonywania zadań na listach hostów. Jeśli spróbujesz zmienić listę hostów w zadaniu, zasadniczo próbujesz zmienić listę podczas iteracji po niej. Lub w przypadku, gdy nie masz zdefiniowanych żadnych hostów, zapętlaj pustą listę, w której kod, w którym ustawiono pętlę listy, nigdy nie jest wykonywany.
Użycie env.host_string jest obejściem tego zachowania tylko dlatego, że określa bezpośrednio w funkcjach, z którymi hostami mają się łączyć. Powoduje to pewne problemy polegające na tym, że przerobisz pętlę wykonywania, jeśli chcesz mieć kilka hostów do wykonania.
Najprostszym sposobem, w jaki ludzie udostępniają możliwość ustawiania hostów w czasie wykonywania, jest utrzymywanie zapełniania środowiska środowiska jako odrębnego zadania, które konfiguruje wszystkie ciągi znaków hosta, użytkowników itp. Następnie uruchamiają zadanie wdrażania. To wygląda tak:
lub
Tam, gdzie inscenizacja i produkcja są podobne do zadań, które powierzyłeś, ale same nie nazywają następnego zadania. Powodem, dla którego musi tak działać, jest to, że zadanie musi zakończyć się i wyjść z pętli (hostów, w przypadku env Brak, ale w tym momencie jest to pętla jednego), a następnie pętla hosty (teraz zdefiniowane przez poprzednie zadanie) na nowo.
źródło
Musisz zmodyfikować env.hosts na poziomie modułu, a nie w ramach funkcji zadania. Popełniłem ten sam błąd.
źródło
To jest bardzo proste. Wystarczy zainicjować zmienną env.host_string i wszystkie poniższe polecenia zostaną wykonane na tym hoście.
źródło
Jestem zupełnie nowy w strukturze, ale aby uzyskać Fabric do uruchamiania tych samych poleceń na wielu hostach (np. Aby wdrożyć na wielu serwerach, w jednym poleceniu), możesz uruchomić:
gdzie staging-serwer i produkcyjno-serwer są 2 serwery chcesz uruchomić akcję wdrożyć przeciwko. Oto prosty plik fabfile.py, który wyświetli nazwę systemu operacyjnego. Zauważ, że plik fabfile.py powinien znajdować się w tym samym katalogu, w którym uruchamiasz polecenie fab.
Działa to przynajmniej z tkaniną 1.8.1.
źródło
Tak więc, aby ustawić hosty i uruchomić polecenia na wszystkich hostach, musisz zacząć od:
Po ich zdefiniowaniu uruchom polecenie w wierszu poleceń:
Co spowoduje uruchomienie zadania wdrażania na wszystkich serwerach wymienionych w funkcji PROD, ponieważ ustawia env.hosts przed uruchomieniem zadania.
źródło
Możesz przypisać do
env.hoststring
przed wykonaniem podzadania. Przypisz do tej zmiennej globalnej w pętli, jeśli chcesz iterować na wielu hostach.Niestety dla ciebie i dla mnie tkanina nie jest przeznaczona do tego przypadku. Sprawdź
main
funkcję na http://github.com/bitprophet/fabric/blob/master/fabric/main.py, aby zobaczyć, jak to działa.źródło
Oto kolejny wzorzec „summersault”, który umożliwia rozszerzenie
fab my_env_1 my_command
użycie:W przypadku tego wzorca wystarczy, że raz zdefiniujemy środowiska za pomocą słownika.
env_factory
tworzy funkcje na podstawie nazw kluczyENVS
. UmieściłemENVS
we własnym katalogu i plikusecrets.config.py
aby oddzielić konfigurację od kodu tkaniny.Wadą jest to, że jak napisano, dodanie
@task
dekoratora spowoduje przerwanie .Uwagi: Używamy
def func(k=k):
zamiastdef func():
w fabryce z powodu późnego wiązania . Otrzymujemy działający moduł z tym rozwiązaniem i poprawiamy go, aby zdefiniować funkcję.secrets.config.py
fabfile.py
źródło
Używanie ról jest obecnie uważane za „właściwy” i „prawidłowy” sposób robienia tego i jest tym, co „powinieneś” robić.
To powiedziawszy, jeśli jesteś podobny do większości tego, co „chciałbyś” lub „pragniesz”, to umiejętność wykonywania „skręconej potyczki” lub przełączania systemów docelowych w locie.
Tak więc, wyłącznie dla celów rozrywkowych (!), Poniższy przykład ilustruje, co wielu może uznać za ryzykowny, a jednocześnie w pełni satysfakcjonujący manewr, który wygląda mniej więcej tak:
Następnie bieganie:
źródło