文件配置器

原文


类型: file

Packer 的文件配置器可以将文件上传到由 Packer 构建的机器上。建议使用文件配置器上传文件,然后使用 shell 配置器将它们移动到正确的位置,设置权限等。

警告:您只能上传文件到配置器使用的用户(通常不是root用户)有权限访问的位置。在 /tmp 中创建文件,并使用 shell 配置器将它们移动到目标位置,是上传文件到 root 所拥有的目录的唯一方法。

文件配置器可以上传单个文件,也可以上传整个目录。

基础样例

JSON:

{
  "type": "file",
  "source": "app.tar.gz",
  "destination": "/tmp/app.tar.gz"
}

HCL:

provisioner "file" {
  source = "app.tar.gz"
  destination = "/tmp/app.tar.gz"
}

配置参数

必填参数:

content (string) - 这是要复制到目的地的内容。如果 destination 是一个文件,内容将被写入该文件,如果是目录,则会创建一个名为 pkr-file-content 的文件。建议使用文件作为目标。可以在此处使用 templatefile 函数或任何插值语法。该参数不可与 sourcesources 一同设置。 source (string) - 要上传到机器的本地文件或目录的路径。路径可以是绝对的或相对的。如果是相对路径,就是相对于 Packer 执行时的工作目录。如果这是一个目录,路径务必以斜杠结尾。下文会详述关于上传目录的内容。除非设置了 sources,否则必须设置该参数。 destination (string) - 文件将被上传到机器上的目标路径。位置必须可写,并且所有父级目录必须已经存在。如果配置器使用的用户(通常不是 root)无法写入此目录,您将收到“Permission Denied”错误。如果源是一个文件,那么将最好也把目标设置为文件,但是如果将目标设置为目录,至少要确保目标路径以斜杠结尾,以便 Packer 知道使用源文件的文件名拼接到目标路径之后。否则可能会导致 Packer 无法上传文件。如果目标文件已经存在,它将被覆盖。

选填参数:

  • sources ([]string) - 要上传的文件夹列表。如果你有多个文件要上传到同一个地方,这可以用来代替 source 选项。请注意,目标必须是带尾部斜杠的目录,sources 中列出的所有文件都将上传到同一目录,并保留其文件名。
  • direction (string) - 文件传输的方向。默认值为 upload。如果设置为 download,则远程机器中的文件 source 将下载到本地 destination
  • generated (bool) - 仅适用于高级用户。如果为 true,则仅在上传前检查文件是否存在,而不是在构建前验证时检查。这允许用户在上传时即时地创建的文件。该参数默认为 false。我们不建议使用此功能,因为它会导致 Packer 变得依赖于系统状态。我们希望您在 Packer 运行之前生成您的文件,但我们也承认在某些情况下这可能是不可避免的。

所有配置器共有的参数:

  • pause_before (duration) - 执行前休眠一段时间。
  • max_retries (int) - provisioner 在失败的情况下重试的最大次数。默认为零 (0)。零表示不会重试错误。
  • only (array of string) - 只运行列表中指定的的配置器程序。
  • override (object) - 使用特定配置器的不同设置覆盖配置器,例如:

HCL2:

source "null" "example1" {
  communicator = "none"
}

source "null" "example2" {
  communicator = "none"
}

build {
  sources = ["source.null.example1", "source.null.example2"]
  provisioner "shell-local" {
    inline = ["echo not overridden"]
    override = {
      example1 = {
        inline = ["echo yes overridden"]
      }
    }
  }
}

Json:

{
  "builders": [
    {
      "type": "null",
      "name": "example1",
      "communicator": "none"
    },
    {
      "type": "null",
      "name": "example2",
      "communicator": "none"
    }
  ],
  "provisioners": [
    {
      "type": "shell-local",
      "inline": ["echo not overridden"],
      "override": {
        "example1": {
          "inline": ["echo yes overridden"]
        }
      }
    }
  ]
}
  • timeout(duration)- 如果配置器完成时间超过配置值(例如 1h10m1s10m),则配置器将超时并失败。

上传目录

file 配置器还能够将完整的目录上传到远程机器。上传目录时,您应该了解一些重要事项。 首先,目标目录必须已经存在。如果您需要创建它,请在运行文件配置器之前使用 shell 配置器来创建目录。如果目标目录不存在,文件配置器可能不会报错,同时引发意外的结果。

接下来,source 路径上尾部是否有斜杠将决定目录名称是否将嵌入到目标路径中,或者是否将创建目标。我们举例说明:

如果 source/foo(尾部没有斜杠),目标是 /tmp,那么本地机器上 /foo 的内容将被上传到远程机器上的 /tmp/foo。远程机器上的 foo 目录将由 Packer 创建。

但是,如果源是 /foo/(尾部有斜杠),而目标是 /tmp,那么 /foo 的内容将直接上传到 /tmp

此行为源自 rsync。请注意,Packer 在实际运行时,不一定会使用 rsync。

上传在 Packer 运行前还不存在的文件

通常来说,作为 source 的本地文件必须在 Packer 运行之前就已存在。这对于捕获拼写错误并确保构建一旦开始就会成功非常有用。但是,这也意味着您不能在构建期间生成文件,然后再使用文件配置器上传它。一个窍门是上传目录而不是文件。该目录仍然必须存在,但其内容一开始可以不存在。您可以在 Packer 运行期间将生成的文件写入该目录,并在稍后上传。

上传符号链接

上传符号链接时的行为取决于通信器。 Docker 通信器将保留符号链接,但所有其他通信器会将本地符号链接视为常规文件。如果您希望在上传时保留符号链接,建议您使用 tar。下面是一个可能的例子:

$ ls -l files
total 16
drwxr-xr-x  3 mwhooker  staff  102 Jan 27 17:10 a
lrwxr-xr-x  1 mwhooker  staff    1 Jan 27 17:10 b -> a
-rw-r--r--  1 mwhooker  staff    0 Jan 27 17:10 file1
lrwxr-xr-x  1 mwhooker  staff    5 Jan 27 17:10 file1link -> file1
$ ls -l toupload
total 0
-rw-r--r--  1 mwhooker  staff    0 Jan 27 17:10 files.tar

Json:

{
  "provisioners": [
    {
      "type": "shell-local",
      "command": "tar cf toupload/files.tar files"
    },
    {
      "destination": "/tmp/",
      "source": "./toupload",
      "type": "file"
    },
    {
      "inline": [
        "cd /tmp && tar xf toupload/files.tar",
        "rm toupload/files.tar"
      ],
      "type": "shell"
    }
  ]
}

HCL2:

build {
  sources = [
    "source.docker.example"
  ]

  provisioner "shell-local" {
    command = "tar cf toupload/files.tar files"
  }
  provisioner "file" {
    destination = "/tmp/"
    source      = "./toupload"
  }
  provisioner "shell" {
    inline = [
      "cd /tmp && tar xf toupload/files.tar",
      "rm toupload/files.tar"
    ]
  }
}

通过 WinRM 传输大文件时速度缓慢的问题

由于我们的 WinRM 传输方式的限制,即使是中等大小的文件,上传和下载可能也需要很长时间。如果您在 Windows 上使用 file 配置器时遇到缓慢问题,建议您设置 SSH 服务并使用 ssh 通信器。如果您只想将文件传输给构建的机器,并且您的构建器支持使用 HTTP,您也可以使用 http_directoryhttp_content 指令。这将使构建机可以通过 HTTP 来访问该目录,并将环境变量 PACKER_HTTP_ADDR 设置为该地址。

results matching ""

    No results matching ""