我正在尝试使用shell配置程序,以避免重新配置虚拟机实例(如果之前已经这样做过)。
考虑以下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
如果您运行vagrant up minimal
,它将创建该框并最初进行配置。如果然后运行vagrant provision minimal
,它将尝试重新配置该框但会失败(因为/ tmp / foobar目录已经存在)。
有没有办法让Vagrant记住它过去是否配置了一台机器并避免以后重置它?
更多上下文:如果我运行vagrant up minimal
,重新启动我的主机,然后再次运行vagrant up minimal
,它将尝试重新配置该框并失败。这种情况经常发生,因为VirtualBox经常在我的主机上引起内核恐慌。
答案 0 :(得分:10)
这可能不是您想要的答案,但如果您将mkdir
更改为mkdir -p
,则可以使用;)
但是,严肃地说,我认为Vagrant希望供应商是幂等的(也就是说,如果第二次运行,它将不采取任何行动)。
实现真正的幂等性可能很棘手,具体取决于您在配置脚本中实际执行的操作,但mkdir -p
是一个良好的开端。您还可以在系统上创建一个标志文件,并首先检查该标志文件是否存在;如果存在,只需exit 0
。
答案 1 :(得分:6)
如果你正在使用bash配置脚本,那么它的可能性就不会是幂等的。
这是一个如何避免配置两次的低级示例:
PROVISIONED="/some-app-dir/PROVISIONED";
if [[ -f $PROVISIONED ]]; then
echo "Skipping provisioning";
exit;
else
echo "Provisioning";
fi
#...do provisioning things
touch $PROVISIONED;
答案 2 :(得分:5)
你看过这个吗?
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
答案 3 :(得分:4)
Vagrant通常只在第一个 vagrant up
和上运行配置代码,当您明确告知它时,例如使用vagrant provision
或vagrant reload --provision
。实际上没有必要尽量避免再次运行配置脚本。 (这may not have been the case when you posted the question, however。)
如果您正在使用Chef或Puppet进行配置,那么它们已经被设计为制作所有内容idempotent,并且我认为Salt和Ansible也是如此。
如果您正在使用shell脚本并且希望使它们具有幂等性,则可以在if
语句中检查某些条件(如文件的存在):
if [[! -f "$HOME/bin/something.sh" ]]; then
# install something.sh into ~/bin
fi
我已经给出了一个非常一般的答案,因为我假设mkdir /tmp/foobar
不是真的你想要实现的目标,但如果是,那么添加{ {1}}。
答案 4 :(得分:-1)
我无法重现错误。一旦盒子启动,它就不应该提供,除非你使用设施明确地实现它。
更重要的是,正如许多其他人所指出的那样,配置应始终为idempotent
。
Idempotence 配方可以在同一系统上多次运行,结果将始终相同。资源在a中定义 配方,然后定义要在系统上执行的操作。 厨师 - 客户确保如果不执行操作 资源没有改变,任何执行的动作都是 每次都以同样的方式完成。如果重新运行配方而没有任何配方 改变了,然后厨师 - 客户不会做任何事情。