class VagrantPlugins::ProviderLibvirt::Action::PackageDomain
Action
for create new box for Libvirt provider
Public Class Methods
new(app, env)
click to toggle source
# File lib/vagrant-libvirt/action/package_domain.rb, line 9 def initialize(app, env) @logger = Log4r::Logger.new('vagrant_libvirt::action::package_domain') @app = app env['package.files'] ||= {} env['package.output'] ||= 'package.box' end
Public Instance Methods
assemble_box(boxname, extra)
click to toggle source
# File lib/vagrant-libvirt/action/package_domain.rb, line 81 def assemble_box(boxname, extra) `tar cvzf "#{boxname}" --totals ./metadata.json ./Vagrantfile ./box.img #{extra}` end
call(env)
click to toggle source
# File lib/vagrant-libvirt/action/package_domain.rb, line 16 def call(env) env[:ui].info(I18n.t('vagrant_libvirt.package_domain')) libvirt_domain = env[:machine].provider.driver.connection.client.lookup_domain_by_uuid( env[:machine].id ) domain = env[:machine].provider.driver.connection.servers.get(env[:machine].id.to_s) 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' 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 # remove hw association with interface # working for centos with lvs default disks options = ENV.fetch('VAGRANT_LIBVIRT_VIRT_SYSPREP_OPTIONS', '') operations = ENV.fetch('VAGRANT_LIBVIRT_VIRT_SYSPREP_OPERATIONS', 'defaults,-ssh-userdir') `virt-sysprep --no-logfile --operations #{operations} -a #{@tmp_img} #{options}` # add any user provided file extra = '' @tmp_include = @tmp_dir + '/_include' if env['package.include'] extra = './_include' Dir.mkdir(@tmp_include) env['package.include'].each do |f| env[:ui].info("Including user file: #{f}") FileUtils.cp(f, @tmp_include) end end if env['package.vagrantfile'] extra = './_include' Dir.mkdir(@tmp_include) unless File.directory?(@tmp_include) env[:ui].info('Including user Vagrantfile') FileUtils.cp(env['package.vagrantfile'], @tmp_include + '/Vagrantfile') end Dir.chdir(@tmp_dir) info = JSON.parse(`qemu-img info --output=json #{@tmp_img}`) img_size = (Float(info['virtual-size'])/(1024**3)).ceil File.write(@tmp_dir + '/metadata.json', metadata_content(img_size)) File.write(@tmp_dir + '/Vagrantfile', vagrantfile_content) assemble_box(boxname, extra) FileUtils.mv(@tmp_dir + '/' + boxname, '../' + boxname) FileUtils.rm_rf(@tmp_dir) env[:ui].info('Box created') env[:ui].info('You can now add the box:') env[:ui].info("vagrant box add #{boxname} --name any_comfortable_name") @app.call(env) end
metadata_content(filesize)
click to toggle source
# File lib/vagrant-libvirt/action/package_domain.rb, line 101 def metadata_content(filesize) <<-EOF { "provider": "libvirt", "format": "qcow2", "virtual_size": #{filesize} } EOF end
vagrantfile_content()
click to toggle source
# File lib/vagrant-libvirt/action/package_domain.rb, line 85 def vagrantfile_content <<-EOF Vagrant.configure("2") do |config| config.vm.provider :libvirt do |libvirt| libvirt.driver = "kvm" libvirt.host = "" libvirt.connect_via_ssh = false libvirt.storage_pool_name = "default" end end user_vagrantfile = File.expand_path('../_include/Vagrantfile', __FILE__) load user_vagrantfile if File.exists?(user_vagrantfile) EOF end
Protected Instance Methods
download_image(image_file, pool_name, volume_name, env) { |progress, image_size| ... }
click to toggle source
Fog libvirt currently doesn't support downloading images from storage pool volumes. Use ruby-libvirt client instead.
# File lib/vagrant-libvirt/action/package_domain.rb, line 115 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