go-getter 是 Go (golang) 的一个库,用于使用 URL 作为主要输入形式从各种来源下载文件或目录。
该库的强大之处在于能够灵活地使用单个字符串作为输入从多个不同的源(文件路径、Git、HTTP、Mercurial 等)下载。这消除了实现者了解如何从各种来源下载的负担。
检测器的概念会自动将无效 URL 转换为正确的 URL。例如:“github.com/hashicorp/go-getter”将转换为 Git URL。或者“./foo”会变成一个文件 URL。这些是可扩展的。
Terraform 使用该库下载模块,Nomad 使用该库下载二进制文件。
包文档可以在 GoDoc 上找到。
可以使用普通的go get
来完成安装:
$ go get github.com/hashicorp/go-getter
go-getter 还有一个可用于测试 URL 字符串的命令:
$ go install github.com/hashicorp/go-getter/cmd/go-getter ... $ go-getter github.com/foo/bar ./foo ...
该命令对于验证 URL 结构很有用。
从用户提供的 URL 获取资源本质上是一种危险的操作,可能会使您的应用程序容易受到服务器端请求伪造、路径遍历、拒绝服务或其他安全漏洞的攻击。
go-getter 包含针对其中一些安全问题的缓解措施,但在安全关键环境中仍应谨慎使用。查看可配置以减轻其中一些风险的可用安全选项。
go-getter 可能返回包含调用者提供的查询参数的值,这些参数可能包含敏感数据。围绕哪些参数敏感和不敏感的上下文只有 go-getter 的调用者知道,并且特定于每个用例。我们建议调用者确保正确处理和清理 go-getter 的返回值(例如,错误消息),以确保敏感数据不会保留到日志中。
go-getter 使用单个字符串 URL 作为输入来从各种协议下载。 go-getter 有各种“技巧”使用此 URL 来执行某些操作。本节记录了 URL 格式。
协议用于使用特定机制下载文件/目录。示例协议有 Git 和 HTTP。
检测器用于将有效或无效的 URL 转换为另一个 URL(如果它与特定模式匹配)。示例:“github.com/user/repo”会自动转换为完全有效的 Git URL。这使得 go-getter 变得非常用户友好。
go-getter 开箱即用,支持以下协议。通过实现Getter
接口,可以在运行时增强其他协议。
本地文件
git
水银
HTTP协议
亚马逊S3
谷歌GCP
除了上述协议之外,go-getter 还有所谓的“探测器”。它们采用 URL 并尝试自动为其选择最佳协议,这甚至可能涉及更改协议。默认情况下内置以下检测:
文件路径(例如“./foo”)会自动更改为绝对文件 URL。
GitHub URL(例如“github.com/mitchellh/vagrant”)会自动更改为基于 HTTP 的 Git 协议。
GitLab URL(例如“gitlab.com/inkscape/inkscape”)会自动更改为基于 HTTP 的 Git 协议。
BitBucket URL(例如“bitbucket.org/mitchellh/vagrant”)会使用 BitBucket API 自动更改为 Git 或 Mercurial 协议。
在某些情况下,根据源 URL,要使用的协议是不明确的。例如,“http://github.com/mitchellh/vagrant.git”可以引用 HTTP URL 或 Git URL。强制协议语法用于消除此 URL 的歧义。
强制协议可以通过在 URL 前加上协议前缀并后跟双冒号来完成。例如: git::http://github.com/mitchellh/vagrant.git
将使用 Git 协议下载给定的 HTTP URL。
强制协议也将覆盖任何检测器。
在没有强制协议的情况下,检测器可以在 URL 上运行,无论如何都会转换协议。无论哪种方式,上面的示例都会使用 Git 协议,因为 Git 检测器会检测到它是 GitHub URL。
每个协议都可以支持特定于协议的选项来配置该协议。例如, git
协议支持指定ref
查询参数,告诉它要为该 Git 存储库签出什么引用。
这些选项被指定为提供给 go-getter 的 URL(或类似 URL 的字符串)上的查询参数。使用上面的 Git 示例,下面的 URL 是 go-getter 的有效输入:
github.com/hashicorp/go-getter?ref=abcd1234
特定于协议的选项记录在 URL 格式部分下方。但因为它们是 URL 的一部分,所以我们在这里指出它们,以便您知道它们的存在。
如果只想从下载目录中下载特定子目录,可以在双斜杠//
后指定子目录。 go-getter 将首先下载双斜杠之前指定的 URL(就好像您没有指定双斜杠一样),但随后会将双斜杠之后的路径复制到目标目录中。
例如,如果您正在下载此 GitHub 存储库,但只想下载testdata
目录,则可以执行以下操作:
https://github.com/hashicorp/go-getter.git//testdata
如果您将其下载到/tmp
目录,则文件/tmp/archive.gz
将存在。请注意,该文件位于此存储库的testdata
目录中,但因为我们指定了子目录,所以 go-getter 仅自动复制该目录内容。
子目录路径也可以使用文件系统 glob 模式。该路径必须与一个条目完全匹配,否则 go-getter 将返回错误。如果您不确定确切的目录名称,但它遵循可预测的命名结构,这非常有用。
例如,以下 URL 也可以工作:
https://github.com/hashicorp/go-getter.git//test-*
对于任何协议的文件下载,go-getter 都可以自动为您验证校验和。请注意,校验和仅适用于下载文件,不适用于目录,但校验和适用于任何协议。
要对文件进行校验和,请将checksum
查询参数附加到 URL。 go-getter 会自动解析出这个查询参数并用它来验证校验和。参数值的格式可以为type:value
或value
,其中 type 为 "md5"、"sha1"、"sha256"、"sha512" 或 "file" 。 “值”应该是“文件”的实际校验和值或下载 URL。当省略type
部分时,将根据校验和字符串的长度猜测类型。示例:
./foo.txt?checksum=md5:b7d96c89d09d9e204f5fedc4d5d55b21
./foo.txt?checksum=b7d96c89d09d9e204f5fedc4d5d55b21
./foo.txt?checksum=file:./foo.txt.sha256sum
当从文件中进行校验和时 - 例如:使用checksum=file:url
- go-getter 将使用相同的配置在file:
之后获取 URL 中链接的文件。例如,在file:http://releases.ubuntu.com/cosmic/MD5SUMS
中,go-getter 将使用 http 协议在上述 url 下下载校验和文件。 go-getter 支持的所有协议都可以使用。校验和文件将被下载到临时文件中,然后进行解析。临时文件的目的地可以通过设置系统特定的环境变量来更改: TMPDIR
for unix; Windows 上的TMP
、 TEMP
或USERPROFILE
。有关临时目录选择的更多信息,请阅读 os.TempDir 的 godoc。文件内容应为 BSD 或 GNU 风格。一旦 go-getter 完成了校验和文件;它被删除了。
校验和查询参数永远不会发送到后端协议实现。它被积极进取者自己在更高的层面上使用。
如果目标文件存在并且校验和匹配:将跳过下载。
go-getter 将根据所请求的文件的扩展名(通过任何协议)自动将文件解压缩到文件或目录中。这适用于文件和目录下载。
go-getter 查找archive
查询参数来指定存档的格式。如果未指定,go-getter 将使用路径的扩展名来查看它是否显示为已存档。可以通过将archive
查询参数设置为false
来显式禁用取消存档。
支持以下存档格式:
tar.gz
和tgz
tar.bz2
和tbz2
tar.xz
和txz
zip
gz
bz2
xz
例如,示例 URL 如下所示:
./foo.zip
这将自动推断为 ZIP 文件并将被提取。您还可以明确说明存档类型:
./some/other/path?archive=zip
最后,您可以完全禁用存档:
./some/path?archive=false
您可以将取消归档与 go-getter 的其他功能(例如校验和)结合起来。在进入最终协议下载器之前,特殊的archive
查询参数将从 URL 中删除。
本节记录了可以为 go-getter 指定的特定于协议的选项。这些选项应作为普通查询参数附加到输入(但是,HTTP 标头是一个例外)。根据 go-getter 的使用情况,应用程序可能会提供输入选项的替代方法。例如,Nomad 提供了一个很好的选项块来指定选项而不是在 URL 中。
以下选项适用于所有协议:
archive
- 用于取消存档此文件的存档格式,或“”(空字符串)以禁用取消存档。有关更多详细信息,请参阅上面有关存档支持的完整部分。
checksum
- 用于验证下载的文件或存档的校验和。有关格式和更多详细信息,请参阅上面有关校验和的整个部分。
filename
- 当处于文件下载模式时,允许指定磁盘上下载文件的名称。在目录模式下无效。
file
)没有任何
git
) ref
- 要签出的 Git 引用。这是一个引用,因此它可以指向提交 SHA、分支名称等。如果它是命名引用(例如分支名称),go-getter 会在每次获取时将其更新为最新版本。
sshkey
- 在克隆期间使用的 SSH 私钥。提供的密钥必须是 base64 编码的字符串。例如,要从磁盘上的私钥文件生成合适的sshkey
,您可以运行base64 -w0
。
注意:使用此功能需要 Git 2.3+。
depth
- Git 克隆深度。提供的编号指定要从存储库克隆的最后n
修订版。
git
getter 接受 URL 样式的 SSH 地址(如git::ssh://[email protected]/foo/bar
)和“scp 样式”地址(如git::[email protected]/foo/bar
。在后一种情况下,如果用户名前缀恰好是git@
则允许省略git::
force 前缀。
“scp 样式”地址不能与ssh://
方案前缀结合使用,因为在这种情况下,冒号用于标记要连接的可选端口号,而不是分隔主机的路径。
hg
) rev
- Mercurial 对结账的修订。
http
)要将 HTTP 基本身份验证与 go-getter 结合使用,只需在 URL 中的主机名前面添加username:password@
即可,例如https://Aladdin:[email protected]/index.html
。所有特殊字符,包括用户名和密码,都必须进行 URL 编码。
可以通过在自定义HttpGetter
中提供可选请求标头来添加它们(不像大多数其他选项那样作为查询参数)。这些标头将在相关 getter 发出的每个请求中发送出去。
s3
)S3 在 URL 中采用各种访问配置。请注意,如果已设置,它还会从标准 AWS 环境变量中读取这些变量。还支持 Minio 等 S3 兼容服务器。如果存在查询参数,则这些参数优先。
aws_access_key_id
- AWS 访问密钥。
aws_access_key_secret
- AWS 访问密钥秘密。
aws_access_token
- AWS 访问令牌(如果正在使用)。
aws_profile
- 使用本地 ~/.aws/ config 中的此配置文件。优先于其他三者。
如果您使用 go-getter 并希望使用 EC2 IAM 实例配置文件来避免使用凭证,则只需忽略这些配置文件即可,如果可用,将自动使用配置文件。
如果您使用 go-gitter 来支持 Minio,则必须考虑以下事项:
aws_access_key_id
(必需)- Minio 访问密钥。
aws_access_key_secret
(必需)- Minio 访问密钥秘密。
region
(可选 - 默认为 us-east-1) - 要使用的区域标识符。
version
(可选 - 默认为 Minio 默认值) - 配置文件格式。
S3 有多种寻址方案用于引用您的存储桶。此处列出:https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-bucket-intro.html
这些寻址方案的一些示例:
s3::https://s3.amazonaws.com/bucket/foo
s3::https://s3-eu-west-1.amazonaws.com/bucket/foo
Bucket.s3.amazonaws.com/foo
Bucket.s3-eu-west-1.amazonaws.com/foo/bar
“s3::http://127.0.0.1:9000/test-bucket/hello.txt?aws_access_key_id=KEYID&aws_access_key_secret=SECRETKEY®ion=us-east-2”
gcs
)为了访问 GCS,应提供身份验证凭据。更多信息可以在这里找到
gcs::https://www.googleapis.com/storage/v1/bucket
gcs::https://www.googleapis.com/storage/v1/bucket/foo.zip
www.googleapis.com/storage/v1/bucket/foo
get_gcs.go
的测试要求您在环境中设置 GCP 凭据。 这些凭证可以对任何项目具有任何级别的权限,它们只需要存在即可。 这意味着设置GOOGLE_APPLICATION_CREDENTIALS="~/path/to/credentials.json"
或GOOGLE_CREDENTIALS="{stringified-credentials-json}"
。 由于此配置,CircleCI 中的外部贡献者的get_gcs_test.go
将失败。
禁用符号链接
在您的 getter 客户端配置中,我们建议使用DisableSymlinks
选项,该选项可防止写入或复制符号链接(可能指向目录外部)。
client := getter.Client{ // 这将阻止通过符号链接复制或写入文件 DisableSymlinks: true, }
禁用或限制X-Terraform-Get
Go-Getter 支持通过X-Terraform-Get
标头进行任意重定向。此功能的存在是为了支持 Terraform 用例,但在大多数应用程序中可能不需要。
对于使用HttpGetter
的代码,添加以下配置选项:
var httpGetter = &getter.HttpGetter{ // 大多数客户端应该禁用 X-Terraform-Get // 请参阅下面的注释 XTerraformGetDisabled: true, // 您的软件可能不依赖于 X-Terraform-Get,但是 // 如果依赖的话,您应该将上述字段设置为 false,加上 // 设置 XTerraformGet Limit 以防止无休止的重定向 // XTerraformGetLimit: 10,}
强制超时
HttpGetter
支持超时和其他资源限制配置选项。 GitGetter
和HgGetter
仅支持超时。
HttpGetter
的配置:
var httpGetter = &getter.HttpGetter{ // 禁用预取 HEAD 请求 DoNotCheckHeadFirst: true, // 作为上述设置的替代方案,您可以为 HEAD 请求设置合理的超时 // HeadFirstTimeout: 10 * time.Second, // HTTP 操作的读取超时 ReadTimeout: 30 * time.Second, // 设置getter 可以读取的最大字节数 MaxBytes: 500000000, // 500 MB}
对于使用GitGetter
或HgGetter
的代码,请设置Timeout
选项:
var gitGetter = &getter.GitGetter{ // 为 git 操作设置合理的超时时间 Timeout: 5 * time.Minute, }
var hgGetter = &getter.HgGetter{ // 为 hg 操作设置合理的超时时间 Timeout: 5 * time.Minute, }