mirror of
https://github.com/vagrant-libvirt/vagrant-libvirt.git
synced 2025-02-25 18:55:27 -06:00
Customising libvirt settings can only be done when creating a box #418
* Added support to modify domain specific options on already defined domain, updated relevant documentation. For list of modifiable options please see updated documentation. * Added new domain specific option - uuid. To force domain UUID when creating new VM. Task-Url: https://github.com/pradels/vagrant-libvirt/issues/418 Signed-off-by: Max Kutsevol <max@coolvds.com>
This commit is contained in:
parent
329725740b
commit
d11b0b970f
86
README.md
86
README.md
@ -7,34 +7,35 @@ control and provision machines via Libvirt toolkit.
|
||||
**Note:** Actual version is still a development one. Feedback is
|
||||
welcome and can help a lot :-)
|
||||
|
||||
- [Features](#)
|
||||
- [Future work](#)
|
||||
- [Installation](#)
|
||||
- [Possible problems with plugin installation on Linux](#)
|
||||
- [Vagrant Project Preparation](#)
|
||||
- [Add Box](#)
|
||||
- [Create Vagrantfile](#)
|
||||
- [Start VM](#)
|
||||
- [How Project Is Created](#)
|
||||
- [Libvirt Configuration](#)
|
||||
- [Provider Options](#)
|
||||
- [Domain Specific Options](#)
|
||||
- [Networks](#)
|
||||
- [Private Network Options](#)
|
||||
- [Public Network Options](#)
|
||||
- [Management Network](#)
|
||||
- [Additional Disks](#)
|
||||
- [CDROMs](#)
|
||||
- [Input](#)
|
||||
- [No box and PXE boot](#)
|
||||
- [SSH Access To VM](#)
|
||||
- [Forwarded Ports](#)
|
||||
- [Synced Folders](#)
|
||||
- [Customized Graphics](#)
|
||||
- [Box Format](#)
|
||||
- [Create Box](#)
|
||||
- [Development](#)
|
||||
- [Contributing](#)
|
||||
- [Features](#features)
|
||||
- [Future work](#future-work)
|
||||
- [Installation](#installation)
|
||||
- [Possible problems with plugin installation on Linux](#possible-problems-with-plugin-installation-on-linux)
|
||||
- [Vagrant Project Preparation](#vagrant-project-preparation)
|
||||
- [Add Box](#add-box)
|
||||
- [Create Vagrantfile](#create-vagrantfile)
|
||||
- [Start VM](#start-vm)
|
||||
- [How Project Is Created](#how-project-is-created)
|
||||
- [Libvirt Configuration](#libvirt-configuration)
|
||||
- [Provider Options](#provider-options)
|
||||
- [Domain Specific Options](#domain-specific-options)
|
||||
- [Reload behavior](#reload-behavior)
|
||||
- [Networks](#networks)
|
||||
- [Private Network Options](#private-network-options)
|
||||
- [Public Network Options](#public-network-options)
|
||||
- [Management Network](#management-network)
|
||||
- [Additional Disks](#additional-disks)
|
||||
- [CDROMs](#cdroms)
|
||||
- [Input](#input)
|
||||
- [No box and PXE boot](#no-box-and-pxe-boot)
|
||||
- [SSH Access To VM](#ssh-access-to-vm)
|
||||
- [Forwarded Ports](#forwarded-ports)
|
||||
- [Synced Folders](#synced-folders)
|
||||
- [Customized Graphics](#customized-graphics)
|
||||
- [Box Format](#box-format)
|
||||
- [Create Box](#create-box)
|
||||
- [Development](#development)
|
||||
- [Contributing](#contributing)
|
||||
|
||||
## Features
|
||||
|
||||
@ -157,7 +158,7 @@ Although it should work without any configuration for most people, this provider
|
||||
|
||||
* `driver` - A hypervisor name to access. For now only kvm and qemu are supported.
|
||||
* `host` - The name of the server, where libvirtd is running.
|
||||
* `connect_via_ssh` - If use ssh tunnel to connect to Libvirt.
|
||||
* `connect_via_ssh` - If use ssh tunnel to connect to Libvirt. Absolutely needed to access libvirt on remote host. It will not be able to get the IP address of a started VM otherwise.
|
||||
* `username` - Username and password to access Libvirt.
|
||||
* `password` - Password to access Libvirt.
|
||||
* `id_ssh_key_file` - If not nil, uses this ssh private key to access Libvirt. Default is $HOME/.ssh/id_rsa. Prepends $HOME/.ssh/ if no directory.
|
||||
@ -181,11 +182,11 @@ end
|
||||
### Domain Specific Options
|
||||
|
||||
* `disk_bus` - The type of disk device to emulate. Defaults to virtio if not set. Possible values are documented in libvirt's [description for _target_](http://libvirt.org/formatdomain.html#elementsDisks).
|
||||
* `nic_model_type` - parameter specifies the model of the network adapter when you create a domain value by default virtio KVM believe possible values, see the documentation for libvirt
|
||||
* `nic_model_type` - parameter specifies the model of the network adapter when you create a domain value by default virtio KVM believe possible values, see the [documentation for libvirt](https://libvirt.org/formatdomain.html#elementsNICSModel).
|
||||
* `memory` - Amount of memory in MBytes. Defaults to 512 if not set.
|
||||
* `cpus` - Number of virtual cpus. Defaults to 1 if not set.
|
||||
* `nested` - [Enable nested virtualization](https://github.com/torvalds/linux/blob/master/Documentation/virtual/kvm/nested-vmx.txt). Default is false.
|
||||
* `cpu_mode` - [What cpu type to emulate](https://libvirt.org/formatdomain.html#elementsCPU). Defaults to 'host-model' if not set. Allowed values: host-model, host-passthrough.
|
||||
* `cpu_mode` - [CPU emulation mode](https://libvirt.org/formatdomain.html#elementsCPU). Defaults to 'host-model' if not set. Allowed values: host-model, host-passthrough.
|
||||
* `loader` - Sets path to custom UEFI loader.
|
||||
* `volume_cache` - Controls the cache mechanism. Possible values are "default", "none", "writethrough", "writeback", "directsync" and "unsafe". [See driver->cache in libvirt documentation](http://libvirt.org/formatdomain.html#elementsDisks).
|
||||
* `kernel` - To launch the guest with a kernel residing on host filesystems. Equivalent to qemu `-kernel`.
|
||||
@ -196,14 +197,16 @@ end
|
||||
* `graphics_port` - Sets the port for the display protocol to bind to. Defaults to 5900.
|
||||
* `graphics_ip` - Sets the IP for the display protocol to bind to. Defaults to "127.0.0.0.1".
|
||||
* `graphics_passwd` - Sets the password for the display protocol. Working for vnc and spice. by default working without passsword.
|
||||
* `video_type` - Sets the graphics card type exposed to the guest. Defaults to "cirrus". [Possible values](http://libvirt.org/formatdomain.html#elementsVideo) are "vga", "cirrus", "vmvga", "xen", "vbox", or "qxl".
|
||||
* `graphics_autoport` - Sets autoport for graphics, libvirt in this case ignores graphics_port value, Defaults to 'yes'. Possible value are "yes" and "no"
|
||||
* `keymap` - Set keymap for vm. default: en-us
|
||||
* `video_type` - Sets the graphics card type exposed to the guest. Defaults to "cirrus". [Possible values](http://libvirt.org/formatdomain.html#elementsVideo) are "vga", "cirrus", "vmvga", "xen", "vbox", or "qxl".
|
||||
* `video_vram` - Used by some graphics card types to vary the amount of RAM dedicated to video. Defaults to 9216.
|
||||
* `machine` - Sets machine type. Equivalent to qemu `-machine`. Use `qemu-system-x86_64 -machine help` to get a list of supported machines.
|
||||
* `machine_arch` - Sets machine architecture. This helps libvirt to determine the correct emulator type. Possible values depend on your version of qemu. For possible values, see which emulator executable `qemu-system-*` your system provides. Common examples are `aarch64`, `alpha`, `arm`, `cris`, `i386`, `lm32`, `m68k`, `microblaze`, `microblazeel`, `mips`, `mips64`, `mips64el`, `mipsel`, `moxie`, `or32`, `ppc`, `ppc64`, `ppcemb`, `s390x`, `sh4`, `sh4eb`, `sparc`, `sparc64`, `tricore`, `unicore32`, `x86_64`, `xtensa`, `xtensaeb`.
|
||||
* `machine_virtual_size` - Sets the disk size in GB for the machine overriding the default specified in the box. Allows boxes to defined with a minimal size disk by default and to be grown to a larger size at creation time. Will ignore sizes smaller than the size specified by the box metadata. Note that currently there is no support for automatically resizing the filesystem to take advantage of the larger disk.
|
||||
* `boot` - Change the boot order and enables the boot menu. Possible options are "hd", "network", "cdrom". Defaults to "hd" with boot menu disabled. When "network" is set without "hd", only all NICs will be tried; see below for more detail.
|
||||
* `nic_adapter_count` - Defaults to '8'. Only use case for increasing this count is for VMs that virtualize switches such as Cumulus Linux. Max value for Cumulus Linux VMs is 33.
|
||||
* `uuid` - Force a domain UUID. Defaults to autogenerated value by libvirt if not set.
|
||||
|
||||
|
||||
Specific domain settings can be set for each domain separately in multi-VM
|
||||
@ -243,6 +246,25 @@ Vagrant.configure("2") do |config|
|
||||
# ...
|
||||
```
|
||||
|
||||
#### Reload behavior
|
||||
On vagrant reload the following domain specific attributes are updated in defined domain:
|
||||
|
||||
* `disk_bus` - Is updated only on disks. It skips cdroms.
|
||||
* `nic_model_type` - Updated.
|
||||
* `memory` - Updated.
|
||||
* `cpus` - Updated.
|
||||
* `nested` - Updated.
|
||||
* `cpu_mode` - Updated. Pay attention that custom mode is not supported.
|
||||
* `graphics_type` - Updated.
|
||||
* `graphics_port` - Updated.
|
||||
* `graphics_ip` - Updated.
|
||||
* `graphics_passwd` - Updated.
|
||||
* `graphics_autoport` - Updated.
|
||||
* `keymap` - Updated.
|
||||
* `video_type` - Updated.
|
||||
* `video_vram` - Updated.
|
||||
|
||||
|
||||
## Networks
|
||||
|
||||
Networking features in the form of `config.vm.network` support private networks
|
||||
|
@ -31,6 +31,7 @@ module VagrantPlugins
|
||||
|
||||
# Gather some info about domain
|
||||
@name = env[:domain_name]
|
||||
@uuid = config.uuid
|
||||
@cpus = config.cpus.to_i
|
||||
@cpu_mode = config.cpu_mode
|
||||
@loader = config.loader
|
||||
@ -133,6 +134,9 @@ module VagrantPlugins
|
||||
# Output the settings we're going to use to the user
|
||||
env[:ui].info(I18n.t('vagrant_libvirt.creating_domain'))
|
||||
env[:ui].info(" -- Name: #{@name}")
|
||||
if @uuid != ''
|
||||
env[:ui].info(" -- Forced UUID: #{@uuid}")
|
||||
end
|
||||
env[:ui].info(" -- Domain type: #{@domain_type}")
|
||||
env[:ui].info(" -- Cpus: #{@cpus}")
|
||||
env[:ui].info(" -- Memory: #{@memory_size / 1024}M")
|
||||
@ -177,7 +181,7 @@ module VagrantPlugins
|
||||
env[:ui].info(" -- CDROM(#{cdrom[:dev]}): #{cdrom[:path]}")
|
||||
end
|
||||
@inputs.each do |input|
|
||||
env[:ui].info(" -- INPUT : type=#{input[:type]}, bus=#{input[:bus]}")
|
||||
env[:ui].info(" -- INPUT: type=#{input[:type]}, bus=#{input[:bus]}")
|
||||
end
|
||||
env[:ui].info(" -- Command line : #{@cmd_line}")
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
require 'log4r'
|
||||
require 'rexml/document'
|
||||
|
||||
module VagrantPlugins
|
||||
module ProviderLibvirt
|
||||
module Action
|
||||
|
||||
# Just start the domain.
|
||||
class StartDomain
|
||||
def initialize(app, env)
|
||||
@ -16,8 +16,157 @@ module VagrantPlugins
|
||||
|
||||
domain = env[:machine].provider.driver.connection.servers.get(env[:machine].id.to_s)
|
||||
raise Errors::NoDomainError if domain == nil
|
||||
config = env[:machine].provider_config
|
||||
|
||||
begin
|
||||
# update domain settings on change.
|
||||
|
||||
libvirt_domain = env[:machine].provider.driver.connection.client.lookup_domain_by_uuid(env[:machine].id)
|
||||
|
||||
if config.memory*1024 != libvirt_domain.max_memory
|
||||
libvirt_domain.max_memory = config.memory*1024
|
||||
libvirt_domain.memory = libvirt_domain.max_memory
|
||||
end
|
||||
begin
|
||||
# XML definition manipulation
|
||||
descr = libvirt_domain.xml_desc(1)
|
||||
xml_descr = REXML::Document.new descr
|
||||
descr_changed = false
|
||||
|
||||
# disk_bus
|
||||
REXML::XPath.each(xml_descr,'/domain/devices/disk[@device="disk"]/target') {|disk_target|
|
||||
if disk_target.attributes['bus'] != config.disk_bus
|
||||
descr_changed = true
|
||||
disk_target.attributes['bus'] = config.disk_bus
|
||||
disk_target.parent.delete_element('//address')
|
||||
end
|
||||
}
|
||||
|
||||
# Iterface type
|
||||
REXML::XPath.each(xml_descr,'/domain/devices/interface/model') {|iface_model|
|
||||
if iface_model.attributes['type'] != config.nic_model_type
|
||||
descr_changed = true
|
||||
iface_model.attributes['type'] = config.nic_model_type
|
||||
end
|
||||
}
|
||||
|
||||
# vCpu count
|
||||
if config.cpus.to_i != libvirt_domain.vcpus.length
|
||||
descr_changed = true
|
||||
REXML::XPath.first(xml_descr,'/domain/vcpu').text = config.cpus
|
||||
end
|
||||
|
||||
# cpu_mode
|
||||
cpu = REXML::XPath.first(xml_descr,'/domain/cpu')
|
||||
if cpu.nil?
|
||||
descr_changed = true
|
||||
cpu = REXML::Element.new('cpu', REXML::XPath.first(xml_descr,'/domain'))
|
||||
cpu.attributes['mode'] = config.cpu_mode
|
||||
else
|
||||
if cpu.attributes['mode'] != config.cpu_mode
|
||||
descr_changed = true
|
||||
cpu.attributes['mode'] = config.cpu_mode
|
||||
end
|
||||
end
|
||||
|
||||
if config.cpu_mode != 'host-passthrough'
|
||||
cpu_model = REXML::XPath.first(xml_descr,'/domain/cpu/model')
|
||||
if cpu_model.nil?
|
||||
descr_changed = true
|
||||
cpu_model = REXML::Element.new('model', REXML::XPath.first(xml_descr,'/domain/cpu'))
|
||||
cpu_model.attributes['fallback'] = 'allow'
|
||||
cpu_model.text = 'qemu64'
|
||||
end
|
||||
vmx_feature = REXML::XPath.first(xml_descr,'/domain/cpu/feature[@name="vmx"]')
|
||||
svm_feature = REXML::XPath.first(xml_descr,'/domain/cpu/feature[@name="svm"]')
|
||||
if config.nested
|
||||
if vmx_feature.nil?
|
||||
descr_changed = true
|
||||
vmx_feature = REXML::Element.new('feature', REXML::XPath.first(xml_descr,'/domain/cpu'))
|
||||
vmx_feature.attributes['policy'] = 'optional'
|
||||
vmx_feature.attributes['name'] = 'vmx'
|
||||
end
|
||||
if svm_feature.nil?
|
||||
descr_changed = true
|
||||
svm_feature = REXML::Element.new('feature', REXML::XPath.first(xml_descr,'/domain/cpu'))
|
||||
svm_feature.attributes['policy'] = 'optional'
|
||||
svm_feature.attributes['name'] = 'svm'
|
||||
end
|
||||
else
|
||||
if !vmx_feature.nil?
|
||||
descr_changed = true
|
||||
cpu.delete_element(vmx_feature)
|
||||
end
|
||||
if !svm_feature.nil?
|
||||
descr_changed = true
|
||||
cpu.delete_element(svm_feature)
|
||||
end
|
||||
end
|
||||
else
|
||||
if cpu.elements.to_a.length > 0
|
||||
descr_changed = true
|
||||
cpu.elements.each {|elem|
|
||||
cpu.delete_element(elem)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
# Graphics
|
||||
graphics = REXML::XPath.first(xml_descr,'/domain/devices/graphics')
|
||||
if graphics.attributes['type'] != config.graphics_type
|
||||
descr_changed = true
|
||||
graphics.attributes['type'] = config.graphics_type
|
||||
end
|
||||
if graphics.attributes['listen'] != config.graphics_ip
|
||||
descr_changed = true
|
||||
graphics.attributes['listen'] = config.graphics_ip
|
||||
graphics.delete_element('//listen')
|
||||
end
|
||||
if graphics.attributes['autoport'] != config.graphics_autoport
|
||||
descr_changed = true
|
||||
graphics.attributes['autoport'] = config.graphics_autoport
|
||||
if config.graphics_autoport == 'no'
|
||||
graphics.attributes['port'] = config.graphics_port
|
||||
end
|
||||
end
|
||||
if graphics.attributes['keymap'] != config.keymap
|
||||
descr_changed = true
|
||||
graphics.attributes['keymap'] = config.keymap
|
||||
end
|
||||
if graphics.attributes['passwd'] != config.graphics_passwd
|
||||
descr_changed = true
|
||||
if config.graphics_passwd.nil?
|
||||
graphics.attributes.delete 'passwd'
|
||||
else
|
||||
graphics.attributes['passwd'] = config.graphics_passwd
|
||||
end
|
||||
end
|
||||
|
||||
# Video device
|
||||
video = REXML::XPath.first(xml_descr,'/domain/devices/video/model')
|
||||
if video.attributes['type'] != config.video_type || video.attributes['vram'] != config.video_vram
|
||||
descr_changed = true
|
||||
video.attributes.each_attribute {|attr| video.attributes.delete attr}
|
||||
video.attributes['type'] = config.video_type
|
||||
video.attributes['vram'] = config.video_vram
|
||||
end
|
||||
|
||||
# Apply
|
||||
if descr_changed
|
||||
begin
|
||||
libvirt_domain.undefine
|
||||
new_descr = ""
|
||||
xml_descr.write new_descr
|
||||
server = env[:machine].provider.driver.connection.servers.create(xml: new_descr)
|
||||
rescue Fog::Errors::Error => e
|
||||
server = env[:machine].provider.driver.connection.servers.create(xml: descr)
|
||||
raise Errors::FogCreateServerError, error_message: e.message
|
||||
end
|
||||
end
|
||||
rescue => e
|
||||
env[:ui].info("Error when updating domain settings: #{e.message}")
|
||||
end
|
||||
# Actually start the domain
|
||||
domain.start
|
||||
rescue => e
|
||||
raise Errors::FogError, :message => e.message
|
||||
|
@ -53,6 +53,7 @@ module VagrantPlugins
|
||||
attr_accessor :default_prefix
|
||||
|
||||
# Domain specific settings used while creating new domain.
|
||||
attr_accessor :uuid
|
||||
attr_accessor :memory
|
||||
attr_accessor :cpus
|
||||
attr_accessor :cpu_mode
|
||||
@ -105,6 +106,7 @@ module VagrantPlugins
|
||||
@management_network_mac = UNSET_VALUE
|
||||
|
||||
# Domain specific settings.
|
||||
@uuid = UNSET_VALUE
|
||||
@memory = UNSET_VALUE
|
||||
@cpus = UNSET_VALUE
|
||||
@cpu_mode = UNSET_VALUE
|
||||
@ -317,6 +319,7 @@ module VagrantPlugins
|
||||
@uri = _generate_uri() if @uri == UNSET_VALUE
|
||||
|
||||
# Domain specific settings.
|
||||
@uuid = '' if @uuid == UNSET_VALUE
|
||||
@memory = 512 if @memory == UNSET_VALUE
|
||||
@cpus = 1 if @cpus == UNSET_VALUE
|
||||
@cpu_mode = 'host-model' if @cpu_mode == UNSET_VALUE
|
||||
|
@ -1,5 +1,6 @@
|
||||
<domain type='<%= @domain_type %>'>
|
||||
<name><%= @name %></name>
|
||||
<uuid><%= @uuid %></uuid>
|
||||
<memory><%= @memory_size %></memory>
|
||||
<vcpu><%= @cpus %></vcpu>
|
||||
|
||||
@ -87,9 +88,9 @@
|
||||
|
||||
<%# Video device -%>
|
||||
<graphics type='<%= @graphics_type %>' port='<%= @graphics_port %>' autoport='<%= @graphics_autoport %>' listen='<%= @graphics_ip %>' keymap='<%= @keymap %>' <%= @graphics_passwd%> />
|
||||
<video>
|
||||
<model type='<%= @video_type %>' vram='<%= @video_vram %>' heads='1'/>
|
||||
</video>
|
||||
<video>
|
||||
<model type='<%= @video_type %>' vram='<%= @video_vram %>' heads='1'/>
|
||||
</video>
|
||||
<%#End Video -%>
|
||||
</devices>
|
||||
</domain>
|
||||
|
Loading…
Reference in New Issue
Block a user