vagrant-libvirt 0.0.42 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
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: |-