6

我想在“供应商”阶段在打包程序模板中使用条件语句。

  "provisioners": [
    {
      "execute_command": "echo 'vagrant'|sudo -S sh '{{.Path}}'",
      "override": {
        "virtualbox-iso": {
          "scripts": [
            "scripts/base.sh",
            "scripts/puppet.sh",
          ]
        }
      },
      "type": "shell",
    }
  ]

例如,如果用户在“packer build”命令行以某种方式指定“puppet”参数,那么“scripts/puppet.sh”将被执行,否则将被跳过。

我怎样才能做到这一点?

4

2 回答 2

10

我不认为打包机原生模板格式是可能的,因为打包机使用 JSON 格式进行配置,只要我知道它不支持条件语句等流控制机制。但是应该可以使用用户变量和 shell 配置器来归档类似的行为。

这个想法

最简单的方法应该是从构建命令中设置一个用户变量,并将这个变量从打包程序传递到 shell 配置程序脚本,该脚本检测用户变量的值并调用适当的配置程序脚本,例如 puppet、salt、...

免责声明:

我没有测试这种方法,但它应该给你一个暗示我的意思,也许你可以想出一个更好的解决方案。;-)

解决问题的方法

1. 定义表示使用的provisioner的变量:

有多种方法可以定义用户变量,

  • 通过使用 -var 标志调用打包程序构建命令(请参阅答案末尾)

  • 在 box-template 文件中定义用户变量

    The packer box template file: **template.json**
    
         "variables": [
             "using_provision_system": "puppet"
         ]
         "provisioners": [
              {...}
    
  • 定义一个变量定义文件并在构建命令中使用 -var-file 指定它的路径

    The variable file: **variables.json**
    Is a great alternative if you want to define variables in a seperate file.
    
         {
            "using_provision_system": "puppet"
         }
    

2.调用调用provisioner脚本的shell脚本:

现在修改 execute_command,以使用定义的变量作为参数调用“主”脚本。

"provisioners": [
    {
      "execute_command": "echo 'vagrant'|sudo -S sh '{{.Path}}' '{{user `using_provision_system`}}'",
      "override": {
        "virtualbox-iso": {
          "scripts": [
            call_provisioner_script.sh
          ]
        }
      },
      "type": "shell",
    }
  ]

注意,我们只需要指定一个脚本。这个“主”脚本将传递的变量作为参数,并在切换条件下将该值与一些预定义的供应商名称进行比较。(简短:它选择将执行哪些配置器脚本。)

主配置脚本:call_provisioner_script.sh

case $1 in
    puppet*) sh puppet_provisioner.sh
    *) sh shell_provisioner.sh

小心!
因为此脚本将在您的盒子内运行,您可能需要在执行此命令之前将脚本上传到盒子。

3.最后一步是建立你的盒子:)

调用打包程序构建命令:

#define variable in build command (first option from above)
$ packer build -var 'using_provision_system=puppet' template.json

#define variables in variable file and set path in build command
$ packer build -var-file=variables.json template.json

而不是使用用户变量,应该有一种方法可以在你的盒子中设置环境变量并使用这种类型的变量来指定供应商。

于 2015-04-19T14:08:27.923 回答
7

另一种方法是定义 2 个不同的构建器,它们类型相同但名称不同。only然后,您可以使用以下字段从特定构建中排除配置步骤:

{
  "source": "foo.txt",
  "destination": "/opt/foo.txt",
  "type": "file",
  "only": ["docker-local"]
}
于 2016-12-07T10:04:14.697 回答