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 +4 -4
- data/README.md +44 -8
- data/lib/vagrant-libvirt/action/create_domain.rb +24 -0
- data/lib/vagrant-libvirt/action/create_networks.rb +11 -0
- data/lib/vagrant-libvirt/action/handle_box_image.rb +19 -10
- data/lib/vagrant-libvirt/action/prepare_nfs_settings.rb +1 -1
- data/lib/vagrant-libvirt/action/shutdown_domain.rb +28 -6
- data/lib/vagrant-libvirt/action/start_domain.rb +36 -0
- data/lib/vagrant-libvirt/action.rb +14 -19
- data/lib/vagrant-libvirt/config.rb +45 -2
- data/lib/vagrant-libvirt/driver.rb +8 -8
- data/lib/vagrant-libvirt/errors.rb +8 -0
- data/lib/vagrant-libvirt/templates/domain.xml.erb +18 -5
- data/lib/vagrant-libvirt/util/network_util.rb +2 -1
- data/lib/vagrant-libvirt/util/nfs.rb +2 -0
- data/lib/vagrant-libvirt/version +1 -1
- data/locales/en.yml +9 -0
- data/spec/spec_helper.rb +8 -0
- data/spec/support/libvirt_context.rb +7 -4
- data/spec/support/sharedcontext.rb +1 -1
- data/spec/unit/action/handle_box_image_spec.rb +30 -0
- data/spec/unit/action/prepare_nfs_settings_spec.rb +55 -0
- data/spec/unit/action/shutdown_domain_spec.rb +32 -3
- data/spec/unit/action/wait_till_up_spec.rb +2 -1
- data/spec/unit/action_spec.rb +78 -0
- data/spec/unit/config_spec.rb +48 -0
- data/spec/unit/driver_spec.rb +138 -3
- data/spec/unit/templates/domain_all_settings.xml +10 -4
- data/spec/unit/templates/domain_spec.rb +3 -0
- metadata +39 -38
- data/spec/unit/provider_spec.rb +0 -11
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 696535927498f1996c3fd02f6e5503bd8ac47e92eb226d03cd28c46329232b93
|
|
4
|
+
data.tar.gz: 73cfeb05a09dad74122a6f09f562b5d56ac7c43a7ec029f2e8f5c8dcfa2a9413
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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
|
[](https://gitter.im/vagrant-libvirt/vagrant-libvirt?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
|
4
|
-
[](https://github.com/vagrant-libvirt/vagrant-libvirt/actions/workflows/unit-tests.yml)
|
|
5
5
|
[](https://coveralls.io/github/vagrant-libvirt/vagrant-libvirt?branch=master)
|
|
6
|
+
[](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 [
|
|
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 =>
|
|
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
|
|
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 =
|
|
37
|
+
start_time = env[:shutdown_start_time]
|
|
19
38
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
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
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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::
|
|
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
|
-
|
|
171
|
+
libvirt_domain = connection.client.lookup_domain_by_uuid(machine_id)
|
|
172
172
|
begin
|
|
173
|
-
response =
|
|
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|
|