JSON 元数据文件的 Vagrant 框 URL

Bra*_*rad 19 vagrant

在我的 Vagrantfile 中,我可以指定一个框的 URL:

config.vm.box_url = "http://example.com/my-box.pkg"
Run Code Online (Sandbox Code Playgroud)

根据最近的文档,我应该能够创建一个 JSON 文件,其中包含不同版本的盒子的 URL。文档还说我可以在运行时使用这个 JSON 文件的 URL vagrant box add。我希望能够将该 JSON 文件的 URL 用于config.vm.box_url. 但是,这似乎不起作用。当我尝试时,它把它当作一个盒子文件:

Bringing machine 'default' up with 'virtualbox' provider...
==> default: Box 'my-box' could not be found. Attempting to find and install...
    default: Box Provider: virtualbox
    default: Box Version: >= 0
==> default: Adding box 'my-box' (v0) for provider: virtualbox
    default: Downloading: http://example.com/my-box.pkg.json
    default: Progress: 100% (Rate: 876k/s, Estimated time remaining: 0:00:01)
The box failed to unpackage properly. Please verify that the box
file you're trying to add is not corrupted and try again. The
output from attempting to unpackage (if any):

bsdtar.EXE: Unrecognized archive format: Illegal byte sequence
bsdtar.EXE: Error exit delayed from previous errors.
Run Code Online (Sandbox Code Playgroud)

是否可以告诉 Vagrant 在我的 Vagrantfile 中使用框元数据 JSON 文件?我宁愿不必使用 Vagrant Cloud。

Jim*_*ein 19

再次阅读您的问题后,您似乎正在尝试做一些与我有所不同的事情 - 但我认为我们的最终目标是相同的。

我不想使用 Vagrant Cloud 服务来托管我的基本框,但我希望能够将开发环境分发给我的开发团队,并利用metadata.json文件的功能来维护开发环境的版本控制系统,然后我的开发团队只需使用 vagrant 内置的工具就可以使用它。

在撰写本文时(2014 年 8 月 5 日),该领域的 vagrant 文档非常稀少,大概是因为它是一个相对较新的功能,但我确信 VagrantCloud 具有付费层的事实也与它有关.

为了弄清楚如何利用该metadata.json文件进行版本控制和分发盒子,我查看了 VagrantCloud 上可用的一些 VM。在浏览了这些内容并阅读了一些流浪代码之后 - 弄清楚如何实现我的目标变得非常容易。

  • 像往常一样包装你的盒子。就我而言,我只为虚拟盒打包,因为我们的开发人员将使用它来运行 Vm。我还用我的 basebox 打包了一个 Vagrantfile,它为开发环境做了一些配置(将共享设置到适当的文件夹、一些基本的 apache 配置、错误日志等)
  • 创建一个metadata.json文件来描述您的基本框,我的看起来类似于:

    {
        "description": "long box description",
        "short_description": "short box description",
        "name": "company/developer-environment",
        "versions": [{
            "version": "1",
            "status": "active",
            "description_html": "<p>Dev Environment</p>",
            "description_markdown": "Dev Environment",
            "providers": [{
                "name": "virtualbox",
                "url": "http:\/\/vagrant.domain.local/dev/company-developer-environment-1.box"
            }]
        }]
    }
    
    Run Code Online (Sandbox Code Playgroud)

创建metadata.json文件后,我将其上传到在我们的内部网络 ( vagrant.domain.local/metadata.json)上运行的本地服务器。一旦我这样做了,剩下的就是用 vagrant 测试一下:

# add the box to vagrant using the definition from metadata.json
# (the box is actually downloaded here, so it can take a minute...or 10)
$ vagrant box add http://vagrant.domain.local/dev/metadata.json

# init the box (this creates a .vagrant folder and a Vagrantfile in the cwd with the appropriate box name)
$ vagrant init company/developer-environment

# boot the box
$ vagrant up
Run Code Online (Sandbox Code Playgroud)

瞧,一个远程托管、共享和版本控制的私人盒子,不需要使用 Vagrant Cloud。

当您创建您的盒子的新版本时,您将把它打包并编辑metadata.json文件。据我所知,您可以使用任何您想要的版本控制方案,无论是语义版本控制(1.0.0、1.0.1 等)还是版本的简单整数(1、2、3 等)。当你的 box 用户vagrant upvagrant 会自动检查你的 metadata.json 文件是否有新版本,并会提示他们vagrant box update更新 box。

您还可以通过定义一个带有框名称和框 url 的基本 Vagrantfile来跳过vagrant box add <metadata.json url>vagrant init位,如下所示:

# -*- mode: ruby -*-
# vi: set ft=ruby :

# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = "company/developer-environment"
  config.vm.box_url = "https://vagrant.domain.local/dev/metadata.json"
end
Run Code Online (Sandbox Code Playgroud)

您可以分发包含这些内容的 Vagrantfile,所有用户都可以vagrant up. 不过,我不确定当版本更新时它是如何工作的。


小智 10

截至今天(2016-07-12,vagrant 1.8.4),如果您想以手动方式运行您自己的目录(即手动更新框并编辑 metadata.json 文件),但仍使其行为就像实际目录一样,请记住以下几点:

  • 无需将该文件命名为“metadata.json”。它可以命名为任何名称,只要它包含预期值即可。我在这里使用“metadata.json”来进一步阐明下面的步骤。

  • 每个 metadata.json 文件只能包含一个框。它可以有多个版本,每个版本可以有多个提供程序(virtualbox、vmware、libvirt)。如果您需要有多个盒子(比如“fedora”和“ubuntu”),您需要两个不同的元数据文件。

  • Vagrant 期望 metadata.json 文件具有“application/json”类型(如 Nicholas Hinds 上面提到的。如果您的网络服务器不返回它(或返回“text/plain”),vagrant 将假定它是一个实际的 box 文件,并尝试解析它(并惨遭失败)。

  • Hashicorp 的 Atlas(曾经是 Vagrant Cloud)是一个例外,因为重定向会将您引导至作为“text/html”提供的内容。我对此的最佳猜测是它与重定向有关(更多内容见下文)。

  • box 文件不需要与元数据文件位于同一位置。您可以将元数据文件保存在本地网络服务器中,并将框保存在 Amazon S3 中,这没有问题。

因此,据我所知,我发现在网络服务器上运行它并仍然具有非常正常的功能的最简单方法是这样做:

在您的虚拟主机上,创建一个类似于以下内容的文件和目录结构:

d wwwroot/
d wwwroot/boxes
d wwwroot/boxes/yourname
f wwwroot/boxes/yourname/.htaccess
d wwwroot/boxes/yourname/box1
f wwwroot/boxes/yourname/box1/metadata.json
f wwwroot/boxes/yourname/box1/box1-$version1-$provider.box
f wwwroot/boxes/yourname/box1/box1-$version2-$provider.box
f wwwroot/boxes/yourname/box1/box1-$version2-$otherprovider.box
d wwwroot/boxes/yourname/box2
f wwwroot/boxes/yourname/box2/metadata.json
f wwwroot/boxes/yourname/box2/box2-$version1-$provider.box
(... etc)
Run Code Online (Sandbox Code Playgroud)

(这种布局意味着 box1 的“metadata.json”必须让它的 URL 指向类似“ http://yourhost/boxes/yourname/box1/box1- $version1-$provider.box”)

在您的 .htaccess 上,确保为目录索引设置了“metadata.json”。其余的是可选的,用于负缓存和隐藏实际内容:

Header unset Pragma
FileETag None
Header unset ETag
DirectoryIndex metadata.json
IndexIgnore *
Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate, private"
Header set Pragma "no-cache"
Header set Expires "Wed, 11 Jan 1984 05:00:00 GMT"
Run Code Online (Sandbox Code Playgroud)

在您的环境中,导出指向您的虚拟主机的 VAGRANT_SERVER_URL。注意没有尾随斜线!

export VAGRANT_SERVER_URL="http://yourhost/boxes"
Run Code Online (Sandbox Code Playgroud)

有了这个(以及所有具有正确内容的文件),您可以直接添加您的框:

vagrant box add yourname/box1
Run Code Online (Sandbox Code Playgroud)

由于“metadata.json”是 box1 目录的索引文件,它应该正确地将内容重定向到它,vagrant 将拾取它,解释元数据并下载适当的框。


小智 9

Vagrant 要求框元数据 URL 与application/json内容类型一起提供。您收到的错误表明 vagrant 已将您的 URL 解释为常规框。

确保您的 HTTP 服务器Content-Type正确设置标头。如果您的文件具有扩展名,大多数 HTTP 服务器会自动将Content-Type 标头设置为application/json.json