mirror of
https://github.com/vagrant-libvirt/vagrant-libvirt.git
synced 2025-02-25 18:55:27 -06:00
Download images with libvirt instead of copying (#928)
Packaging an existing vagrant environment relied on copying the backing image. Users may not have permission to read this file despite being able to interact with it through libvirt. Use ruby-libvirt to download the image instead so any user with libvirt access can run the package command.
This commit is contained in:
parent
7e966febbd
commit
a83900f1ae
@ -1,3 +1,4 @@
|
||||
require 'fileutils'
|
||||
require 'log4r'
|
||||
|
||||
module VagrantPlugins
|
||||
@ -21,21 +22,26 @@ module VagrantPlugins
|
||||
root_disk = domain.volumes.select do |x|
|
||||
x.name == libvirt_domain.name + '.img'
|
||||
end.first
|
||||
raise Errors::NoDomainVolume if root_disk.nil?
|
||||
boxname = env['package.output']
|
||||
raise "#{boxname}: Already exists" if File.exist?(boxname)
|
||||
@tmp_dir = Dir.pwd + '/_tmp_package'
|
||||
@tmp_img = @tmp_dir + '/box.img'
|
||||
Dir.mkdir(@tmp_dir)
|
||||
if File.readable?(root_disk.path)
|
||||
backing = `qemu-img info "#{root_disk.path}" | grep 'backing file:' | cut -d ':' -f2`.chomp
|
||||
else
|
||||
env[:ui].error("Require set read access to #{root_disk.path}. sudo chmod a+r #{root_disk.path}")
|
||||
FileUtils.rm_rf(@tmp_dir)
|
||||
raise 'Have no access'
|
||||
FileUtils.mkdir_p(@tmp_dir)
|
||||
env[:ui].info("Downloading #{root_disk.name} to #{@tmp_img}")
|
||||
ret = download_image(@tmp_img, env[:machine].provider_config.storage_pool_name,
|
||||
root_disk.name, env) do |progress,image_size|
|
||||
env[:ui].clear_line
|
||||
env[:ui].report_progress(progress, image_size, false)
|
||||
end
|
||||
# Clear the line one last time since the progress meter doesn't
|
||||
# disappear immediately.
|
||||
env[:ui].clear_line
|
||||
backing = `qemu-img info "#{@tmp_img}" | grep 'backing file:' | cut -d ':' -f2`.chomp
|
||||
if backing
|
||||
env[:ui].info('Image has backing image, copying image and rebasing ...')
|
||||
`qemu-img rebase -p -b "" #{@tmp_img}`
|
||||
end
|
||||
env[:ui].info('Image has backing image, copying image and rebasing ...')
|
||||
FileUtils.cp(root_disk.path, @tmp_img)
|
||||
`qemu-img rebase -p -b "" #{@tmp_img}`
|
||||
# remove hw association with interface
|
||||
# working for centos with lvs default disks
|
||||
options = ENV.fetch('VAGRANT_LIBVIRT_VIRT_SYSPREP_OPTIONS', '')
|
||||
@ -101,6 +107,44 @@ module VagrantPlugins
|
||||
}
|
||||
EOF
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
# Fog libvirt currently doesn't support downloading images from storage
|
||||
# pool volumes. Use ruby-libvirt client instead.
|
||||
def download_image(image_file, pool_name, volume_name, env)
|
||||
begin
|
||||
pool = env[:machine].provider.driver.connection.client.lookup_storage_pool_by_name(
|
||||
pool_name
|
||||
)
|
||||
volume = pool.lookup_volume_by_name(volume_name)
|
||||
image_size = volume.info.allocation # B
|
||||
|
||||
stream = env[:machine].provider.driver.connection.client.stream
|
||||
|
||||
# Use length of 0 to download remaining contents after offset
|
||||
volume.download(stream, offset = 0, length = 0)
|
||||
|
||||
buf_size = 1024 * 250 # 250K, copied from upload_image in handle_box_image.rb
|
||||
progress = 0
|
||||
retval = stream.recv(buf_size)
|
||||
open(image_file, 'wb') do |io|
|
||||
while (retval.at(0) > 0)
|
||||
recvd = io.write(retval.at(1))
|
||||
progress += recvd
|
||||
yield [progress, image_size]
|
||||
retval = stream.recv(buf_size)
|
||||
end
|
||||
end
|
||||
rescue => e
|
||||
raise Errors::ImageDownloadError,
|
||||
volume_name: volume_name,
|
||||
pool_name: pool_name,
|
||||
error_message: e.message
|
||||
end
|
||||
|
||||
progress == image_size
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -33,6 +33,10 @@ module VagrantPlugins
|
||||
error_key(:image_upload_error)
|
||||
end
|
||||
|
||||
class ImageDownloadError < VagrantLibvirtError
|
||||
error_key(:image_download_error)
|
||||
end
|
||||
|
||||
# Box exceptions
|
||||
class NoBoxVolume < VagrantLibvirtError
|
||||
error_key(:no_box_volume)
|
||||
|
@ -111,6 +111,8 @@ en:
|
||||
There was error while creating Libvirt storage pool: %{error_message}
|
||||
image_upload_error: |-
|
||||
Error while uploading image to storage pool: %{error_message}
|
||||
image_download_error: |-
|
||||
Error while downloading volume '%{volume_name}' from storage pool '%{pool_name}': %{error_message}
|
||||
no_domain_error: |-
|
||||
No domain found. %{error_message}
|
||||
attach_device_error: |-
|
||||
|
Loading…
Reference in New Issue
Block a user