2013-01-10 7 views
16

Próbuję uzyskać regułę powłoki, aby uniknąć reprovisioning wystąpienie maszyny wirtualnej, jeśli już to zrobił wcześniej.Unikaj reprovisioning Vagrant VM, jeśli jest już dostarczona

Rozważmy następujący Vagrantfile:

Vagrant::Config.run do |config| 
    config.vm.define :minimal do |config| 
    # Base image 
    config.vm.box = "lucid32" 
    config.vm.box_url = "http://files.vagrantup.com/lucid32.box" 

    config.vm.provision :shell, :inline => "mkdir /tmp/foobar" 
    end 
end 

Jeśli prowadzisz vagrant up minimal, stworzy pole i świadczenia początkowo. Jeśli następnie uruchomisz vagrant provision minimal, spróbujesz wyreperować to pole, ale to się nie powiedzie (ponieważ katalog/tmp/foobar już istnieje).

Czy istnieje sposób na sprawienie, by Vagrant pamiętał, czy w przeszłości udostępnił maszynę i uniknął jej późniejszego przeprojektowania?

Więcej kontekst: Jeżeli biegnę vagrant up minimal, ponownie uruchomić maszynę hosta, a następnie uruchom ponownie vagrant up minimal, będzie starał się zastrzegania pola i niepowodzeniem. Zdarza się to dość często, ponieważ VirtualBox często powoduje paniki jądra na moim komputerze-hoście.

Odpowiedz

10

To może nie być odpowiedź chcesz, ale jeśli zmieni mkdir Do mkdir -p, to będzie działać;)

Z całą powagą, choć myślę, Vagrant spodziewa provisioners być idempotent (czyli , jeśli zostanie uruchomiony po raz drugi, nie podejmie żadnych działań).

Wykonanie prawdziwej idempotencji może być trudne, w zależności od tego, co faktycznie robisz w skrypcie obsługi administracyjnej, ale dobry początek to mkdir -p. Można również utworzyć plik flagi w systemie i sprawdzić istnienie tego pliku flagowego; jeśli istnieje, po prostu exit 0.

+0

Dokonywanie idempotent Provisioner wydaje się być uzasadnione. Chociaż niekoniecznie łatwe. –

+1

Przebijam skrypt obsługi administracyjnej na sekcje w otoczeniu instrukcji if. Dotykam pliku na końcu każdej sekcji, a instrukcja if sprawdza, czy plik istnieje. Każda sekcja kodu będzie uruchamiana tylko raz. To dodaje bardzo małą złożoność, a ja mam funkcje do sprawdzania i zapisywania pliku, aby ograniczyć bałagan. Jak dotąd działa to całkiem dobrze. Sugerowałbym również, że "test -d/path/to/dir || mkdir/path/to/dir" może być lepszym sposobem radzenia sobie z tym konkretnym problemem. Istnieje również -f dla plików i -L dla dowiązań symbolicznych. "man bash" ma więcej. – bogeymin

+5

Prostym i głupim sposobem tworzenia idempotencji jest "dotknięcie ~/.VM_PROVISIONED" pod koniec procesu dostarczania (pod warunkiem, że wszystko się udało) i sprawdzenie jego istnienia na początku za pomocą '[-e ~/.VM_PROVISIONED]'. –

5

Czy sprawdziłeś to?

vagrant up --no-provision

$ vagrant up --help 
Usage: vagrant up [vm-name] [options] [-h] 

    --[no-]provision    Enable or disable provisioning 
    --provision-with x,y,z  Enable only certain provisioners, by type. 
    --[no-]parallel    Enable or disable parallelism if provider supports it. 
    --provider provider   Back the machine with a specific provider. 
-h, --help      Print this help 
+0

Użycie --no-provision wygląda tak, jak to będzie bezwarunkowo unikać udostępniania. Określanie opcji warunkowo za pomocą skryptu może zrobić lewy, choć nie jest idealny. –

4

Vagrant normalnie uruchamia kod zastrzegania tylko na pierwszejvagrant upi kiedy konkretnie powiedzieć to zrobić tak, jak z vagrant provision lub vagrant reload --provision. Naprawdę nie ma potrzeby, aby wyjść z drogi, aby uniknąć ponownego uruchamiania skryptów obsługi administracyjnej. (Ten may not have been the case when you posted the question, however.)

Jeśli używasz Chef lub Puppet do zapewniania, że ​​są już zaprojektowane, aby wszystko było gotowe, idempotent, i zakładam, że to samo dotyczy Salt and Ansible.

Jeśli używasz skryptów powłoki i chcesz uczynić je idempotent, można sprawdzić jakiegoś warunku (jak istnienie pliku) w instrukcji if:

if [[! -f "$HOME/bin/something.sh" ]]; then 
    # install something.sh into ~/bin 
fi 

Dałem bardzo ogólna odpowiedź, ponieważ zakładam, że mkdir /tmp/foobar nie jest naprawdę co chcesz osiągnąć, ale jeśli tak, to dodaj -p.

+0

Dziękuję za wzmiankę, że tylko uruchamianie narzędzia przy pierwszym uruchomieniu jest stosunkowo nową zmianą (7 miesięcy temu). –

-1

Nie mogę zgłosić błędu. Gdy pudło się podniesie, nie powinno się go udostępniać, chyba że użyjesz urządzeń, aby to wyjaśnić.

Co ważniejsze, rezerwowanie powinno zawsze wynosić idempotent, jak zauważyło wiele innych osób.

idempotentność Przepis można uruchomić wiele razy na tym samym systemie, a wyniki zawsze będą identyczne. Zasób jest zdefiniowany w recepturze , która następnie określa działania, które mają zostać wykonane w systemie. Szef kuchni-klient zapewnia, że ​​działania nie są wykonywane, jeśli zasoby nie uległy zmianie, a każda wykonywana czynność jest wykonana w ten sam sposób za każdym razem. Jeśli przepis zostanie ponownie uruchomiony i nic się nie zmieniło, szef kuchni-klient nic nie zrobi.

ref: https://docs.getchef.com/chef_why.html#idempotence

+0

Wydaje się, że tak się stanie, jeśli po raz pierwszy uruchomisz 'vagrant up --some-option', wydaje się, że pamiętasz tę opcję. Tak więc następnym razem, gdy uruchomisz 'vagrant up', to nadal będzie przekazywać' --some-option'. Ja sam zostałem do tego trafiony, ponieważ ktoś udokumentował użycie 'vagrant up --provision' ... i po ponownym uruchomieniu komputera, zrobiłem" vagrant up ", a wszystko zostało zlikwidowane. – Danosaure

6

Jeśli używasz skryptu zastrzegania bash, kursy są nie zostanie idempotent.

Oto przykład niskie czoło, w jaki sposób uniknąć zastrzegania dwukrotnie:

PROVISIONED="/some-app-dir/PROVISIONED"; 

if [[ -f $PROVISIONED ]]; then 
    echo "Skipping provisioning"; 
    exit; 
else 
    echo "Provisioning"; 
fi 

#...do provisioning things 

touch $PROVISIONED;