vagrant-libvirt 0.0.42 → 0.2.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 (60) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +393 -147
  3. data/lib/vagrant-libvirt/action.rb +3 -2
  4. data/lib/vagrant-libvirt/action/create_domain.rb +87 -37
  5. data/lib/vagrant-libvirt/action/create_domain_volume.rb +19 -14
  6. data/lib/vagrant-libvirt/action/create_network_interfaces.rb +9 -5
  7. data/lib/vagrant-libvirt/action/create_networks.rb +7 -2
  8. data/lib/vagrant-libvirt/action/destroy_domain.rb +1 -1
  9. data/lib/vagrant-libvirt/action/destroy_networks.rb +5 -0
  10. data/lib/vagrant-libvirt/action/forward_ports.rb +10 -8
  11. data/lib/vagrant-libvirt/action/halt_domain.rb +1 -1
  12. data/lib/vagrant-libvirt/action/handle_box_image.rb +26 -15
  13. data/lib/vagrant-libvirt/action/handle_storage_pool.rb +9 -4
  14. data/lib/vagrant-libvirt/action/package_domain.rb +58 -12
  15. data/lib/vagrant-libvirt/action/prepare_nfs_settings.rb +3 -9
  16. data/lib/vagrant-libvirt/action/prune_nfs_exports.rb +19 -9
  17. data/lib/vagrant-libvirt/action/remove_libvirt_image.rb +2 -2
  18. data/lib/vagrant-libvirt/action/remove_stale_volume.rb +17 -11
  19. data/lib/vagrant-libvirt/action/set_boot_order.rb +2 -2
  20. data/lib/vagrant-libvirt/action/set_name_of_domain.rb +6 -9
  21. data/lib/vagrant-libvirt/action/start_domain.rb +2 -2
  22. data/lib/vagrant-libvirt/action/wait_till_up.rb +31 -16
  23. data/lib/vagrant-libvirt/cap/public_address.rb +16 -0
  24. data/lib/vagrant-libvirt/cap/synced_folder.rb +3 -3
  25. data/lib/vagrant-libvirt/config.rb +177 -29
  26. data/lib/vagrant-libvirt/driver.rb +31 -2
  27. data/lib/vagrant-libvirt/errors.rb +5 -1
  28. data/lib/vagrant-libvirt/plugin.rb +7 -2
  29. data/lib/vagrant-libvirt/templates/default_storage_pool.xml.erb +3 -3
  30. data/lib/vagrant-libvirt/templates/domain.xml.erb +48 -8
  31. data/lib/vagrant-libvirt/util.rb +1 -0
  32. data/lib/vagrant-libvirt/util/erb_template.rb +6 -7
  33. data/lib/vagrant-libvirt/util/network_util.rb +33 -13
  34. data/lib/vagrant-libvirt/util/nfs.rb +17 -0
  35. data/lib/vagrant-libvirt/util/storage_util.rb +27 -0
  36. data/lib/vagrant-libvirt/version.rb +1 -1
  37. data/locales/en.yml +8 -4
  38. data/spec/support/environment_helper.rb +1 -1
  39. data/spec/support/libvirt_context.rb +1 -1
  40. data/spec/support/sharedcontext.rb +2 -2
  41. data/spec/unit/action/destroy_domain_spec.rb +2 -2
  42. data/spec/unit/action/set_name_of_domain_spec.rb +3 -3
  43. data/spec/unit/config_spec.rb +173 -0
  44. data/spec/unit/templates/domain_all_settings.xml +20 -4
  45. data/spec/unit/templates/domain_custom_cpu_model.xml +48 -0
  46. data/spec/unit/templates/domain_defaults.xml +2 -0
  47. data/spec/unit/templates/domain_spec.rb +26 -2
  48. metadata +24 -32
  49. data/.coveralls.yml +0 -1
  50. data/.github/issue_template.md +0 -37
  51. data/.gitignore +0 -21
  52. data/.travis.yml +0 -24
  53. data/Gemfile +0 -26
  54. data/Rakefile +0 -8
  55. data/example_box/README.md +0 -29
  56. data/example_box/Vagrantfile +0 -60
  57. data/example_box/metadata.json +0 -5
  58. data/tools/create_box.sh +0 -130
  59. data/tools/prepare_redhat_for_box.sh +0 -119
  60. data/vagrant-libvirt.gemspec +0 -54
@@ -1,4 +1,5 @@
1
1
  require 'fog/libvirt'
2
+ require 'libvirt'
2
3
  require 'log4r'
3
4
 
4
5
  module VagrantPlugins
@@ -10,6 +11,7 @@ module VagrantPlugins
10
11
  # settings as a key to allow per machine connection attributes
11
12
  # to be used.
12
13
  @@connection = nil
14
+ @@system_connection = nil
13
15
 
14
16
  def initialize(machine)
15
17
  @logger = Log4r::Logger.new('vagrant_libvirt::driver')
@@ -17,11 +19,11 @@ module VagrantPlugins
17
19
  end
18
20
 
19
21
  def connection
20
- # If already connected to libvirt, just use it and don't connect
22
+ # If already connected to Libvirt, just use it and don't connect
21
23
  # again.
22
24
  return @@connection if @@connection
23
25
 
24
- # Get config options for libvirt provider.
26
+ # Get config options for Libvirt provider.
25
27
  config = @machine.provider_config
26
28
  uri = config.uri
27
29
 
@@ -47,6 +49,17 @@ module VagrantPlugins
47
49
  @@connection
48
50
  end
49
51
 
52
+ def system_connection
53
+ # If already connected to Libvirt, just use it and don't connect
54
+ # again.
55
+ return @@system_connection if @@system_connection
56
+
57
+ config = @machine.provider_config
58
+
59
+ @@system_connection = Libvirt::open_read_only(config.system_uri)
60
+ @@system_connection
61
+ end
62
+
50
63
  def get_domain(mid)
51
64
  begin
52
65
  domain = connection.servers.get(mid)
@@ -70,6 +83,9 @@ module VagrantPlugins
70
83
  def get_ipaddress(machine)
71
84
  # Find the machine
72
85
  domain = get_domain(machine.id)
86
+ if @machine.provider_config.qemu_use_session
87
+ return get_ipaddress_system domain.mac
88
+ end
73
89
 
74
90
  if domain.nil?
75
91
  # The machine can't be found
@@ -99,6 +115,19 @@ module VagrantPlugins
99
115
  ip_address
100
116
  end
101
117
 
118
+ def get_ipaddress_system(mac)
119
+ ip_address = nil
120
+
121
+ system_connection.list_all_networks.each do |net|
122
+ leases = net.dhcp_leases(mac, 0)
123
+ # Assume the lease expiring last is the current IP address
124
+ ip_address = leases.sort_by { |lse| lse["expirytime"] }.last["ipaddr"] if !leases.empty?
125
+ break if ip_address
126
+ end
127
+
128
+ return ip_address
129
+ end
130
+
102
131
  def state(machine)
103
132
  # may be other error states with initial retreival we can't handle
104
133
  begin
@@ -33,6 +33,10 @@ module VagrantPlugins
33
33
  error_key(:image_upload_error)
34
34
  end
35
35
 
36
+ class ImageDownloadError < VagrantLibvirtError
37
+ error_key(:image_download_error)
38
+ end
39
+
36
40
  # Box exceptions
37
41
  class NoBoxVolume < VagrantLibvirtError
38
42
  error_key(:no_box_volume)
@@ -50,7 +54,7 @@ module VagrantPlugins
50
54
  error_key(:wrong_box_format)
51
55
  end
52
56
 
53
- # Fog libvirt exceptions
57
+ # Fog Libvirt exceptions
54
58
  class FogError < VagrantLibvirtError
55
59
  error_key(:fog_error)
56
60
  end
@@ -4,7 +4,7 @@ rescue LoadError
4
4
  raise 'The Vagrant Libvirt plugin must be run within Vagrant.'
5
5
  end
6
6
 
7
- # compatibility fix to define constant not available vagrant <1.6
7
+ # compatibility fix to define constant not available Vagrant <1.6
8
8
  ::Vagrant::MachineState::NOT_CREATED_ID ||= :not_created
9
9
 
10
10
  module VagrantPlugins
@@ -12,7 +12,7 @@ module VagrantPlugins
12
12
  class Plugin < Vagrant.plugin('2')
13
13
  name 'libvirt'
14
14
  description <<-DESC
15
- Vagrant plugin to manage VMs in libvirt.
15
+ Vagrant plugin to manage VMs in Libvirt.
16
16
  DESC
17
17
 
18
18
  config('libvirt', :provider) do
@@ -39,6 +39,11 @@ module VagrantPlugins
39
39
  Cap::NicMacAddresses
40
40
  end
41
41
 
42
+ provider_capability(:libvirt, :public_address) do
43
+ require_relative 'cap/public_address'
44
+ Cap::PublicAddress
45
+ end
46
+
42
47
  # lower priority than nfs or rsync
43
48
  # https://github.com/vagrant-libvirt/vagrant-libvirt/pull/170
44
49
  synced_folder('9p', 4) do
@@ -3,11 +3,11 @@
3
3
  <source>
4
4
  </source>
5
5
  <target>
6
- <path>/var/lib/libvirt/images</path>
6
+ <path><%= @storage_pool_path %></path>
7
7
  <permissions>
8
8
  <mode>0755</mode>
9
- <owner>-1</owner>
10
- <group>-1</group>
9
+ <owner><%= @storage_pool_uid %></owner>
10
+ <group><%= @storage_pool_gid %></group>
11
11
  </permissions>
12
12
  </target>
13
13
  </pool>
@@ -1,16 +1,22 @@
1
1
  <domain type='<%= @domain_type %>' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
2
2
  <name><%= @name %></name>
3
+ <title><%= @title %></title>
4
+ <description><%= @description %></description>
3
5
  <uuid><%= @uuid %></uuid>
4
6
  <memory><%= @memory_size %></memory>
5
- <vcpu><%= @cpus %></vcpu>
7
+ <vcpu<% if @cpuset %> cpuset='<%= @cpuset %>'<% end %>><%= @cpus %></vcpu>
6
8
 
7
9
 
8
10
  <cpu mode='<%= @cpu_mode %>'>
9
11
  <% if @cpu_mode != 'host-passthrough' %>
10
12
  <model fallback='<%= @cpu_fallback %>'><% if @cpu_mode == 'custom' %><%= @cpu_model %><% end %></model>
11
13
  <% if @nested %>
12
- <feature policy='optional' name='vmx'/>
13
- <feature policy='optional' name='svm'/>
14
+ <% if @cpu_features.select{|x| x[:name] == 'vmx'}.empty? %>
15
+ <feature policy='optional' name='vmx'/>
16
+ <% end %>
17
+ <% if @cpu_features.select{|x| x[:name] == 'svm'}.empty? %>
18
+ <feature policy='optional' name='svm'/>
19
+ <% end %>
14
20
  <% end %>
15
21
  <% @cpu_features.each do |cpu_feature| %>
16
22
  <feature name='<%= cpu_feature[:name] %>' policy='<%= cpu_feature[:policy] %>'/>
@@ -29,6 +35,11 @@
29
35
  <% end %>
30
36
  </cpu>
31
37
 
38
+ <%- if @nodeset -%>
39
+ <numatune>
40
+ <memory nodeset='<%= @nodeset %>'/>
41
+ </numatune>
42
+ <%- end -%>
32
43
  <% unless @memory_backing.empty? %>
33
44
  <memoryBacking>
34
45
  <% @memory_backing.each do |backing| %>
@@ -36,6 +47,11 @@
36
47
  <% end %>
37
48
  </memoryBacking>
38
49
  <% end%>
50
+ <% if @shares %>
51
+ <cputune>
52
+ <shares><%= @shares %></shares>
53
+ </cputune>
54
+ <% end %>
39
55
 
40
56
  <os>
41
57
  <% if @machine_type %>
@@ -52,7 +68,14 @@
52
68
  <% end %>
53
69
  <% end %>
54
70
  <% if @loader %>
55
- <loader readonly='yes' type='rom'><%= @loader %></loader>
71
+ <% if @nvram %>
72
+ <loader readonly='yes' type='pflash'><%= @loader %></loader>
73
+ <% else %>
74
+ <loader readonly='yes' type='rom'><%= @loader %></loader>
75
+ <% end %>
76
+ <% end %>
77
+ <% if @nvram %>
78
+ <nvram><%= @nvram %></nvram>
56
79
  <% end %>
57
80
  <% if @boot_order.count >= 1 %>
58
81
  <bootmenu enable='yes'/>
@@ -73,6 +96,13 @@
73
96
  <hidden state='on'/>
74
97
  </kvm>
75
98
  <% end %>
99
+ <% if !@features_hyperv.empty? %>
100
+ <hyperv>
101
+ <% @features_hyperv.each do |feature| %>
102
+ <<%= feature[:name] %> state='<%= feature[:state] %>' />
103
+ <% end %>
104
+ </hyperv>
105
+ <% end %>
76
106
  </features>
77
107
  <clock offset='utc'/>
78
108
  <devices>
@@ -99,7 +129,10 @@
99
129
  <% if d[:serial] %>
100
130
  <serial><%= d[:serial] %></serial>
101
131
  <% end %>
102
- <%# this will get auto generated by libvirt
132
+ <% if d[:wwn] %>
133
+ <wwn><%= d[:wwn] %></wwn>
134
+ <% end %>
135
+ <%# this will get auto generated by Libvirt
103
136
  <address type='pci' domain='0x0000' bus='0x00' slot='???' function='0x0'/>
104
137
  -%>
105
138
  </disk>
@@ -172,7 +205,7 @@
172
205
  <% @pcis.each do |pci| %>
173
206
  <hostdev mode='subsystem' type='pci' managed='yes'>
174
207
  <source>
175
- <address domain='0x0000'
208
+ <address domain='<%= pci[:domain] %>'
176
209
  bus='<%= pci[:bus] %>'
177
210
  slot='<%= pci[:slot] %>'
178
211
  function='<%= pci[:function] %>'/>
@@ -232,13 +265,20 @@
232
265
  </backend>
233
266
  </tpm>
234
267
  <% end -%>
268
+ <% if not @usbctl_dev.empty? %>
269
+ <%# USB Controller -%>
270
+ <controller type='usb' model='<%= @usbctl_dev[:model] %>' <%= "ports=\"#{@usbctl_dev[:ports]}\" " if @usbctl_dev[:ports] %>/>
271
+ <% end %>
235
272
  </devices>
236
273
 
237
- <% unless @qargs.empty? %>
274
+ <% if not @qemu_args.empty? or not @qemu_env.empty? %>
238
275
  <qemu:commandline>
239
- <% @qargs.each do |arg| %>
276
+ <% @qemu_args.each do |arg| %>
240
277
  <qemu:arg value='<%= arg[:value] %>'/>
241
278
  <% end %>
279
+ <% @qemu_env.each do |env_var, env_value| %>
280
+ <qemu:env name='<%= env_var.to_s %>' value='<%= env_value %>'/>
281
+ <% end %>
242
282
  </qemu:commandline>
243
283
  <% end %>
244
284
  </domain>
@@ -5,6 +5,7 @@ module VagrantPlugins
5
5
  autoload :Collection, 'vagrant-libvirt/util/collection'
6
6
  autoload :Timer, 'vagrant-libvirt/util/timer'
7
7
  autoload :NetworkUtil, 'vagrant-libvirt/util/network_util'
8
+ autoload :StorageUtil, 'vagrant-libvirt/util/storage_util'
8
9
  autoload :ErrorCodes, 'vagrant-libvirt/util/error_codes'
9
10
  end
10
11
  end
@@ -1,20 +1,19 @@
1
- require 'erubis'
2
-
3
1
  module VagrantPlugins
4
2
  module ProviderLibvirt
5
3
  module Util
6
4
  module ErbTemplate
7
5
  # TODO: remove and use nokogiri builder
8
- # TODO: might be a chance to use vagrant template system according to https://github.com/mitchellh/vagrant/issues/3231
9
6
  def to_xml(template_name = nil, data = binding)
10
7
  erb = template_name || self.class.to_s.split('::').last.downcase
11
- path = File.join(File.dirname(__FILE__), '..', 'templates',
12
- "#{erb}.xml.erb")
13
- template = File.read(path)
8
+ path = File.join(File.dirname(__FILE__), '..', 'templates')
9
+ template = "#{erb}.xml"
14
10
 
15
11
  # TODO: according to erubis documentation, we should rather use evaluate and forget about
16
12
  # binding since the template may then change variables values
17
- Erubis::Eruby.new(template, trim: true).result(data)
13
+ Vagrant::Util::TemplateRenderer.render_with(:render, template, template_root: path) do |renderer|
14
+ iv = data.eval ("instance_variables.collect {|i| [i, instance_variable_get(i.to_sym)]}")
15
+ iv.each {|k, v| renderer.instance_variable_set(k, v)}
16
+ end
18
17
  end
19
18
  end
20
19
  end
@@ -8,6 +8,8 @@ module VagrantPlugins
8
8
  include Vagrant::Util::NetworkIP
9
9
 
10
10
  def configured_networks(env, logger)
11
+ qemu_use_session = env[:machine].provider_config.qemu_use_session
12
+ management_network_device = env[:machine].provider_config.management_network_device
11
13
  management_network_name = env[:machine].provider_config.management_network_name
12
14
  management_network_address = env[:machine].provider_config.management_network_address
13
15
  management_network_mode = env[:machine].provider_config.management_network_mode
@@ -16,6 +18,7 @@ module VagrantPlugins
16
18
  management_network_autostart = env[:machine].provider_config.management_network_autostart
17
19
  management_network_pci_bus = env[:machine].provider_config.management_network_pci_bus
18
20
  management_network_pci_slot = env[:machine].provider_config.management_network_pci_slot
21
+ management_network_domain = env[:machine].provider_config.management_network_domain
19
22
  logger.info "Using #{management_network_name} at #{management_network_address} as the management network #{management_network_mode} is the mode"
20
23
 
21
24
  begin
@@ -33,23 +36,40 @@ module VagrantPlugins
33
36
  error_message: "#{management_network_address} does not include both an address and subnet mask"
34
37
  end
35
38
 
36
- management_network_options = {
37
- iface_type: :private_network,
38
- network_name: management_network_name,
39
- ip: Regexp.last_match(1),
40
- netmask: Regexp.last_match(2),
41
- dhcp_enabled: true,
42
- forward_mode: management_network_mode,
43
- guest_ipv6: management_network_guest_ipv6,
44
- autostart: management_network_autostart,
45
- bus: management_network_pci_bus,
46
- slot: management_network_pci_slot
47
- }
39
+ if qemu_use_session
40
+ management_network_options = {
41
+ iface_type: :public_network,
42
+ dev: management_network_device,
43
+ mode: 'bridge',
44
+ type: 'bridge',
45
+ bus: management_network_pci_bus,
46
+ slot: management_network_pci_slot
47
+ }
48
+ else
49
+ management_network_options = {
50
+ iface_type: :private_network,
51
+ network_name: management_network_name,
52
+ ip: Regexp.last_match(1),
53
+ netmask: Regexp.last_match(2),
54
+ dhcp_enabled: true,
55
+ forward_mode: management_network_mode,
56
+ guest_ipv6: management_network_guest_ipv6,
57
+ autostart: management_network_autostart,
58
+ bus: management_network_pci_bus,
59
+ slot: management_network_pci_slot
60
+ }
61
+ end
62
+
63
+
48
64
 
49
65
  unless management_network_mac.nil?
50
66
  management_network_options[:mac] = management_network_mac
51
67
  end
52
68
 
69
+ unless management_network_domain.nil?
70
+ management_network_options[:domain_name] = management_network_domain
71
+ end
72
+
53
73
  unless management_network_pci_bus.nil? and management_network_pci_slot.nil?
54
74
  management_network_options[:bus] = management_network_pci_bus
55
75
  management_network_options[:slot] = management_network_pci_slot
@@ -94,7 +114,7 @@ module VagrantPlugins
94
114
  networks
95
115
  end
96
116
 
97
- # Return a list of all (active and inactive) libvirt networks as a list
117
+ # Return a list of all (active and inactive) Libvirt networks as a list
98
118
  # of hashes with their name, network address and status (active or not)
99
119
  def libvirt_networks(libvirt_client)
100
120
  libvirt_networks = []
@@ -0,0 +1,17 @@
1
+ module VagrantPlugins
2
+ module ProviderLibvirt
3
+ module Util
4
+ module Nfs
5
+ include Vagrant::Action::Builtin::MixinSyncedFolders
6
+
7
+ # We're using NFS if we have any synced folder with NFS configured. If
8
+ # we are not using NFS we don't need to do the extra work to
9
+ # populate these fields in the environment.
10
+ def using_nfs?
11
+ !!synced_folders(@machine)[:nfs]
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+
@@ -0,0 +1,27 @@
1
+
2
+ module VagrantPlugins
3
+ module ProviderLibvirt
4
+ module Util
5
+ module StorageUtil
6
+ def storage_uid(env)
7
+ env[:machine].provider_config.qemu_use_session ? Process.uid : 0
8
+ end
9
+
10
+ def storage_gid(env)
11
+ env[:machine].provider_config.qemu_use_session ? Process.gid : 0
12
+ end
13
+
14
+ def storage_pool_path(env)
15
+ if env[:machine].provider_config.storage_pool_path
16
+ env[:machine].provider_config.storage_pool_path
17
+ elsif env[:machine].provider_config.qemu_use_session
18
+ File.expand_path('~/.local/share/libvirt/images')
19
+ else
20
+ '/var/lib/libvirt/images'
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+
@@ -1,5 +1,5 @@
1
1
  module VagrantPlugins
2
2
  module ProviderLibvirt
3
- VERSION = '0.0.42'.freeze
3
+ VERSION = '0.2.1'.freeze
4
4
  end
5
5
  end
@@ -16,7 +16,7 @@ en:
16
16
  Created volume larger than box defaults, will require manual resizing of
17
17
  filesystems to utilize.
18
18
  uploading_volume: |-
19
- Uploading base box image as volume into libvirt storage...
19
+ Uploading base box image as volume into Libvirt storage...
20
20
  creating_domain_volume: |-
21
21
  Creating image (snapshot of base box volume).
22
22
  removing_domain_volume: |-
@@ -35,6 +35,8 @@ en:
35
35
  Resuming domain...
36
36
  suspending_domain: |-
37
37
  Suspending domain...
38
+ package_domain: |-
39
+ Packaging domain...
38
40
  waiting_for_ready: |-
39
41
  Waiting for domain to become "ready"...
40
42
  waiting_for_ip: |-
@@ -58,7 +60,7 @@ en:
58
60
  Forwarding UDP ports is not supported. Ignoring.
59
61
 
60
62
  errors:
61
- package_not_supported: No support for package with libvirt. Create box manually.
63
+ package_not_supported: No support for package with Libvirt. Create box manually.
62
64
  fog_error: |-
63
65
  There was an error talking to Libvirt. The error message is shown
64
66
  below:
@@ -95,7 +97,7 @@ en:
95
97
  wrong_box_format: |-
96
98
  Wrong image format specified for box.
97
99
  fog_libvirt_connection_error: |-
98
- Error while connecting to libvirt: %{error_message}
100
+ Error while connecting to Libvirt: %{error_message}
99
101
  fog_create_volume_error: |-
100
102
  Error while creating a storage pool volume: %{error_message}
101
103
  fog_create_domain_volume_error: |-
@@ -106,9 +108,11 @@ en:
106
108
  Name `%{domain_name}` of domain about to create is already taken. Please try to run
107
109
  `vagrant up` command again.
108
110
  creating_storage_pool_error: |-
109
- There was error while creating libvirt storage pool: %{error_message}
111
+ There was error while creating Libvirt storage pool: %{error_message}
110
112
  image_upload_error: |-
111
113
  Error while uploading image to storage pool: %{error_message}
114
+ image_download_error: |-
115
+ Error while downloading volume '%{volume_name}' from storage pool '%{pool_name}': %{error_message}
112
116
  no_domain_error: |-
113
117
  No domain found. %{error_message}
114
118
  attach_device_error: |-