vagrant-libvirt 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/Gemfile +12 -0
  4. data/LICENSE +22 -0
  5. data/README.md +33 -0
  6. data/Rakefile +7 -0
  7. data/example_box/README.md +14 -0
  8. data/example_box/Vagrantfile +45 -0
  9. data/example_box/metadata.json +5 -0
  10. data/lib/vagrant-libvirt/action/connect_libvirt.rb +72 -0
  11. data/lib/vagrant-libvirt/action/create_domain.rb +62 -0
  12. data/lib/vagrant-libvirt/action/create_domain_volume.rb +58 -0
  13. data/lib/vagrant-libvirt/action/create_network_interfaces.rb +85 -0
  14. data/lib/vagrant-libvirt/action/destroy_domain.rb +28 -0
  15. data/lib/vagrant-libvirt/action/handle_box_image.rb +121 -0
  16. data/lib/vagrant-libvirt/action/handle_storage_pool.rb +49 -0
  17. data/lib/vagrant-libvirt/action/is_created.rb +18 -0
  18. data/lib/vagrant-libvirt/action/message_already_created.rb +16 -0
  19. data/lib/vagrant-libvirt/action/message_not_created.rb +16 -0
  20. data/lib/vagrant-libvirt/action/read_ssh_info.rb +51 -0
  21. data/lib/vagrant-libvirt/action/read_state.rb +38 -0
  22. data/lib/vagrant-libvirt/action/set_name_of_domain.rb +31 -0
  23. data/lib/vagrant-libvirt/action/start_domain.rb +27 -0
  24. data/lib/vagrant-libvirt/action/sync_folders.rb +58 -0
  25. data/lib/vagrant-libvirt/action/timed_provision.rb +21 -0
  26. data/lib/vagrant-libvirt/action/wait_till_up.rb +96 -0
  27. data/lib/vagrant-libvirt/action.rb +94 -0
  28. data/lib/vagrant-libvirt/config.rb +48 -0
  29. data/lib/vagrant-libvirt/errors.rb +90 -0
  30. data/lib/vagrant-libvirt/plugin.rb +77 -0
  31. data/lib/vagrant-libvirt/provider.rb +76 -0
  32. data/lib/vagrant-libvirt/templates/default_storage_pool.xml.erb +13 -0
  33. data/lib/vagrant-libvirt/templates/domain.xml.erb +34 -0
  34. data/lib/vagrant-libvirt/templates/interface.xml.erb +7 -0
  35. data/lib/vagrant-libvirt/templates/volume_snapshot.xml.erb +26 -0
  36. data/lib/vagrant-libvirt/util/collection.rb +22 -0
  37. data/lib/vagrant-libvirt/util/erb_template.rb +21 -0
  38. data/lib/vagrant-libvirt/util/timer.rb +17 -0
  39. data/lib/vagrant-libvirt/util.rb +10 -0
  40. data/lib/vagrant-libvirt/version.rb +5 -0
  41. data/lib/vagrant-libvirt.rb +30 -0
  42. data/locales/en.yml +103 -0
  43. data/vagrant-libvirt.gemspec +23 -0
  44. metadata +127 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 857a7572e2968583b54a002899aeb4ed206ce1a9
4
+ data.tar.gz: b2272a7a10779ccbaef6f5c8aa1eda3d7cc77d9f
5
+ SHA512:
6
+ metadata.gz: 1eb41e05a79497bd68f8b8616d75b61ed8a4e7d4a9787ea90ec5ef0a061847f8ca12e2b6f80e3d95b941a6483cd2ef21df48ffd020cdda1949e4ea5d30784c2e
7
+ data.tar.gz: cb6363c8c70efaac9b3ed73cdace2ef42c658b946571a5d5bc8693144273af6612b0afdcc79ca8de69b685380fc33c7b009ca46bcae8b1de0cf9d5ce37125e91
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in vagrant-libvirt.gemspec
4
+ gemspec
5
+
6
+ group :development do
7
+ # We depend on Vagrant for development, but we don't add it as a
8
+ # gem dependency because we expect to be installed within the
9
+ # Vagrant environment itself using `vagrant plugin`.
10
+ gem "vagrant", :git => "git://github.com/mitchellh/vagrant.git"
11
+ end
12
+
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Lukas Stanek
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,33 @@
1
+ # Vagrant Libvirt Provider
2
+
3
+ This is a [Vagrant](http://www.vagrantup.com) 1.1+ plugin that adds an
4
+ [Libvirt](http://libvirt.org) provider to Vagrant, allowing Vagrant to
5
+ control and provision machines via Libvirt toolkit.
6
+
7
+ **Note:** This plugin requires Vagrant 1.1+.
8
+
9
+ ## Features
10
+
11
+ * Upload of box image (qcow2 format) to Libvirt storage pool.
12
+ * Volume creation as COW diff image for each new domain.
13
+ * Create and boot Libvirt domains.
14
+ * SSH into domains.
15
+ * Provision domains with any built-in Vagrant provisioner.
16
+ * Minimal synced folder support via `rsync`.
17
+
18
+ ## Usage
19
+
20
+ Install using standard Vagrant 1.1+ plugin installation methods. After
21
+ installing, `vagrant up` and specify the `libvirt` provider. An example is
22
+ shown below.
23
+
24
+ ```
25
+ $ vagrant plugin install vagrant-libvirt
26
+ ...
27
+ $ vagrant up --provider=libvirt
28
+ ...
29
+ ```
30
+
31
+ Of course prior to doing this, you'll need to obtain an Libvirt-compatible
32
+ box file for Vagrant.
33
+
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env rake
2
+
3
+ require 'rubygems'
4
+ require 'bundler/setup'
5
+ #require 'bundler/gem_tasks'
6
+ Bundler::GemHelper.install_tasks
7
+
@@ -0,0 +1,14 @@
1
+ # Vagrant Libvirt Example Box
2
+
3
+ Vagrant providers each require a custom provider-specific box format.
4
+ This folder shows the example contents of a box for the `libvirt` provider.
5
+ To turn this into a box create a vagrant image according documentation (don't
6
+ forget to install rsync command) and create box with following command:
7
+
8
+ ```
9
+ $ tar cvzf custom_box.box ./metadata.json ./Vagrantfile ./box.img
10
+ ```
11
+
12
+ This box works by using Vagrant's built-in Vagrantfile merging to setup
13
+ defaults for Libvirt. These defaults can easily be overwritten by higher-level
14
+ Vagrantfiles (such as project root Vagrantfiles).
@@ -0,0 +1,45 @@
1
+ # -*- mode: ruby -*-
2
+ # vi: set ft=ruby :
3
+
4
+ Vagrant.configure("2") do |config|
5
+
6
+ # Example configuration of new VM..
7
+ #
8
+ #config.vm.define :test_vm do |test_vm|
9
+ # Box name
10
+ #test_vm.vm.box = "centos64"
11
+
12
+ # Interfaces for VM
13
+ #
14
+ # Hostonly network is not supported in this version of provider. Bridged
15
+ # interface with network id specified can be created.
16
+ #test_vm.vm.network :bridged, :bridge => "default", :adapter => 1
17
+ #end
18
+
19
+ # Options for libvirt vagrant provider.
20
+ config.vm.provider :libvirt do |libvirt|
21
+
22
+ # A hypervisor name to access. Different drivers can be specified, but
23
+ # this version of provider creates KVM machines only. Some examples of
24
+ # drivers are qemu (KVM/qemu), xen (Xen hypervisor), lxc (Linux Containers),
25
+ # esx (VMware ESX), vmwarews (VMware Workstation) and more. Refer to
26
+ # documentation for available drivers (http://libvirt.org/drivers.html).
27
+ libvirt.driver = "qemu"
28
+
29
+ # The name of the server, where libvirtd is running.
30
+ libvirt.host = "localhost"
31
+
32
+ # If use ssh tunnel to connect to Libvirt.
33
+ libvirt.connect_via_ssh = false
34
+
35
+ # The username and password to access Libvirt. Password is not used when
36
+ # connecting via ssh.
37
+ libvirt.username = "root"
38
+ #libvirt.password = "secret"
39
+
40
+ # Libvirt storage pool name, where box image and instance snapshots will
41
+ # be stored.
42
+ libvirt.storage_pool_name = "default"
43
+ end
44
+ end
45
+
@@ -0,0 +1,5 @@
1
+ {
2
+ "provider" : "libvirt"
3
+ "format" : "qcow2"
4
+ "virtual_size" : "40"
5
+ }
@@ -0,0 +1,72 @@
1
+ require 'fog'
2
+ require 'log4r'
3
+
4
+ module VagrantPlugins
5
+ module Libvirt
6
+ module Action
7
+ class ConnectLibvirt
8
+ def initialize(app, env)
9
+ @logger = Log4r::Logger.new("vagrant_libvirt::action::connect_libvirt")
10
+ @app = app
11
+ end
12
+
13
+ def call(env)
14
+
15
+ # If already connected to libvirt, just use it and don't connect
16
+ # again.
17
+ if Libvirt.libvirt_connection
18
+ env[:libvirt_compute] = Libvirt.libvirt_connection
19
+ return @app.call(env)
20
+ end
21
+
22
+ # Get config options for libvirt provider.
23
+ config = env[:machine].provider_config
24
+
25
+ # Setup connection uri.
26
+ uri = config.driver
27
+ if config.connect_via_ssh
28
+ uri << '+ssh://'
29
+ if config.username
30
+ uri << config.username + '@'
31
+ end
32
+
33
+ if config.host
34
+ uri << config.host
35
+ else
36
+ uri << 'localhost'
37
+ end
38
+ else
39
+ uri << '://'
40
+ uri << config.host if config.host
41
+ end
42
+ uri << '/system?no_verify=1'
43
+
44
+ conn_attr = {}
45
+ conn_attr[:provider] = 'libvirt'
46
+ conn_attr[:libvirt_uri] = uri
47
+ conn_attr[:libvirt_username] = config.username if config.username
48
+ conn_attr[:libvirt_password] = config.password if config.password
49
+
50
+ # Setup command for retrieving IP address for newly created machine
51
+ # with some MAC address. Get it via arp table. This solution doesn't
52
+ # require arpwatch to be installed.
53
+ conn_attr[:libvirt_ip_command] = "arp -an | grep $mac | sed '"
54
+ conn_attr[:libvirt_ip_command] << 's/.*(\([0-9\.]*\)).*/\1/'
55
+ conn_attr[:libvirt_ip_command] << "'"
56
+
57
+ @logger.info("Connecting to Libvirt (#{uri}) ...")
58
+ begin
59
+ env[:libvirt_compute] = Fog::Compute.new(conn_attr)
60
+ rescue Fog::Errors::Error => e
61
+ raise Errors::FogLibvirtConnectionError,
62
+ :error_message => e.message
63
+ end
64
+ Libvirt.libvirt_connection = env[:libvirt_compute]
65
+
66
+ @app.call(env)
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+
@@ -0,0 +1,62 @@
1
+ require 'log4r'
2
+
3
+ module VagrantPlugins
4
+ module Libvirt
5
+ module Action
6
+
7
+ class CreateDomain
8
+ include VagrantPlugins::Libvirt::Util::ErbTemplate
9
+
10
+ def initialize(app, env)
11
+ @logger = Log4r::Logger.new("vagrant_libvirt::action::create_domain")
12
+ @app = app
13
+ end
14
+
15
+ def call(env)
16
+ # Gather some info about domain
17
+ # TODO from Vagrantfile
18
+ @name = env[:domain_name]
19
+ @cpus = 1
20
+ @memory_size = 512*1024
21
+
22
+ # TODO get type from driver config option
23
+ @domain_type = 'kvm'
24
+
25
+ @os_type = 'hvm'
26
+
27
+ # Get path to domain image.
28
+ domain_volume = Libvirt::Util::Collection.find_matching(
29
+ env[:libvirt_compute].volumes.all, "#{@name}.img")
30
+ raise Errors::DomainVolumeExists if domain_volume == nil
31
+ @domain_volume_path = domain_volume.path
32
+
33
+ # Output the settings we're going to use to the user
34
+ env[:ui].info(I18n.t("vagrant_libvirt.creating_domain"))
35
+ env[:ui].info(" -- Name: #{@name}")
36
+ env[:ui].info(" -- Domain type: #{@domain_type}")
37
+ env[:ui].info(" -- Cpus: #{@cpus}")
38
+ env[:ui].info(" -- Memory: #{@memory_size/1024}M")
39
+ env[:ui].info(" -- Base box: #{env[:machine].box.name}")
40
+ env[:ui].info(" -- Image: #{@domain_volume_path}")
41
+
42
+ # Create libvirt domain.
43
+ # Is there a way to tell fog to create new domain with already
44
+ # existing volume? Use domain creation from template..
45
+ begin
46
+ server = env[:libvirt_compute].servers.create(
47
+ :xml => to_xml('domain'))
48
+ rescue Fog::Errors::Error => e
49
+ raise Errors::FogCreateServerError,
50
+ :error_message => e.message
51
+ end
52
+
53
+ # Immediately save the ID since it is created at this point.
54
+ env[:machine].id = server.id
55
+
56
+ @app.call(env)
57
+ end
58
+ end
59
+
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,58 @@
1
+ require 'log4r'
2
+
3
+ module VagrantPlugins
4
+ module Libvirt
5
+ module Action
6
+
7
+ # Create a snapshot of base box image. This new snapshot is just new
8
+ # cow image with backing storage pointing to base box image. Use this
9
+ # image as new domain volume.
10
+ class CreateDomainVolume
11
+ include VagrantPlugins::Libvirt::Util::ErbTemplate
12
+
13
+ def initialize(app, env)
14
+ @logger = Log4r::Logger.new("vagrant_libvirt::action::create_domain_volume")
15
+ @app = app
16
+ end
17
+
18
+ def call(env)
19
+ env[:ui].info(I18n.t("vagrant_libvirt.creating_domain_volume"))
20
+
21
+ # Get config options.
22
+ config = env[:machine].provider_config
23
+
24
+ # This is name of newly created image for vm.
25
+ @name = "#{env[:domain_name]}.img"
26
+
27
+ # Verify the volume doesn't exist already.
28
+ domain_volume = Libvirt::Util::Collection.find_matching(
29
+ env[:libvirt_compute].volumes.all, @name)
30
+ raise Errors::DomainVolumeExists if domain_volume
31
+
32
+ # Get path to backing image - box volume.
33
+ box_volume = Libvirt::Util::Collection.find_matching(
34
+ env[:libvirt_compute].volumes.all, env[:box_volume_name])
35
+ @backing_file = box_volume.path
36
+
37
+ # Virtual size of image. Same as box image size.
38
+ @capacity = env[:machine].box.metadata['virtual_size'] #G
39
+
40
+ # Create new volume from xml template. Fog currently doesn't support
41
+ # volume snapshots directly.
42
+ begin
43
+ domain_volume = env[:libvirt_compute].volumes.create(
44
+ :xml => to_xml('volume_snapshot'),
45
+ :pool_name => config.storage_pool_name)
46
+ rescue Fog::Errors::Error => e
47
+ raise Errors::FogDomainVolumeCreateError,
48
+ :error_message => e.message
49
+ end
50
+
51
+ @app.call(env)
52
+ end
53
+ end
54
+
55
+ end
56
+ end
57
+ end
58
+
@@ -0,0 +1,85 @@
1
+ require 'log4r'
2
+
3
+ module VagrantPlugins
4
+ module Libvirt
5
+ module Action
6
+
7
+ # Create network interfaces for domain, before domain is running.
8
+ class CreateNetworkInterfaces
9
+ include VagrantPlugins::Libvirt::Util::ErbTemplate
10
+
11
+ def initialize(app, env)
12
+ @logger = Log4r::Logger.new("vagrant_libvirt::action::create_network_interfaces")
13
+ @app = app
14
+ end
15
+
16
+ def call(env)
17
+ # Get domain first.
18
+ begin
19
+ domain = env[:libvirt_compute].client.lookup_domain_by_uuid(
20
+ env[:machine].id.to_s)
21
+ rescue => e
22
+ raise Errors::NoDomainError,
23
+ :error_message => e.message
24
+ end
25
+
26
+ # Setup list of interfaces before creating them
27
+ adapters = []
28
+
29
+ # Assign main interface for provisioning to first slot.
30
+ # Use network 'default' as network for ssh connecting and
31
+ # machine provisioning. This should be maybe configurable in
32
+ # Vagrantfile in future.
33
+ adapters[0] = 'default'
34
+
35
+ env[:machine].config.vm.networks.each do |type, options|
36
+ # Other types than bridged are not supported for now.
37
+ next if type != :bridged
38
+
39
+ network_name = 'default'
40
+ network_name = options[:bridge] if options[:bridge]
41
+
42
+ if options[:adapter]
43
+ if adapters[options[:adapter]]
44
+ raise Errors::InterfaceSlotNotAvailable
45
+ end
46
+
47
+ adapters[options[:adapter].to_i] = network_name
48
+ else
49
+ empty_slot = find_empty(adapters, start=1)
50
+ raise Errors::InterfaceSlotNotAvailable if empty_slot == nil
51
+
52
+ adapters[empty_slot] = network_name
53
+ end
54
+ end
55
+
56
+ # Create each interface as new domain device
57
+ adapters.each_with_index do |network_name, slot_number|
58
+ @iface_number = slot_number
59
+ @network_name = network_name
60
+ @logger.info("Creating network interface eth#{@iface_number}")
61
+ begin
62
+ domain.attach_device(to_xml('interface'))
63
+ rescue => e
64
+ raise Errors::AttachDeviceError,
65
+ :error_message => e.message
66
+ end
67
+ end
68
+
69
+ @app.call(env)
70
+ end
71
+
72
+ private
73
+
74
+ def find_empty(array, start=0, stop=8)
75
+ for i in start..stop
76
+ return i if !array[i]
77
+ end
78
+ return nil
79
+ end
80
+ end
81
+
82
+ end
83
+ end
84
+ end
85
+
@@ -0,0 +1,28 @@
1
+ require 'log4r'
2
+
3
+ module VagrantPlugins
4
+ module Libvirt
5
+ module Action
6
+ class DestroyDomain
7
+
8
+ def initialize(app, env)
9
+ @logger = Log4r::Logger.new("vagrant_libvirt::action::destroy_domain")
10
+ @app = app
11
+ end
12
+
13
+ def call(env)
14
+
15
+ # Destroy the server and remove the tracking ID
16
+ env[:ui].info(I18n.t("vagrant_libvirt.destroy_domain"))
17
+
18
+ domain = env[:libvirt_compute].servers.get(env[:machine].id.to_s)
19
+ domain.destroy(:destroy_volumes => true)
20
+ env[:machine].id = nil
21
+
22
+ @app.call(env)
23
+ end
24
+
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,121 @@
1
+ require 'log4r'
2
+
3
+ module VagrantPlugins
4
+ module Libvirt
5
+ module Action
6
+ class HandleBoxImage
7
+ def initialize(app, env)
8
+ @logger = Log4r::Logger.new("vagrant_libvirt::action::handle_box_image")
9
+ @app = app
10
+ end
11
+
12
+ def call(env)
13
+
14
+ # Verify box metadata for mandatory values.
15
+ #
16
+ # Virtual size has to be set for allocating space in storage pool.
17
+ box_virtual_size = env[:machine].box.metadata['virtual_size']
18
+ if box_virtual_size == nil
19
+ raise Errors::NoBoxVirtualSizeSet
20
+ end
21
+
22
+ # Support qcow2 format only for now, but other formats with backing
23
+ # store capability should be usable.
24
+ box_format = env[:machine].box.metadata['format']
25
+ if box_format == nil
26
+ raise Errors::NoBoxFormatSet
27
+ elsif box_format != 'qcow2'
28
+ raise Errors::WrongBoxFormatSet
29
+ end
30
+
31
+ # Get config options
32
+ config = env[:machine].provider_config
33
+ box_image_file = env[:machine].box.directory.join("box.img").to_s
34
+ env[:box_volume_name] = env[:machine].box.name.to_s.dup
35
+ env[:box_volume_name] << '_vagrant_box_image.img'
36
+
37
+ # Don't continue if image already exists in storage pool.
38
+ return @app.call(env) if Libvirt::Util::Collection.find_matching(
39
+ env[:libvirt_compute].volumes.all, env[:box_volume_name])
40
+
41
+ # Box is not available as a storage pool volume. Create and upload
42
+ # it as a copy of local box image.
43
+ env[:ui].info(I18n.t("vagrant_libvirt.uploading_volume"))
44
+
45
+ # Create new volume in storage pool
46
+ box_image_size = File.size(box_image_file) # B
47
+ message = "Creating volume #{env[:box_volume_name]}"
48
+ message << " in storage pool #{config.storage_pool_name}."
49
+ @logger.info(message)
50
+ begin
51
+ fog_volume = env[:libvirt_compute].volumes.create(
52
+ :name => env[:box_volume_name],
53
+ :allocation => "#{box_image_size/1024/1024}M",
54
+ :capacity => "#{box_virtual_size}G",
55
+ :format_type => box_format,
56
+ :pool_name => config.storage_pool_name)
57
+ rescue Fog::Errors::Error => e
58
+ raise Errors::FogCreateVolumeError,
59
+ :error_message => e.message
60
+ end
61
+
62
+ # Upload box image to storage pool
63
+ ret = upload_image(box_image_file, config.storage_pool_name,
64
+ env[:box_volume_name], env) do |progress|
65
+ env[:ui].clear_line
66
+ env[:ui].report_progress(progress, box_image_size, false)
67
+ end
68
+
69
+ # Clear the line one last time since the progress meter doesn't
70
+ # disappear immediately.
71
+ env[:ui].clear_line
72
+
73
+ # If upload failed or was interrupted, remove created volume from
74
+ # storage pool.
75
+ if env[:interrupted] or !ret
76
+ begin
77
+ fog_volume.destroy
78
+ rescue
79
+ nil
80
+ end
81
+ end
82
+
83
+ @app.call(env)
84
+ end
85
+
86
+ protected
87
+
88
+ # Fog libvirt currently doesn't support uploading images to storage
89
+ # pool volumes. Use ruby-libvirt client instead.
90
+ def upload_image(image_file, pool_name, volume_name, env)
91
+ image_size = File.size(image_file) # B
92
+
93
+ begin
94
+ pool = env[:libvirt_compute].client.lookup_storage_pool_by_name(
95
+ pool_name)
96
+ volume = pool.lookup_volume_by_name(volume_name)
97
+ stream = env[:libvirt_compute].client.stream
98
+ volume.upload(stream, offset=0, length=image_size)
99
+ buf_size = 1024*1024 # 1M
100
+ progress = 0
101
+ open(image_file, 'rb') do |io|
102
+ while (buff = io.read(buf_size)) do
103
+ sent = stream.send buff
104
+ progress += sent
105
+ yield progress
106
+ end
107
+ end
108
+ rescue => e
109
+ raise Errors::ImageUploadError,
110
+ :error_message => e.message
111
+ end
112
+
113
+ return true if progress == image_size
114
+ false
115
+ end
116
+
117
+ end
118
+ end
119
+ end
120
+ end
121
+
@@ -0,0 +1,49 @@
1
+ require 'log4r'
2
+
3
+ module VagrantPlugins
4
+ module Libvirt
5
+ module Action
6
+ class HandleStoragePool
7
+ include VagrantPlugins::Libvirt::Util::ErbTemplate
8
+
9
+ def initialize(app, env)
10
+ @logger = Log4r::Logger.new("vagrant_libvirt::action::handle_storage_pool")
11
+ @app = app
12
+ end
13
+
14
+ def call(env)
15
+ # Get config options.
16
+ config = env[:machine].provider_config
17
+
18
+ # Check for storage pool, where box image should be created
19
+ fog_pool = Libvirt::Util::Collection.find_matching(
20
+ env[:libvirt_compute].pools.all, config.storage_pool_name)
21
+ return @app.call(env) if fog_pool
22
+
23
+ @logger.info("No storage pool '#{config.storage_pool_name}' is available.")
24
+
25
+ # If user specified other pool than default, don't create default
26
+ # storage pool, just write error message.
27
+ raise Errors::NoStoragePool if config.storage_pool_name != 'default'
28
+
29
+ @logger.info("Creating storage pool 'default'")
30
+
31
+ # Fog libvirt currently doesn't support creating pools. Use
32
+ # ruby-libvirt client directly.
33
+ begin
34
+ libvirt_pool = env[:libvirt_compute].client.create_storage_pool_xml(
35
+ to_xml('default_storage_pool'))
36
+ rescue => e
37
+ raise Errors::CreatingStoragePoolError,
38
+ :error_message => e.message
39
+ end
40
+ raise Errors::NoStoragePool if !libvirt_pool
41
+
42
+ @app.call(env)
43
+ end
44
+
45
+ end
46
+ end
47
+ end
48
+ end
49
+
@@ -0,0 +1,18 @@
1
+ module VagrantPlugins
2
+ module Libvirt
3
+ module Action
4
+ # This can be used with "Call" built-in to check if the machine
5
+ # is created and branch in the middleware.
6
+ class IsCreated
7
+ def initialize(app, env)
8
+ @app = app
9
+ end
10
+
11
+ def call(env)
12
+ env[:result] = env[:machine].state.id != :not_created
13
+ @app.call(env)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end