vagrant-libvirt 0.6.0 → 0.7.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9e37a27120aef75fdd73d704321b96c7c881b07fa3cbdd655855300bf11163a3
4
- data.tar.gz: 4639827cc360b3f06304310f02dffea445f19d2f4b8675a6e0e05a9be3cea307
3
+ metadata.gz: 696535927498f1996c3fd02f6e5503bd8ac47e92eb226d03cd28c46329232b93
4
+ data.tar.gz: 73cfeb05a09dad74122a6f09f562b5d56ac7c43a7ec029f2e8f5c8dcfa2a9413
5
5
  SHA512:
6
- metadata.gz: cb13d39445a95f3514cc1be73bcf6e81ec7924959ec86e6cc712c50050ac8211f6b5beb26bbd42c137020e98143794d7b67aa7241e2461cdf2d1ca5ed2a15c30
7
- data.tar.gz: b341135cabad7d59963df62e9dd921470a43e4794fb203ff78b893bd058a38af877717f48b25a72135211e72d82082ec444227b97157e365903103240dfb1311
6
+ metadata.gz: b4237cc046b138f9fbd5efad00bcc80d97b964d6a374e68b94c20cc19fd668e6eda2ea2939d8782ca05b9ea80478907a9728c3b34692b1b2adbb6305f1798cf4
7
+ data.tar.gz: 5a3e8094b553fd2557be01514f782139bfa52edca8c7dc811138932a84c7f3bffe44e7c0a5a5b322868e648016146efc9b67f5e3a7356e98b2d58b0e6ca2db74
data/README.md CHANGED
@@ -1,8 +1,9 @@
1
1
  # Vagrant Libvirt Provider
2
2
 
3
3
  [![Join the chat at https://gitter.im/vagrant-libvirt/vagrant-libvirt](https://badges.gitter.im/vagrant-libvirt/vagrant-libvirt.svg)](https://gitter.im/vagrant-libvirt/vagrant-libvirt?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
4
- [![Build Status](https://travis-ci.org/vagrant-libvirt/vagrant-libvirt.svg)](https://travis-ci.org/vagrant-libvirt/vagrant-libvirt)
4
+ [![Build Status](https://github.com/vagrant-libvirt/vagrant-libvirt/actions/workflows/unit-tests.yml/badge.svg)](https://github.com/vagrant-libvirt/vagrant-libvirt/actions/workflows/unit-tests.yml)
5
5
  [![Coverage Status](https://coveralls.io/repos/github/vagrant-libvirt/vagrant-libvirt/badge.svg?branch=master)](https://coveralls.io/github/vagrant-libvirt/vagrant-libvirt?branch=master)
6
+ [![Gem Version](https://badge.fury.io/rb/vagrant-libvirt.svg)](https://badge.fury.io/rb/vagrant-libvirt)
6
7
 
7
8
  This is a [Vagrant](http://www.vagrantup.com) plugin that adds a
8
9
  [Libvirt](http://libvirt.org) provider to Vagrant, allowing Vagrant to
@@ -49,6 +50,7 @@ can help a lot :-)
49
50
  * [USB Redirector Devices](#usb-redirector-devices)
50
51
  * [Filter for USB Redirector Devices](#filter-for-usb-redirector-devices)
51
52
  * [Random number generator passthrough](#random-number-generator-passthrough)
53
+ * [Serial Console Devices](#serial-console-devices)
52
54
  * [Watchdog device](#watchdog-device)
53
55
  * [Smartcard device](#smartcard-device)
54
56
  * [Hypervisor Features](#hypervisor-features)
@@ -137,12 +139,6 @@ docker pull vagrantlibvirt/vagrant-libvirt:edge
137
139
  ```
138
140
  ---
139
141
 
140
- Preparing the docker run, only once:
141
-
142
- ```bash
143
- mkdir -p ~/.vagrant.d/{boxes,data,tmp}
144
- ```
145
-
146
142
  Running the image:
147
143
  ```bash
148
144
  docker run -it --rm \
@@ -173,6 +169,14 @@ vagrant(){
173
169
  ```
174
170
 
175
171
  ### Using Podman
172
+
173
+ Preparing the podman run, only once:
174
+
175
+ ```bash
176
+ mkdir -p ~/.vagrant.d/{boxes,data,tmp}
177
+ ```
178
+ _N.B. This is needed until the entrypoint works for podman to only mount the `~/.vagrant.d` directory_
179
+
176
180
  To run with Podman you need to include
177
181
 
178
182
  ```bash
@@ -180,6 +184,7 @@ To run with Podman you need to include
180
184
  --security-opt label=disable \
181
185
  -v ~/.vagrant.d/boxes:/vagrant/boxes \
182
186
  -v ~/.vagrant.d/data:/vagrant/data \
187
+ -v ~/.vagrant.d/data:/vagrant/tmp \
183
188
  ```
184
189
 
185
190
  for example:
@@ -191,6 +196,7 @@ vagrant(){
191
196
  -v /var/run/libvirt/:/var/run/libvirt/ \
192
197
  -v ~/.vagrant.d/boxes:/vagrant/boxes \
193
198
  -v ~/.vagrant.d/data:/vagrant/data \
199
+ -v ~/.vagrant.d/data:/vagrant/tmp \
194
200
  -v $(realpath "${PWD}"):${PWD} \
195
201
  -w $(realpath "${PWD}") \
196
202
  --network host \
@@ -232,7 +238,7 @@ installed](http://docs.vagrantup.com/v2/installation/index.html).
232
238
  Vagrant-libvirt supports Vagrant 2.0, 2.1 & 2.2. It should also work with earlier
233
239
  releases from 1.5 onwards but they are not actively tested.
234
240
 
235
- Check the [.travis.yml](https://github.com/vagrant-libvirt/vagrant-libvirt/blob/master/.travis.yml)
241
+ Check the [unit tests](https://github.com/vagrant-libvirt/vagrant-libvirt/blob/master/.github/workflows/unit-tests.yml)
236
242
  for the current list of tested versions.
237
243
 
238
244
  *We only test with the upstream version!* If you decide to install your distro's
@@ -593,6 +599,8 @@ end
593
599
  * `graphics_autoport` - Sets autoport for graphics, Libvirt in this case
594
600
  ignores graphics_port value, Defaults to 'yes'. Possible value are "yes" and
595
601
  "no"
602
+ * `graphics_gl` - Set to `true` to enable OpenGL. Defaults to `true` if
603
+ `video_accel3d` is `true`.
596
604
  * `keymap` - Set keymap for vm. default: en-us
597
605
  * `kvm_hidden` - [Hide the hypervisor from the
598
606
  guest](https://libvirt.org/formatdomain.html#elementsFeatures). Useful for
@@ -603,6 +611,8 @@ end
603
611
  "cirrus", "vmvga", "xen", "vbox", or "qxl".
604
612
  * `video_vram` - Used by some graphics card types to vary the amount of RAM
605
613
  dedicated to video. Defaults to 9216.
614
+ * `video_accel3d` - Set to `true` to enable 3D acceleration. Defaults to
615
+ `false`.
606
616
  * `sound_type` - [Set the virtual sound card](https://libvirt.org/formatdomain.html#elementsSound)
607
617
  Defaults to "ich6".
608
618
  * `machine_type` - Sets machine type. Equivalent to qemu `-machine`. Use
@@ -657,6 +667,9 @@ end
657
667
  it is not possible to communicate with VM through `vagrant ssh` or run
658
668
  provisioning. Setting to 'false' is only possible when VM doesn't use box.
659
669
  Defaults set to 'true'.
670
+ * `serial` - [libvirt serial devices](https://libvirt.org/formatdomain.html#elementsConsole).
671
+ Configure a serial/console port to communicate with the guest. Can be used
672
+ to log to file boot time messages sent to ttyS0 console by the guest.
660
673
 
661
674
  Specific domain settings can be set for each domain separately in multi-VM
662
675
  environment. Example below shows a part of Vagrantfile, where specific options
@@ -906,6 +919,9 @@ starts with `libvirt__` string. Here is a list of those options:
906
919
  If not specified the default is 'false'.
907
920
  * `:bus` - The bus of the PCI device. Both :bus and :slot have to be defined.
908
921
  * `:slot` - The slot of the PCI device. Both :bus and :slot have to be defined.
922
+ * `:libvirt__always_destroy` - Allow domains that use but did not create a
923
+ network to destroy it when the domain is destroyed (default: `true`). Set to
924
+ `false` to only allow the domain that created the network to destroy it.
909
925
 
910
926
  When the option `:libvirt__dhcp_enabled` is to to 'false' it shouldn't matter
911
927
  whether the virtual network contains a DHCP server or not and vagrant-libvirt
@@ -1249,6 +1265,26 @@ Vagrant.configure("2") do |config|
1249
1265
  end
1250
1266
  ```
1251
1267
 
1268
+ ## Serial Console Devices
1269
+ You can define settings to redirect output from the serial console of any VM brought up with libvirt to a file or other devices that are listening. [See libvirt documentation](https://libvirt.org/formatdomain.html#elementCharSerial).
1270
+
1271
+ Currently only redirecting to a file is supported.
1272
+
1273
+ * `type` - only value that has an effect is file, in the future support may be added for virtual console, pty, dev, pipe, tcp, udp, unix socket, spiceport & nmdm.
1274
+ * `source` - options pertaining to how the connection attaches to the host, contains sub-settings dependent on `type`.
1275
+ `source` options for type `file`
1276
+ * `path` - file on host to connect to the serial port to record all output. May be created by qemu system user causing some permissions issues.
1277
+
1278
+ ```ruby
1279
+ Vagrant.configure("2") do |config|
1280
+ config.vm.define :test do |test|
1281
+ test.vm.provider :libvirt do |domain|
1282
+ domain.serial :type => "file", :source => {:path => "/var/log/vm_consoles/test.log}
1283
+ end
1284
+ end
1285
+ end
1286
+ ```
1287
+
1252
1288
  ## Random number generator passthrough
1253
1289
 
1254
1290
  You can pass through `/dev/random` to your VM by configuring the domain like this:
@@ -78,9 +78,11 @@ module VagrantPlugins
78
78
  else
79
79
  "passwd='#{config.graphics_passwd}'"
80
80
  end
81
+ @graphics_gl = config.graphics_gl
81
82
  @video_type = config.video_type
82
83
  @sound_type = config.sound_type
83
84
  @video_vram = config.video_vram
85
+ @video_accel3d = config.video_accel3d
84
86
  @keymap = config.keymap
85
87
  @kvm_hidden = config.kvm_hidden
86
88
 
@@ -171,6 +173,20 @@ module VagrantPlugins
171
173
  storage_prefix = get_disk_storage_prefix(env, @storage_pool_name)
172
174
  end
173
175
 
176
+ @serials = config.serials
177
+
178
+ @serials.each do |serial|
179
+ next unless serial[:source] && serial[:source][:path]
180
+
181
+ dir = File.dirname(serial[:source][:path])
182
+ begin
183
+ FileUtils.mkdir_p(dir)
184
+ rescue ::Errno::EACCES
185
+ raise Errors::SerialCannotCreatePathError,
186
+ path: dir
187
+ end
188
+ end
189
+
174
190
  @disks.each do |disk|
175
191
  disk[:path] ||= _disk_name(@name, disk)
176
192
 
@@ -285,6 +301,7 @@ module VagrantPlugins
285
301
  env[:ui].info(" -- Graphics Password: #{@graphics_passwd.empty? ? 'Not defined' : 'Defined'}")
286
302
  env[:ui].info(" -- Video Type: #{@video_type}")
287
303
  env[:ui].info(" -- Video VRAM: #{@video_vram}")
304
+ env[:ui].info(" -- Video 3D accel: #{@video_accel3d}")
288
305
  env[:ui].info(" -- Sound Type: #{@sound_type}")
289
306
  env[:ui].info(" -- Keymap: #{@keymap}")
290
307
  env[:ui].info(" -- TPM Backend: #{@tpm_type}")
@@ -379,6 +396,13 @@ module VagrantPlugins
379
396
  env[:ui].info(" -- smartcard device: mode=#{@smartcard_dev[:mode]}, type=#{@smartcard_dev[:type]}")
380
397
  end
381
398
 
399
+ @serials.each_with_index do |serial, port|
400
+ if serial[:source]
401
+ env[:ui].info(" -- SERIAL(COM#{port}: redirect to #{serial[:source][:path]}")
402
+ env[:ui].warn(I18n.t('vagrant_libvirt.warnings.creating_domain_console_access_disabled'))
403
+ end
404
+ end
405
+
382
406
  unless @qemu_args.empty?
383
407
  env[:ui].info(' -- Command line args: ')
384
408
  @qemu_args.each do |arg|
@@ -208,6 +208,9 @@ module VagrantPlugins
208
208
 
209
209
  # Create a private network.
210
210
  create_private_network(env)
211
+ write_created_network(env)
212
+ else
213
+ write_created_network(env) unless @options[:always_destroy] == false
211
214
  end
212
215
  end
213
216
 
@@ -247,6 +250,9 @@ module VagrantPlugins
247
250
 
248
251
  # Create a private network.
249
252
  create_private_network(env)
253
+ write_created_network(env)
254
+ else
255
+ write_created_network(env) unless @options[:always_destroy] == false
250
256
  end
251
257
  end
252
258
 
@@ -273,6 +279,9 @@ module VagrantPlugins
273
279
 
274
280
  # Create a private network.
275
281
  create_private_network(env)
282
+ write_created_network(env)
283
+ else
284
+ write_created_network(env) unless @options[:always_destroy] == false
276
285
  end
277
286
  end
278
287
 
@@ -347,7 +356,9 @@ module VagrantPlugins
347
356
  rescue => e
348
357
  raise Errors::CreateNetworkError, error_message: e.message
349
358
  end
359
+ end
350
360
 
361
+ def write_created_network(env)
351
362
  created_networks_file = env[:machine].data_dir + 'created_networks'
352
363
 
353
364
  message = 'Saving information about created network ' \
@@ -34,10 +34,11 @@ module VagrantPlugins
34
34
  box_format = env[:machine].box.metadata['format']
35
35
  HandleBoxImage.verify_box_format(box_format)
36
36
 
37
+ image_path = HandleBoxImage.get_box_image_path(env[:machine].box, 'box.img')
37
38
  env[:box_volume_number] = 1
38
39
  env[:box_volumes] = [{
39
- :path => HandleBoxImage.get_box_image_path(env[:machine].box, 'box.img'),
40
- :name => HandleBoxImage.get_volume_name(env[:machine].box, 'box'),
40
+ :path => image_path,
41
+ :name => HandleBoxImage.get_volume_name(env[:machine].box, 'box', image_path, env[:ui]),
41
42
  :virtual_size => HandleBoxImage.get_virtual_size(env),
42
43
  :format => box_format,
43
44
  }]
@@ -58,6 +59,8 @@ module VagrantPlugins
58
59
  volume_name = HandleBoxImage.get_volume_name(
59
60
  env[:machine].box,
60
61
  disks[i].fetch('name', disks[i]['path'].sub(/#{File.extname(disks[i]['path'])}$/, '')),
62
+ image_path,
63
+ env[:ui],
61
64
  )
62
65
 
63
66
  # allowing name means needing to check that it doesn't cause a clash
@@ -122,15 +125,21 @@ module VagrantPlugins
122
125
 
123
126
  protected
124
127
 
125
- def self.get_volume_name(box, name)
128
+ def self.get_volume_name(box, name, path, ui)
129
+ version = begin
130
+ box.version.to_s
131
+ rescue
132
+ ''
133
+ end
134
+
135
+ if version.empty?
136
+ ui.warn(I18n.t('vagrant_libvirt.box_version_missing', name: box.name.to_s))
137
+
138
+ version = "0_#{File.mtime(path).to_i}"
139
+ end
140
+
126
141
  vol_name = box.name.to_s.dup.gsub('/', '-VAGRANTSLASH-')
127
- vol_name << "_vagrant_box_image_#{
128
- begin
129
- box.version.to_s
130
- rescue
131
- ''
132
- end
133
- }_#{name.dup.gsub('/', '-SLASH-')}.img"
142
+ vol_name << "_vagrant_box_image_#{version}_#{name.dup.gsub('/', '-SLASH-')}.img"
134
143
  end
135
144
 
136
145
  def self.get_virtual_size(env)
@@ -59,7 +59,7 @@ module VagrantPlugins
59
59
  command = "ip=$(which ip); ${ip:-/sbin/ip} addr show | grep -i 'inet ' | grep -v '127.0.0.1' | tr -s ' ' | cut -d' ' -f3 | cut -d'/' -f 1"
60
60
  result = ''
61
61
  machine.communicate.execute(command) do |type, data|
62
- result << data if type == :stdout
62
+ result += data if type == :stdout
63
63
  end
64
64
 
65
65
  ips = result.chomp.split("\n").uniq
@@ -1,5 +1,24 @@
1
1
  require 'log4r'
2
2
 
3
+ module VagrantPlugins
4
+ module ProviderLibvirt
5
+ module Action
6
+ # To wrap GracefulShutdown need to track the time taken
7
+ class StartShutdownTimer
8
+ def initialize(app, _env)
9
+ @app = app
10
+ end
11
+
12
+ def call(env)
13
+ env[:shutdown_start_time] = Time.now
14
+
15
+ @app.call(env)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+
3
22
  module VagrantPlugins
4
23
  module ProviderLibvirt
5
24
  module Action
@@ -15,21 +34,22 @@ module VagrantPlugins
15
34
  def call(env)
16
35
  timeout = env[:machine].config.vm.graceful_halt_timeout
17
36
 
18
- start_time = Time.now
37
+ start_time = env[:shutdown_start_time]
19
38
 
20
- # call nested action first under the assumption it should try to
21
- # handle shutdown via client capabilities
22
- @app.call(env)
39
+ if start_time.nil?
40
+ # this really shouldn't happen
41
+ raise Errors::CallChainError, require_action: StartShutdownTimer.name, current_action: ShutdownDomain.name
42
+ end
23
43
 
24
44
  # return if successful, otherwise will ensure result is set to false
25
45
  env[:result] = env[:machine].state.id == @target_state
26
46
 
27
- return if env[:result]
47
+ return @app.call(env) if env[:result]
28
48
 
29
49
  current_time = Time.now
30
50
 
31
51
  # if we've already exceeded the timeout
32
- return if current_time - start_time >= timeout
52
+ return @app.call(env) if current_time - start_time >= timeout
33
53
 
34
54
  # otherwise construct a new timeout.
35
55
  timeout = timeout - (current_time - start_time)
@@ -42,6 +62,8 @@ module VagrantPlugins
42
62
  end
43
63
 
44
64
  env[:result] = env[:machine].state.id == @target_state
65
+
66
+ @app.call(env)
45
67
  end
46
68
  end
47
69
  end
@@ -222,6 +222,24 @@ module VagrantPlugins
222
222
  graphics.attributes['passwd'] = config.graphics_passwd
223
223
  end
224
224
  end
225
+ graphics_gl = REXML::XPath.first(xml_descr, '/domain/devices/graphics/gl')
226
+ if graphics_gl.nil?
227
+ if config.graphics_gl
228
+ graphics_gl = REXML::Element.new('gl', REXML::XPath.first(xml_descr, '/domain/devices/graphics'))
229
+ graphics_gl.attributes['enable'] = 'yes'
230
+ descr_changed = true
231
+ end
232
+ else
233
+ if config.graphics_gl
234
+ if graphics_gl.attributes['enable'] != 'yes'
235
+ graphics_gl.attributes['enable'] = 'yes'
236
+ descr_changed = true
237
+ end
238
+ else
239
+ graphics_gl.parent.delete_element(graphics_gl)
240
+ descr_changed = true
241
+ end
242
+ end
225
243
  else
226
244
  # graphics_type = none, remove entire element
227
245
  graphics.parent.delete_element(graphics) unless graphics.nil?
@@ -280,6 +298,24 @@ module VagrantPlugins
280
298
  video_model.attributes['vram'] = config.video_vram
281
299
  end
282
300
  end
301
+ video_accel = REXML::XPath.first(xml_descr, '/domain/devices/video/model/acceleration')
302
+ if video_accel.nil?
303
+ if config.video_accel3d
304
+ video_accel = REXML::Element.new('acceleration', REXML::XPath.first(xml_descr, '/domain/devices/video/model'))
305
+ video_accel.attributes['accel3d'] = 'yes'
306
+ descr_changed = true
307
+ end
308
+ else
309
+ if config.video_accel3d
310
+ if video_accel.attributes['accel3d'] != 'yes'
311
+ video_accel.attributes['accel3d'] = 'yes'
312
+ descr_changed = true
313
+ end
314
+ else
315
+ video_accel.parent.delete_element(video_accel)
316
+ descr_changed = true
317
+ end
318
+ end
283
319
  end
284
320
 
285
321
  # Sound device
@@ -143,19 +143,17 @@ module VagrantPlugins
143
143
  b2.use Call, IsRunning do |env2, b3|
144
144
  next unless env2[:result]
145
145
 
146
- b3.use Call, Message, "Attempting nice shutdowns..." do |_, b4|
147
- # ShutdownDomain will perform the domain shutdown on the out calls
148
- # so it runs after the remaining actions in the same action builder.
149
- b4.use ShutdownDomain, :shutoff, :running
150
- b4.use GracefulHalt, :shutoff, :running
146
+ b3.use StartShutdownTimer
147
+ b3.use Call, GracefulHalt, :shutoff, :running do |env3, b4|
148
+ if !env3[:result]
149
+ b4.use Call, ShutdownDomain, :shutoff, :running do |env4, b5|
150
+ if !env4[:result]
151
+ b5.use HaltDomain
152
+ end
153
+ end
154
+ end
151
155
  end
152
156
 
153
- # Only force halt if previous actions insufficient.
154
- b3.use Call, IsRunning do |env3, b4|
155
- next unless env3[:result]
156
-
157
- b4.use HaltDomain
158
- end
159
157
  end
160
158
  end
161
159
  end
@@ -235,14 +233,12 @@ module VagrantPlugins
235
233
  b.use ConfigValidate
236
234
  b.use Call, IsCreated do |env, b2|
237
235
  unless env[:result]
238
- b2.use MessageNotCreated
239
- next
236
+ raise Vagrant::Errors::VMNotCreatedError
240
237
  end
241
238
 
242
239
  b2.use Call, IsRunning do |env2, b3|
243
240
  unless env2[:result]
244
- b3.use MessageNotRunning
245
- next
241
+ raise Vagrant::Errors::VMNotRunningError
246
242
  end
247
243
 
248
244
  b3.use SSHExec
@@ -332,14 +328,12 @@ module VagrantPlugins
332
328
  b.use ConfigValidate
333
329
  b.use Call, IsCreated do |env, b2|
334
330
  unless env[:result]
335
- b2.use MessageNotCreated
336
- next
331
+ raise Vagrant::Errors::VMNotCreatedError
337
332
  end
338
333
 
339
334
  b2.use Call, IsRunning do |env2, b3|
340
335
  unless env2[:result]
341
- b3.use MessageNotRunning
342
- next
336
+ raise Vagrant::Errors::VMNotRunningError
343
337
  end
344
338
 
345
339
  b3.use SSHRun
@@ -360,6 +354,7 @@ module VagrantPlugins
360
354
  autoload :ForwardPorts, action_root.join('forward_ports')
361
355
  autoload :ClearForwardedPorts, action_root.join('forward_ports')
362
356
  autoload :HaltDomain, action_root.join('halt_domain')
357
+ autoload :StartShutdownTimer, action_root.join('shutdown_domain')
363
358
  autoload :ShutdownDomain, action_root.join('shutdown_domain')
364
359
  autoload :HandleBoxImage, action_root.join('handle_box_image')
365
360
  autoload :HandleStoragePool, action_root.join('handle_storage_pool')
@@ -119,8 +119,10 @@ module VagrantPlugins
119
119
  attr_accessor :graphics_port
120
120
  attr_accessor :graphics_passwd
121
121
  attr_accessor :graphics_ip
122
+ attr_accessor :graphics_gl
122
123
  attr_accessor :video_type
123
124
  attr_accessor :video_vram
125
+ attr_accessor :video_accel3d
124
126
  attr_accessor :keymap
125
127
  attr_accessor :kvm_hidden
126
128
  attr_accessor :sound_type
@@ -196,6 +198,9 @@ module VagrantPlugins
196
198
  # Use QEMU Agent to get ip address
197
199
  attr_accessor :qemu_use_agent
198
200
 
201
+ # serial consoles
202
+ attr_accessor :serials
203
+
199
204
  def initialize
200
205
  @uri = UNSET_VALUE
201
206
  @driver = UNSET_VALUE
@@ -267,8 +272,10 @@ module VagrantPlugins
267
272
  @graphics_port = UNSET_VALUE
268
273
  @graphics_ip = UNSET_VALUE
269
274
  @graphics_passwd = UNSET_VALUE
275
+ @graphics_gl = UNSET_VALUE
270
276
  @video_type = UNSET_VALUE
271
277
  @video_vram = UNSET_VALUE
278
+ @video_accel3d = UNSET_VALUE
272
279
  @sound_type = UNSET_VALUE
273
280
  @keymap = UNSET_VALUE
274
281
  @kvm_hidden = UNSET_VALUE
@@ -338,6 +345,8 @@ module VagrantPlugins
338
345
 
339
346
  # Use Qemu agent to get ip address
340
347
  @qemu_use_agent = UNSET_VALUE
348
+
349
+ @serials = []
341
350
  end
342
351
 
343
352
  def boot(device)
@@ -705,6 +714,20 @@ module VagrantPlugins
705
714
  @qemu_env.merge!(options)
706
715
  end
707
716
 
717
+ def serial(options={})
718
+ options = {
719
+ :type => "pty",
720
+ :source => nil,
721
+ }.merge(options)
722
+
723
+ serial = {
724
+ :type => options[:type],
725
+ :source => options[:source],
726
+ }
727
+
728
+ @serials << serial
729
+ end
730
+
708
731
  def _default_uri
709
732
  # Determine if any settings except driver provided explicitly, if not
710
733
  # and the LIBVIRT_DEFAULT_URI var is set, use that.
@@ -817,7 +840,6 @@ module VagrantPlugins
817
840
  @management_network_pci_slot = nil if @management_network_pci_slot == UNSET_VALUE
818
841
  @management_network_domain = nil if @management_network_domain == UNSET_VALUE
819
842
  @management_network_mtu = nil if @management_network_mtu == UNSET_VALUE
820
- @system_uri = 'qemu:///system' if @system_uri == UNSET_VALUE
821
843
 
822
844
  # Domain specific settings.
823
845
  @title = '' if @title == UNSET_VALUE
@@ -871,6 +893,8 @@ module VagrantPlugins
871
893
  @graphics_ip = '127.0.0.1' if @graphics_ip == UNSET_VALUE
872
894
  @video_type = 'cirrus' if @video_type == UNSET_VALUE
873
895
  @video_vram = 9216 if @video_vram == UNSET_VALUE
896
+ @video_accel3d = false if @video_accel3d == UNSET_VALUE
897
+ @graphics_gl = @video_accel3d if @graphics_gl == UNSET_VALUE
874
898
  @sound_type = nil if @sound_type == UNSET_VALUE
875
899
  @keymap = 'en-us' if @keymap == UNSET_VALUE
876
900
  @kvm_hidden = false if @kvm_hidden == UNSET_VALUE
@@ -945,7 +969,9 @@ module VagrantPlugins
945
969
  # Additional QEMU commandline environment variables
946
970
  @qemu_env = {} if @qemu_env == UNSET_VALUE
947
971
 
948
- @qemu_use_agent = true if @qemu_use_agent != UNSET_VALUE
972
+ @qemu_use_agent = false if @qemu_use_agent == UNSET_VALUE
973
+
974
+ @serials = [{:type => 'pty', :source => nil}] if @serials == []
949
975
  end
950
976
 
951
977
  def validate(machine)
@@ -959,6 +985,9 @@ module VagrantPlugins
959
985
  end
960
986
  end
961
987
 
988
+ unless @qemu_use_agent == true || @qemu_use_agent == false
989
+ errors << "libvirt.qemu_use_agent must be a boolean."
990
+ end
962
991
 
963
992
  if @qemu_use_agent == true
964
993
  # if qemu agent is used to optain domain ip configuration, at least
@@ -976,6 +1005,12 @@ module VagrantPlugins
976
1005
  end
977
1006
  end
978
1007
 
1008
+ machine.provider_config.serials.each do |serial|
1009
+ if serial[:source] and serial[:source][:path].nil?
1010
+ errors << "serial :source requires :path to be defined"
1011
+ end
1012
+ end
1013
+
979
1014
  machine.config.vm.networks.each do |_type, opts|
980
1015
  if opts[:mac]
981
1016
  if opts[:mac] =~ /\A([0-9a-fA-F]{12})\z/
@@ -1017,6 +1052,10 @@ module VagrantPlugins
1017
1052
  c = qemu_env != UNSET_VALUE ? qemu_env.dup : {}
1018
1053
  c.merge!(other.qemu_env) if other.qemu_env != UNSET_VALUE
1019
1054
  result.qemu_env = c
1055
+
1056
+ s = serials.dup
1057
+ s += other.serials
1058
+ result.serials = s
1020
1059
  end
1021
1060
  end
1022
1061
 
@@ -1026,6 +1065,10 @@ module VagrantPlugins
1026
1065
  # Parse uri to extract individual components
1027
1066
  uri = _parse_uri(@uri)
1028
1067
 
1068
+ system_uri = uri.dup
1069
+ system_uri.path = '/system'
1070
+ @system_uri = system_uri.to_s if @system_uri == UNSET_VALUE
1071
+
1029
1072
  # only set @connect_via_ssh if not explicitly to avoid overriding
1030
1073
  # and allow an error to occur if the @uri and @connect_via_ssh disagree
1031
1074
  @connect_via_ssh = uri.scheme.include? "ssh" if @connect_via_ssh == UNSET_VALUE
@@ -61,7 +61,7 @@ module VagrantPlugins
61
61
 
62
62
  config = @machine.provider_config
63
63
 
64
- @system_connection = Libvirt::open(config.system_uri)
64
+ @system_connection = Libvirt::open_read_only(config.system_uri)
65
65
  @system_connection
66
66
  end
67
67
 
@@ -98,16 +98,16 @@ module VagrantPlugins
98
98
  end
99
99
 
100
100
  def get_domain_ipaddress(machine, domain)
101
- if @machine.provider_config.qemu_use_session
102
- return get_ipaddress_from_system domain.mac
103
- end
104
-
105
101
  # attempt to get ip address from qemu agent
106
102
  if @machine.provider_config.qemu_use_agent == true
107
103
  @logger.info('Get IP via qemu agent')
108
104
  return get_ipaddress_from_qemu_agent(domain, machine.id)
109
105
  end
110
106
 
107
+ if @machine.provider_config.qemu_use_session
108
+ return get_ipaddress_from_system domain.mac
109
+ end
110
+
111
111
  # Get IP address from dhcp leases table
112
112
  begin
113
113
  ip_address = get_ipaddress_from_domain(domain)
@@ -168,9 +168,9 @@ module VagrantPlugins
168
168
  def get_ipaddress_from_qemu_agent(domain, machine_id)
169
169
  ip_address = nil
170
170
  addresses = nil
171
- dom = system_connection.lookup_domain_by_uuid(machine_id)
171
+ libvirt_domain = connection.client.lookup_domain_by_uuid(machine_id)
172
172
  begin
173
- response = dom.qemu_agent_command('{"execute":"guest-network-get-interfaces"}', timeout=10)
173
+ response = libvirt_domain.qemu_agent_command('{"execute":"guest-network-get-interfaces"}', timeout=10)
174
174
  @logger.debug("Got Response from qemu agent")
175
175
  @logger.debug(response)
176
176
  addresses = JSON.parse(response)
@@ -180,7 +180,7 @@ module VagrantPlugins
180
180
 
181
181
  unless addresses.nil?
182
182
  addresses["return"].each{ |interface|
183
- if domain.mac == interface["hardware-address"]
183
+ if domain.mac.downcase == interface["hardware-address"].downcase
184
184
  @logger.debug("Found mathing interface: [%s]" % interface["name"])
185
185
  if interface.has_key?("ip-addresses")
186
186
  interface["ip-addresses"].each{ |ip|