|
@@ -0,0 +1,168 @@
|
|
|
+
|
|
|
+# libvirt
|
|
|
+
|
|
|
+I would rather not be beholden to Oracle so one of my goals is to transition away from `virtualbox` and towards the messy combination of `libvirt`, `kvm`, `qemu`, and ovmf uefi (eg. `edk2-ovmf`).
|
|
|
+
|
|
|
+A first-attempt went fairly well, but in addition to adding four separate packages to replace two, it also seems to introduce platform-dependent paths and extra plugins required per-tool. _These are just the expenses of using open sourced code without first-party integration support._
|
|
|
+
|
|
|
+In addition to lacking integration support, it also lacks decent documentation as you'll be scouring dozens of sources and praying what you are reading is up to date.
|
|
|
+
|
|
|
+
|
|
|
+## packages
|
|
|
+
|
|
|
+You'll need all of these packages:
|
|
|
+
|
|
|
+- libvirt
|
|
|
+- qemu
|
|
|
+- libguestfs
|
|
|
+- virt-install
|
|
|
+- edk2-ovmf
|
|
|
+
|
|
|
+_The `edk2-ovmf` will install a UEFI disk image to `/usr/share/ovmf/x64/OVMF.fd`, and both the package and path may vary depending on which linux distribution you are using._
|
|
|
+
|
|
|
+
|
|
|
+## vagrant
|
|
|
+
|
|
|
+For vagrant to work you will need to add a plugin:
|
|
|
+
|
|
|
+ vagrant plugin install vagrant-libvirt
|
|
|
+
|
|
|
+_After this it will be able to communicate with qemu/kvm._
|
|
|
+
|
|
|
+A `Vagrantfile` may look like this:
|
|
|
+
|
|
|
+ ENV['VAGRANT_DEFAULT_PROVIDER'] = 'libvirt'
|
|
|
+
|
|
|
+ Vagrant.configure("2") do |config|
|
|
|
+ config.vm.box_url = 'file://' + File.dirname(__FILE__) + '/dist/arch-desktop.box'
|
|
|
+ config.vm.box = 'arch-desktop'
|
|
|
+ config.vm.boot_timeout = 1
|
|
|
+ config.vm.graceful_halt_timeout = 1
|
|
|
+ config.vm.synced_folder '.', '/vagrant', disabled: true
|
|
|
+ config.ssh.insert_key = false
|
|
|
+
|
|
|
+ config.vm.provider :libvirt do |v|
|
|
|
+ v.memory = 2048
|
|
|
+ v.cpus = 2
|
|
|
+ v.driver = "kvm"
|
|
|
+ v.machine_arch = 'x86_64'
|
|
|
+ v.loader = '/usr/share/ovmf/x64/OVMF.fd'
|
|
|
+ end
|
|
|
+ end
|
|
|
+
|
|
|
+
|
|
|
+## libvirt
|
|
|
+
|
|
|
+Libvirt needs to run as a service:
|
|
|
+
|
|
|
+ systemctl enable libvirtd.service
|
|
|
+
|
|
|
+_This service requires some control of the network and so you'll have to ensure your network utility does not have a dnsproxy._
|
|
|
+
|
|
|
+For example if using `connman` then you need to add `/etc/systemd/system/connman.service.d/disable_dns_proxy.conf` with:
|
|
|
+
|
|
|
+ [Service]
|
|
|
+ ExecStart=
|
|
|
+ ExecStart=/usr/bin/connmand -n --nodnsproxy
|
|
|
+
|
|
|
+Finally, you need to create a polkit policy at `/etc/polkit-1/rules.d/50-libvirt.rules` for users to operate it:
|
|
|
+
|
|
|
+ polkit.addRule(function(action, subject) {
|
|
|
+ if (action.id == "org.libvirt.unix.manage" &&
|
|
|
+ subject.isInGroup("sudo")) {
|
|
|
+ return polkit.Result.YES;
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+_This example allows only users with `sudo` group access to do so, but you could use looser restrictions._
|
|
|
+
|
|
|
+
|
|
|
+## packer
|
|
|
+
|
|
|
+While packer does work without much effort, it does require you to point to the host path of OVMF:
|
|
|
+
|
|
|
+ {
|
|
|
+ "variables": {
|
|
|
+ "iso_url": "https://mirrors.kernel.org/archlinux/iso/{{isotime \"2006.01\"}}.01/archlinux-{{isotime \"2006.01\"}}.01-x86_64.iso",
|
|
|
+ "iso_checksum_url": "https://mirrors.kernel.org/archlinux/iso/{{isotime \"2006.01\"}}.01/sha1sums.txt",
|
|
|
+ "efi_bios": "/usr/share/ovmf/x64/OVMF.fd",
|
|
|
+ "root_password": "arch",
|
|
|
+ "username": "vagrant",
|
|
|
+ "password": "vagrant"
|
|
|
+ },
|
|
|
+ "builders": [
|
|
|
+ {
|
|
|
+ "headless": true,
|
|
|
+ "type": "qemu",
|
|
|
+ "iso_url": "{{ user `iso_url` }}",
|
|
|
+ "iso_checksum": "file:{{ user `iso_checksum_url` }}",
|
|
|
+ "vm_name": "arch-desktop",
|
|
|
+ "format": "qcow2",
|
|
|
+ "accelerator": "kvm",
|
|
|
+ "output_directory": "dist/arch-desktop",
|
|
|
+ "firmware": "{{ user `efi_bios` }}",
|
|
|
+ "memory": 1024,
|
|
|
+ "disk_size": "20G",
|
|
|
+ "disk_interface": "virtio",
|
|
|
+ "net_device": "virtio-net",
|
|
|
+ "ssh_username": "root",
|
|
|
+ "ssh_password": "{{user `root_password`}}",
|
|
|
+ "ssh_timeout": "20m",
|
|
|
+ "shutdown_command": "systemctl poweroff",
|
|
|
+ "boot_wait": "5s",
|
|
|
+ "boot_command": [
|
|
|
+ "<enter><wait90s>",
|
|
|
+ "printf \"{{user `root_password`}}\\n{{user `root_password`}}\\n\" | passwd<enter>",
|
|
|
+ "systemctl start sshd.service<enter>"
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ "provisioners": [
|
|
|
+ {
|
|
|
+ "type": "file",
|
|
|
+ "source": "arch.sh",
|
|
|
+ "destination": "arch.sh"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "type": "file",
|
|
|
+ "source": "install",
|
|
|
+ "destination": "install"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "type": "shell",
|
|
|
+ "skip_clean": true,
|
|
|
+ "expect_disconnect": true,
|
|
|
+ "environment_vars": [
|
|
|
+ "DEBUG=y",
|
|
|
+ "enable_hibernation=y",
|
|
|
+ "disk=vda",
|
|
|
+ "root_password={{user `root_password`}}",
|
|
|
+ "username={{user `username`}}",
|
|
|
+ "password={{user `password`}}"
|
|
|
+ ],
|
|
|
+ "script": "setup/install.sh"
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ "post-processors": [
|
|
|
+ {
|
|
|
+ "type": "vagrant",
|
|
|
+ "compression_level": 9,
|
|
|
+ "output": "dist/arch-desktop.img"
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+## conclusion
|
|
|
+
|
|
|
+It works, but it's not as simple nor well integrated.
|
|
|
+
|
|
|
+To begin with you need 4-6 packages to get things working. Whether this is better or worse than a single monolithic package is debatable, but more packages means more complexity in terms of knowing what you need to get started.
|
|
|
+
|
|
|
+With regards to packer support, it works relatively well actually. The few problems I ran into were related to disk names based on the types of disk drivers specified.
|
|
|
+
|
|
|
+With vagrant you need to install an extra plugin. Further, I have been unable to get vagrant to launch a GUI regardless of the `graphics_type` or `video_type` used.
|
|
|
+
|
|
|
+It also requires significantly more work to clear when testing a new build. Apparently vagrant box is not linked to virsh (eg. libvirt cli) storage, so you have to delete the image in root storage using `virsh` or `virt-manager`, and while it is possible to establish userspace storage that's even more undocumented complexity that I haven't had time to get working.
|
|
|
+
|
|
|
+Overall, it's nice to have a purely open sourced build option, but it's way more complicated with less documentation and fewer integrations.
|