vagrant-libvirt 0.3.0 → 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +421 -50
  3. data/lib/vagrant-libvirt/action.rb +7 -1
  4. data/lib/vagrant-libvirt/action/clean_machine_folder.rb +30 -0
  5. data/lib/vagrant-libvirt/action/create_domain.rb +56 -18
  6. data/lib/vagrant-libvirt/action/create_domain_volume.rb +57 -55
  7. data/lib/vagrant-libvirt/action/create_network_interfaces.rb +0 -3
  8. data/lib/vagrant-libvirt/action/create_networks.rb +11 -4
  9. data/lib/vagrant-libvirt/action/destroy_domain.rb +1 -1
  10. data/lib/vagrant-libvirt/action/forward_ports.rb +37 -38
  11. data/lib/vagrant-libvirt/action/halt_domain.rb +25 -9
  12. data/lib/vagrant-libvirt/action/handle_box_image.rb +163 -74
  13. data/lib/vagrant-libvirt/action/is_running.rb +1 -3
  14. data/lib/vagrant-libvirt/action/is_suspended.rb +4 -4
  15. data/lib/vagrant-libvirt/action/package_domain.rb +2 -1
  16. data/lib/vagrant-libvirt/action/set_boot_order.rb +6 -2
  17. data/lib/vagrant-libvirt/action/start_domain.rb +86 -29
  18. data/lib/vagrant-libvirt/action/wait_till_up.rb +8 -52
  19. data/lib/vagrant-libvirt/cap/{mount_p9.rb → mount_9p.rb} +2 -2
  20. data/lib/vagrant-libvirt/cap/mount_virtiofs.rb +37 -0
  21. data/lib/vagrant-libvirt/cap/{synced_folder.rb → synced_folder_9p.rb} +4 -5
  22. data/lib/vagrant-libvirt/cap/synced_folder_virtiofs.rb +109 -0
  23. data/lib/vagrant-libvirt/config.rb +236 -43
  24. data/lib/vagrant-libvirt/driver.rb +49 -32
  25. data/lib/vagrant-libvirt/errors.rb +24 -1
  26. data/lib/vagrant-libvirt/plugin.rb +14 -5
  27. data/lib/vagrant-libvirt/provider.rb +2 -9
  28. data/lib/vagrant-libvirt/templates/domain.xml.erb +35 -10
  29. data/lib/vagrant-libvirt/templates/private_network.xml.erb +1 -1
  30. data/lib/vagrant-libvirt/util/network_util.rb +21 -3
  31. data/lib/vagrant-libvirt/version +1 -1
  32. data/lib/vagrant-libvirt/version.rb +57 -9
  33. data/locales/en.yml +12 -0
  34. data/spec/spec_helper.rb +37 -3
  35. data/spec/support/binding_proc.rb +24 -0
  36. data/spec/support/libvirt_context.rb +2 -0
  37. data/spec/support/matchers/have_file_content.rb +63 -0
  38. data/spec/support/sharedcontext.rb +4 -0
  39. data/spec/unit/action/clean_machine_folder_spec.rb +58 -0
  40. data/spec/unit/action/create_domain_spec.rb +121 -36
  41. data/spec/unit/action/create_domain_spec/additional_disks_domain.xml +54 -0
  42. data/spec/unit/action/create_domain_spec/default_domain.xml +49 -0
  43. data/spec/unit/action/create_domain_spec/{default_storage_pool.xml → default_system_storage_pool.xml} +0 -0
  44. data/spec/unit/action/create_domain_spec/default_user_storage_pool.xml +17 -0
  45. data/spec/unit/action/create_domain_volume_spec.rb +102 -0
  46. data/spec/unit/action/create_domain_volume_spec/one_disk_in_storage.xml +21 -0
  47. data/spec/unit/action/create_domain_volume_spec/three_disks_in_storage_disk_0.xml +21 -0
  48. data/spec/unit/action/create_domain_volume_spec/three_disks_in_storage_disk_1.xml +21 -0
  49. data/spec/unit/action/create_domain_volume_spec/three_disks_in_storage_disk_2.xml +21 -0
  50. data/spec/unit/action/destroy_domain_spec.rb +1 -1
  51. data/spec/unit/action/forward_ports_spec.rb +202 -0
  52. data/spec/unit/action/halt_domain_spec.rb +90 -0
  53. data/spec/unit/action/handle_box_image_spec.rb +363 -0
  54. data/spec/unit/action/start_domain_spec.rb +183 -1
  55. data/spec/unit/action/start_domain_spec/clock_timer_rtc.xml +50 -0
  56. data/spec/unit/action/start_domain_spec/default.xml +2 -2
  57. data/spec/unit/action/start_domain_spec/default_added_tpm_path.xml +48 -0
  58. data/spec/unit/action/start_domain_spec/default_added_tpm_version.xml +48 -0
  59. data/spec/unit/action/wait_till_up_spec.rb +22 -21
  60. data/spec/unit/config_spec.rb +395 -127
  61. data/spec/unit/templates/domain_all_settings.xml +14 -3
  62. data/spec/unit/templates/domain_custom_cpu_model.xml +2 -1
  63. data/spec/unit/templates/domain_defaults.xml +2 -1
  64. data/spec/unit/templates/domain_spec.rb +100 -3
  65. data/spec/unit/templates/tpm/version_1.2.xml +54 -0
  66. data/spec/unit/templates/tpm/version_2.0.xml +53 -0
  67. metadata +105 -19
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4200a82105f1c9bf2860841eb3c801b103649c76afae39e303f28542316f0bbd
4
- data.tar.gz: fd14f23b17262da08eac29401b779cde545913cb9b6bf4240b044a93a35fed52
3
+ metadata.gz: 318bb5e0023b717064b450108e5a8974386562b88c814cbe22e6ff98c7aebb3a
4
+ data.tar.gz: 784a85de569e533693e0d4478c013574fddb9dd9c11ba8c1fbae19d3d667d099
5
5
  SHA512:
6
- metadata.gz: 7c068629389967340010d5d94594111fbbf661e895ede714bc45898bc7d2e21f860a8c8d6e9cdc4b7ae5ee77cdd1b6dd313193cb2d7b634971a251456695959b
7
- data.tar.gz: 724c11548cf02a12567bbb87470087539e39ed70aa67dd2d5938a6ed5879667fc03315022dfc1c2c6ca367b2da2552cb408e264c9fd1b2ab090506723f67a688
6
+ metadata.gz: 133fb557db9fdfe87c5b81b2f0875b436ec60c71ac9d86199c02b23f44024d720331b8615507a3c8394c6b3172ca11959677e30bc283d1a75baccdbb444c0e84
7
+ data.tar.gz: '0873ca30d8422dc71070e69652a8f8edea1d85a0bd1708ce0ad8a6b0c5df66a0726dfc636a34d3ff690d5e0346fefab9cec5437d01ff05b3228797dfc4564b9a'
data/README.md CHANGED
@@ -21,6 +21,7 @@ can help a lot :-)
21
21
  * [Using Docker based Installation](#using-docker-based-installation)
22
22
  * [Installation](#installation)
23
23
  * [Possible problems with plugin installation on Linux](#possible-problems-with-plugin-installation-on-linux)
24
+ * [Additional Notes for Fedora and Similar Linux Distributions](#additional-notes-for-fedora-and-similar-linux-distributions)
24
25
  * [Vagrant Project Preparation](#vagrant-project-preparation)
25
26
  * [Add Box](#add-box)
26
27
  * [Create Vagrantfile](#create-vagrantfile)
@@ -48,18 +49,23 @@ can help a lot :-)
48
49
  * [Watchdog device](#watchdog-device)
49
50
  * [Smartcard device](#smartcard-device)
50
51
  * [Hypervisor Features](#hypervisor-features)
52
+ * [Clock](#clock)
51
53
  * [CPU features](#cpu-features)
52
54
  * [Memory Backing](#memory-backing)
53
55
  * [No box and PXE boot](#no-box-and-pxe-boot)
54
56
  * [SSH Access To VM](#ssh-access-to-vm)
55
57
  * [Forwarded Ports](#forwarded-ports)
58
+ * [Forwarding the ssh-port](#forwarding-the-ssh-port)
56
59
  * [Synced Folders](#synced-folders)
57
60
  * [QEMU Session Support](#qemu-session-support)
58
61
  * [Customized Graphics](#customized-graphics)
59
62
  * [TPM Devices](#tpm-devices)
63
+ * [Memory balloon](#memory-balloon)
60
64
  * [Libvirt communication channels](#libvirt-communication-channels)
61
65
  * [Custom command line arguments and environment variables](#custom-command-line-arguments-and-environment-variables)
62
- * [Box Format](#box-format)
66
+ * [Box Formats](#box-formats)
67
+ * [Version 1](#version-1)
68
+ * [Version 2 (Experimental)](#version-2-experimental)
63
69
  * [Create Box](#create-box)
64
70
  * [Package Box from VM](#package-box-from-vm)
65
71
  * [Troubleshooting VMs](#troubleshooting-vms)
@@ -80,7 +86,7 @@ can help a lot :-)
80
86
  * SSH into domains.
81
87
  * Setup hostname and network interfaces.
82
88
  * Provision domains with any built-in Vagrant provisioner.
83
- * Synced folder support via `rsync`, `nfs` or `9p`.
89
+ * Synced folder support via `rsync`, `nfs`, `9p` or `virtiofs`.
84
90
  * Snapshots via [sahara](https://github.com/jedi4ever/sahara).
85
91
  * Package caching via
86
92
  [vagrant-cachier](http://fgrehm.viewdocs.io/vagrant-cachier/).
@@ -108,6 +114,12 @@ To get the image:
108
114
  docker pull vagrantlibvirt/vagrant-libvirt:latest
109
115
  ```
110
116
 
117
+ Preparing the docker run, only once:
118
+
119
+ ```bash
120
+ mkdir -p ~/.vagrant.d/{boxes,data,tmp}
121
+ ```
122
+
111
123
  Running the image:
112
124
  ```bash
113
125
  docker run -it --rm \
@@ -116,10 +128,26 @@ docker run -it --rm \
116
128
  -v ~/.vagrant.d:/.vagrant.d \
117
129
  -v $(pwd):$(pwd) \
118
130
  -w $(pwd) \
131
+ --network host \
119
132
  vagrantlibvirt/vagrant-libvirt:latest \
120
133
  vagrant status
121
134
  ```
122
135
 
136
+ It's possible to define an alias in `~/.bashrc`, for example:
137
+ ```bash
138
+ alias vagrant='
139
+ mkdir -p ~/.vagrant.d/{boxes,data,tmp}; \
140
+ docker run -it --rm \
141
+ -e LIBVIRT_DEFAULT_URI \
142
+ -v /var/run/libvirt/:/var/run/libvirt/ \
143
+ -v ~/.vagrant.d:/.vagrant.d \
144
+ -v $(pwd):$(pwd) \
145
+ -w $(pwd) \
146
+ --network host \
147
+ vagrantlibvirt/vagrant-libvirt:latest \
148
+ vagrant'
149
+ ```
150
+
123
151
  Note that if you are connecting to a remote system libvirt, you may omit the
124
152
  `-v /var/run/libvirt/:/var/run/libvirt/` mount bind. Some distributions patch the local
125
153
  vagrant environment to ensure vagrant-libvirt uses `qemu:///session`, which means you
@@ -155,6 +183,7 @@ vagrant-libvirt. This depends on your distro. An overview:
155
183
  apt-get build-dep vagrant ruby-libvirt
156
184
  apt-get install qemu libvirt-daemon-system libvirt-clients ebtables dnsmasq-base
157
185
  apt-get install libxslt-dev libxml2-dev libvirt-dev zlib1g-dev ruby-dev
186
+ apt-get install libguestfs-tools
158
187
  ```
159
188
 
160
189
  * Ubuntu 18.04, Debian 8 and older:
@@ -162,23 +191,24 @@ apt-get install libxslt-dev libxml2-dev libvirt-dev zlib1g-dev ruby-dev
162
191
  apt-get build-dep vagrant ruby-libvirt
163
192
  apt-get install qemu libvirt-bin ebtables dnsmasq-base
164
193
  apt-get install libxslt-dev libxml2-dev libvirt-dev zlib1g-dev ruby-dev
194
+ apt-get install libguestfs-tools
165
195
  ```
166
196
 
167
197
  (It is possible some users will already have libraries from the third line installed, but this is the way to make it work OOTB.)
168
198
 
169
199
  * CentOS 6, 7, Fedora 21:
170
200
  ```shell
171
- yum install qemu libvirt libvirt-devel ruby-devel gcc qemu-kvm
201
+ yum install qemu libvirt libvirt-devel ruby-devel gcc qemu-kvm libguestfs-tools
172
202
  ```
173
203
 
174
204
  * Fedora 22 and up:
175
205
  ```shell
176
- dnf install -y gcc libvirt libvirt-devel libxml2-devel make ruby-devel
206
+ dnf install -y gcc libvirt libvirt-devel libxml2-devel make ruby-devel libguestfs-tools
177
207
  ```
178
208
 
179
209
  * OpenSUSE leap 15.1:
180
210
  ```shell
181
- zypper install qemu libvirt libvirt-devel ruby-devel gcc qemu-kvm
211
+ zypper install qemu libvirt libvirt-devel ruby-devel gcc qemu-kvm libguestfs
182
212
  ```
183
213
 
184
214
  * Arch Linux: please read the related [ArchWiki](https://wiki.archlinux.org/index.php/Vagrant#vagrant-libvirt) page.
@@ -213,8 +243,7 @@ On Ubuntu, Debian, make sure you are running all three of the `apt` commands abo
213
243
  On RedHat, Centos, Fedora, ...
214
244
 
215
245
  ```shell
216
- $ sudo dnf install libxslt-devel libxml2-devel libvirt-devel \
217
- libguestfs-tools-c ruby-devel gcc
246
+ $ sudo dnf install libxslt-devel libxml2-devel libvirt-devel ruby-devel gcc
218
247
  ```
219
248
 
220
249
  On Arch Linux it is recommended to follow [steps from ArchWiki](https://wiki.archlinux.org/index.php/Vagrant#vagrant-libvirt).
@@ -241,7 +270,20 @@ If you encounter the following load error when using the vagrant-libvirt plugin
241
270
  then the following steps have been found to resolve the problem. Thanks to James Reynolds (see https://github.com/hashicorp/vagrant/issues/11020#issuecomment-540043472). The specific version of libssh will change over time so references to the rpm in the commands below will need to be adjusted accordingly.
242
271
 
243
272
  ```shell
273
+ # Fedora
244
274
  dnf download --source libssh
275
+
276
+ # centos 8 stream, doesn't provide source RPMs, so you need to download like so
277
+ git clone https://git.centos.org/centos-git-common
278
+ # centos-git-common needs its tools in PATH
279
+ export PATH=$(readlink -f ./centos-git-common):$PATH
280
+ git clone https://git.centos.org/rpms/libssh
281
+ cd libssh
282
+ git checkout imports/c8s/libssh-0.9.4-1.el8
283
+ into_srpm.sh -d c8s
284
+ cd SRPMS
285
+
286
+ # common commands (make sure to adjust verison accordingly)
245
287
  rpm2cpio libssh-0.9.0-5.fc30.src.rpm | cpio -imdV
246
288
  tar xf libssh-0.9.0.tar.xz
247
289
  mkdir build
@@ -260,7 +302,20 @@ If you encounter the following load error when using the vagrant-libvirt plugin
260
302
  then the following steps have been found to resolve the problem. After the steps below are complete, then reinstall the vagrant-libvirt plugin without setting the `CONFIGURE_ARGS`. Thanks to Marco Bevc (see https://github.com/hashicorp/vagrant/issues/11020#issuecomment-625801983):
261
303
 
262
304
  ```shell
305
+ # Fedora
263
306
  dnf download --source krb5-libs
307
+
308
+ # centos 8 stream, doesn't provide source RPMs, so you need to download like so
309
+ git clone https://git.centos.org/centos-git-common
310
+ # centos-git-common needs its tools in PATH
311
+ export PATH=$(readlink -f ./centos-git-common):$PATH
312
+ git clone https://git.centos.org/rpms/krb5
313
+ cd krb5
314
+ git checkout imports/c8s/krb5-1.18.2-8.el8
315
+ into_srpm.sh -d c8s
316
+ cd SRPMS
317
+
318
+ # common commands (make sure to adjust verison accordingly)
264
319
  rpm2cpio krb5-1.18-1.fc32.src.rpm | cpio -imdV
265
320
  tar xf krb5-1.18.tar.gz
266
321
  cd krb5-1.18/src
@@ -349,10 +404,25 @@ URI](http://libvirt.org/uri.html):
349
404
  Default is `$HOME/.ssh/id_rsa`. Prepends `$HOME/.ssh/` if no directory
350
405
  * `socket` - Path to the Libvirt unix socket (e.g.
351
406
  `/var/run/libvirt/libvirt-sock`)
407
+ * `proxy_command` - For advanced usage. When connecting to remote libvirt
408
+ instances, if the default constructed proxy\_command which uses `-W %h:%p`
409
+ does not work, set this as needed. It performs interpolation using `{key}`
410
+ and supports only `{host}`, `{username}`, and `{id_ssh_key_file}`. This is
411
+ to try and avoid issues with escaping `%` and `$` which might be necessary
412
+ to the ssh command itself. e.g.:
413
+ `libvirt.proxy_command = "ssh {host} -l {username} -i {id_ssh_key_file} nc %h %p"`
352
414
  * `uri` - For advanced usage. Directly specifies what Libvirt connection URI
353
415
  vagrant-libvirt should use. Overrides all other connection configuration
354
416
  options
355
417
 
418
+ In the event that none of these are set (excluding the `driver` option) the
419
+ provider will attempt to retrieve the uri from the environment variable
420
+ `LIBVIRT_DEFAULT_URI` similar to how virsh works. If any of them are set, it
421
+ will ignore the environment variable. The reason the driver option is ignored
422
+ is that it is not uncommon for this to be explicitly set on the box itself
423
+ and there is no easily to determine whether it is being set by the user or
424
+ the box packager.
425
+
356
426
  Connection-independent options:
357
427
 
358
428
  * `storage_pool_name` - Libvirt storage pool name, where box image and instance
@@ -384,6 +454,14 @@ end
384
454
  set, which should be fine for paravirtualized guests, but some fully
385
455
  virtualized guests may require hda. NOTE: this option also applies only to
386
456
  disks associated with a box image.
457
+ * `disk_driver` - Extra options for the main disk driver ([see Libvirt documentation](http://libvirt.org/formatdomain.html#elementsDisks)).
458
+ NOTE: this option also applies only to disks associated with a box image. In all cases, the value `nil` can be used to force the hypervisor default behaviour (e.g. to override settings defined in top-level Vagrantfiles). Supported options include:
459
+ * `:cache` - Controls the cache mechanism. Possible values are "default", "none", "writethrough", "writeback", "directsync" and "unsafe".
460
+ * `:io` - Controls specific policies on I/O. Possible values are "threads" and "native".
461
+ * `:copy_on_read` - Controls whether to copy read backing file into the image file. The value can be either "on" or "off".
462
+ * `:discard` - Controls whether discard requests (also known as "trim" or "unmap") are ignored or passed to the filesystem. Possible values are "unmap" or "ignore".
463
+ Note: for discard to work, you will likely also need to set `disk_bus = 'scsi'`
464
+ * `:detect_zeroes` - Controls whether to detect zero write requests. The value can be "off", "on" or "unmap".
387
465
  * `nic_model_type` - parameter specifies the model of the network adapter when
388
466
  you create a domain value by default virtio KVM believe possible values, see
389
467
  the [documentation for
@@ -429,10 +507,6 @@ end
429
507
  ]
430
508
  ```
431
509
  * `loader` - Sets path to custom UEFI loader.
432
- * `volume_cache` - Controls the cache mechanism. Possible values are "default",
433
- "none", "writethrough", "writeback", "directsync" and "unsafe". [See
434
- driver->cache in Libvirt
435
- documentation](http://libvirt.org/formatdomain.html#elementsDisks).
436
510
  * `kernel` - To launch the guest with a kernel residing on host filesystems.
437
511
  Equivalent to qemu `-kernel`.
438
512
  * `initrd` - To specify the initramfs/initrd to use for the guest. Equivalent
@@ -504,6 +578,7 @@ end
504
578
  * `tpm_model` - The model of the TPM to which you wish to connect.
505
579
  * `tpm_type` - The type of TPM device to which you are connecting.
506
580
  * `tpm_path` - The path to the TPM device on the host system.
581
+ * `tpm_version` - The TPM version to use.
507
582
  * `dtb` - The device tree blob file, mostly used for non-x86 platforms. In case
508
583
  the device tree isn't added in-line to the kernel, it can be manually
509
584
  specified here.
@@ -532,7 +607,7 @@ Vagrant.configure("2") do |config|
532
607
  domain.memory = 2048
533
608
  domain.cpus = 2
534
609
  domain.nested = true
535
- domain.volume_cache = 'none'
610
+ domain.disk_driver :cache => 'none'
536
611
  end
537
612
  end
538
613
 
@@ -579,6 +654,7 @@ defined domain:
579
654
  * `tpm_model` - Updated
580
655
  * `tpm_type` - Updated
581
656
  * `tpm_path` - Updated
657
+ * `tpm_version` - Updated
582
658
 
583
659
  ## Networks
584
660
 
@@ -820,6 +896,8 @@ used by this network are configurable at the provider level.
820
896
  * `management_network_pci_slot` - The slot of the PCI device.
821
897
  * `management_network_mac` - MAC address of management network interface.
822
898
  * `management_network_domain` - Domain name assigned to the management network.
899
+ * `management_network_mtu` - MTU size of management network. If not specified,
900
+ the Libvirt default (1500) will be used.
823
901
 
824
902
  You may wonder how vagrant-libvirt knows the IP address a VM received. Libvirt
825
903
  doesn't provide a standard way to find out the IP address of a running domain.
@@ -841,11 +919,6 @@ It has a number of options:
841
919
  * `size` - Size of the disk image. If unspecified, defaults to 10G.
842
920
  * `type` - Type of disk image to create. Defaults to *qcow2*.
843
921
  * `bus` - Type of bus to connect device to. Defaults to *virtio*.
844
- * `cache` - Cache mode to use, e.g. `none`, `writeback`, `writethrough` (see
845
- the [libvirt documentation for possible
846
- values](http://libvirt.org/formatdomain.html#elementsDisks) or
847
- [here](https://www.suse.com/documentation/sles11/book_kvm/data/sect1_chapter_book_kvm.html)
848
- for a fuller explanation). Defaults to *default*.
849
922
  * `allow_existing` - Set to true if you want to allow the VM to use a
850
923
  pre-existing disk. If the disk doesn't exist it will be created.
851
924
  Disks with this option set to true need to be removed manually.
@@ -853,13 +926,25 @@ It has a number of options:
853
926
  * `serial` - Serial number of the disk device.
854
927
  * `wwn` - WWN number of the disk device.
855
928
 
929
+ The following disk performance options can also be configured
930
+ (see the [libvirt documentation for possible values](http://libvirt.org/formatdomain.html#elementsDisks)
931
+ or [here](https://www.suse.com/documentation/sles11/book_kvm/data/sect1_chapter_book_kvm.html) for a fuller explanation).
932
+ In all cases, the options use the hypervisor default if not specified, or if set to `nil`.
933
+
934
+ * `cache` - Cache mode to use. Value may be `default`, `none`, `writeback`, `writethrough`, `directsync` or `unsafe`.
935
+ * `io` - Controls specific policies on I/O. Value may be `threads` or `native`.
936
+ * `copy_on_read` - Controls whether to copy read backing file into the image file. Value may be `on` or `off`.
937
+ * `discard` - Controls whether discard requests (also known as "trim" or "unmap") are ignored or passed to the filesystem. Value may be `unmap` or `ignore`.
938
+ Note: for discard to work, you will likely also need to set `:bus => 'scsi'`
939
+ * `detect_zeroes` - Controls whether to detect zero write requests. Value may be `off`, `on` or `unmap`.
940
+
856
941
  The following example creates two additional disks.
857
942
 
858
943
  ```ruby
859
944
  Vagrant.configure("2") do |config|
860
945
  config.vm.provider :libvirt do |libvirt|
861
946
  libvirt.storage :file, :size => '20G'
862
- libvirt.storage :file, :size => '40G', :type => 'raw'
947
+ libvirt.storage :file, :size => '40G', :bus => 'scsi', :type => 'raw', :discard => 'unmap', :detect_zeroes => 'on'
863
948
  end
864
949
  end
865
950
  ```
@@ -1177,6 +1262,29 @@ Vagrant.configure("2") do |config|
1177
1262
  libvirt.hyperv_feature :name => 'relaxed', :state => 'on'
1178
1263
  # Enable virtual APIC
1179
1264
  libvirt.hyperv_feature :name => 'vapic', :state => 'on'
1265
+ # Enable spinlocks (requires retries to be specified)
1266
+ libvirt.hyperv_feature :name => 'spinlocks', :state => 'on', :retries => '8191'
1267
+ end
1268
+ end
1269
+ ```
1270
+
1271
+ ## Clock
1272
+
1273
+ Clock offset can be specified via `libvirt.clock_offset`. (Default is utc)
1274
+
1275
+ Additionally timers can be specified via `libvirt.clock_timer`.
1276
+ Available options for timers are: name, track, tickpolicy, frequency, mode, present
1277
+
1278
+ ```ruby
1279
+ Vagrant.configure("2") do |config|
1280
+ config.vm.provider :libvirt do |libvirt|
1281
+ # Set clock offset to localtime
1282
+ libvirt.clock_offset = 'localtime'
1283
+ # Timers ...
1284
+ libvirt.clock_timer :name => 'rtc', :tickpolicy => 'catchup'
1285
+ libvirt.clock_timer :name => 'pit', :tickpolicy => 'delay'
1286
+ libvirt.clock_timer :name => 'hpet', :present => 'no'
1287
+ libvirt.clock_timer :name => 'hypervclock', :present => 'yes'
1180
1288
  end
1181
1289
  end
1182
1290
  ```
@@ -1282,6 +1390,24 @@ Name of network "foreman_managed" is key for define boot order
1282
1390
  end
1283
1391
  ```
1284
1392
 
1393
+ An example VM that is PXE booted from the `br1` device (which must already be configured in the host machine), and if that fails, is booted from the disk:
1394
+
1395
+ ```ruby
1396
+ Vagrant.configure("2") do |config|
1397
+ config.vm.define :pxeclient do |pxeclient|
1398
+ pxeclient.vm.network :public_network,
1399
+ dev: 'br1',
1400
+ auto_config: false
1401
+ pxeclient.vm.provider :libvirt do |domain|
1402
+ boot_network = {'dev' => 'br1'}
1403
+ domain.storage :file, :size => '100G'
1404
+ domain.boot boot_network
1405
+ domain.boot 'hd'
1406
+ end
1407
+ end
1408
+ end
1409
+ ```
1410
+
1285
1411
  ## SSH Access To VM
1286
1412
 
1287
1413
  vagrant-libvirt supports vagrant's [standard ssh
@@ -1312,40 +1438,157 @@ Default is `eth0`.
1312
1438
 
1313
1439
  `config.vm.network :forwarded_port, guest: 80, host: 2000, host_ip: "0.0.0.0"`
1314
1440
 
1441
+ ### Forwarding the ssh-port
1442
+
1443
+ Vagrant-libvirt now supports forwarding the standard ssh-port on port 2222 from
1444
+ the localhost to allow for consistent provisioning steps/ports to be used when
1445
+ defining across multiple providers.
1446
+
1447
+ To enable, set the following:
1448
+ ```ruby
1449
+ Vagrant.configure("2") do |config|
1450
+ config.vm.provider :libvirt do |libvirt|
1451
+ # Enable forwarding of forwarded_port with id 'ssh'.
1452
+ libvirt.forward_ssh_port = true
1453
+ end
1454
+ end
1455
+ ```
1456
+
1457
+ Previously by default libvirt skipped the forwarding of the ssh-port because
1458
+ you can access the machine directly. In the future it is expected that this
1459
+ will be enabled by default once autocorrect support is added to handle port
1460
+ collisions for multi machine environments gracefully.
1461
+
1315
1462
  ## Synced Folders
1316
1463
 
1317
- Vagrant automatically syncs the project folder on the host to `/vagrant` in the guest. You can also configure
1318
- additional synced folders.
1464
+ Vagrant automatically syncs the project folder on the host to `/vagrant` in
1465
+ the guest. You can also configure additional synced folders.
1319
1466
 
1320
- `vagrant-libvirt` supports bidirectional synced folders via [NFS](https://en.wikipedia.org/wiki/Network_File_System) or [VirtFS](http://www.linux-kvm.org/page/VirtFS) ([9p or Plan 9](https://en.wikipedia.org/wiki/9P_(protocol))) and
1321
- unidirectional via rsync. The default is NFS. Difference between NFS and 9p is explained [here](https://unix.stackexchange.com/questions/240281/virtfs-plan-9-vs-nfs-as-tool-for-share-folder-for-virtual-machine).
1467
+ **SECURITY NOTE:** for remote Libvirt, nfs synced folders requires a bridged
1468
+ public network interface and you must connect to Libvirt via ssh.
1322
1469
 
1323
- You can change the synced folder type for `/vagrant` by explicity configuring
1324
- it an setting the type, e.g.
1470
+ **NFS**
1325
1471
 
1326
- ```shell
1327
- config.vm.synced_folder './', '/vagrant', type: 'rsync'
1328
- ```
1472
+ `vagrant-libvirt` supports
1473
+ [NFS](https://www.vagrantup.com/docs/synced-folders/nfs) as default with
1474
+ bidirectional synced folders.
1329
1475
 
1330
- or
1476
+ Example with NFS:
1331
1477
 
1332
- ```shell
1333
- config.vm.synced_folder './', '/vagrant', type: '9p', disabled: false, accessmode: "squash", owner: "1000"
1478
+ ``` ruby
1479
+ Vagrant.configure("2") do |config|
1480
+ config.vm.synced_folder "./", "/vagrant"
1481
+ end
1334
1482
  ```
1335
1483
 
1336
- or
1484
+ **RSync**
1337
1485
 
1338
- ```shell
1339
- config.vm.synced_folder './', '/vagrant', type: '9p', disabled: false, accessmode: "mapped", mount: false
1486
+ `vagrant-libvirt` supports
1487
+ [rsync](https://www.vagrantup.com/docs/synced-folders/rsync) with
1488
+ unidirectional synced folders.
1489
+
1490
+ Example with rsync:
1491
+
1492
+ ``` ruby
1493
+ Vagrant.configure("2") do |config|
1494
+ config.vm.synced_folder "./", "/vagrant", type: "rsync"
1495
+ end
1340
1496
  ```
1341
1497
 
1498
+ **9P**
1499
+
1500
+ `vagrant-libvirt` supports [VirtFS](http://www.linux-kvm.org/page/VirtFS) ([9p
1501
+ or Plan 9](https://en.wikipedia.org/wiki/9P_\(protocol\))) with bidirectional
1502
+ synced folders.
1503
+
1504
+ Difference between NFS and 9p is explained
1505
+ [here](https://unix.stackexchange.com/questions/240281/virtfs-plan-9-vs-nfs-as-tool-for-share-folder-for-virtual-machine).
1506
+
1342
1507
  For 9p shares, a `mount: false` option allows to define synced folders without
1343
1508
  mounting them at boot.
1344
1509
 
1345
- Further documentation on using 9p can be found in [kernel docs](https://www.kernel.org/doc/Documentation/filesystems/9p.txt) and in [QEMU wiki](https://wiki.qemu.org/Documentation/9psetup#Starting_the_Guest_directly). Please do note that 9p depends on support in the guest and not all distros come with the 9p module by default.
1510
+ Example for `accessmode: "squash"` with 9p:
1346
1511
 
1347
- **SECURITY NOTE:** for remote Libvirt, nfs synced folders requires a bridged
1348
- public network interface and you must connect to Libvirt via ssh.
1512
+ ``` ruby
1513
+ Vagrant.configure("2") do |config|
1514
+ config.vm.synced_folder "./", "/vagrant", type: "9p", disabled: false, accessmode: "squash", owner: "1000"
1515
+ end
1516
+ ```
1517
+
1518
+ Example for `accessmode: "mapped"` with 9p:
1519
+
1520
+ ``` ruby
1521
+ Vagrant.configure("2") do |config|
1522
+ config.vm.synced_folder "./", "/vagrant", type: "9p", disabled: false, accessmode: "mapped", mount: false
1523
+ end
1524
+ ```
1525
+
1526
+ Further documentation on using 9p can be found in [kernel
1527
+ docs](https://www.kernel.org/doc/Documentation/filesystems/9p.txt) and in
1528
+ [QEMU
1529
+ wiki](https://wiki.qemu.org/Documentation/9psetup#Starting_the_Guest_directly).
1530
+
1531
+ Please do note that 9p depends on support in the guest and not all distros
1532
+ come with the 9p module by default.
1533
+
1534
+ **Virtio-fs**
1535
+
1536
+ `vagrant-libvirt` supports [Virtio-fs](https://virtio-fs.gitlab.io/) with
1537
+ bidirectional synced folders.
1538
+
1539
+ For virtiofs shares, a `mount: false` option allows to define synced folders
1540
+ without mounting them at boot.
1541
+
1542
+ So far, passthrough is the only supported access mode and it requires running
1543
+ the virtiofsd daemon as root.
1544
+
1545
+ QEMU needs to allocate the backing memory for all the guest RAM as shared
1546
+ memory, e.g. [Use file-backed
1547
+ memory](https://libvirt.org/kbase/virtiofs.html#host-setup) by enable
1548
+ `memory_backing_dir` option in `/etc/libvirt/qemu.conf`:
1549
+
1550
+ ``` shell
1551
+ memory_backing_dir = "/dev/shm"
1552
+ ```
1553
+
1554
+ Example for Libvirt \>= 6.2.0 (e.g. Ubuntu 20.10 with Linux 5.8.0 + QEMU 5.0 +
1555
+ Libvirt 6.6.0, i.e. NUMA nodes required) with virtiofs:
1556
+
1557
+ ``` ruby
1558
+ Vagrant.configure("2") do |config|
1559
+ config.vm.provider :libvirt do |libvirt|
1560
+ libvirt.cpus = 2
1561
+ libvirt.numa_nodes = [{ :cpus => "0-1", :memory => 8192, :memAccess => "shared" }]
1562
+ libvirt.memorybacking :access, :mode => "shared"
1563
+ end
1564
+ config.vm.synced_folder "./", "/vagrant", type: "virtiofs"
1565
+ end
1566
+ ```
1567
+
1568
+ Example for Libvirt \>= 6.9.0 (e.g. Ubuntu 21.04 with Linux 5.11.0 + QEMU 5.2 +
1569
+ Libvirt 7.0.0, or Ubuntu 20.04 + [PPA
1570
+ enabled](https://launchpad.net/~savoury1/+archive/ubuntu/virtualisation)) with
1571
+ virtiofs:
1572
+
1573
+ ``` ruby
1574
+ Vagrant.configure("2") do |config|
1575
+ config.vm.provider :libvirt do |libvirt|
1576
+ libvirt.cpus = 2
1577
+ libvirt.memory = 8192
1578
+ libvirt.memorybacking :access, :mode => "shared"
1579
+ end
1580
+ config.vm.synced_folder "./", "/vagrant", type: "virtiofs"
1581
+ end
1582
+ ```
1583
+
1584
+ Further documentation on using virtiofs can be found in [official
1585
+ HowTo](https://virtio-fs.gitlab.io/index.html#howto) and in [Libvirt
1586
+ KB](https://libvirt.org/kbase/virtiofs.html).
1587
+
1588
+ Please do note that virtiofs depends on:
1589
+
1590
+ - Host: Linux \>= 5.4, QEMU \>= 4.2 and Libvirt \>= 6.2 (e.g. Ubuntu 20.10)
1591
+ - Guest: Linux \>= 5.4 (e.g. Ubuntu 20.04)
1349
1592
 
1350
1593
  ## QEMU Session Support
1351
1594
 
@@ -1408,13 +1651,14 @@ Modern versions of Libvirt support connecting to TPM devices on the host
1408
1651
  system. This allows you to enable Trusted Boot Extensions, among other
1409
1652
  features, on your guest VMs.
1410
1653
 
1411
- In general, you will only need to modify the `tpm_path` variable in your guest
1412
- configuration. However, advanced usage, such as the application of a Software
1413
- TPM, may require modifying the `tpm_model` and `tpm_type` variables.
1654
+ To passthrough a hardware TPM, you will generally only need to modify the
1655
+ `tpm_path` variable in your guest configuration. However, advanced usage,
1656
+ such as the application of a Software TPM, may require modifying the
1657
+ `tpm_model`, `tpm_type` and `tpm_version` variables.
1414
1658
 
1415
- The TPM options will only be used if you specify a TPM path. Declarations of
1416
- any TPM options without specifying a path will result in those options being
1417
- ignored.
1659
+ The TPM options will only be used if you specify a TPM path or version.
1660
+ Declarations of any TPM options without specifying a path or version will
1661
+ result in those options being ignored.
1418
1662
 
1419
1663
  Here is an example of using the TPM options:
1420
1664
 
@@ -1428,6 +1672,41 @@ Vagrant.configure("2") do |config|
1428
1672
  end
1429
1673
  ```
1430
1674
 
1675
+ It's also possible for Libvirt to start an emulated TPM device on the host.
1676
+ Requires `swtpm` and `swtpm-tools`
1677
+
1678
+ ```ruby
1679
+ Vagrant.configure("2") do |config|
1680
+ config.vm.provider :libvirt do |libvirt|
1681
+ libvirt.tpm_model = "tpm-crb"
1682
+ libvirt.tpm_type = "emulator"
1683
+ libvirt.tpm_version = "2.0"
1684
+ end
1685
+ end
1686
+ ```
1687
+
1688
+ ## Memory balloon
1689
+
1690
+ The configuration of the memory balloon device can be overridden. By default,
1691
+ libvirt will automatically attach a memory balloon; this behavior is preserved
1692
+ by not configuring any memballoon-related options. The memory balloon can be
1693
+ explicitly disabled by setting `memballoon_enabled` to `false`. Setting
1694
+ `memballoon_enabled` to `true` will allow additional configuration of
1695
+ memballoon-related options.
1696
+
1697
+ Here is an example of using the memballoon options:
1698
+
1699
+ ```ruby
1700
+ Vagrant.configure("2") do |config|
1701
+ config.vm.provider :libvirt do |libvirt|
1702
+ libvirt.memballoon_enabled = true
1703
+ libvirt.memballoon_model = 'virtio'
1704
+ libvirt.memballoon_pci_bus = '0x00'
1705
+ libvirt.memballoon_pci_slot = '0x0f'
1706
+ end
1707
+ end
1708
+ ```
1709
+
1431
1710
  ## Libvirt communication channels
1432
1711
 
1433
1712
  For certain functionality to be available within a guest, a private
@@ -1516,7 +1795,11 @@ Vagrant.configure("2") do |config|
1516
1795
  end
1517
1796
  ```
1518
1797
 
1519
- ## Box Format
1798
+ ## Box Formats
1799
+
1800
+ ### Version 1
1801
+
1802
+ This is the original format that most boxes currently use.
1520
1803
 
1521
1804
  You can view an example box in the
1522
1805
  [`example_box/directory`](https://github.com/vagrant-libvirt/vagrant-libvirt/tree/master/example_box).
@@ -1530,8 +1813,64 @@ The box is a tarball containing:
1530
1813
  * `Vagrantfile` that does default settings for the provider-specific
1531
1814
  configuration for this provider
1532
1815
 
1816
+
1817
+ ### Version 2 (Experimental)
1818
+
1819
+ Due to the limitation of only being able to handle a single disk with the version 1 format, a new
1820
+ format was added to support boxes that need to specify multiple disks. This is still currently
1821
+ experimental and as such support for packaging has yet to be added. There is a script in the tools
1822
+ folder (tools/create_box_with_two_disks.sh) that should provide a guideline on how to create such
1823
+ a box for those that wish to experiment and provide early feedback.
1824
+
1825
+ At it's most basic, it expects an array of disks to allow a specific order to be presented. Disks
1826
+ will be attached in this order and as such assume device names base on this within the VM. The
1827
+ 'path' attribute is required, and is expected to be relative to the base of the box. This should
1828
+ allow placing the disk images within a nested directory within the box if it useful for those
1829
+ with a larger number of disks. The name allows overriding the target volume name that will be
1830
+ used in the libvirt storage pool. Note that vagrant-libvirt will still prefix the volume name
1831
+ with `#{box_name}_vagrant_box_image_#{box_version}_` to avoid accidental clashes with other boxes.
1832
+
1833
+ Format and virtual size need no longer be specified as they are now retrieved directly from the
1834
+ provided image using `qemu-img info ...`.
1835
+
1836
+ Example format:
1837
+ ```json
1838
+ {
1839
+ 'disks': [
1840
+ {
1841
+ 'path': 'disk1.img'
1842
+ },
1843
+ {
1844
+ 'path': 'disk2.img',
1845
+ 'name': 'secondary_disk'
1846
+ },
1847
+ {
1848
+ 'path': 'disk3.img'
1849
+ }
1850
+ ],
1851
+ 'provider': 'libvirt'
1852
+ }
1853
+ ```
1854
+
1533
1855
  ## Create Box
1534
1856
 
1857
+ If creating a box from a modified vagrant-libvirt machine, ensure that
1858
+ you have set the `config.ssh.insert_key = false` in the original Vagrantfile
1859
+ as otherwise Vagrant will replace the default connection key-pair that is
1860
+ required on first boot with one specific to the machine and prevent
1861
+ the default key from working on the exported result.
1862
+ ```ruby
1863
+ Vagrant.configure("2") do |config|
1864
+ # this setting is only recommended if planning to export the
1865
+ # resulting machine
1866
+ config.ssh.insert_key = false
1867
+
1868
+ config.vm.define :test_vm do |test_vm|
1869
+ test_vm.vm.box = "fedora/32-cloud-base"
1870
+ end
1871
+ end
1872
+ ```
1873
+
1535
1874
  To create a vagrant-libvirt box from a qcow2 image, run `create_box.sh`
1536
1875
  (located in the tools directory):
1537
1876
 
@@ -1629,17 +1968,49 @@ $ bundle install
1629
1968
  Once you have the dependencies, verify the unit tests pass with `rspec`:
1630
1969
 
1631
1970
  ```shell
1632
- $ bundle exec rspec spec/
1971
+ $ export VAGRANT_HOME=$(mktemp -d)
1972
+ $ bundle exec rspec --fail-fast --color --format documentation
1633
1973
  ```
1634
1974
 
1635
- If those pass, you're ready to start developing the plugin. You can test the
1636
- plugin without installing it into your Vagrant environment by just creating a
1637
- `Vagrantfile` in the top level of this directory (it is gitignored) that uses
1638
- it. Don't forget to add following line at the beginning of your `Vagrantfile`
1639
- while in development mode:
1975
+ If those pass, you're ready to start developing the plugin.
1640
1976
 
1977
+ Setting `VAGRANT_HOME` is to avoid issues with conflicting with other
1978
+ plugins/gems or data already present under `~/.vagrant.d`.
1979
+
1980
+ Additionally if you wish to test against a specific version of vagrant you
1981
+ can control the version using the following before running the tests:
1982
+
1983
+ ```shell
1984
+ $ export VAGRANT_VERSION=v2.2.14
1985
+ ```
1986
+
1987
+ **Note** rvm is used by the maintainers to help provide an environment to test
1988
+ against multiple ruby versions that align with the ones used by vagrant for
1989
+ their embedded ruby depending on the release. You can see what version is used
1990
+ by looking at the current [unit tests](.github/workflows/unit-tests.yml)
1991
+ workflow.
1992
+
1993
+ You can test the plugin without installing it into your Vagrant environment by
1994
+ just creating a `Vagrantfile` in the top level of this directory (it is
1995
+ gitignored) that uses it. You can add the following line to your Vagrantfile
1996
+ while in development to ensure vagrant checks that the plugin is installed:
1997
+
1998
+ ```ruby
1999
+ Vagrant.configure("2") do |config|
2000
+ config.vagrant.plugins = "vagrant-libvirt"
2001
+ end
2002
+ ```
2003
+ Or add the following to the top of the file to ensure that any required plugins
2004
+ are installed globally:
1641
2005
  ```ruby
1642
- Vagrant.require_plugin "vagrant-libvirt"
2006
+ REQUIRED_PLUGINS = %w(vagrant-libvirt)
2007
+ exit unless REQUIRED_PLUGINS.all? do |plugin|
2008
+ Vagrant.has_plugin?(plugin) || (
2009
+ puts "The #{plugin} plugin is required. Please install it with:"
2010
+ puts "$ vagrant plugin install #{plugin}"
2011
+ false
2012
+ )
2013
+ end
1643
2014
  ```
1644
2015
 
1645
2016
  Now you can use bundler to execute Vagrant: