/usr/share/rubygems-integration/all/gems/vagrant-libvirt-0.0.43/lib/vagrant-libvirt/action/handle_box_image.rb is in vagrant-libvirt 0.0.43-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | require 'log4r'
module VagrantPlugins
module ProviderLibvirt
module Action
class HandleBoxImage
@@lock = Mutex.new
def initialize(app, _env)
@logger = Log4r::Logger.new('vagrant_libvirt::action::handle_box_image')
@app = app
end
def call(env)
# Verify box metadata for mandatory values.
#
# Virtual size has to be set for allocating space in storage pool.
box_virtual_size = env[:machine].box.metadata['virtual_size']
raise Errors::NoBoxVirtualSizeSet if box_virtual_size.nil?
# Support qcow2 format only for now, but other formats with backing
# store capability should be usable.
box_format = env[:machine].box.metadata['format']
if box_format.nil?
raise Errors::NoBoxFormatSet
elsif box_format != 'qcow2'
raise Errors::WrongBoxFormatSet
end
# Get config options
config = env[:machine].provider_config
box_image_file = env[:machine].box.directory.join('box.img').to_s
env[:box_volume_name] = env[:machine].box.name.to_s.dup.gsub('/', '-VAGRANTSLASH-')
env[:box_volume_name] << "_vagrant_box_image_#{begin
env[:machine].box.version.to_s
rescue
''
end}.img"
# Override box_virtual_size
if config.machine_virtual_size
if config.machine_virtual_size < box_virtual_size
# Warn that a virtual size less than the box metadata size
# is not supported and will be ignored
env[:ui].warn I18n.t(
'vagrant_libvirt.warnings.ignoring_virtual_size_too_small',
requested: config.machine_virtual_size, minimum: box_virtual_size
)
else
env[:ui].info I18n.t('vagrant_libvirt.manual_resize_required')
box_virtual_size = config.machine_virtual_size
end
end
# save for use by later actions
env[:box_virtual_size] = box_virtual_size
# while inside the synchronize block take care not to call the next
# action in the chain, as must exit this block first to prevent
# locking all subsequent actions as well.
@@lock.synchronize do
# Don't continue if image already exists in storage pool.
break if ProviderLibvirt::Util::Collection.find_matching(
env[:machine].provider.driver.connection.volumes.all, env[:box_volume_name]
)
# Box is not available as a storage pool volume. Create and upload
# it as a copy of local box image.
env[:ui].info(I18n.t('vagrant_libvirt.uploading_volume'))
# Create new volume in storage pool
unless File.exist?(box_image_file)
raise Vagrant::Errors::BoxNotFound, name: env[:machine].box.name
end
box_image_size = File.size(box_image_file) # B
message = "Creating volume #{env[:box_volume_name]}"
message << " in storage pool #{config.storage_pool_name}."
@logger.info(message)
begin
fog_volume = env[:machine].provider.driver.connection.volumes.create(
name: env[:box_volume_name],
allocation: "#{box_image_size / 1024 / 1024}M",
capacity: "#{box_virtual_size}G",
format_type: box_format,
pool_name: config.storage_pool_name
)
rescue Fog::Errors::Error => e
raise Errors::FogCreateVolumeError,
error_message: e.message
end
# Upload box image to storage pool
ret = upload_image(box_image_file, config.storage_pool_name,
env[:box_volume_name], env) do |progress|
env[:ui].clear_line
env[:ui].report_progress(progress, box_image_size, false)
end
# Clear the line one last time since the progress meter doesn't
# disappear immediately.
env[:ui].clear_line
# If upload failed or was interrupted, remove created volume from
# storage pool.
if env[:interrupted] || !ret
begin
fog_volume.destroy
rescue
nil
end
end
end
@app.call(env)
end
protected
# Fog libvirt currently doesn't support uploading images to storage
# pool volumes. Use ruby-libvirt client instead.
def upload_image(image_file, pool_name, volume_name, env)
image_size = File.size(image_file) # B
begin
pool = env[:machine].provider.driver.connection.client.lookup_storage_pool_by_name(
pool_name
)
volume = pool.lookup_volume_by_name(volume_name)
stream = env[:machine].provider.driver.connection.client.stream
volume.upload(stream, offset = 0, length = image_size)
# Exception ProviderLibvirt::RetrieveError can be raised if buffer is
# longer than length accepted by API send function.
#
# TODO: How to find out if buffer is too large and what is the
# length that send function will accept?
buf_size = 1024 * 250 # 250K
progress = 0
open(image_file, 'rb') do |io|
while (buff = io.read(buf_size))
sent = stream.send buff
progress += sent
yield progress
end
end
rescue => e
raise Errors::ImageUploadError,
error_message: e.message
end
progress == image_size
end
end
end
end
end
|