3
votes

I'm using Vagrant for virtual machines and want to start creating my own base boxes to try and match a production environment.

I've created a plain Debian base box using VMware Fusion Pro 8.1.1 and I've been able to add the box, but I'd like to start using the box metadata.json to set version numbers. I read in the vagrant doc that the only required key is the "provider", and that works great, but when I vagrant box list I get v0

work-debian7-11-64              (vmware_fusion, 0)

I can see it when I remove to try again with a an updated metadata.json file.

$ vagrant box remove work-debian7-11-64
Removing box 'work-debian7-11-64' (v0) with provider 'vmware_fusion'...

If I follow the documentation and use "version":"0.1.0" something like:

{
  "name": "hashicorp/precise64",
  "description": "This box contains Ubuntu 12.04 LTS 64-bit.",
  "versions": [
    {
      "version": "0.1.0",
      "providers": [
        {
          "name": "virtualbox",
          "url": "http://somewhere.com/precise64_010_virtualbox.box",
          "checksum_type": "sha1",
          "checksum": "foo"
        }
      ]
    }
  ]
}

I end up with an error when I go to add the box. This is some of the output (it goes on with more details with from)

$ vagrant box add work-debian7-11-64 debian-7.11-64.vmware.box
==> box: Box file was not detected as metadata. Adding it directly...
==> box: Adding box 'work-debian7-11-64' (v0) for provider: 
    box: Unpacking necessary files from: file:///Users/dave/Code/code_resources/vagrant_examples/vagrant-bird-box-vmware-debian-nodesktop/debian-7.11-64.vmware.box
/opt/vagrant/embedded/gems/gems/vagrant-1.8.4/lib/vagrant/box_collection.rb:155:in `block (3 levels) in add': undefined method `to_sym' for nil:NilClass (NoMethodError)

This is my metadata.json file:

{
  "name": "workalicious/debian7-11-64",
  "description": "Debian 7.11.0 64-bit web server.",
  "versions": [{
    "version": "0.1.0",
    "providers": [{
        "name": "vmware_fusion"
        }]
    }]
}

I'm wondering if it's something I'm doing wrong with the format of the metadata.json? When I only use the provider key box add works without errors. I know there is Altas and Packer, but I wanted to try this locally.

1

1 Answers

4
votes

I believe I have a better understanding now, after reading the Vagrant doc very slowly.

I should include a metadata.json file in the .box that has at least the provider, it's required.

Within the archive, Vagrant does expect a single file: metadata.json. This is a JSON file that is completely unrelated to the above box catalog metadata component; there is only one metadata.json per box file (inside the box file), whereas one catalog metadata JSON document can describe multiple versions of the same box, potentially spanning multiple providers.

metadata.json must contain at least the "provider" key with the provider the box is for. Vagrant uses this to verify the provider of the box. For example, if your box was for VirtualBox, the metadata.json would look like this:

// metadata.json inside of WorkaliciousDebian7-64-nogui.vmwarevm
{
  "provider": "vmware_fusion"
}

If there is no metadata.json file or the file does not contain valid JSON with at least a "provider" key, then Vagrant will error when adding the box, because it cannot verify the provider.

Other keys/values may be added to the metadata without issue. The value of the metadata file is passed opaquely into Vagrant and plugins can make use of it. At this point, Vagrant core does not use any other keys in this file.

That's part 1 (BOX FILE), metadata.json file inside the .vmwarevm directory. Part 2 (BOX METADATA) is having another metadata.json file with keys for name, version, url, checksum, and ... From the doc:

The metadata is an optional component for a box (but highly recommended) that enables versioning, updating, multiple providers from a single file, and more.

// get the checksum
$ md5 debian-7.11-64.vmware.box 
MD5 (debian-7.11-64.vmware.box) = f1a2b7982031a1e53c1e39011f8d5f37

// metadata.json file used with the vagrant box add
{
  "name": "workalicious/debian71164",
  "description": "Debian 7.11.0 64-bit web server.",
  "versions": [
    {
      "version": "0.1.0",
      "providers": [
        {
          "name": "vmware_fusion",
          "url": "file:///Users/dave/Code/code_resources/vagrant_examples/vagrant-bird-box-vmware-debian-nodesktop/debian-7.11-64.vmware.box",
          "checksum_type": "md5",
          "checksum": "f1a2b7982031a1e53c1e39011f8d5f37"
        }
      ]
    }
  ]
}

Now that there's a box metadata.json that can be referenced during the vagrant box add.

$ vagrant box add metadata.json --provider vmware_fusion
==> box: Loading metadata for box 'metadata.json'
    box: URL: file:///Users/dave/Code/code_resources/vagrant_examples/vagrant-bird-box-vmware-debian-nodesktop/metadata.json
==> box: Adding box 'workalicious/debian71164' (v0.1.0) for provider: vmware_fusion
    box: Unpacking necessary files from: file:///Users/dave/Code/code_resources/vagrant_examples/vagrant-bird-box-vmware-debian-nodesktop/debian-7.11-64.vmware.box
    box: Calculating and comparing box checksum...
==> box: Successfully added box 'workalicious/debian71164' (v0.1.0) for 'vmware_fusion'!

Maybe this helps someone else looking to do the same kind of workflow.