español - Evite reprovisionar una máquina virtual Vagrant si ya está aprovisionada
vagrant manual (5)
Estoy tratando de obtener un aprovisionador de shell para evitar reprovisionar una instancia de VM si ya lo ha hecho anteriormente.
Considere el siguiente 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
Si ejecuta vagrant up minimal
, creará la caja y la aprovisionará inicialmente. Si luego ejecuta vagrant provision minimal
, intentará reprovisionar la caja pero fallará (ya que el directorio / tmp / foobar ya existe).
¿Hay alguna forma de hacer que Vagrant recuerde si ha aprovisionado una máquina en el pasado y evitar volver a aprovisionarla más tarde?
Más contexto: si ejecuto vagrant up minimal
, reinicio mi máquina host, y luego vuelvo a ejecutar vagrant vagrant up minimal
, tratará de reprovisionar la caja y fallará. Esto ocurre con bastante frecuencia, ya que VirtualBox con frecuencia causa problemas de kernel en mi máquina host.
¿Has mirado en esto?
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
No soy capaz de repetir el error. Una vez que una caja está arriba, no se debe aprovisionar a menos que use las instalaciones para hacerlo explícitamente.
Más importante aún, el aprovisionamiento siempre debe ser idempotent
como lo señalan muchos otros.
Idempotence Una receta puede ejecutarse varias veces en el mismo sistema y los resultados siempre serán idénticos. Un recurso se define en una receta, que luego define las acciones a realizar en el sistema. El cliente-chef garantiza que las acciones no se realicen si los recursos no han cambiado y que cualquier acción que se realice se realiza de la misma manera cada vez. Si una receta se vuelve a ejecutar y nada ha cambiado, entonces el chef-cliente no hará nada.
Puede que esta no sea la respuesta que desea, pero si cambia mkdir
a mkdir -p
, funcionará;)
Sin embargo, con toda seriedad, creo que Vagrant espera que los aprovisionadores sean idempotentes (es decir, si se ejecutan por segunda vez, no tomará ninguna medida).
Puede ser difícil lograr la verdadera idempotencia, dependiendo de lo que realmente esté haciendo en su script de aprovisionamiento, pero mkdir -p
es un buen comienzo. También puede crear un archivo de marca en el sistema y verificar la existencia de ese archivo de bandera a primera vista; si existe, simplemente exit 0
.
Si está utilizando un script de provisión de bash, las probabilidades son que no será idempotente.
Aquí hay un ejemplo de cómo evitar el aprovisionamiento dos veces:
PROVISIONED="/some-app-dir/PROVISIONED";
if [[ -f $PROVISIONED ]]; then
echo "Skipping provisioning";
exit;
else
echo "Provisioning";
fi
#...do provisioning things
touch $PROVISIONED;
Vagrant normalmente ejecuta el código de aprovisionamiento solo en el primer vagrant up
y cuando usted le dice específicamente que lo haga, por ejemplo, con vagrant provision
o vagrant reload --provision
. Realmente no hay necesidad de salir de su camino para evitar ejecutar los scripts de aprovisionamiento nuevamente. ( Sin embargo, puede que este no haya sido el caso cuando publicó la pregunta ).
Si está utilizando Chef o Puppet para el aprovisionamiento, ya están diseñados para hacer que todo sea idempotent , y supongo que lo mismo es cierto para Salt y Ansible.
Si está utilizando scripts de shell y desea que sean idempotentes, puede verificar alguna condición (como la existencia de un archivo) en una declaración if
:
if [[! -f "$HOME/bin/something.sh" ]]; then
# install something.sh into ~/bin
fi
He dado una respuesta muy general, ya que mkdir /tmp/foobar
que mkdir /tmp/foobar
no es realmente lo que estás tratando de lograr, pero si es así, agrega -p
.