class VagrantPlugins::ProviderLibvirt::Action::CreateDomainVolume

Create a snapshot of base box image. This new snapshot is just new cow image with backing storage pointing to base box image. Use this image as new domain volume.

Public Class Methods

new(app, _env) click to toggle source
# File lib/vagrant-libvirt/action/create_domain_volume.rb, line 14
def initialize(app, _env)
  @logger = Log4r::Logger.new('vagrant_libvirt::action::create_domain_volume')
  @app = app
end

Public Instance Methods

call(env) click to toggle source
# File lib/vagrant-libvirt/action/create_domain_volume.rb, line 19
def call(env)
  env[:ui].info(I18n.t('vagrant_libvirt.creating_domain_volume'))

  env[:box_volumes].each_index do |index|
    suffix_index = index > 0 ? "_#{index}" : ''
    # Get config options.
    config = env[:machine].provider_config

    # This is name of newly created image for vm.
    @name = "#{env[:domain_name]}#{suffix_index}.img"

    # Verify the volume doesn't exist already.
    domain_volume = env[:machine].provider.driver.connection.volumes.all(
      name: @name
    ).first
    raise Errors::DomainVolumeExists if domain_volume && domain_volume.id

    # Get path to backing image - box volume.
    box_volume = env[:machine].provider.driver.connection.volumes.all(
      name: env[:box_volumes][index][:name]
    ).first
    @backing_file = box_volume.path

    # Virtual size of image. Take value worked out by HandleBoxImage
    @capacity = env[:box_volumes][index][:virtual_size].to_B # Byte

    # Create new volume from xml template. Fog currently doesn't support
    # volume snapshots directly.
    begin
      xml = Nokogiri::XML::Builder.new do |xml|
        xml.volume do
          xml.name(@name)
          xml.capacity(@capacity, unit: 'B')
          xml.target do
            xml.format(type: 'qcow2')
            xml.permissions do
              xml.owner storage_uid(env)
              xml.group storage_gid(env)
              xml.label 'virt_image_t'
            end
          end
          xml.backingStore do
            xml.path(@backing_file)
            xml.format(type: 'qcow2')
            xml.permissions do
              xml.owner storage_uid(env)
              xml.group storage_gid(env)
              xml.label 'virt_image_t'
            end
          end
        end
      end.to_xml(
        save_with: Nokogiri::XML::Node::SaveOptions::NO_DECLARATION |
                  Nokogiri::XML::Node::SaveOptions::NO_EMPTY_TAGS |
                  Nokogiri::XML::Node::SaveOptions::FORMAT
      )
      if config.snapshot_pool_name != config.storage_pool_name
          pool_name = config.snapshot_pool_name
      else
          pool_name = config.storage_pool_name
      end
      @logger.debug {
        "Creating Volume with XML:\n#{xml}"
      }
      @logger.debug "Using pool #{pool_name} for base box snapshot"
      domain_volume = env[:machine].provider.driver.connection.volumes.create(
        xml: xml,
        pool_name: pool_name
      )
    rescue Fog::Errors::Error => e
      raise Errors::FogDomainVolumeCreateError,
            error_message: e.message
    end
  end
  @app.call(env)
end