From 08037d1941a394fc178a080a78cac177568bdc91 Mon Sep 17 00:00:00 2001 From: dima Date: Sat, 16 May 2015 17:35:00 +0200 Subject: [PATCH] port tools/create_box.sh to package action. close #11 --- lib/vagrant-libvirt/action.rb | 7 +- lib/vagrant-libvirt/action/destroy_domain.rb | 6 +- lib/vagrant-libvirt/action/package_domain.rb | 79 ++++++++++++++++++++ 3 files changed, 87 insertions(+), 5 deletions(-) create mode 100644 lib/vagrant-libvirt/action/package_domain.rb diff --git a/lib/vagrant-libvirt/action.rb b/lib/vagrant-libvirt/action.rb index 7c3d47e..4c4f9cf 100644 --- a/lib/vagrant-libvirt/action.rb +++ b/lib/vagrant-libvirt/action.rb @@ -144,8 +144,10 @@ module VagrantPlugins # not implemented and looks like not require def self.action_package - lambda do |env| - raise Errors::PackageNotSupported + Vagrant::Action::Builder.new.tap do |b| + b.use ConfigValidate + b.use ConnectLibvirt + b.use PackageDomain end end @@ -317,6 +319,7 @@ module VagrantPlugins action_root = Pathname.new(File.expand_path('../action', __FILE__)) autoload :ConnectLibvirt, action_root.join('connect_libvirt') + autoload :PackageDomain, action_root.join('package_domain') autoload :CreateDomain, action_root.join('create_domain') autoload :CreateDomainVolume, action_root.join('create_domain_volume') autoload :CreateNetworkInterfaces, action_root.join('create_network_interfaces') diff --git a/lib/vagrant-libvirt/action/destroy_domain.rb b/lib/vagrant-libvirt/action/destroy_domain.rb index 6d13d6a..e4610be 100644 --- a/lib/vagrant-libvirt/action/destroy_domain.rb +++ b/lib/vagrant-libvirt/action/destroy_domain.rb @@ -41,14 +41,14 @@ module VagrantPlugins next if disk[:allow_existing] diskname = libvirt_domain.name + '-' + disk[:device] + '.' + disk[:type].to_s # diskname is uniq - libvirt_disk = env[:libvirt_compute].volumes.all.select do |x| + libvirt_disk = domain.volumes.select do |x| x.name == diskname end.first if libvirt_disk libvirt_disk.destroy elsif disk[:path] poolname = env[:machine].provider_config.storage_pool_name - libvirt_disk = env[:libvirt_compute].volumes.all.select do |x| + libvirt_disk = domain.volumes.select do |x| # FIXME can remove pool/target.img and pool/123/target.img x.path =~ /\/#{disk[:path]}$/ && x.pool_name == poolname end.first @@ -57,7 +57,7 @@ module VagrantPlugins end # remove root storage - root_disk = env[:libvirt_compute].volumes.all.select do |x| + root_disk = domain.volumes.select do |x| x.name == libvirt_domain.name + '.img' end.first root_disk.destroy if root_disk diff --git a/lib/vagrant-libvirt/action/package_domain.rb b/lib/vagrant-libvirt/action/package_domain.rb new file mode 100644 index 0000000..d1b58b8 --- /dev/null +++ b/lib/vagrant-libvirt/action/package_domain.rb @@ -0,0 +1,79 @@ +require 'log4r' + +module VagrantPlugins + module ProviderLibvirt + module Action + # Action for create new box for libvirt provider + class PackageDomain + def initialize(app, env) + @logger = Log4r::Logger.new('vagrant_libvirt::action::package_domain') + @app = app + env['package.files'] ||= {} + env['package.output'] ||= 'package.box' + end + + def call(env) + env[:ui].info(I18n.t('vagrant_libvirt.package_domain')) + libvirt_domain = env[:libvirt_compute].client.lookup_domain_by_uuid( + env[:machine].id) + domain = env[:libvirt_compute].servers.get(env[:machine].id.to_s) + root_disk = domain.volumes.select do |x| + x.name == libvirt_domain.name + '.img' + end.first + boxname = env['package.output'] + raise "#{boxname}: Already exists" if File.exists?(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' + 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}` + Dir.chdir(@tmp_dir) + img_size = `qemu-img info #{@tmp_img} | grep 'virtual size' | awk '{print $3;}' | tr -d 'G'`.chomp + File.write(@tmp_dir + '/metadata.json', metadata_content(img_size)) + File.write(@tmp_dir + '/Vagrantfile',vagrantfile_content) + assebmle_box(boxname) + FileUtils.mv(@tmp_dir + '/' + boxname, '../' + boxname) + 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 + + def assebmle_box(boxname) + `tar cvzf "#{boxname}" --totals ./metadata.json ./Vagrantfile ./box.img` + end + + 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 + EOF + end + + def metadata_content(filesize) + <<-EOF + { + "provider": "libvirt", + "format": "qcow2", + "virtual_size": #{filesize} + } + EOF + end + end + end + end +end