class Vagrant::Box

Represents a “box,” which is a package Vagrant environment that is used as a base image when creating a new guest machine.

Attributes

directory[R]

This is the directory on disk where this box exists.

@return [Pathname]

metadata[R]

This is the metadata for the box. This is read from the “metadata.json” file that all boxes require.

@return [Hash]

metadata_url[R]

This is the URL to the version info and other metadata for this box.

@return [String]

name[R]

The box name. This is the logical name used when adding the box.

@return [String]

provider[R]

This is the provider that this box is built for.

@return [Symbol]

version[R]

The version of this box.

@return [String]

Public Class Methods

new(name, provider, version, directory, **opts) click to toggle source

This is used to initialize a box.

@param [String] name Logical name of the box. @param [Symbol] provider The provider that this box implements. @param [Pathname] directory The directory where this box exists on

disk.
# File lib/vagrant/box.rb, line 57
def initialize(name, provider, version, directory, **opts)
  @name      = name
  @version   = version
  @provider  = provider
  @directory = directory
  @metadata_url = opts[:metadata_url]

  metadata_file = directory.join("metadata.json")
  raise Errors::BoxMetadataFileNotFound, :name => @name if !metadata_file.file?

  begin
    @metadata = JSON.parse(directory.join("metadata.json").read)
  rescue JSON::ParserError
    raise Errors::BoxMetadataCorrupted, name: @name
  end

  @logger = Log4r::Logger.new("vagrant::box")
end

Public Instance Methods

<=>(other) click to toggle source

Implemented for comparison with other boxes. Comparison is implemented by comparing names and providers.

Calls superclass method
# File lib/vagrant/box.rb, line 162
def <=>(other)
  return super if !other.is_a?(self.class)

  # Comparison is done by composing the name and provider
  "#{@name}-#{@version}-#{@provider}" <=>
  "#{other.name}-#{other.version}-#{other.provider}"
end
destroy!() click to toggle source

This deletes the box. This is NOT undoable.

# File lib/vagrant/box.rb, line 77
def destroy!
  # Delete the directory to delete the box.
  FileUtils.rm_r(@directory)

  # Just return true always
  true
rescue Errno::ENOENT
  # This means the directory didn't exist. Not a problem.
  return true
end
has_update?(version=nil) click to toggle source

Checks if the box has an update and returns the metadata, version, and provider. If the box doesn't have an update that satisfies the constraints, it will return nil.

This will potentially make a network call if it has to load the metadata from the network.

@param [String] version Version constraints the update must

satisfy. If nil, the version constrain defaults to being a
larger version than this box.

@return [Array]

# File lib/vagrant/box.rb, line 124
def has_update?(version=nil)
  if !@metadata_url
    raise Errors::BoxUpdateNoMetadata, name: @name
  end

  version += ", " if version
  version ||= ""
  version += "> #{@version}"
  md      = self.load_metadata
  newer   = md.version(version, provider: @provider)
  return nil if !newer

  [md, newer, newer.provider(@provider)]
end
load_metadata() click to toggle source

Loads the metadata URL and returns the latest metadata associated with this box.

@return [BoxMetadata]

# File lib/vagrant/box.rb, line 92
def load_metadata
  tf = Tempfile.new("vagrant")
  tf.close

  url = @metadata_url
  if File.file?(url) || url !~ /^[a-z0-9]+:.*$/
    url = File.expand_path(url)
    url = Util::Platform.cygwin_windows_path(url)
    url = "file:#{url}"
  end

  opts = { headers: ["Accept: application/json"] }
  Util::Downloader.new(url, tf.path, **opts).download!
  BoxMetadata.new(File.open(tf.path, "r"))
rescue Errors::DownloaderError => e
  raise Errors::BoxMetadataDownloadError,
    message: e.extra_data[:message]
ensure
  tf.unlink if tf
end
repackage(path) click to toggle source

This repackages this box and outputs it to the given path.

@param [Pathname] path The full path (filename included) of where

to output this box.

@return [Boolean] true if this succeeds.

# File lib/vagrant/box.rb, line 144
def repackage(path)
  @logger.debug("Repackaging box '#{@name}' to: #{path}")

  Util::SafeChdir.safe_chdir(@directory) do
    # Find all the files in our current directory and tar it up!
    files = Dir.glob(File.join(".", "**", "*"))

    # Package!
    Util::Subprocess.execute("bsdtar", "-czf", path.to_s, *files)
  end

  @logger.info("Repackaged box '#{@name}' successfully: #{path}")

  true
end