mirror of
https://github.com/vagrant-libvirt/vagrant-libvirt.git
synced 2025-02-25 18:55:27 -06:00
Merge pull request #606 from shawnlower/shawnlower_add-guest-agent-support
Add support for libvirt channels:
This commit is contained in:
commit
c86a6f4527
64
README.md
64
README.md
@ -222,7 +222,7 @@ end
|
||||
* `tpm_path` - The path to the TPM device on the host system.
|
||||
* `dtb` - The device tree blob file, mostly used for non-x86 platforms. In case the device tree isn't added in-line to the kernel, it can be manually specified here.
|
||||
* `autostart` - Automatically start the domain when the host boots. Defaults to 'false'.
|
||||
|
||||
* `channel` - [libvirt channels](https://libvirt.org/formatdomain.html#elementCharChannel). Configure a private communication channel between the host and guest, e.g. for use by the [qemu guest agent](http://wiki.libvirt.org/page/Qemu_guest_agent) and the Spice/QXL graphics type.
|
||||
|
||||
Specific domain settings can be set for each domain separately in multi-VM
|
||||
environment. Example below shows a part of Vagrantfile, where specific options
|
||||
@ -715,6 +715,68 @@ Vagrant.configure("2") do |config|
|
||||
end
|
||||
```
|
||||
|
||||
## Libvirt communication channels
|
||||
|
||||
For certain functionality to be available within a guest, a private
|
||||
communication channel must be established with the host. Two notable examples of
|
||||
this are the qemu guest agent, and the Spice/QXL graphics type.
|
||||
|
||||
Below is a simple example which exposes a virtio serial channel to the guest. Note: in a multi-VM environment, the channel would be created for all VMs.
|
||||
|
||||
```ruby
|
||||
vagrant.configure(2) do |config|
|
||||
config.vm.provider :libvirt do |libvirt|
|
||||
libvirt.channel :type => 'unix', :target_name => 'org.qemu.guest_agent.0', :target_type => 'virtio'
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
Below is the syntax for creating a spicevmc channel for use by a qxl graphics card.
|
||||
|
||||
```ruby
|
||||
vagrant.configure(2) do |config|
|
||||
config.vm.provider :libvirt do |libvirt|
|
||||
libvirt.channel :type => 'spicevmc', :target_name => 'com.redhat.spice.0', :target_type => 'virtio'
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
These settings can be specified on a per-VM basis, however the per-guest settings will OVERRIDE any global 'config' setting. In the following example, we create 3 VM with the following configuration:
|
||||
|
||||
master: No channel settings specified, so we default to the provider setting of a single virtio guest agent channel.
|
||||
node1: Override the channel setting, setting both the guest agent channel, and a spicevmc channel
|
||||
node2: Override the channel setting, setting both the guest agent channel, and a 'guestfwd' channel. TCP traffic sent by the guest to the given IP address and port is forwarded to the host socket /tmp/foo. Note: this device must be unique for each VM.
|
||||
|
||||
Example
|
||||
|
||||
```ruby
|
||||
Vagrant.configure(2) do |config|
|
||||
config.vm.box = "fedora/23-cloud-base"
|
||||
config.vm.provider :libvirt do |libvirt|
|
||||
libvirt.channel :type => 'unix', :target_name => 'org.qemu.guest_agent.0', :target_type => 'virtio'
|
||||
end
|
||||
|
||||
config.vm.define "master" do |master|
|
||||
master.vm.provider :libvirt do |domain|
|
||||
domain.memory = 1024
|
||||
end
|
||||
end
|
||||
config.vm.define "node1" do |node1|
|
||||
node1.vm.provider :libvirt do |domain|
|
||||
domain.channel :type => 'unix', :target_name => 'org.qemu.guest_agent.0', :target_type => 'virtio'
|
||||
domain.channel :type => 'spicevmc', :target_name => 'com.redhat.spice.0', :target_type => 'virtio'
|
||||
end
|
||||
end
|
||||
config.vm.define "node2" do |node2|
|
||||
node2.vm.provider :libvirt do |domain|
|
||||
domain.channel :type => 'unix', :target_name => 'org.qemu.guest_agent.0', :target_type => 'virtio'
|
||||
domain.channel :type => 'unix', :target_type => 'guestfwd', :target_address => '192.0.2.42', :target_port => '4242',
|
||||
:source_path => '/tmp/foo'
|
||||
end
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
## Box Format
|
||||
|
||||
You can view an example box in the [example_box/directory](https://github.com/vagrant-libvirt/vagrant-libvirt/tree/master/example_box). That directory also contains instructions on how to build a box.
|
||||
|
@ -79,6 +79,9 @@ module VagrantPlugins
|
||||
# Input
|
||||
@inputs = config.inputs
|
||||
|
||||
# Channels
|
||||
@channels = config.channels
|
||||
|
||||
# PCI device passthrough
|
||||
@pcis = config.pcis
|
||||
|
||||
@ -205,6 +208,11 @@ module VagrantPlugins
|
||||
env[:ui].info(" -- INPUT: type=#{input[:type]}, bus=#{input[:bus]}")
|
||||
end
|
||||
|
||||
@channels.each do |channel|
|
||||
env[:ui].info(" -- CHANNEL: type=#{channel[:type]}, mode=#{channel[:source_mode]}")
|
||||
env[:ui].info(" -- CHANNEL: target_type=#{channel[:target_type]}, target_name=#{channel[:target_name]}")
|
||||
end
|
||||
|
||||
@pcis.each do |pci|
|
||||
env[:ui].info(" -- PCI passthrough: #{pci[:bus]}:#{pci[:slot]}.#{pci[:function]}")
|
||||
end
|
||||
|
@ -56,6 +56,7 @@ module VagrantPlugins
|
||||
# Domain specific settings used while creating new domain.
|
||||
attr_accessor :uuid
|
||||
attr_accessor :memory
|
||||
attr_accessor :channel
|
||||
attr_accessor :cpus
|
||||
attr_accessor :cpu_mode
|
||||
attr_accessor :cpu_model
|
||||
@ -103,6 +104,9 @@ module VagrantPlugins
|
||||
# Inputs
|
||||
attr_accessor :inputs
|
||||
|
||||
# Channels
|
||||
attr_accessor :channels
|
||||
|
||||
# PCI device passthrough
|
||||
attr_accessor :pcis
|
||||
|
||||
@ -177,6 +181,9 @@ module VagrantPlugins
|
||||
# Inputs
|
||||
@inputs = UNSET_VALUE
|
||||
|
||||
# Channels
|
||||
@channels = UNSET_VALUE
|
||||
|
||||
# PCI device passthrough
|
||||
@pcis = UNSET_VALUE
|
||||
|
||||
@ -255,6 +262,32 @@ module VagrantPlugins
|
||||
})
|
||||
end
|
||||
|
||||
def channel(options={})
|
||||
if options[:type].nil?
|
||||
raise "Channel type must be specified."
|
||||
elsif options[:type] == 'unix' && options[:target_type] == 'guestfwd'
|
||||
# Guest forwarding requires a target (ip address) and a port
|
||||
if options[:target_address].nil? || options[:target_port].nil? ||
|
||||
options[:source_path].nil?
|
||||
raise 'guestfwd requires target_address, target_port and source_path'
|
||||
end
|
||||
end
|
||||
|
||||
if @channels == UNSET_VALUE
|
||||
@channels = []
|
||||
end
|
||||
|
||||
@channels.push({
|
||||
type: options[:type],
|
||||
source_mode: options[:source_mode],
|
||||
source_path: options[:source_path],
|
||||
target_address: options[:target_address],
|
||||
target_name: options[:target_name],
|
||||
target_port: options[:target_port],
|
||||
target_type: options[:target_type]
|
||||
})
|
||||
end
|
||||
|
||||
def pci(options={})
|
||||
if options[:bus].nil? || options[:slot].nil? || options[:function].nil?
|
||||
raise 'Bus AND slot AND function must be specified. Check `lspci` for that numbers.'
|
||||
@ -465,6 +498,9 @@ module VagrantPlugins
|
||||
# Inputs
|
||||
@inputs = [{:type => "mouse", :bus => "ps2"}] if @inputs == UNSET_VALUE
|
||||
|
||||
# Channels
|
||||
@channels = [ ] if @channels == UNSET_VALUE
|
||||
|
||||
# PCI device passthrough
|
||||
@pcis = [] if @pcis == UNSET_VALUE
|
||||
|
||||
|
@ -96,6 +96,27 @@
|
||||
<target port='0'/>
|
||||
</console>
|
||||
|
||||
<% @channels.each do |channel| %>
|
||||
<channel type='<%= channel[:type] %>' >
|
||||
<source mode='<%= channel[:source_mode] %>'
|
||||
<% if channel[:source_path] %>
|
||||
path="<%= channel[:source_path] %>"
|
||||
<% end %>
|
||||
/>
|
||||
<target type='<%= channel[:target_type] %>'
|
||||
<% if channel[:target_name] %>
|
||||
name="<%= channel[:target_name] %>"
|
||||
<% end %>
|
||||
<% if channel[:target_address] %>
|
||||
address="<%= channel[:target_address] %>"
|
||||
<% end %>
|
||||
<% if channel[:target_port] %>
|
||||
port="<%= channel[:target_port] %>"
|
||||
<% end %>
|
||||
/>
|
||||
</channel>
|
||||
<% end %>
|
||||
|
||||
<% @inputs.each do |input| %>
|
||||
<input type='<%= input[:type] %>' bus='<%= input[:bus] %>'/>
|
||||
<% end %>
|
||||
|
Loading…
Reference in New Issue
Block a user