Vagrant 手册之 Provisioning

原文地址

虽然 Vagrant 提供了多种配置机器的选项,但还是有一个标准的使用模式,以及所有需要了解的重要问题。

1. 配置

首先,每个 provisioner 都使用 config.vm.provision 方法调用在 Vagrantfile 中进行配置。例如,下面的 Vagrantfile 启用了 shell provisioning:

Vagrant.configure("2") do |config|
  # ... other configuration

  config.vm.provision "shell", inline: "echo hello"
end

每个 provisioner 都有一个类型,例如“shell”,用作 provisioning 配置的第一个参数。以下是配置该特定 provisioner 的基本键/值。除了基本的键/值之外,还可以使用 Ruby 块来创建更像变量赋值的语法。以下示例与前面的示例相同:

Vagrant.configure("2") do |config|
  # ... other configuration

  config.vm.provision "shell" do |s|
    s.inline = "echo hello"
  end
end

基于块的语法的好处是,使用多个选项时可以大大提高可读性。此外,一些 provisioners(如 Chef provisioners)具有可在该块内调用的特殊方法,以简化无法使用键/值方法进行的配置,或者可以使用此语法将参数传递给 shell 脚本。

使用 = 样式设置的属性可以在单行中设置,例如上面的 inline="echo hello"。如果样式更像是一个函数调用,比如 add_recipe "foo",那么这不能在一行中指定。

Provisioner 也可以被命名(自 1.7.0 起)。这些名称可以用于输出以及覆盖 provisioner 设置(下面会进一步介绍)。下面显示了一个命名过的 provisioner 的示例:

Vagrant.configure("2") do |config|
  # ... other configuration

  config.vm.provision "bootstrap", type: "shell" do |s|
    s.inline = "echo hello"
  end
end

命名 provisioner 很简单。config.vm.provision 的第一个参数就是名字,然后是用于指定 provisioner 类型的 type 选项。

2. 运行 Provisioner

Provisioner 在三种情况下运行:首次 vagrant up`vagrant provisionvagrant reload --provision

如果不想运行 provisioner,则可以将 --no-provision 标志传递给 up 以及 reload。同样,可以通过 --provision 来强制运行 provisioner。

如果只希望在指定了多个 provisioner 的情况下运行特定 provisioner,则可以使用 --provision-with 标志。例如,如果你有 shell 和 Puppet 两个 provisioner,并且只想运行 shell,可以使用 vagrant provision --provision-with shell--provision-with 的参数可以是 provisioner 的类型(例如“shell”)或名称(例如上面的“bootstrap”)。

3. 一次运行或总是运行

默认情况下,除非设置了 --provision 标志,否则 provisioner 只在上次 vagrant destroy 后的第一个 vagrant up 期间运行一次,如上所述。

或者,可以配置 provisioner 在每次启动或重新加载时运行。只有在显式指定 --no-provision 标志时才会运行它们。为此,请将运行选项设置为“always”,如下所示:

Vagrant.configure("2") do |config|
  config.vm.provision "shell", inline: "echo hello",
    run: "always"
end

You can also set run: to “never” if you have an optional provisioner that you want to mention to the user in a “post up message” or that requires some other configuration before it is possible, then call this with .
如果有一个可选 provisioner,可以将其 run: 设置为“never”,如果希望在“发布消息”中向用户提及可选配置器,或者在之前需要其他配置,然后通过 vagrant provision --provision-with bootstrap 调用。

如果使用块格式,则必须在块外指定它,如下所示:

Vagrant.configure("2") do |config|
  config.vm.provision "shell", run: "always" do |s|
    s.inline = "echo hello"
  end
end

4. 多个 Provisioner

可以使用多个 config.vm.provision 方法来定义多个 provisioner。这些 provisioner 将按照他们定义的顺序运行。由于各种原因,这很有用,但通常会用于 shell 脚本引导某些系统,以便其他设置程序可以稍后进行。

如果在多个“scope”级别定义 provisioner(例如在配置块中全局化,或在多机器定义中,或在 provider 特定的覆盖中),那么外部范围将始终在任何内部范围之前运行。例如,在下面的 Vagrantfile 中:

Vagrant.configure("2") do |config|
  config.vm.provision "shell", inline: "echo foo"

  config.vm.define "web" do |web|
    web.vm.provision "shell", inline: "echo bar"
  end

  config.vm.provision "shell", inline: "echo baz"
end

provisioner 的顺序是打印“foo”、“baz”、“bar”。注意,顺序是由外而内。

有多个 provisioner 时,使用指定了名字的 --provision-with 选项可以更好地控制运行时间和运行的东西。

5. 覆盖 Provisioner 设置

警告:高级话题! Provisioner (配置程序)覆盖是一个高级主题,如果您已经在使用多机器和/或提供程序覆盖,那么它只会变得非常有用。如果你刚刚开始使用 Vagrant,可以放心地跳过这个。

在使用多机或特定于 provider 的替代功能时,可能需要在 Vagrantfile 的全局配置范围中定义通用 provisioner,但在内部覆盖它们的某些方面。Vagrant 允许你这样做,但有一些细节需要考虑。

要覆盖设置,必须为你的 provisioner 分配一个名称。

Vagrant.configure("2") do |config|
  config.vm.provision "foo", type: "shell",
    inline: "echo foo"

  config.vm.define "web" do |web|
    web.vm.provision "foo", type: "shell",
      inline: "echo bar"
  end
end

上面只会回显“bar”,因为内联设置会覆盖外部 provisioner。这个覆盖只在该范围内有效:“web”虚拟机。如果定义了另一个虚拟机,它仍会回显“foo”,除非它本身也覆盖了 provisioner。

排序时要小心。当覆盖子范围中的 provisioner 时,provisioner 将在该点运行。在下面的例子中,输出将是“foo”,然后是“bar”:

Vagrant.configure("2") do |config|
  config.vm.provision "foo", type: "shell",
    inline: "echo ORIGINAL!"

  config.vm.define "web" do |web|
    web.vm.provision "shell",
      inline: "echo foo"
    web.vm.provision "foo", type: "shell",
      inline: "echo bar"
  end
end

如果想保留原来的顺序,你可以指定 preserve_order: true 标志:

Vagrant.configure("2") do |config|
  config.vm.provision "do-this",
    type: "shell",
    preserve_order: true,
    inline: "echo FIRST!"
  config.vm.provision "then-this",
    type: "shell",
    preserve_order: true,
    inline: "echo SECOND!"
end
原文地址:https://www.cnblogs.com/kika/p/10851635.html