17

如果之前已经这样做过,我正在尝试获取一个 shell 配置程序以避免重新配置 VM 实例。

考虑以下 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 经常在我的主机上导致内核崩溃。

4

5 回答 5

10

这可能不是您想要的答案,但是如果您将其更改mkdir为 a mkdir -p,它将起作用;)

不过,说真的,我认为 Vagrant 期望供应商是幂等的(也就是说,如果第二次运行,它将不采取任何行动)。

实现真正的幂等性可能很棘手,具体取决于您在配置脚本中实际执行的操作,但这mkdir -p是一个好的开始。您还可以在系统上创建一个标志文件,并首先检查该标志文件的存在;如果存在,就exit 0.

于 2013-05-23T01:02:54.520 回答
6

如果您使用的是 bash 配置脚本,那么它很可能不是幂等的。

这是一个关于如何避免配置两次的低俗示例:

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

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

#...do provisioning things

touch $PROVISIONED;
于 2014-11-12T22:45:19.517 回答
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
于 2013-06-28T06:52:25.473 回答
4

Vagrant 通常只在第一次运行配置代码, vagrant up 并且当你明确告诉它这样做时,例如 with vagrant provisionor vagrant reload --provision。真的没有必要竭尽全力避免再次运行配置脚本。(但是,当您发布问题时,情况可能并非如此。)

如果您使用 Chef 或 Puppet 进行配置,它们已经被设计为使一切都具有幂等性,我认为 Salt 和 Ansible 也是如此。

如果您正在使用 shell 脚本并且想让它们具有幂等性,则可以在if语句中检查某些条件(例如文件的存在):

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

我给出了一个非常笼统的答案,因为我假设这mkdir /tmp/foobar并不是您真正想要实现的目标,但如果是,那么添加-p.

于 2014-02-19T18:39:28.187 回答
-1

我无法重现该错误。一旦一个盒子启动,它就不应该提供,除非你使用设施来明确地实现它。

更重要的是,配置应始终idempotent如许多其他人所指出的那样。

幂等性一个配方可以在同一个系统上运行多次,并且结果总是相同的。资源在配方中定义,然后定义要在系统上执行的操作。chef-client 确保在资源没有更改的情况下不执行操作,并且每次执行的任何操作都以相同的方式完成。如果重新运行食谱并且没有任何改变,那么厨师客户将不会做任何事情。

参考:https ://docs.getchef.com/chef_why.html#idempotence

于 2014-09-06T20:57:08.440 回答