vagrant-libvirt 0.0.45 → 0.1.0

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 (48) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +253 -109
  3. data/lib/vagrant-libvirt/action.rb +2 -2
  4. data/lib/vagrant-libvirt/action/create_domain.rb +59 -29
  5. data/lib/vagrant-libvirt/action/create_domain_volume.rb +14 -8
  6. data/lib/vagrant-libvirt/action/create_network_interfaces.rb +7 -5
  7. data/lib/vagrant-libvirt/action/create_networks.rb +2 -2
  8. data/lib/vagrant-libvirt/action/destroy_domain.rb +1 -1
  9. data/lib/vagrant-libvirt/action/forward_ports.rb +6 -5
  10. data/lib/vagrant-libvirt/action/halt_domain.rb +1 -1
  11. data/lib/vagrant-libvirt/action/handle_box_image.rb +22 -57
  12. data/lib/vagrant-libvirt/action/handle_storage_pool.rb +4 -4
  13. data/lib/vagrant-libvirt/action/package_domain.rb +58 -12
  14. data/lib/vagrant-libvirt/action/prepare_nfs_settings.rb +3 -9
  15. data/lib/vagrant-libvirt/action/prune_nfs_exports.rb +18 -9
  16. data/lib/vagrant-libvirt/action/remove_libvirt_image.rb +2 -2
  17. data/lib/vagrant-libvirt/action/remove_stale_volume.rb +17 -11
  18. data/lib/vagrant-libvirt/action/set_boot_order.rb +2 -2
  19. data/lib/vagrant-libvirt/action/set_name_of_domain.rb +6 -9
  20. data/lib/vagrant-libvirt/action/start_domain.rb +2 -2
  21. data/lib/vagrant-libvirt/action/wait_till_up.rb +7 -9
  22. data/lib/vagrant-libvirt/cap/synced_folder.rb +3 -3
  23. data/lib/vagrant-libvirt/config.rb +62 -11
  24. data/lib/vagrant-libvirt/driver.rb +3 -3
  25. data/lib/vagrant-libvirt/errors.rb +5 -5
  26. data/lib/vagrant-libvirt/plugin.rb +2 -2
  27. data/lib/vagrant-libvirt/templates/domain.xml.erb +18 -5
  28. data/lib/vagrant-libvirt/util/network_util.rb +6 -1
  29. data/lib/vagrant-libvirt/util/nfs.rb +17 -0
  30. data/lib/vagrant-libvirt/version.rb +1 -1
  31. data/locales/en.yml +6 -6
  32. data/spec/unit/action/set_name_of_domain_spec.rb +1 -1
  33. data/spec/unit/templates/domain_all_settings.xml +12 -2
  34. data/spec/unit/templates/domain_spec.rb +10 -2
  35. metadata +21 -34
  36. data/.coveralls.yml +0 -1
  37. data/.github/issue_template.md +0 -37
  38. data/.gitignore +0 -21
  39. data/.travis.yml +0 -24
  40. data/Gemfile +0 -26
  41. data/Rakefile +0 -8
  42. data/example_box/README.md +0 -29
  43. data/example_box/Vagrantfile +0 -60
  44. data/example_box/metadata.json +0 -5
  45. data/lib/vagrant-libvirt/templates/default_storage_volume.xml.erb +0 -14
  46. data/tools/create_box.sh +0 -130
  47. data/tools/prepare_redhat_for_box.sh +0 -119
  48. data/vagrant-libvirt.gemspec +0 -51
@@ -1,9 +1,10 @@
1
+ require 'fileutils'
1
2
  require 'log4r'
2
3
 
3
4
  module VagrantPlugins
4
5
  module ProviderLibvirt
5
6
  module Action
6
- # Action for create new box for libvirt provider
7
+ # Action for create new box for Libvirt provider
7
8
  class PackageDomain
8
9
  def initialize(app, env)
9
10
  @logger = Log4r::Logger.new('vagrant_libvirt::action::package_domain')
@@ -21,24 +22,31 @@ module VagrantPlugins
21
22
  root_disk = domain.volumes.select do |x|
22
23
  x.name == libvirt_domain.name + '.img'
23
24
  end.first
25
+ raise Errors::NoDomainVolume if root_disk.nil?
24
26
  boxname = env['package.output']
25
27
  raise "#{boxname}: Already exists" if File.exist?(boxname)
26
28
  @tmp_dir = Dir.pwd + '/_tmp_package'
27
29
  @tmp_img = @tmp_dir + '/box.img'
28
- Dir.mkdir(@tmp_dir)
29
- if File.readable?(root_disk.path)
30
- backing = `qemu-img info "#{root_disk.path}" | grep 'backing file:' | cut -d ':' -f2`.chomp
31
- else
32
- env[:ui].error("Require set read access to #{root_disk.path}. sudo chmod a+r #{root_disk.path}")
33
- FileUtils.rm_rf(@tmp_dir)
34
- raise 'Have no access'
30
+ FileUtils.mkdir_p(@tmp_dir)
31
+ env[:ui].info("Downloading #{root_disk.name} to #{@tmp_img}")
32
+ ret = download_image(@tmp_img, env[:machine].provider_config.storage_pool_name,
33
+ root_disk.name, env) do |progress,image_size|
34
+ env[:ui].clear_line
35
+ env[:ui].report_progress(progress, image_size, false)
36
+ end
37
+ # Clear the line one last time since the progress meter doesn't
38
+ # disappear immediately.
39
+ env[:ui].clear_line
40
+ backing = `qemu-img info "#{@tmp_img}" | grep 'backing file:' | cut -d ':' -f2`.chomp
41
+ if backing
42
+ env[:ui].info('Image has backing image, copying image and rebasing ...')
43
+ `qemu-img rebase -p -b "" #{@tmp_img}`
35
44
  end
36
- env[:ui].info('Image has backing image, copying image and rebasing ...')
37
- FileUtils.cp(root_disk.path, @tmp_img)
38
- `qemu-img rebase -p -b "" #{@tmp_img}`
39
45
  # remove hw association with interface
40
46
  # working for centos with lvs default disks
41
- `virt-sysprep --no-logfile --operations defaults,-ssh-userdir -a #{@tmp_img}`
47
+ options = ENV.fetch('VAGRANT_LIBVIRT_VIRT_SYSPREP_OPTIONS', '')
48
+ operations = ENV.fetch('VAGRANT_LIBVIRT_VIRT_SYSPREP_OPERATIONS', 'defaults,-ssh-userdir')
49
+ `virt-sysprep --no-logfile --operations #{operations} -a #{@tmp_img} #{options}`
42
50
  # add any user provided file
43
51
  extra = ''
44
52
  @tmp_include = @tmp_dir + '/_include'
@@ -99,6 +107,44 @@ module VagrantPlugins
99
107
  }
100
108
  EOF
101
109
  end
110
+
111
+ protected
112
+
113
+ # Fog libvirt currently doesn't support downloading images from storage
114
+ # pool volumes. Use ruby-libvirt client instead.
115
+ def download_image(image_file, pool_name, volume_name, env)
116
+ begin
117
+ pool = env[:machine].provider.driver.connection.client.lookup_storage_pool_by_name(
118
+ pool_name
119
+ )
120
+ volume = pool.lookup_volume_by_name(volume_name)
121
+ image_size = volume.info.allocation # B
122
+
123
+ stream = env[:machine].provider.driver.connection.client.stream
124
+
125
+ # Use length of 0 to download remaining contents after offset
126
+ volume.download(stream, offset = 0, length = 0)
127
+
128
+ buf_size = 1024 * 250 # 250K, copied from upload_image in handle_box_image.rb
129
+ progress = 0
130
+ retval = stream.recv(buf_size)
131
+ open(image_file, 'wb') do |io|
132
+ while (retval.at(0) > 0)
133
+ recvd = io.write(retval.at(1))
134
+ progress += recvd
135
+ yield [progress, image_size]
136
+ retval = stream.recv(buf_size)
137
+ end
138
+ end
139
+ rescue => e
140
+ raise Errors::ImageDownloadError,
141
+ volume_name: volume_name,
142
+ pool_name: pool_name,
143
+ error_message: e.message
144
+ end
145
+
146
+ progress == image_size
147
+ end
102
148
  end
103
149
  end
104
150
  end
@@ -1,12 +1,13 @@
1
1
  require 'nokogiri'
2
2
  require 'socket'
3
3
  require 'timeout'
4
+ require 'vagrant-libvirt/util/nfs'
4
5
 
5
6
  module VagrantPlugins
6
7
  module ProviderLibvirt
7
8
  module Action
8
9
  class PrepareNFSSettings
9
- include Vagrant::Action::Builtin::MixinSyncedFolders
10
+ include VagrantPlugins::ProviderLibvirt::Util::Nfs
10
11
 
11
12
  def initialize(app, _env)
12
13
  @app = app
@@ -28,13 +29,6 @@ module VagrantPlugins
28
29
  end
29
30
  end
30
31
 
31
- # We're using NFS if we have any synced folder with NFS configured. If
32
- # we are not using NFS we don't need to do the extra work to
33
- # populate these fields in the environment.
34
- def using_nfs?
35
- !!synced_folders(@machine)[:nfs]
36
- end
37
-
38
32
  # Returns the IP address of the host
39
33
  #
40
34
  # @param [Machine] machine
@@ -79,7 +73,7 @@ module VagrantPlugins
79
73
  # Check if we can open a connection to the host
80
74
  def ping(host, timeout = 3)
81
75
  ::Timeout.timeout(timeout) do
82
- s = TCPSocket.new(host, 'echo')
76
+ s = TCPSocket.new(host, 'ssh')
83
77
  s.close
84
78
  end
85
79
  true
@@ -1,22 +1,31 @@
1
+ require 'vagrant-libvirt/util/nfs'
1
2
  require 'yaml'
3
+
2
4
  module VagrantPlugins
3
5
  module ProviderLibvirt
4
6
  module Action
5
7
  class PruneNFSExports
8
+ include VagrantPlugins::ProviderLibvirt::Util::Nfs
9
+
6
10
  def initialize(app, _env)
7
11
  @app = app
8
12
  end
9
13
 
10
14
  def call(env)
11
- if env[:host]
12
- uuid = env[:machine].id
13
- # get all uuids
14
- uuids = env[:machine].provider.driver.connection.servers.all.map(&:id)
15
- # not exiisted in array will removed from nfs
16
- uuids.delete(uuid)
17
- env[:host].capability(
18
- :nfs_prune, env[:machine].ui, uuids
19
- )
15
+ @machine = env[:machine]
16
+
17
+ if using_nfs?
18
+ @logger.info('Using NFS, prunning NFS settings from host')
19
+ if env[:host]
20
+ uuid = env[:machine].id
21
+ # get all uuids
22
+ uuids = env[:machine].provider.driver.connection.servers.all.map(&:id)
23
+ # not exiisted in array will removed from nfs
24
+ uuids.delete(uuid)
25
+ env[:host].capability(
26
+ :nfs_prune, env[:machine].ui, uuids
27
+ )
28
+ end
20
29
  end
21
30
 
22
31
  @app.call(env)
@@ -10,8 +10,8 @@ module VagrantPlugins
10
10
  end
11
11
 
12
12
  def call(env)
13
- env[:ui].info('Vagrant-libvirt plugin removed box only from you LOCAL ~/.vagrant/boxes directory')
14
- env[:ui].info('From libvirt storage pool you have to delete image manually(virsh, virt-manager or by any other tool)')
13
+ env[:ui].info('Vagrant-libvirt plugin removed box only from your LOCAL ~/.vagrant/boxes directory')
14
+ env[:ui].info('From Libvirt storage pool you have to delete image manually(virsh, virt-manager or by any other tool)')
15
15
  @app.call(env)
16
16
  end
17
17
  end
@@ -16,13 +16,19 @@ module VagrantPlugins
16
16
 
17
17
  def call(env)
18
18
  # Remove stale server volume
19
- env[:ui].info(I18n.t('vagrant_libvirt.remove_stale_volume'))
20
-
21
19
  config = env[:machine].provider_config
22
20
  # Check for storage pool, where box image should be created
23
- fog_pool = ProviderLibvirt::Util::Collection.find_matching(
24
- env[:machine].provider.driver.connection.pools.all, config.storage_pool_name
25
- )
21
+ fog_pool = env[:machine].provider.driver.connection.pools.all(
22
+ name: config.storage_pool_name
23
+ ).first
24
+
25
+ env[:result] = nil
26
+
27
+ if not fog_pool
28
+ @logger.debug("**** Pool #{config.storage_pool_name} not found")
29
+ return @app.call(env)
30
+ end
31
+
26
32
  @logger.debug("**** Pool #{fog_pool.name}")
27
33
 
28
34
  # This is name of newly created image for vm.
@@ -30,17 +36,17 @@ module VagrantPlugins
30
36
  @logger.debug("**** Volume name #{name}")
31
37
 
32
38
  # remove root storage
33
- box_volume = ProviderLibvirt::Util::Collection.find_matching(
34
- env[:machine].provider.driver.connection.volumes.all, name
35
- )
36
- if box_volume && box_volume.pool_name == fog_pool.name
39
+ box_volume = env[:machine].provider.driver.connection.volumes.all(
40
+ name: name
41
+ ).find { |x| x.pool_name == fog_pool.name }
42
+ if box_volume && box_volume.id
43
+ env[:ui].info(I18n.t('vagrant_libvirt.remove_stale_volume'))
37
44
  @logger.info("Deleting volume #{box_volume.key}")
38
45
  box_volume.destroy
39
46
  env[:result] = box_volume
40
47
  else
41
- env[:result] = nil
48
+ @logger.debug("**** Volume #{name} not found in pool #{fog_pool.name}")
42
49
  end
43
-
44
50
  # Continue the middleware chain.
45
51
  @app.call(env)
46
52
  end
@@ -33,7 +33,7 @@ module VagrantPlugins
33
33
  if @boot_order.count >= 1
34
34
 
35
35
  # If a domain is initially defined with no box or disk or
36
- # with an explicit boot order, libvirt adds <boot dev="foo">
36
+ # with an explicit boot order, Libvirt adds <boot dev="foo">
37
37
  # This conflicts with an explicit boot_order configuration,
38
38
  # so we need to remove it from the domain xml and feed it back.
39
39
  # Also see https://bugzilla.redhat.com/show_bug.cgi?id=1248514
@@ -66,7 +66,7 @@ module VagrantPlugins
66
66
  logger_msg(node, index)
67
67
  end
68
68
 
69
- # Finally redefine the domain XML through libvirt
69
+ # Finally redefine the domain XML through Libvirt
70
70
  # to apply the boot ordering
71
71
  env[:machine].provider
72
72
  .driver
@@ -13,20 +13,17 @@ module VagrantPlugins
13
13
  env[:domain_name] = build_domain_name(env)
14
14
 
15
15
  begin
16
- @logger.info("Looking for domain #{env[:domain_name]} through list " \
17
- "#{env[:machine].provider.driver.connection.servers.all}")
16
+ @logger.info("Looking for domain #{env[:domain_name]}")
18
17
  # Check if the domain name is not already taken
19
18
 
20
- domain = ProviderLibvirt::Util::Collection.find_matching(
21
- env[:machine].provider.driver.connection.servers.all, env[:domain_name]
19
+ domain = env[:machine].provider.driver.connection.servers.all(
20
+ name: env[:domain_name]
22
21
  )
23
- rescue Fog::Errors::Error => e
22
+ rescue Libvirt::RetrieveError => e
24
23
  @logger.info(e.to_s)
25
24
  domain = nil
26
25
  end
27
26
 
28
- @logger.info("Looking for domain #{env[:domain_name]}")
29
-
30
27
  unless domain.nil?
31
28
  raise ProviderLibvirt::Errors::DomainNameExists,
32
29
  domain_name: env[:domain_name]
@@ -41,7 +38,7 @@ module VagrantPlugins
41
38
  # parsable and sortable by epoch time
42
39
  # @example
43
40
  # development-centos-6-chef-11_1404488971_3b7a569e2fd7c554b852
44
- # @return [String] libvirt domain name
41
+ # @return [String] Libvirt domain name
45
42
  def build_domain_name(env)
46
43
  config = env[:machine].provider_config
47
44
  domain_name =
@@ -51,7 +48,7 @@ module VagrantPlugins
51
48
  # don't have any prefix, not even "_"
52
49
  ''
53
50
  else
54
- config.default_prefix.to_s.dup.concat('_')
51
+ config.default_prefix.to_s.dup
55
52
  end
56
53
  domain_name << env[:machine].name.to_s
57
54
  domain_name.gsub!(/[^-a-z0-9_\.]/i, '')
@@ -23,7 +23,7 @@ module VagrantPlugins
23
23
 
24
24
  libvirt_domain = env[:machine].provider.driver.connection.client.lookup_domain_by_uuid(env[:machine].id)
25
25
 
26
- # libvirt API doesn't support modifying memory on NUMA enabled CPUs
26
+ # Libvirt API doesn't support modifying memory on NUMA enabled CPUs
27
27
  # http://libvirt.org/git/?p=libvirt.git;a=commit;h=d174394105cf00ed266bf729ddf461c21637c736
28
28
  if config.numa_nodes == nil
29
29
  if config.memory.to_i * 1024 != libvirt_domain.max_memory
@@ -68,7 +68,7 @@ module VagrantPlugins
68
68
  end
69
69
 
70
70
  # vCpu count
71
- if config.cpus.to_i != libvirt_domain.vcpus.length
71
+ if config.cpus.to_i != libvirt_domain.num_vcpus(0)
72
72
  descr_changed = true
73
73
  REXML::XPath.first(xml_descr, '/domain/vcpu').text = config.cpus
74
74
  end
@@ -28,7 +28,7 @@ module VagrantPlugins
28
28
  end
29
29
 
30
30
  # Wait for domain to obtain an ip address. Ip address is searched
31
- # from arp table, either localy or remotely via ssh, if libvirt
31
+ # from arp table, either locally or remotely via ssh, if Libvirt
32
32
  # connection was done via ssh.
33
33
  env[:ip_address] = nil
34
34
  @logger.debug("Searching for IP for MAC address: #{domain.mac}")
@@ -37,8 +37,8 @@ module VagrantPlugins
37
37
  if env[:machine].provider_config.qemu_use_session
38
38
  env[:metrics]['instance_ip_time'] = Util::Timer.time do
39
39
  retryable(on: Fog::Errors::TimeoutError, tries: 300) do
40
- # If we're interrupted don't worry about waiting
41
- return terminate(env) if env[:interrupted]
40
+ # just return if interrupted and let the warden call recover
41
+ return if env[:interrupted]
42
42
 
43
43
  # Wait for domain to obtain an ip address
44
44
  domain.wait_for(2) do
@@ -50,8 +50,8 @@ module VagrantPlugins
50
50
  else
51
51
  env[:metrics]['instance_ip_time'] = Util::Timer.time do
52
52
  retryable(on: Fog::Errors::TimeoutError, tries: 300) do
53
- # If we're interrupted don't worry about waiting
54
- return terminate(env) if env[:interrupted]
53
+ # just return if interrupted and let the warden call recover
54
+ return if env[:interrupted]
55
55
 
56
56
  # Wait for domain to obtain an ip address
57
57
  domain.wait_for(2) do
@@ -84,8 +84,8 @@ module VagrantPlugins
84
84
  end
85
85
  end
86
86
  end
87
- # if interrupted above, just terminate immediately
88
- return terminate(env) if env[:interrupted]
87
+ # just return if interrupted and let the warden call recover
88
+ return if env[:interrupted]
89
89
  @logger.info("Time for SSH ready: #{env[:metrics]['instance_ssh_time']}")
90
90
 
91
91
  # Booted and ready for use.
@@ -95,8 +95,6 @@ module VagrantPlugins
95
95
  end
96
96
 
97
97
  def recover(env)
98
- return if env['vagrant.error'].is_a?(Vagrant::Errors::VagrantError)
99
-
100
98
  # Undo the import
101
99
  terminate(env)
102
100
  end
@@ -20,7 +20,7 @@ module VagrantPlugins
20
20
  end
21
21
 
22
22
  def usable?(machine, _raise_error = false)
23
- # bail now if not using libvirt since checking version would throw error
23
+ # bail now if not using Libvirt since checking version would throw error
24
24
  return false unless machine.provider_name == :libvirt
25
25
 
26
26
  # <filesystem/> support in device attach/detach introduced in 1.2.2
@@ -30,7 +30,7 @@ module VagrantPlugins
30
30
  end
31
31
 
32
32
  def prepare(machine, folders, _opts)
33
- raise Vagrant::Errors::Error('No libvirt connection') if machine.provider.driver.connection.nil?
33
+ raise Vagrant::Errors::Error('No Libvirt connection') if machine.provider.driver.connection.nil?
34
34
  @conn = machine.provider.driver.connection.client
35
35
 
36
36
  begin
@@ -89,7 +89,7 @@ module VagrantPlugins
89
89
 
90
90
  def cleanup(machine, _opts)
91
91
  if machine.provider.driver.connection.nil?
92
- raise Vagrant::Errors::Error('No libvirt connection')
92
+ raise Vagrant::Errors::Error('No Libvirt connection')
93
93
  end
94
94
  @conn = machine.provider.driver.connection.client
95
95
  begin
@@ -20,12 +20,12 @@ module VagrantPlugins
20
20
  # A hypervisor name to access via Libvirt.
21
21
  attr_accessor :driver
22
22
 
23
- # The name of the server, where libvirtd is running.
23
+ # The name of the server, where Libvirtd is running.
24
24
  attr_accessor :host
25
25
 
26
26
  # If use ssh tunnel to connect to Libvirt.
27
27
  attr_accessor :connect_via_ssh
28
- # Path towards the libvirt socket
28
+ # Path towards the Libvirt socket
29
29
  attr_accessor :socket
30
30
 
31
31
  # The username to access Libvirt.
@@ -42,6 +42,9 @@ module VagrantPlugins
42
42
  attr_accessor :storage_pool_name
43
43
  attr_accessor :storage_pool_path
44
44
 
45
+ # Libvirt storage pool where the base image snapshot shall be stored
46
+ attr_accessor :snapshot_pool_name
47
+
45
48
  # Turn on to prevent hostname conflicts
46
49
  attr_accessor :random_hostname
47
50
 
@@ -55,6 +58,7 @@ module VagrantPlugins
55
58
  attr_accessor :management_network_autostart
56
59
  attr_accessor :management_network_pci_bus
57
60
  attr_accessor :management_network_pci_slot
61
+ attr_accessor :management_network_domain
58
62
 
59
63
  # System connection information
60
64
  attr_accessor :system_uri
@@ -65,14 +69,17 @@ module VagrantPlugins
65
69
  # Domain specific settings used while creating new domain.
66
70
  attr_accessor :uuid
67
71
  attr_accessor :memory
72
+ attr_accessor :nodeset
68
73
  attr_accessor :memory_backing
69
74
  attr_accessor :channel
70
75
  attr_accessor :cpus
76
+ attr_accessor :cpuset
71
77
  attr_accessor :cpu_mode
72
78
  attr_accessor :cpu_model
73
79
  attr_accessor :cpu_fallback
74
80
  attr_accessor :cpu_features
75
81
  attr_accessor :cpu_topology
82
+ attr_accessor :shares
76
83
  attr_accessor :features
77
84
  attr_accessor :features_hyperv
78
85
  attr_accessor :numa_nodes
@@ -158,7 +165,10 @@ module VagrantPlugins
158
165
  # Additional qemuargs arguments
159
166
  attr_accessor :qemu_args
160
167
 
161
- # Use qemu session instead of system
168
+ # Additional qemuenv arguments
169
+ attr_accessor :qemu_env
170
+
171
+ # Use QEMU session instead of system
162
172
  attr_accessor :qemu_use_session
163
173
 
164
174
  def initialize
@@ -170,6 +180,7 @@ module VagrantPlugins
170
180
  @password = UNSET_VALUE
171
181
  @id_ssh_key_file = UNSET_VALUE
172
182
  @storage_pool_name = UNSET_VALUE
183
+ @snapshot_pool_name = UNSET_VALUE
173
184
  @random_hostname = UNSET_VALUE
174
185
  @management_network_device = UNSET_VALUE
175
186
  @management_network_name = UNSET_VALUE
@@ -180,6 +191,7 @@ module VagrantPlugins
180
191
  @management_network_autostart = UNSET_VALUE
181
192
  @management_network_pci_slot = UNSET_VALUE
182
193
  @management_network_pci_bus = UNSET_VALUE
194
+ @management_network_domain = UNSET_VALUE
183
195
 
184
196
  # System connection information
185
197
  @system_uri = UNSET_VALUE
@@ -187,13 +199,16 @@ module VagrantPlugins
187
199
  # Domain specific settings.
188
200
  @uuid = UNSET_VALUE
189
201
  @memory = UNSET_VALUE
202
+ @nodeset = UNSET_VALUE
190
203
  @memory_backing = UNSET_VALUE
191
204
  @cpus = UNSET_VALUE
205
+ @cpuset = UNSET_VALUE
192
206
  @cpu_mode = UNSET_VALUE
193
207
  @cpu_model = UNSET_VALUE
194
208
  @cpu_fallback = UNSET_VALUE
195
209
  @cpu_features = UNSET_VALUE
196
210
  @cpu_topology = UNSET_VALUE
211
+ @shares = UNSET_VALUE
197
212
  @features = UNSET_VALUE
198
213
  @features_hyperv = UNSET_VALUE
199
214
  @numa_nodes = UNSET_VALUE
@@ -272,7 +287,12 @@ module VagrantPlugins
272
287
  # Attach mgmt network
273
288
  @mgmt_attach = UNSET_VALUE
274
289
 
275
- @qemu_args = []
290
+ # Additional QEMU commandline arguments
291
+ @qemu_args = UNSET_VALUE
292
+
293
+ # Additional QEMU commandline environment variables
294
+ @qemu_env = UNSET_VALUE
295
+
276
296
  @qemu_use_session = UNSET_VALUE
277
297
  end
278
298
 
@@ -305,7 +325,7 @@ module VagrantPlugins
305
325
  end
306
326
  end
307
327
 
308
- # is it better to raise our own error, or let libvirt cause the exception?
328
+ # is it better to raise our own error, or let Libvirt cause the exception?
309
329
  raise 'Only four cdroms may be attached at a time'
310
330
  end
311
331
 
@@ -349,7 +369,10 @@ module VagrantPlugins
349
369
  raise 'Feature name AND state must be specified'
350
370
  end
351
371
 
352
- @features_hyperv = [{name: options[:name], state: options[:state]}] if @features_hyperv == UNSET_VALUE
372
+ @features_hyperv = [] if @features_hyperv == UNSET_VALUE
373
+
374
+ @features_hyperv.push(name: options[:name],
375
+ state: options[:state])
353
376
  end
354
377
 
355
378
  def cputopology(options = {})
@@ -431,7 +454,14 @@ module VagrantPlugins
431
454
 
432
455
  @pcis = [] if @pcis == UNSET_VALUE
433
456
 
434
- @pcis.push(bus: options[:bus],
457
+ if options[:domain].nil?
458
+ pci_domain = '0x0000'
459
+ else
460
+ pci_domain = options[:domain]
461
+ end
462
+
463
+ @pcis.push(domain: pci_domain,
464
+ bus: options[:bus],
435
465
  slot: options[:slot],
436
466
  function: options[:function])
437
467
  end
@@ -577,12 +607,20 @@ module VagrantPlugins
577
607
  end
578
608
 
579
609
  def qemuargs(options = {})
610
+ @qemu_args = [] if @qemu_args == UNSET_VALUE
611
+
580
612
  @qemu_args << options if options[:value]
581
613
  end
582
614
 
615
+ def qemuenv(options = {})
616
+ @qemu_env = {} if @qemu_env == UNSET_VALUE
617
+
618
+ @qemu_env.merge!(options)
619
+ end
620
+
583
621
  # code to generate URI from a config moved out of the connect action
584
622
  def _generate_uri
585
- # builds the libvirt connection URI from the given driver config
623
+ # builds the Libvirt connection URI from the given driver config
586
624
  # Setup connection uri.
587
625
  uri = @driver.dup
588
626
  virt_path = case uri
@@ -598,7 +636,7 @@ module VagrantPlugins
598
636
  raise "Require specify driver #{uri}"
599
637
  end
600
638
  if uri == 'kvm'
601
- uri = 'qemu' # use qemu uri for kvm domain type
639
+ uri = 'qemu' # use QEMU uri for KVM domain type
602
640
  end
603
641
 
604
642
  if @connect_via_ssh
@@ -619,13 +657,13 @@ module VagrantPlugins
619
657
  uri << '?no_verify=1'
620
658
 
621
659
  if @id_ssh_key_file
622
- # set ssh key for access to libvirt host
660
+ # set ssh key for access to Libvirt host
623
661
  uri << "\&keyfile="
624
662
  # if no slash, prepend $HOME/.ssh/
625
663
  @id_ssh_key_file.prepend("#{`echo ${HOME}`.chomp}/.ssh/") if @id_ssh_key_file !~ /\A\//
626
664
  uri << @id_ssh_key_file
627
665
  end
628
- # set path to libvirt socket
666
+ # set path to Libvirt socket
629
667
  uri << "\&socket=" + @socket if @socket
630
668
  uri
631
669
  end
@@ -638,6 +676,7 @@ module VagrantPlugins
638
676
  @password = nil if @password == UNSET_VALUE
639
677
  @id_ssh_key_file = 'id_rsa' if @id_ssh_key_file == UNSET_VALUE
640
678
  @storage_pool_name = 'default' if @storage_pool_name == UNSET_VALUE
679
+ @snapshot_pool_name = @storage_pool_name if @snapshot_pool_name == UNSET_VALUE
641
680
  @storage_pool_path = nil if @storage_pool_path == UNSET_VALUE
642
681
  @random_hostname = false if @random_hostname == UNSET_VALUE
643
682
  @management_network_device = 'virbr0' if @management_network_device == UNSET_VALUE
@@ -649,6 +688,7 @@ module VagrantPlugins
649
688
  @management_network_autostart = false if @management_network_autostart == UNSET_VALUE
650
689
  @management_network_pci_bus = nil if @management_network_pci_bus == UNSET_VALUE
651
690
  @management_network_pci_slot = nil if @management_network_pci_slot == UNSET_VALUE
691
+ @management_network_domain = nil if @management_network_domain == UNSET_VALUE
652
692
  @system_uri = 'qemu:///system' if @system_uri == UNSET_VALUE
653
693
 
654
694
  @qemu_use_session = false if @qemu_use_session == UNSET_VALUE
@@ -659,8 +699,10 @@ module VagrantPlugins
659
699
  # Domain specific settings.
660
700
  @uuid = '' if @uuid == UNSET_VALUE
661
701
  @memory = 512 if @memory == UNSET_VALUE
702
+ @nodeset = nil if @nodeset == UNSET_VALUE
662
703
  @memory_backing = [] if @memory_backing == UNSET_VALUE
663
704
  @cpus = 1 if @cpus == UNSET_VALUE
705
+ @cpuset = nil if @cpuset == UNSET_VALUE
664
706
  @cpu_mode = 'host-model' if @cpu_mode == UNSET_VALUE
665
707
  @cpu_model = if (@cpu_model == UNSET_VALUE) && (@cpu_mode == 'custom')
666
708
  'qemu64'
@@ -672,6 +714,7 @@ module VagrantPlugins
672
714
  @cpu_topology = {} if @cpu_topology == UNSET_VALUE
673
715
  @cpu_fallback = 'allow' if @cpu_fallback == UNSET_VALUE
674
716
  @cpu_features = [] if @cpu_features == UNSET_VALUE
717
+ @shares = nil if @shares == UNSET_VALUE
675
718
  @features = ['acpi','apic','pae'] if @features == UNSET_VALUE
676
719
  @features_hyperv = [] if @features_hyperv == UNSET_VALUE
677
720
  @numa_nodes = @numa_nodes == UNSET_VALUE ? nil : _generate_numa
@@ -761,7 +804,11 @@ module VagrantPlugins
761
804
  # Attach mgmt network
762
805
  @mgmt_attach = true if @mgmt_attach == UNSET_VALUE
763
806
 
807
+ # Additional QEMU commandline arguments
764
808
  @qemu_args = [] if @qemu_args == UNSET_VALUE
809
+
810
+ # Additional QEMU commandline environment variables
811
+ @qemu_env = {} if @qemu_env == UNSET_VALUE
765
812
  end
766
813
 
767
814
  def validate(machine)
@@ -797,6 +844,10 @@ module VagrantPlugins
797
844
  c = cdroms.dup
798
845
  c += other.cdroms
799
846
  result.cdroms = c
847
+
848
+ c = qemu_env != UNSET_VALUE ? qemu_env.dup : {}
849
+ c.merge!(other.qemu_env) if other.qemu_env != UNSET_VALUE
850
+ result.qemu_env = c
800
851
  end
801
852
  end
802
853
  end