vagrant-libvirt 0.0.43 → 0.0.45
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +72 -10
- data/lib/vagrant-libvirt/action/create_domain.rb +24 -8
- data/lib/vagrant-libvirt/action/create_domain_volume.rb +5 -4
- data/lib/vagrant-libvirt/action/create_network_interfaces.rb +2 -0
- data/lib/vagrant-libvirt/action/create_networks.rb +5 -0
- data/lib/vagrant-libvirt/action/destroy_networks.rb +5 -0
- data/lib/vagrant-libvirt/action/handle_box_image.rb +64 -18
- data/lib/vagrant-libvirt/action/handle_storage_pool.rb +5 -0
- data/lib/vagrant-libvirt/action/wait_till_up.rb +28 -11
- data/lib/vagrant-libvirt/config.rb +63 -5
- data/lib/vagrant-libvirt/driver.rb +29 -0
- data/lib/vagrant-libvirt/errors.rb +4 -0
- data/lib/vagrant-libvirt/templates/default_storage_pool.xml.erb +3 -3
- data/lib/vagrant-libvirt/templates/default_storage_volume.xml.erb +14 -0
- data/lib/vagrant-libvirt/templates/domain.xml.erb +25 -3
- data/lib/vagrant-libvirt/util.rb +1 -0
- data/lib/vagrant-libvirt/util/network_util.rb +27 -12
- data/lib/vagrant-libvirt/util/storage_util.rb +27 -0
- data/lib/vagrant-libvirt/version.rb +1 -1
- data/locales/en.yml +4 -0
- data/spec/support/environment_helper.rb +1 -1
- data/spec/unit/templates/domain_all_settings.xml +6 -2
- data/spec/unit/templates/domain_custom_cpu_model.xml +46 -0
- data/spec/unit/templates/domain_spec.rb +14 -0
- data/vagrant-libvirt.gemspec +2 -5
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 418a49ce7fd1b2f951f64f38e13479bbe2b894933b3127d8e70ad47a27ec78a5
|
4
|
+
data.tar.gz: 6450a6b6a234718c59481418ecb8568af1dc1ddd8d924af1f5879e632dc3cabd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 81a5f88b26b1048b66c8bc7249443c6f013d157dd2d43df4c2cc523f94d5e9fc96f52b522f2addab2347607ce9d8226695662032da08caaf4aabd0a5f1667120
|
7
|
+
data.tar.gz: 90dca18364b8b9eb23c9598d480717d2113d9b43f5846189174e4ca25868cd52a7d37ed3fde5614d8a132cf3163c8e07c8682cb9c6cb518bfa3f28381a99f0f8
|
data/README.md
CHANGED
@@ -11,15 +11,6 @@ control and provision machines via Libvirt toolkit.
|
|
11
11
|
**Note:** Actual version is still a development one. Feedback is welcome and
|
12
12
|
can help a lot :-)
|
13
13
|
|
14
|
-
## QA status
|
15
|
-
|
16
|
-
We periodically test basic functionality for vagrant-libvirt on various distributions.
|
17
|
-
In the table below, build passing means that specific version combination of Vagrant + Vagrant-libvirt was installed correctly and `vagrant up` is working. Click the badge to see the log.
|
18
|
-
|
19
|
-
|Vagrant|Vagrant-libvirt|ubuntu-12.04|ubuntu-14.04|ubuntu-16.04|debian-8|debian-9|centos-6|centos-7|fedora-21|fedora-22|fedora-23|fedora-24|arch|
|
20
|
-
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
21
|
-
|2.0.1|master|[![Build Status](https://jenkins.infernix.net/job/vagrant-libvirt-qa/qa_vagrant_libvirt_version=master,qa_vagrant_version=2.0.1,distro=ubuntu-12.04/badge/icon)](https://jenkins.infernix.net/job/vagrant-libvirt-qa/qa_vagrant_libvirt_version=master,qa_vagrant_version=2.0.1,distro=ubuntu-12.04/)|[![Build Status](https://jenkins.infernix.net/job/vagrant-libvirt-qa/qa_vagrant_libvirt_version=master,qa_vagrant_version=2.0.1,distro=ubuntu-14.04/badge/icon)](https://jenkins.infernix.net/job/vagrant-libvirt-qa/qa_vagrant_libvirt_version=master,qa_vagrant_version=2.0.1,distro=ubuntu-14.04/)|[![Build Status](https://jenkins.infernix.net/job/vagrant-libvirt-qa/qa_vagrant_libvirt_version=master,qa_vagrant_version=2.0.1,distro=ubuntu-16.04/badge/icon)](https://jenkins.infernix.net/job/vagrant-libvirt-qa/qa_vagrant_libvirt_version=master,qa_vagrant_version=2.0.1,distro=ubuntu-16.04/)|[![Build Status](https://jenkins.infernix.net/job/vagrant-libvirt-qa/qa_vagrant_libvirt_version=master,qa_vagrant_version=2.0.1,distro=debian-8/badge/icon)](https://jenkins.infernix.net/job/vagrant-libvirt-qa/qa_vagrant_libvirt_version=master,qa_vagrant_version=2.0.1,distro=debian-8/)|[![Build Status](https://jenkins.infernix.net/job/vagrant-libvirt-qa/qa_vagrant_libvirt_version=master,qa_vagrant_version=2.0.1,distro=debian-9/badge/icon)](https://jenkins.infernix.net/job/vagrant-libvirt-qa/qa_vagrant_libvirt_version=master,qa_vagrant_version=2.0.1,distro=debian-9/)|[![Build Status](https://jenkins.infernix.net/job/vagrant-libvirt-qa/qa_vagrant_libvirt_version=master,qa_vagrant_version=2.0.1,distro=centos-6/badge/icon)](https://jenkins.infernix.net/job/vagrant-libvirt-qa/qa_vagrant_libvirt_version=master,qa_vagrant_version=2.0.1,distro=centos-6/)|[![Build Status](https://jenkins.infernix.net/job/vagrant-libvirt-qa/qa_vagrant_libvirt_version=master,qa_vagrant_version=2.0.1,distro=centos-7/badge/icon)](https://jenkins.infernix.net/job/vagrant-libvirt-qa/qa_vagrant_libvirt_version=master,qa_vagrant_version=2.0.1,distro=centos-7/)|[![Build Status](https://jenkins.infernix.net/job/vagrant-libvirt-qa/qa_vagrant_libvirt_version=master,qa_vagrant_version=2.0.1,distro=fedora-21/badge/icon)](https://jenkins.infernix.net/job/vagrant-libvirt-qa/qa_vagrant_libvirt_version=master,qa_vagrant_version=2.0.1,distro=fedora-21/)|[![Build Status](https://jenkins.infernix.net/job/vagrant-libvirt-qa/qa_vagrant_libvirt_version=master,qa_vagrant_version=2.0.1,distro=fedora-22/badge/icon)](https://jenkins.infernix.net/job/vagrant-libvirt-qa/qa_vagrant_libvirt_version=master,qa_vagrant_version=2.0.1,distro=fedora-22/)|[![Build Status](https://jenkins.infernix.net/job/vagrant-libvirt-qa/qa_vagrant_libvirt_version=master,qa_vagrant_version=2.0.1,distro=fedora-23/badge/icon)](https://jenkins.infernix.net/job/vagrant-libvirt-qa/qa_vagrant_libvirt_version=master,qa_vagrant_version=2.0.1,distro=fedora-23/)|[![Build Status](https://jenkins.infernix.net/job/vagrant-libvirt-qa/qa_vagrant_libvirt_version=master,qa_vagrant_version=2.0.1,distro=fedora-24/badge/icon)](https://jenkins.infernix.net/job/vagrant-libvirt-qa/qa_vagrant_libvirt_version=master,qa_vagrant_version=2.0.1,distro=fedora-24/)|[![Build Status](https://jenkins.infernix.net/job/vagrant-libvirt-qa/qa_vagrant_libvirt_version=master,qa_vagrant_version=2.0.1,distro=arch/badge/icon)](https://jenkins.infernix.net/job/vagrant-libvirt-qa/qa_vagrant_libvirt_version=master,qa_vagrant_version=2.0.1,distro=arch/)|
|
22
|
-
|
23
14
|
## Index
|
24
15
|
|
25
16
|
|
@@ -45,15 +36,18 @@ In the table below, build passing means that specific version combination of Vag
|
|
45
36
|
- [CDROMs](#cdroms)
|
46
37
|
- [Input](#input)
|
47
38
|
- [PCI device passthrough](#pci-device-passthrough)
|
39
|
+
- [USB Controller Configuration](#usb-controller-configuration)
|
48
40
|
- [USB Redirector Devices](#usb-redirector-devices)
|
49
41
|
- [Random number generator passthrough](#random-number-generator-passthrough)
|
50
42
|
- [Watchdog·Device](#watchdog-device)
|
51
43
|
- [Smartcard device](#smartcard-device)
|
44
|
+
- [Hypervisor Features](#hypervisor-features)
|
52
45
|
- [CPU Features](#cpu-features)
|
53
46
|
- [No box and PXE boot](#no-box-and-pxe-boot)
|
54
47
|
- [SSH Access To VM](#ssh-access-to-vm)
|
55
48
|
- [Forwarded Ports](#forwarded-ports)
|
56
49
|
- [Synced Folders](#synced-folders)
|
50
|
+
- [QEMU Session Support](#qemu-session-support)
|
57
51
|
- [Customized Graphics](#customized-graphics)
|
58
52
|
- [Box Format](#box-format)
|
59
53
|
- [Create Box](#create-box)
|
@@ -841,6 +835,26 @@ Note! Above options affect configuration only at domain creation. It won't chang
|
|
841
835
|
|
842
836
|
Don't forget to [set](#domain-specific-options) `kvm_hidden` option to `true` especially if you are passthroughing NVIDIA GPUs. Otherwise GPU is visible from VM but cannot be operated.
|
843
837
|
|
838
|
+
|
839
|
+
## USB Controller Configuration
|
840
|
+
|
841
|
+
The USB controller can be configured using `libvirt.usb_controller`, with the following options:
|
842
|
+
|
843
|
+
* `model` - The USB controller device model to emulate. (mandatory)
|
844
|
+
* `ports` - The number of devices that can be connected to the controller.
|
845
|
+
|
846
|
+
See the [libvirt documentation](https://libvirt.org/formatdomain.html#elementsControllers) for a list of valid models.
|
847
|
+
|
848
|
+
```ruby
|
849
|
+
Vagrant.configure("2") do |config|
|
850
|
+
config.vm.provider :libvirt do |libvirt|
|
851
|
+
# Set up a USB3 controller
|
852
|
+
libvirt.usb_controller :model => "nec-xhci"
|
853
|
+
end
|
854
|
+
end
|
855
|
+
```
|
856
|
+
|
857
|
+
|
844
858
|
## USB Redirector Devices
|
845
859
|
You can specify multiple redirect devices via `libvirt.redirdev`. There are two types, `tcp` and `spicevmc` supported, for forwarding USB-devices to the guest. Available options are listed below.
|
846
860
|
|
@@ -954,7 +968,7 @@ Vagrant.configure("2") do |config|
|
|
954
968
|
end
|
955
969
|
end
|
956
970
|
```
|
957
|
-
## Features
|
971
|
+
## Hypervisor Features
|
958
972
|
|
959
973
|
Hypervisor features can be specified via `libvirt.features` as a list. The default
|
960
974
|
options that are enabled are `acpi`, `apic` and `pae`. If you define `libvirt.features`
|
@@ -982,6 +996,26 @@ Vagrant.configure("2") do |config|
|
|
982
996
|
end
|
983
997
|
```
|
984
998
|
|
999
|
+
You can also specify a special set of features that help improve the behavior of guests
|
1000
|
+
running Microsoft Windows.
|
1001
|
+
|
1002
|
+
You can specify HyperV features via `libvirt.hyperv_feature`. Available
|
1003
|
+
options are listed below. Note that both options are required:
|
1004
|
+
|
1005
|
+
* `name` - The name of the feature Hypervisor feature (see libvirt doc)
|
1006
|
+
* `state` - The state for this feature which can be either `on` or `off`.
|
1007
|
+
|
1008
|
+
```ruby
|
1009
|
+
Vagrant.configure("2") do |config|
|
1010
|
+
config.vm.provider :libvirt do |libvirt|
|
1011
|
+
# Relax constraints on timers
|
1012
|
+
libvirt.hyperv_feature :name => 'relaxed', :state => 'on'
|
1013
|
+
# Enable virtual APIC
|
1014
|
+
libvirt.hyperv_feature :name => 'vapic', :state => 'on'
|
1015
|
+
end
|
1016
|
+
end
|
1017
|
+
```
|
1018
|
+
|
985
1019
|
## CPU features
|
986
1020
|
|
987
1021
|
You can specify CPU feature policies via `libvirt.cpu_feature`. Available
|
@@ -1172,6 +1206,34 @@ Further documentation on using 9p can be found in [kernel docs](https://www.kern
|
|
1172
1206
|
**SECURITY NOTE:** for remote libvirt, nfs synced folders requires a bridged
|
1173
1207
|
public network interface and you must connect to libvirt via ssh.
|
1174
1208
|
|
1209
|
+
## QEMU Session Support
|
1210
|
+
|
1211
|
+
vagrant-libvirt supports using the QEMU session connection to maintain Vagrant VMs. As the session connection does not have root access to the system features which require root will not work. Access to networks created by the system QEMU connection can be granted by using the [QEMU bridge helper](https://wiki.qemu.org/Features/HelperNetworking). The bridge helper is enabled by default on some distros but may need to be enabled/installed on others.
|
1212
|
+
|
1213
|
+
An example configuration of a machine using the QEMU session connection:
|
1214
|
+
|
1215
|
+
```ruby
|
1216
|
+
Vagrant.configure("2") do |config|
|
1217
|
+
config.vm.provider :libvirt do |libvirt|
|
1218
|
+
# Use QEMU session instead of system connection
|
1219
|
+
libvirt.qemu_use_session = true
|
1220
|
+
# URI of QEMU session connection, default is as below
|
1221
|
+
libvirt.uri = 'qemu:///session'
|
1222
|
+
# URI of QEMU system connection, use to obtain IP address for management
|
1223
|
+
libvirt.system_uri = 'qemu:///system'
|
1224
|
+
# Path to store libvirt images for the virtual machine, default is as ~/.local/share/libvirt/images
|
1225
|
+
libvirt.storage_pool_path = '/home/user/.local/share/libvirt/images'
|
1226
|
+
# Management network device
|
1227
|
+
libvirt.management_network_device = 'virbr0'
|
1228
|
+
end
|
1229
|
+
|
1230
|
+
# Public network configuration using existing network device
|
1231
|
+
# Note: Private networks do not work with QEMU session enabled as root access is required to create new network devices
|
1232
|
+
config.vm.network :public_network, :dev => "virbr1",
|
1233
|
+
:mode => "bridge",
|
1234
|
+
:type => "bridge"
|
1235
|
+
end
|
1236
|
+
```
|
1175
1237
|
|
1176
1238
|
## Customized Graphics
|
1177
1239
|
|
@@ -36,11 +36,13 @@ module VagrantPlugins
|
|
36
36
|
@cpu_features = config.cpu_features
|
37
37
|
@cpu_topology = config.cpu_topology
|
38
38
|
@features = config.features
|
39
|
+
@features_hyperv = config.features_hyperv
|
39
40
|
@cpu_mode = config.cpu_mode
|
40
41
|
@cpu_model = config.cpu_model
|
41
42
|
@cpu_fallback = config.cpu_fallback
|
42
43
|
@numa_nodes = config.numa_nodes
|
43
44
|
@loader = config.loader
|
45
|
+
@nvram = config.nvram
|
44
46
|
@machine_type = config.machine_type
|
45
47
|
@machine_arch = config.machine_arch
|
46
48
|
@disk_bus = config.disk_bus
|
@@ -94,6 +96,9 @@ module VagrantPlugins
|
|
94
96
|
# Watchdog device
|
95
97
|
@watchdog_dev = config.watchdog_dev
|
96
98
|
|
99
|
+
# USB controller
|
100
|
+
@usbctl_dev = config.usbctl_dev
|
101
|
+
|
97
102
|
# USB device passthrough
|
98
103
|
@usbs = config.usbs
|
99
104
|
|
@@ -128,13 +133,15 @@ module VagrantPlugins
|
|
128
133
|
# If we have a box, take the path from the domain volume and set our storage_prefix.
|
129
134
|
# If not, we dump the storage pool xml to get its defined path.
|
130
135
|
# the default storage prefix is typically: /var/lib/libvirt/images/
|
131
|
-
if
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
136
|
+
if !config.qemu_use_session
|
137
|
+
if env[:machine].config.vm.box
|
138
|
+
storage_prefix = File.dirname(@domain_volume_path) + '/' # steal
|
139
|
+
else
|
140
|
+
storage_pool = env[:machine].provider.driver.connection.client.lookup_storage_pool_by_name(@storage_pool_name)
|
141
|
+
raise Errors::NoStoragePool if storage_pool.nil?
|
142
|
+
xml = Nokogiri::XML(storage_pool.xml_desc)
|
143
|
+
storage_prefix = xml.xpath('/pool/target/path').inner_text.to_s + '/'
|
144
|
+
end
|
138
145
|
end
|
139
146
|
|
140
147
|
@disks.each do |disk|
|
@@ -180,19 +187,22 @@ module VagrantPlugins
|
|
180
187
|
if not @cpu_topology.empty?
|
181
188
|
env[:ui].info(" -- CPU topology: sockets=#{@cpu_topology[:sockets]}, cores=#{@cpu_topology[:cores]}, threads=#{@cpu_topology[:threads]}")
|
182
189
|
end
|
183
|
-
env[:ui].info("")
|
184
190
|
@cpu_features.each do |cpu_feature|
|
185
191
|
env[:ui].info(" -- CPU Feature: name=#{cpu_feature[:name]}, policy=#{cpu_feature[:policy]}")
|
186
192
|
end
|
187
193
|
@features.each do |feature|
|
188
194
|
env[:ui].info(" -- Feature: #{feature}")
|
189
195
|
end
|
196
|
+
@features_hyperv.each do |feature|
|
197
|
+
env[:ui].info(" -- Feature (HyperV): name=#{feature[:name]}, state=#{feature[:state]}")
|
198
|
+
end
|
190
199
|
env[:ui].info(" -- Memory: #{@memory_size / 1024}M")
|
191
200
|
@memory_backing.each do |backing|
|
192
201
|
env[:ui].info(" -- Memory Backing: #{backing[:name]}: #{backing[:config].map { |k,v| "#{k}='#{v}'"}.join(' ')}")
|
193
202
|
end
|
194
203
|
env[:ui].info(" -- Management MAC: #{@management_network_mac}")
|
195
204
|
env[:ui].info(" -- Loader: #{@loader}")
|
205
|
+
env[:ui].info(" -- Nvram: #{@nvram}")
|
196
206
|
if env[:machine].config.vm.box
|
197
207
|
env[:ui].info(" -- Base box: #{env[:machine].box.name}")
|
198
208
|
end
|
@@ -256,6 +266,12 @@ module VagrantPlugins
|
|
256
266
|
env[:ui].info(" -- Watchdog device: model=#{@watchdog_dev[:model]}, action=#{@watchdog_dev[:action]}")
|
257
267
|
end
|
258
268
|
|
269
|
+
if not @usbctl_dev.empty?
|
270
|
+
msg = " -- USB controller: model=#{@usbctl_dev[:model]}"
|
271
|
+
msg += ", ports=#{@usbctl_dev[:ports]}" if @usbctl_dev[:ports]
|
272
|
+
env[:ui].info(msg)
|
273
|
+
end
|
274
|
+
|
259
275
|
@usbs.each do |usb|
|
260
276
|
usb_dev = []
|
261
277
|
usb_dev.push("bus=#{usb[:bus]}") if usb[:bus]
|
@@ -8,6 +8,7 @@ module VagrantPlugins
|
|
8
8
|
# image as new domain volume.
|
9
9
|
class CreateDomainVolume
|
10
10
|
include VagrantPlugins::ProviderLibvirt::Util::ErbTemplate
|
11
|
+
include VagrantPlugins::ProviderLibvirt::Util::StorageUtil
|
11
12
|
|
12
13
|
def initialize(app, _env)
|
13
14
|
@logger = Log4r::Logger.new('vagrant_libvirt::action::create_domain_volume')
|
@@ -48,8 +49,8 @@ module VagrantPlugins
|
|
48
49
|
xml.target do
|
49
50
|
xml.format(type: 'qcow2')
|
50
51
|
xml.permissions do
|
51
|
-
xml.owner
|
52
|
-
xml.group
|
52
|
+
xml.owner storage_uid(env)
|
53
|
+
xml.group storage_gid(env)
|
53
54
|
xml.mode '0600'
|
54
55
|
xml.label 'virt_image_t'
|
55
56
|
end
|
@@ -58,8 +59,8 @@ module VagrantPlugins
|
|
58
59
|
xml.path(@backing_file)
|
59
60
|
xml.format(type: 'qcow2')
|
60
61
|
xml.permissions do
|
61
|
-
xml.owner
|
62
|
-
xml.group
|
62
|
+
xml.owner storage_uid(env)
|
63
|
+
xml.group storage_gid(env)
|
63
64
|
xml.mode '0600'
|
64
65
|
xml.label 'virt_image_t'
|
65
66
|
end
|
@@ -80,6 +80,8 @@ module VagrantPlugins
|
|
80
80
|
@pci_bus = iface_configuration.fetch(:bus, nil)
|
81
81
|
@pci_slot = iface_configuration.fetch(:slot, nil)
|
82
82
|
template_name = 'interface'
|
83
|
+
@type = nil
|
84
|
+
@udp_tunnel = nil
|
83
85
|
# Configuration for public interfaces which use the macvtap driver
|
84
86
|
if iface_configuration[:iface_type] == :public_network
|
85
87
|
@device = iface_configuration.fetch(:dev, 'eth0')
|
@@ -27,6 +27,11 @@ module VagrantPlugins
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def call(env)
|
30
|
+
if env[:machine].provider_config.qemu_use_session
|
31
|
+
@app.call(env)
|
32
|
+
return
|
33
|
+
end
|
34
|
+
|
30
35
|
# only one vm at a time should try to set up networks
|
31
36
|
# otherwise they'll have inconsitent views of current state
|
32
37
|
# and conduct redundant operations that cause errors
|
@@ -13,6 +13,11 @@ module VagrantPlugins
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def call(env)
|
16
|
+
if env[:machine].provider_config.qemu_use_session
|
17
|
+
@app.call(env)
|
18
|
+
return
|
19
|
+
end
|
20
|
+
|
16
21
|
# If there were some networks created for this machine, in machines
|
17
22
|
# data directory, created_networks file holds UUIDs of each network.
|
18
23
|
created_networks_file = env[:machine].data_dir + 'created_networks'
|
@@ -4,6 +4,10 @@ module VagrantPlugins
|
|
4
4
|
module ProviderLibvirt
|
5
5
|
module Action
|
6
6
|
class HandleBoxImage
|
7
|
+
include VagrantPlugins::ProviderLibvirt::Util::ErbTemplate
|
8
|
+
include VagrantPlugins::ProviderLibvirt::Util::StorageUtil
|
9
|
+
|
10
|
+
|
7
11
|
@@lock = Mutex.new
|
8
12
|
|
9
13
|
def initialize(app, _env)
|
@@ -31,11 +35,12 @@ module VagrantPlugins
|
|
31
35
|
config = env[:machine].provider_config
|
32
36
|
box_image_file = env[:machine].box.directory.join('box.img').to_s
|
33
37
|
env[:box_volume_name] = env[:machine].box.name.to_s.dup.gsub('/', '-VAGRANTSLASH-')
|
34
|
-
env[:box_volume_name] << "_vagrant_box_image_#{
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
38
|
+
env[:box_volume_name] << "_vagrant_box_image_#{
|
39
|
+
begin
|
40
|
+
env[:machine].box.version.to_s
|
41
|
+
rescue
|
42
|
+
''
|
43
|
+
end}.img"
|
39
44
|
|
40
45
|
# Override box_virtual_size
|
41
46
|
if config.machine_virtual_size
|
@@ -44,7 +49,7 @@ module VagrantPlugins
|
|
44
49
|
# is not supported and will be ignored
|
45
50
|
env[:ui].warn I18n.t(
|
46
51
|
'vagrant_libvirt.warnings.ignoring_virtual_size_too_small',
|
47
|
-
|
52
|
+
requested: config.machine_virtual_size, minimum: box_virtual_size
|
48
53
|
)
|
49
54
|
else
|
50
55
|
env[:ui].info I18n.t('vagrant_libvirt.manual_resize_required')
|
@@ -75,17 +80,41 @@ module VagrantPlugins
|
|
75
80
|
message = "Creating volume #{env[:box_volume_name]}"
|
76
81
|
message << " in storage pool #{config.storage_pool_name}."
|
77
82
|
@logger.info(message)
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
83
|
+
|
84
|
+
if config.qemu_use_session
|
85
|
+
begin
|
86
|
+
@name = env[:box_volume_name]
|
87
|
+
@allocation = "#{box_image_size / 1024 / 1024}M"
|
88
|
+
@capacity = "#{box_virtual_size}G"
|
89
|
+
@format_type = box_format ? box_format : 'raw'
|
90
|
+
|
91
|
+
@storage_volume_uid = storage_uid env
|
92
|
+
@storage_volume_gid = storage_gid env
|
93
|
+
|
94
|
+
libvirt_client = env[:machine].provider.driver.connection.client
|
95
|
+
libvirt_pool = libvirt_client.lookup_storage_pool_by_name(
|
96
|
+
config.storage_pool_name
|
97
|
+
)
|
98
|
+
libvirt_volume = libvirt_pool.create_volume_xml(
|
99
|
+
to_xml('default_storage_volume')
|
100
|
+
)
|
101
|
+
rescue => e
|
102
|
+
raise Errors::CreatingVolumeError,
|
103
|
+
error_message: e.message
|
104
|
+
end
|
105
|
+
else
|
106
|
+
begin
|
107
|
+
fog_volume = env[:machine].provider.driver.connection.volumes.create(
|
108
|
+
name: env[:box_volume_name],
|
109
|
+
allocation: "#{box_image_size / 1024 / 1024}M",
|
110
|
+
capacity: "#{box_virtual_size}G",
|
111
|
+
format_type: box_format,
|
112
|
+
pool_name: config.storage_pool_name
|
113
|
+
)
|
114
|
+
rescue Fog::Errors::Error => e
|
115
|
+
raise Errors::FogCreateVolumeError,
|
116
|
+
error_message: e.message
|
117
|
+
end
|
89
118
|
end
|
90
119
|
|
91
120
|
# Upload box image to storage pool
|
@@ -103,7 +132,11 @@ module VagrantPlugins
|
|
103
132
|
# storage pool.
|
104
133
|
if env[:interrupted] || !ret
|
105
134
|
begin
|
106
|
-
|
135
|
+
if config.qemu_use_session
|
136
|
+
libvirt_volume.delete
|
137
|
+
else
|
138
|
+
fog_volume.destroy
|
139
|
+
end
|
107
140
|
rescue
|
108
141
|
nil
|
109
142
|
end
|
@@ -113,6 +146,19 @@ module VagrantPlugins
|
|
113
146
|
@app.call(env)
|
114
147
|
end
|
115
148
|
|
149
|
+
def split_size_unit(text)
|
150
|
+
if text.kind_of? Integer
|
151
|
+
# if text is an integer, match will fail
|
152
|
+
size = text
|
153
|
+
unit = 'G'
|
154
|
+
else
|
155
|
+
matcher = text.match(/(\d+)(.+)/)
|
156
|
+
size = matcher[1]
|
157
|
+
unit = matcher[2]
|
158
|
+
end
|
159
|
+
[size, unit]
|
160
|
+
end
|
161
|
+
|
116
162
|
protected
|
117
163
|
|
118
164
|
# Fog libvirt currently doesn't support uploading images to storage
|
@@ -5,6 +5,8 @@ module VagrantPlugins
|
|
5
5
|
module Action
|
6
6
|
class HandleStoragePool
|
7
7
|
include VagrantPlugins::ProviderLibvirt::Util::ErbTemplate
|
8
|
+
include VagrantPlugins::ProviderLibvirt::Util::StorageUtil
|
9
|
+
|
8
10
|
|
9
11
|
@@lock = Mutex.new
|
10
12
|
|
@@ -37,6 +39,9 @@ module VagrantPlugins
|
|
37
39
|
# Fog libvirt currently doesn't support creating pools. Use
|
38
40
|
# ruby-libvirt client directly.
|
39
41
|
begin
|
42
|
+
@storage_pool_path = storage_pool_path(env)
|
43
|
+
@storage_pool_uid = storage_uid(env)
|
44
|
+
@storage_pool_gid = storage_gid(env)
|
40
45
|
libvirt_pool = env[:machine].provider.driver.connection.client.define_storage_pool_xml(
|
41
46
|
to_xml('default_storage_pool')
|
42
47
|
)
|
@@ -31,22 +31,39 @@ module VagrantPlugins
|
|
31
31
|
# from arp table, either localy or remotely via ssh, if libvirt
|
32
32
|
# connection was done via ssh.
|
33
33
|
env[:ip_address] = nil
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
34
|
+
@logger.debug("Searching for IP for MAC address: #{domain.mac}")
|
35
|
+
env[:ui].info(I18n.t('vagrant_libvirt.waiting_for_ip'))
|
36
|
+
|
37
|
+
if env[:machine].provider_config.qemu_use_session
|
38
|
+
env[:metrics]['instance_ip_time'] = Util::Timer.time do
|
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
42
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
env[:ip_address]
|
43
|
+
# Wait for domain to obtain an ip address
|
44
|
+
domain.wait_for(2) do
|
45
|
+
env[:ip_address] = env[:machine].provider.driver.get_ipaddress_system(domain.mac)
|
46
|
+
!env[:ip_address].nil?
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
else
|
51
|
+
env[:metrics]['instance_ip_time'] = Util::Timer.time do
|
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]
|
55
|
+
|
56
|
+
# Wait for domain to obtain an ip address
|
57
|
+
domain.wait_for(2) do
|
58
|
+
addresses.each_pair do |_type, ip|
|
59
|
+
env[:ip_address] = ip[0] unless ip[0].nil?
|
60
|
+
end
|
61
|
+
!env[:ip_address].nil?
|
45
62
|
end
|
46
|
-
!env[:ip_address].nil?
|
47
63
|
end
|
48
64
|
end
|
49
65
|
end
|
66
|
+
|
50
67
|
@logger.info("Got IP address #{env[:ip_address]}")
|
51
68
|
@logger.info("Time for getting IP: #{env[:metrics]['instance_ip_time']}")
|
52
69
|
|
@@ -40,11 +40,13 @@ module VagrantPlugins
|
|
40
40
|
# Libvirt storage pool name, where box image and instance snapshots will
|
41
41
|
# be stored.
|
42
42
|
attr_accessor :storage_pool_name
|
43
|
+
attr_accessor :storage_pool_path
|
43
44
|
|
44
45
|
# Turn on to prevent hostname conflicts
|
45
46
|
attr_accessor :random_hostname
|
46
47
|
|
47
48
|
# Libvirt default network
|
49
|
+
attr_accessor :management_network_device
|
48
50
|
attr_accessor :management_network_name
|
49
51
|
attr_accessor :management_network_address
|
50
52
|
attr_accessor :management_network_mode
|
@@ -54,6 +56,9 @@ module VagrantPlugins
|
|
54
56
|
attr_accessor :management_network_pci_bus
|
55
57
|
attr_accessor :management_network_pci_slot
|
56
58
|
|
59
|
+
# System connection information
|
60
|
+
attr_accessor :system_uri
|
61
|
+
|
57
62
|
# Default host prefix (alternative to use project folder name)
|
58
63
|
attr_accessor :default_prefix
|
59
64
|
|
@@ -69,8 +74,10 @@ module VagrantPlugins
|
|
69
74
|
attr_accessor :cpu_features
|
70
75
|
attr_accessor :cpu_topology
|
71
76
|
attr_accessor :features
|
77
|
+
attr_accessor :features_hyperv
|
72
78
|
attr_accessor :numa_nodes
|
73
79
|
attr_accessor :loader
|
80
|
+
attr_accessor :nvram
|
74
81
|
attr_accessor :boot_order
|
75
82
|
attr_accessor :machine_type
|
76
83
|
attr_accessor :machine_arch
|
@@ -126,6 +133,9 @@ module VagrantPlugins
|
|
126
133
|
# Watchdog device
|
127
134
|
attr_accessor :watchdog_dev
|
128
135
|
|
136
|
+
# USB controller
|
137
|
+
attr_accessor :usbctl_dev
|
138
|
+
|
129
139
|
# USB device passthrough
|
130
140
|
attr_accessor :usbs
|
131
141
|
|
@@ -148,6 +158,9 @@ module VagrantPlugins
|
|
148
158
|
# Additional qemuargs arguments
|
149
159
|
attr_accessor :qemu_args
|
150
160
|
|
161
|
+
# Use qemu session instead of system
|
162
|
+
attr_accessor :qemu_use_session
|
163
|
+
|
151
164
|
def initialize
|
152
165
|
@uri = UNSET_VALUE
|
153
166
|
@driver = UNSET_VALUE
|
@@ -158,6 +171,7 @@ module VagrantPlugins
|
|
158
171
|
@id_ssh_key_file = UNSET_VALUE
|
159
172
|
@storage_pool_name = UNSET_VALUE
|
160
173
|
@random_hostname = UNSET_VALUE
|
174
|
+
@management_network_device = UNSET_VALUE
|
161
175
|
@management_network_name = UNSET_VALUE
|
162
176
|
@management_network_address = UNSET_VALUE
|
163
177
|
@management_network_mode = UNSET_VALUE
|
@@ -167,6 +181,9 @@ module VagrantPlugins
|
|
167
181
|
@management_network_pci_slot = UNSET_VALUE
|
168
182
|
@management_network_pci_bus = UNSET_VALUE
|
169
183
|
|
184
|
+
# System connection information
|
185
|
+
@system_uri = UNSET_VALUE
|
186
|
+
|
170
187
|
# Domain specific settings.
|
171
188
|
@uuid = UNSET_VALUE
|
172
189
|
@memory = UNSET_VALUE
|
@@ -178,8 +195,10 @@ module VagrantPlugins
|
|
178
195
|
@cpu_features = UNSET_VALUE
|
179
196
|
@cpu_topology = UNSET_VALUE
|
180
197
|
@features = UNSET_VALUE
|
198
|
+
@features_hyperv = UNSET_VALUE
|
181
199
|
@numa_nodes = UNSET_VALUE
|
182
200
|
@loader = UNSET_VALUE
|
201
|
+
@nvram = UNSET_VALUE
|
183
202
|
@machine_type = UNSET_VALUE
|
184
203
|
@machine_arch = UNSET_VALUE
|
185
204
|
@machine_virtual_size = UNSET_VALUE
|
@@ -231,6 +250,9 @@ module VagrantPlugins
|
|
231
250
|
# Watchdog device
|
232
251
|
@watchdog_dev = UNSET_VALUE
|
233
252
|
|
253
|
+
# USB controller
|
254
|
+
@usbctl_dev = UNSET_VALUE
|
255
|
+
|
234
256
|
# USB device passthrough
|
235
257
|
@usbs = UNSET_VALUE
|
236
258
|
|
@@ -251,6 +273,7 @@ module VagrantPlugins
|
|
251
273
|
@mgmt_attach = UNSET_VALUE
|
252
274
|
|
253
275
|
@qemu_args = []
|
276
|
+
@qemu_use_session = UNSET_VALUE
|
254
277
|
end
|
255
278
|
|
256
279
|
def boot(device)
|
@@ -321,6 +344,14 @@ module VagrantPlugins
|
|
321
344
|
policy: options[:policy])
|
322
345
|
end
|
323
346
|
|
347
|
+
def hyperv_feature(options = {})
|
348
|
+
if options[:name].nil? || options[:state].nil?
|
349
|
+
raise 'Feature name AND state must be specified'
|
350
|
+
end
|
351
|
+
|
352
|
+
@features_hyperv = [{name: options[:name], state: options[:state]}] if @features_hyperv == UNSET_VALUE
|
353
|
+
end
|
354
|
+
|
324
355
|
def cputopology(options = {})
|
325
356
|
if options[:sockets].nil? || options[:cores].nil? || options[:threads].nil?
|
326
357
|
raise 'CPU topology must have all of sockets, cores and threads specified'
|
@@ -332,7 +363,7 @@ module VagrantPlugins
|
|
332
363
|
|
333
364
|
@cpu_topology[:sockets] = options[:sockets]
|
334
365
|
@cpu_topology[:cores] = options[:cores]
|
335
|
-
@cpu_topology[:threads] = options[:threads]
|
366
|
+
@cpu_topology[:threads] = options[:threads]
|
336
367
|
end
|
337
368
|
|
338
369
|
def memorybacking(option, config = {})
|
@@ -419,6 +450,19 @@ module VagrantPlugins
|
|
419
450
|
end
|
420
451
|
|
421
452
|
|
453
|
+
def usb_controller(options = {})
|
454
|
+
if options[:model].nil?
|
455
|
+
raise 'USB controller model must be specified.'
|
456
|
+
end
|
457
|
+
|
458
|
+
if @usbctl_dev == UNSET_VALUE
|
459
|
+
@usbctl_dev = {}
|
460
|
+
end
|
461
|
+
|
462
|
+
@usbctl_dev[:model] = options[:model]
|
463
|
+
@usbctl_dev[:ports] = options[:ports]
|
464
|
+
end
|
465
|
+
|
422
466
|
def usb(options = {})
|
423
467
|
if (options[:bus].nil? || options[:device].nil?) && options[:vendor].nil? && options[:product].nil?
|
424
468
|
raise 'Bus and device and/or vendor and/or product must be specified. Check `lsusb` for these.'
|
@@ -447,9 +491,9 @@ module VagrantPlugins
|
|
447
491
|
@redirfilters = [] if @redirfilters == UNSET_VALUE
|
448
492
|
|
449
493
|
@redirfilters.push(class: options[:class] || -1,
|
450
|
-
vendor: options[:
|
451
|
-
product: options[:
|
452
|
-
version: options[:
|
494
|
+
vendor: options[:vendor] || -1,
|
495
|
+
product: options[:product] || -1,
|
496
|
+
version: options[:version] || -1,
|
453
497
|
allow: options[:allow])
|
454
498
|
end
|
455
499
|
|
@@ -542,7 +586,9 @@ module VagrantPlugins
|
|
542
586
|
# Setup connection uri.
|
543
587
|
uri = @driver.dup
|
544
588
|
virt_path = case uri
|
545
|
-
when 'qemu', '
|
589
|
+
when 'qemu', 'kvm'
|
590
|
+
@qemu_use_session ? '/session' : '/system'
|
591
|
+
when 'openvz', 'uml', 'phyp', 'parallels'
|
546
592
|
'/system'
|
547
593
|
when '@en', 'esx'
|
548
594
|
'/'
|
@@ -592,7 +638,9 @@ module VagrantPlugins
|
|
592
638
|
@password = nil if @password == UNSET_VALUE
|
593
639
|
@id_ssh_key_file = 'id_rsa' if @id_ssh_key_file == UNSET_VALUE
|
594
640
|
@storage_pool_name = 'default' if @storage_pool_name == UNSET_VALUE
|
641
|
+
@storage_pool_path = nil if @storage_pool_path == UNSET_VALUE
|
595
642
|
@random_hostname = false if @random_hostname == UNSET_VALUE
|
643
|
+
@management_network_device = 'virbr0' if @management_network_device == UNSET_VALUE
|
596
644
|
@management_network_name = 'vagrant-libvirt' if @management_network_name == UNSET_VALUE
|
597
645
|
@management_network_address = '192.168.121.0/24' if @management_network_address == UNSET_VALUE
|
598
646
|
@management_network_mode = 'nat' if @management_network_mode == UNSET_VALUE
|
@@ -601,6 +649,9 @@ module VagrantPlugins
|
|
601
649
|
@management_network_autostart = false if @management_network_autostart == UNSET_VALUE
|
602
650
|
@management_network_pci_bus = nil if @management_network_pci_bus == UNSET_VALUE
|
603
651
|
@management_network_pci_slot = nil if @management_network_pci_slot == UNSET_VALUE
|
652
|
+
@system_uri = 'qemu:///system' if @system_uri == UNSET_VALUE
|
653
|
+
|
654
|
+
@qemu_use_session = false if @qemu_use_session == UNSET_VALUE
|
604
655
|
|
605
656
|
# generate a URI if none is supplied
|
606
657
|
@uri = _generate_uri if @uri == UNSET_VALUE
|
@@ -615,13 +666,17 @@ module VagrantPlugins
|
|
615
666
|
'qemu64'
|
616
667
|
elsif @cpu_mode != 'custom'
|
617
668
|
''
|
669
|
+
else
|
670
|
+
@cpu_model
|
618
671
|
end
|
619
672
|
@cpu_topology = {} if @cpu_topology == UNSET_VALUE
|
620
673
|
@cpu_fallback = 'allow' if @cpu_fallback == UNSET_VALUE
|
621
674
|
@cpu_features = [] if @cpu_features == UNSET_VALUE
|
622
675
|
@features = ['acpi','apic','pae'] if @features == UNSET_VALUE
|
676
|
+
@features_hyperv = [] if @features_hyperv == UNSET_VALUE
|
623
677
|
@numa_nodes = @numa_nodes == UNSET_VALUE ? nil : _generate_numa
|
624
678
|
@loader = nil if @loader == UNSET_VALUE
|
679
|
+
@nvram = nil if @nvram == UNSET_VALUE
|
625
680
|
@machine_type = nil if @machine_type == UNSET_VALUE
|
626
681
|
@machine_arch = nil if @machine_arch == UNSET_VALUE
|
627
682
|
@machine_virtual_size = nil if @machine_virtual_size == UNSET_VALUE
|
@@ -684,6 +739,9 @@ module VagrantPlugins
|
|
684
739
|
# Watchdog device
|
685
740
|
@watchdog_dev = {} if @watchdog_dev == UNSET_VALUE
|
686
741
|
|
742
|
+
# USB controller
|
743
|
+
@usbctl_dev = {} if @usbctl_dev == UNSET_VALUE
|
744
|
+
|
687
745
|
# USB device passthrough
|
688
746
|
@usbs = [] if @usbs == UNSET_VALUE
|
689
747
|
|
@@ -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')
|
@@ -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
|
@@ -29,6 +29,10 @@ module VagrantPlugins
|
|
29
29
|
error_key(:creating_storage_pool_error)
|
30
30
|
end
|
31
31
|
|
32
|
+
class CreatingVolumeError < VagrantLibvirtError
|
33
|
+
error_key(:creating_volume_error)
|
34
|
+
end
|
35
|
+
|
32
36
|
class ImageUploadError < VagrantLibvirtError
|
33
37
|
error_key(:image_upload_error)
|
34
38
|
end
|
@@ -3,11 +3,11 @@
|
|
3
3
|
<source>
|
4
4
|
</source>
|
5
5
|
<target>
|
6
|
-
<path
|
6
|
+
<path><%= @storage_pool_path %></path>
|
7
7
|
<permissions>
|
8
8
|
<mode>0755</mode>
|
9
|
-
<owner
|
10
|
-
<group
|
9
|
+
<owner><%= @storage_pool_uid %></owner>
|
10
|
+
<group><%= @storage_pool_gid %></group>
|
11
11
|
</permissions>
|
12
12
|
</target>
|
13
13
|
</pool>
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<volume>
|
2
|
+
<name><%= @name %></name>
|
3
|
+
<allocation unit="<%= split_size_unit(@allocation)[1] %>"><%= split_size_unit(@allocation)[0] %></allocation>
|
4
|
+
<capacity unit="<%= split_size_unit(@capacity)[1] %>"><%= split_size_unit(@capacity)[0] %></capacity>
|
5
|
+
<target>
|
6
|
+
<format type="<%= @format_type %>"/>
|
7
|
+
<permissions>
|
8
|
+
<owner><%= @storage_volume_uid %></owner>
|
9
|
+
<group><%= @storage_volume_gid %></group>
|
10
|
+
<mode>0744</mode>
|
11
|
+
<label>virt_image_t</label>
|
12
|
+
</permissions>
|
13
|
+
</target>
|
14
|
+
</volume>
|
@@ -9,8 +9,12 @@
|
|
9
9
|
<% if @cpu_mode != 'host-passthrough' %>
|
10
10
|
<model fallback='<%= @cpu_fallback %>'><% if @cpu_mode == 'custom' %><%= @cpu_model %><% end %></model>
|
11
11
|
<% if @nested %>
|
12
|
-
|
13
|
-
|
12
|
+
<% if @cpu_features.select{|x| x[:name] == 'vmx'}.empty? %>
|
13
|
+
<feature policy='optional' name='vmx'/>
|
14
|
+
<% end %>
|
15
|
+
<% if @cpu_features.select{|x| x[:name] == 'svm'}.empty? %>
|
16
|
+
<feature policy='optional' name='svm'/>
|
17
|
+
<% end %>
|
14
18
|
<% end %>
|
15
19
|
<% @cpu_features.each do |cpu_feature| %>
|
16
20
|
<feature name='<%= cpu_feature[:name] %>' policy='<%= cpu_feature[:policy] %>'/>
|
@@ -52,7 +56,14 @@
|
|
52
56
|
<% end %>
|
53
57
|
<% end %>
|
54
58
|
<% if @loader %>
|
55
|
-
|
59
|
+
<% if @nvram %>
|
60
|
+
<loader readonly='yes' type='pflash'><%= @loader %></loader>
|
61
|
+
<% else %>
|
62
|
+
<loader readonly='yes' type='rom'><%= @loader %></loader>
|
63
|
+
<% end %>
|
64
|
+
<% end %>
|
65
|
+
<% if @nvram %>
|
66
|
+
<nvram><%= @nvram %></nvram>
|
56
67
|
<% end %>
|
57
68
|
<% if @boot_order.count >= 1 %>
|
58
69
|
<bootmenu enable='yes'/>
|
@@ -73,6 +84,13 @@
|
|
73
84
|
<hidden state='on'/>
|
74
85
|
</kvm>
|
75
86
|
<% end %>
|
87
|
+
<% if !@features_hyperv.empty? %>
|
88
|
+
<hyperv>
|
89
|
+
<% @features_hyperv.each do |feature| %>
|
90
|
+
<<%= feature[:name] %> state='<%= feature[:state] %>' />
|
91
|
+
<% end %>
|
92
|
+
</hyperv>
|
93
|
+
<% end %>
|
76
94
|
</features>
|
77
95
|
<clock offset='utc'/>
|
78
96
|
<devices>
|
@@ -232,6 +250,10 @@
|
|
232
250
|
</backend>
|
233
251
|
</tpm>
|
234
252
|
<% end -%>
|
253
|
+
<% if not @usbctl_dev.empty? %>
|
254
|
+
<%# USB Controller -%>
|
255
|
+
<controller type='usb' model='<%= @usbctl_dev[:model] %>' <%= "ports=\"#{@usbctl_dev[:ports]}\" " if @usbctl_dev[:ports] %>/>
|
256
|
+
<% end %>
|
235
257
|
</devices>
|
236
258
|
|
237
259
|
<% unless @qargs.empty? %>
|
data/lib/vagrant-libvirt/util.rb
CHANGED
@@ -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
|
@@ -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
|
@@ -33,18 +35,31 @@ module VagrantPlugins
|
|
33
35
|
error_message: "#{management_network_address} does not include both an address and subnet mask"
|
34
36
|
end
|
35
37
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
38
|
+
if qemu_use_session
|
39
|
+
management_network_options = {
|
40
|
+
iface_type: :public_network,
|
41
|
+
dev: management_network_device,
|
42
|
+
mode: 'bridge',
|
43
|
+
type: 'bridge',
|
44
|
+
bus: management_network_pci_bus,
|
45
|
+
slot: management_network_pci_slot
|
46
|
+
}
|
47
|
+
else
|
48
|
+
management_network_options = {
|
49
|
+
iface_type: :private_network,
|
50
|
+
network_name: management_network_name,
|
51
|
+
ip: Regexp.last_match(1),
|
52
|
+
netmask: Regexp.last_match(2),
|
53
|
+
dhcp_enabled: true,
|
54
|
+
forward_mode: management_network_mode,
|
55
|
+
guest_ipv6: management_network_guest_ipv6,
|
56
|
+
autostart: management_network_autostart,
|
57
|
+
bus: management_network_pci_bus,
|
58
|
+
slot: management_network_pci_slot
|
59
|
+
}
|
60
|
+
end
|
61
|
+
|
62
|
+
|
48
63
|
|
49
64
|
unless management_network_mac.nil?
|
50
65
|
management_network_options[:mac] = management_network_mac
|
@@ -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
|
+
|
data/locales/en.yml
CHANGED
@@ -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: |-
|
@@ -107,6 +109,8 @@ en:
|
|
107
109
|
`vagrant up` command again.
|
108
110
|
creating_storage_pool_error: |-
|
109
111
|
There was error while creating libvirt storage pool: %{error_message}
|
112
|
+
creating_volume_error: |-
|
113
|
+
There was error while creating libvirt volume: %{error_message}
|
110
114
|
image_upload_error: |-
|
111
115
|
Error while uploading image to storage pool: %{error_message}
|
112
116
|
no_domain_error: |-
|
@@ -18,7 +18,7 @@ class EnvironmentHelper
|
|
18
18
|
1024
|
19
19
|
end
|
20
20
|
|
21
|
-
%w(cpus cpu_mode loader boot_order machine_type disk_bus disk_device nested volume_cache kernel cmd_line initrd graphics_type graphics_autoport graphics_port graphics_ip graphics_passwd video_type video_vram keymap storage_pool_name disks cdroms driver).each do |name|
|
21
|
+
%w(cpus cpu_mode loader nvram boot_order machine_type disk_bus disk_device nested volume_cache kernel cmd_line initrd graphics_type graphics_autoport graphics_port graphics_ip graphics_passwd video_type video_vram keymap storage_pool_name disks cdroms driver).each do |name|
|
22
22
|
define_method(name.to_sym) do
|
23
23
|
nil
|
24
24
|
end
|
@@ -14,7 +14,7 @@
|
|
14
14
|
|
15
15
|
<os>
|
16
16
|
<type arch='x86_64' machine='pc-compatible'>hvm</type>
|
17
|
-
|
17
|
+
<loader readonly='yes' type='rom'>/efi/loader</loader>
|
18
18
|
<bootmenu enable='yes'/>
|
19
19
|
<kernel></kernel>
|
20
20
|
<initrd></initrd>
|
@@ -24,6 +24,9 @@
|
|
24
24
|
<acpi/>
|
25
25
|
<apic/>
|
26
26
|
<pae/>
|
27
|
+
<hyperv>
|
28
|
+
<BBB state='on' />
|
29
|
+
</hyperv>
|
27
30
|
</features>
|
28
31
|
<clock offset='utc'/>
|
29
32
|
<devices>
|
@@ -117,7 +120,7 @@
|
|
117
120
|
<redirdev bus='usb' type='tcp'>
|
118
121
|
</redirdev>
|
119
122
|
<redirfilter>
|
120
|
-
<usbdev class='0x0b' vendor='
|
123
|
+
<usbdev class='0x0b' vendor='0x08e6' product='0x3437' version='2.00' allow='yes'/>
|
121
124
|
</redirfilter>
|
122
125
|
<watchdog model='i6300esb' action='reset'/>
|
123
126
|
|
@@ -128,6 +131,7 @@
|
|
128
131
|
<device path='/dev/tpm0'/>
|
129
132
|
</backend>
|
130
133
|
</tpm>
|
134
|
+
<controller type='usb' model='nec-xhci' ports="4" />
|
131
135
|
</devices>
|
132
136
|
|
133
137
|
<qemu:commandline>
|
@@ -0,0 +1,46 @@
|
|
1
|
+
<domain type='' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
|
2
|
+
<name></name>
|
3
|
+
<uuid></uuid>
|
4
|
+
<memory></memory>
|
5
|
+
<vcpu>1</vcpu>
|
6
|
+
|
7
|
+
|
8
|
+
<cpu mode='custom'>
|
9
|
+
<model fallback='allow'>SandyBridge</model>
|
10
|
+
</cpu>
|
11
|
+
|
12
|
+
|
13
|
+
<os>
|
14
|
+
<type>hvm</type>
|
15
|
+
<kernel></kernel>
|
16
|
+
<initrd></initrd>
|
17
|
+
<cmdline></cmdline>
|
18
|
+
</os>
|
19
|
+
<features>
|
20
|
+
<acpi/>
|
21
|
+
<apic/>
|
22
|
+
<pae/>
|
23
|
+
</features>
|
24
|
+
<clock offset='utc'/>
|
25
|
+
<devices>
|
26
|
+
|
27
|
+
|
28
|
+
<serial type='pty'>
|
29
|
+
<target port='0'/>
|
30
|
+
</serial>
|
31
|
+
<console type='pty'>
|
32
|
+
<target port='0'/>
|
33
|
+
</console>
|
34
|
+
|
35
|
+
|
36
|
+
<input type='mouse' bus='ps2'/>
|
37
|
+
|
38
|
+
<graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' keymap='en-us' />
|
39
|
+
<video>
|
40
|
+
<model type='cirrus' vram='9216' heads='1'/>
|
41
|
+
</video>
|
42
|
+
|
43
|
+
|
44
|
+
</devices>
|
45
|
+
|
46
|
+
</domain>
|
@@ -31,6 +31,7 @@ describe 'templates/domain' do
|
|
31
31
|
domain.instance_variable_set('@domain_type', 'kvm')
|
32
32
|
domain.cpu_mode = 'custom'
|
33
33
|
domain.cpu_feature(name: 'AAA', policy: 'required')
|
34
|
+
domain.hyperv_feature(name: 'BBB', state: 'on')
|
34
35
|
domain.cputopology(sockets: '1', cores: '3', threads: '2')
|
35
36
|
domain.machine_type = 'pc-compatible'
|
36
37
|
domain.machine_arch = 'x86_64'
|
@@ -64,6 +65,7 @@ describe 'templates/domain' do
|
|
64
65
|
domain.random(model: 'random')
|
65
66
|
domain.pci(bus: '0x06', slot: '0x12', function: '0x5')
|
66
67
|
domain.pci(bus: '0x03', slot: '0x00', function: '0x0')
|
68
|
+
domain.usb_controller(model: 'nec-xhci', ports: '4')
|
67
69
|
domain.usb(bus: '1', device: '2', vendor: '0x1234', product: '0xabcd')
|
68
70
|
domain.redirdev(type: 'tcp', host: 'localhost', port: '4000')
|
69
71
|
domain.redirfilter(class: '0x0b', vendor: '0x08e6',
|
@@ -81,4 +83,16 @@ describe 'templates/domain' do
|
|
81
83
|
expect(domain.to_xml('domain')).to eq xml_expected
|
82
84
|
end
|
83
85
|
end
|
86
|
+
|
87
|
+
context 'when custom cpu model enabled' do
|
88
|
+
before do
|
89
|
+
domain.cpu_mode = 'custom'
|
90
|
+
domain.cpu_model = 'SandyBridge'
|
91
|
+
end
|
92
|
+
let(:test_file) { 'domain_custom_cpu_model.xml' }
|
93
|
+
it 'renders template' do
|
94
|
+
domain.finalize!
|
95
|
+
expect(domain.to_xml('domain')).to eq xml_expected
|
96
|
+
end
|
97
|
+
end
|
84
98
|
end
|
data/vagrant-libvirt.gemspec
CHANGED
@@ -1,18 +1,15 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
# stub: vagrant-libvirt 0.0.
|
3
|
-
require File.expand_path('../lib/vagrant-libvirt/version', __FILE__)
|
2
|
+
# stub: vagrant-libvirt 0.0.42 ruby lib
|
4
3
|
|
5
4
|
Gem::Specification.new do |s|
|
6
5
|
s.name = "vagrant-libvirt".freeze
|
7
|
-
s.version =
|
6
|
+
s.version = "0.0.45"
|
8
7
|
|
9
8
|
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
10
9
|
s.require_paths = ["lib".freeze]
|
11
10
|
s.authors = ["Lukas Stanek".freeze, "Dima Vasilets".freeze, "Brian Pitts".freeze]
|
12
11
|
s.files = `git ls-files`.split($\)
|
13
12
|
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
14
|
-
|
15
|
-
s.date = "2018-02-02"
|
16
13
|
s.description = "libvirt provider for Vagrant.".freeze
|
17
14
|
s.email = ["ls@elostech.cz".freeze, "pronix.service@gmail.com".freeze, "brian@polibyte.com".freeze]
|
18
15
|
s.homepage = "https://github.com/vagrant-libvirt/vagrant-libvirt".freeze
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vagrant-libvirt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.45
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lukas Stanek
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2018-
|
13
|
+
date: 2018-10-23 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rspec-core
|
@@ -173,6 +173,7 @@ files:
|
|
173
173
|
- lib/vagrant-libvirt/plugin.rb
|
174
174
|
- lib/vagrant-libvirt/provider.rb
|
175
175
|
- lib/vagrant-libvirt/templates/default_storage_pool.xml.erb
|
176
|
+
- lib/vagrant-libvirt/templates/default_storage_volume.xml.erb
|
176
177
|
- lib/vagrant-libvirt/templates/domain.xml.erb
|
177
178
|
- lib/vagrant-libvirt/templates/private_network.xml.erb
|
178
179
|
- lib/vagrant-libvirt/templates/public_interface.xml.erb
|
@@ -181,6 +182,7 @@ files:
|
|
181
182
|
- lib/vagrant-libvirt/util/erb_template.rb
|
182
183
|
- lib/vagrant-libvirt/util/error_codes.rb
|
183
184
|
- lib/vagrant-libvirt/util/network_util.rb
|
185
|
+
- lib/vagrant-libvirt/util/storage_util.rb
|
184
186
|
- lib/vagrant-libvirt/util/timer.rb
|
185
187
|
- lib/vagrant-libvirt/version.rb
|
186
188
|
- locales/en.yml
|
@@ -193,6 +195,7 @@ files:
|
|
193
195
|
- spec/unit/action/wait_till_up_spec.rb
|
194
196
|
- spec/unit/config_spec.rb
|
195
197
|
- spec/unit/templates/domain_all_settings.xml
|
198
|
+
- spec/unit/templates/domain_custom_cpu_model.xml
|
196
199
|
- spec/unit/templates/domain_defaults.xml
|
197
200
|
- spec/unit/templates/domain_spec.rb
|
198
201
|
- tools/create_box.sh
|
@@ -218,7 +221,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
218
221
|
version: '0'
|
219
222
|
requirements: []
|
220
223
|
rubyforge_project:
|
221
|
-
rubygems_version: 2.6
|
224
|
+
rubygems_version: 2.7.6
|
222
225
|
signing_key:
|
223
226
|
specification_version: 4
|
224
227
|
summary: libvirt provider for Vagrant.
|
@@ -232,5 +235,6 @@ test_files:
|
|
232
235
|
- spec/unit/action/wait_till_up_spec.rb
|
233
236
|
- spec/unit/config_spec.rb
|
234
237
|
- spec/unit/templates/domain_all_settings.xml
|
238
|
+
- spec/unit/templates/domain_custom_cpu_model.xml
|
235
239
|
- spec/unit/templates/domain_defaults.xml
|
236
240
|
- spec/unit/templates/domain_spec.rb
|