Rework destroy domain for multiple box volumes (#1404)

When destroying domains were there are multiple box volumes to be
removed, need to perform a series of checks to establish that the
correct volumes are being removed.

- check if device aliases are in use
- process the box volume removals first
- detect if disks attached outside of vagrant-libvirt
- prefer aliases for additional disks
- avoid use of devices for multiple disks to detect as currently
  assigned incorrectly.
- fallback to detecting number of box volumes to determine
  point at which additional disks start

Attempts to flag a number of cases where behaviour might be incorrect to
help users spot when vagrant-libvirt may accidentally remove something
it shouldn't.
This commit is contained in:
Darragh Bailey
2021-11-21 11:52:45 +00:00
committed by GitHub
parent 5eac9de006
commit f8eff3d7a9
9 changed files with 615 additions and 54 deletions

View File

@@ -1,6 +1,7 @@
# frozen_string_literal: true
require 'log4r'
require 'rexml'
module VagrantPlugins
module ProviderLibvirt
@@ -48,37 +49,126 @@ module VagrantPlugins
# cdroms are consider volumes, but cannot be destroyed
domain.destroy(destroy_volumes: true)
else
domain_xml = libvirt_domain.xml_desc(1)
xml_descr = REXML::Document.new(domain_xml)
disks_xml = REXML::XPath.match(xml_descr, '/domain/devices/disk[@device="disk"]')
have_aliases = !(REXML::XPath.match(disks_xml, './alias[@name="ua-box-volume-0"]').first).nil?
if !have_aliases
env[:ui].warn(I18n.t('vagrant_libvirt.destroy.obsolete_method'))
end
domain.destroy(destroy_volumes: false)
env[:machine].provider_config.disks.each do |disk|
# shared disks remove only manually or ???
next if disk[:allow_existing]
diskname = libvirt_domain.name + '-' + disk[:device] + '.' + disk[:type].to_s
# diskname is unique
libvirt_disk = domain.volumes.select do |x|
x.name == diskname
end.first
if libvirt_disk
libvirt_disk.destroy
elsif disk[:path]
poolname = env[:machine].provider_config.storage_pool_name
libvirt_disk = domain.volumes.select do |x|
# FIXME: can remove pool/target.img and pool/123/target.img
x.path =~ /\/#{disk[:path]}$/ && x.pool_name == poolname
volumes = domain.volumes
# Remove root storage. If no aliases available, perform the removal by name and keep track
# of how many matches there are in the volumes. This will provide a fallback offset to where
# the additional storage devices are.
detected_box_volumes = 0
if have_aliases
REXML::XPath.match(disks_xml, './alias[contains(@name, "ua-box-volume-")]').each do |box_disk|
diskname = box_disk.parent.elements['source'].attributes['file'].rpartition('/').last
detected_box_volumes += 1
destroy_volume(volumes, diskname, env)
end
else
# fallback to try and infer which boxes are box images, as they are listed first
# as soon as there is no match, can exit
disks_xml.each_with_index do |box_disk, idx|
name = libvirt_domain.name + (idx == 0 ? '.img' : "_#{idx}.img")
diskname = box_disk.elements['source'].attributes['file'].rpartition('/').last
break if name != diskname
detected_box_volumes += 1
root_disk = volumes.select do |x|
x.name == name if x
end.first
libvirt_disk.destroy if libvirt_disk
if root_disk
root_disk.destroy
end
end
end
# remove root storage
root_disk = domain.volumes.select do |x|
x.name == libvirt_domain.name + '.img' if x
end.first
root_disk.destroy if root_disk
# work out if there are any custom disks attached that wasn't done by vagrant-libvirt,
# and warn there might be unexpected behaviour
total_disks = disks_xml.length
offset = total_disks - env[:machine].provider_config.disks.length
if offset != detected_box_volumes
env[:ui].warn(I18n.t('vagrant_libvirt.destroy.unexpected_volumes'))
end
if !have_aliases
# if no aliases found, see if it's possible to check the number of box disks
# otherwise the destroy could remove the wrong disk by accident.
if env[:machine].box != nil
box_disks = env[:machine].box.metadata.fetch('disks', [1])
offset = box_disks.length
if offset != detected_box_volumes
env[:ui].warn(I18n.t('vagrant_libvirt.destroy.expected_removal_mismatch'))
end
else
env[:ui].warn(I18n.t('vagrant_libvirt.destroy.box_metadata_unavailable'))
end
# offset only used when no aliases available
offset = detected_box_volumes
end
env[:machine].provider_config.disks.each_with_index.each do |disk, index|
# shared disks remove only manually or ???
next if disk[:allow_existing]
# look for exact match using aliases which will be used
# for subsequent domain creations
if have_aliases
domain_disk = REXML::XPath.match(disks_xml, './alias[@name="ua-disk-volume-' + index.to_s + '"]').first
domain_disk = domain_disk.parent if !domain_disk.nil?
else
# otherwise fallback to find the disk by device if specified by user
# and finally index counting with offset and hope the match is correct
if offset > 1
# Currently disk devices are resolved incorrectly if the box has more than one device
# this should be solved subsequently by delaying the resolution, however for now
# default to using offset when more than one box volume.
domain_disk = disks_xml[offset + index]
elsif !disk[:device].nil?
domain_disk = REXML::XPath.match(disks_xml, './target[@dev="' + disk[:device] + '"]').first
domain_disk = domain_disk.parent if !domain_disk.nil?
else
domain_disk = disks_xml[offset + index]
end
end
next if domain_disk.nil?
diskname = domain_disk.elements['source'].attributes['file'].rpartition('/').last
destroy_volume(volumes, diskname, env)
end
end
@app.call(env)
end
protected
def destroy_volume(volumes, diskname, env)
# diskname is unique
libvirt_disk = volumes.select do |x|
x.name == diskname if x
end.first
if libvirt_disk
libvirt_disk.destroy
elsif disk[:path]
poolname = env[:machine].provider_config.storage_pool_name
libvirt_disk = volumes.select do |x|
# FIXME: can remove pool/target.img and pool/123/target.img
x.path =~ /\/#{disk[:path]}$/ && x.pool_name == poolname
end.first
libvirt_disk.destroy if libvirt_disk
end
end
end
end
end

View File

@@ -58,6 +58,17 @@ en:
remove_stale_volume: |-
Remove stale volume...
destroy:
obsolete_method: |
Destroying machine that was originally created without device aliases (pre 0.6.0), using fallback approach.
unexpected_volumes: |
Unexpected number of volumes detected, possibly additional volumes attached outside of vagrant-libvirt.
Attempting to handle this correctly, however may experience unexpected behaviour in the domain destroy.
expected_removal_mismatch: |
mismatch of volumes associated with box to number removed, may be stray box volumes left
box_metadata_unavailable: |
box metadata not available to get volume list during destroy, assuming inferred list
warnings:
ignoring_virtual_size_too_small: |-
Ignoring requested virtual disk size of '%{requested}' as it is below

View File

@@ -17,9 +17,12 @@ describe VagrantPlugins::ProviderLibvirt::Action::DestroyDomain do
let(:libvirt_client) { double('libvirt_client') }
let(:servers) { double('servers') }
let(:domain_xml) { File.read(File.join(File.dirname(__FILE__), File.basename(__FILE__, '.rb'), domain_xml_file)) }
before do
allow(machine.provider).to receive('driver').and_return(driver)
allow(driver).to receive(:connection).and_return(connection)
allow(logger).to receive(:info)
end
describe '#call' do
@@ -27,8 +30,10 @@ describe VagrantPlugins::ProviderLibvirt::Action::DestroyDomain do
allow(connection).to receive(:client).and_return(libvirt_client)
allow(libvirt_client).to receive(:lookup_domain_by_uuid)
.and_return(libvirt_domain)
allow(libvirt_domain).to receive(:name).and_return('vagrant-test_default')
allow(connection).to receive(:servers).and_return(servers)
allow(servers).to receive(:get).and_return(domain)
# always see this at the start of #call
expect(ui).to receive(:info).with('Removing domain...')
end
@@ -39,59 +44,158 @@ describe VagrantPlugins::ProviderLibvirt::Action::DestroyDomain do
before do
allow(libvirt_domain).to receive(:list_snapshots).and_return([])
allow(libvirt_domain).to receive(:has_managed_save?).and_return(nil)
allow(root_disk).to receive(:name).and_return('test.img')
allow(root_disk).to receive(:name).and_return('vagrant-test_default.img')
end
context 'when only has root disk' do
context 'when box only has one root disk' do
it 'calls fog to destroy volumes' do
expect(domain).to receive(:destroy).with(destroy_volumes: true)
expect(subject.call(env)).to be_nil
end
context 'when has additional disks' do
let(:vagrantfile_providerconfig) do
<<-EOF
libvirt.storage :file
EOF
end
let(:domain_xml_file) { 'additional_disks_domain.xml' }
let(:extra_disk) { double('libvirt_extra_disk') }
before do
allow(extra_disk).to receive(:name).and_return('vagrant-test_default-vdb.qcow2')
allow(domain).to receive(:volumes).and_return([root_disk, extra_disk])
expect(libvirt_domain).to receive(:xml_desc).and_return(domain_xml)
end
it 'destroys disks individually' do
expect(domain).to receive(:destroy).with(destroy_volumes: false)
expect(extra_disk).to receive(:destroy) # extra disk remove
expect(root_disk).to receive(:destroy) # root disk remove
expect(subject.call(env)).to be_nil
end
end
end
context 'when has additional disks' do
let(:vagrantfile) do
<<-EOF
Vagrant.configure('2') do |config|
config.vm.define :test
config.vm.provider :libvirt do |libvirt|
libvirt.storage :file
context 'when box has multiple disks' do
let(:domain_xml_file) { 'box_multiple_disks.xml' }
it 'calls fog to destroy volumes' do
expect(domain).to receive(:destroy).with(destroy_volumes: true)
expect(subject.call(env)).to be_nil
end
context 'when has additional disks' do
let(:domain_xml_file) { 'box_multiple_disks_and_additional_disks.xml' }
let(:vagrantfile_providerconfig) do
<<-EOF
libvirt.storage :file
libvirt.storage :file
EOF
end
let(:domain_disks) {[
[double('box-disk-1'), 'vagrant-test_default.img'],
[double('box-disk-2'), 'vagrant-test_default_1.img'],
[double('box-disk-3'), 'vagrant-test_default_2.img'],
[double('additional-disk-1'), 'vagrant-test_default-vdd.qcow2'],
[double('additional-disk-2'), 'vagrant-test_default-vde.qcow2'],
]}
before do
allow(libvirt_domain).to receive(:xml_desc).and_return(domain_xml)
allow(domain).to receive(:volumes).and_return(domain_disks.map { |a| a.first })
end
it 'destroys disks individually' do
domain_disks.each do |disk, name|
expect(disk).to receive(:name).and_return(name).at_least(:once)
expect(disk).to receive(:destroy)
end
expect(domain).to receive(:destroy).with(destroy_volumes: false)
expect(subject.call(env)).to be_nil
end
context 'when has disks added via custom virsh commands' do
let(:domain_xml_file) { 'box_multiple_disks_and_additional_and_custom_disks.xml' }
let(:domain_disks) {[
[double('box-disk-1'), 'vagrant-test_default.img'],
[double('box-disk-2'), 'vagrant-test_default_1.img'],
[double('box-disk-3'), 'vagrant-test_default_2.img'],
[double('additional-disk-1'), 'vagrant-test_default-vdd.qcow2'],
[double('additional-disk-2'), 'vagrant-test_default-vde.qcow2'],
[double('custom-disk-1'), 'vagrant-test_default-vdf.qcow2'],
]}
it 'only destroys expected disks' do
expect(ui).to receive(:warn).with(/Unexpected number of volumes detected.*/)
domain_disks.each do |disk, name|
expect(disk).to receive(:name).and_return(name).at_least(:once)
next if disk == domain_disks.last.first
expect(disk).to receive(:destroy)
end
expect(domain).to receive(:destroy).with(destroy_volumes: false)
expect(subject.call(env)).to be_nil
end
context 'without aliases' do
let(:domain_xml_file) { 'box_multiple_disks_and_additional_and_custom_disks_no_aliases.xml' }
it 'only destroys expected disks' do
expect(ui).to receive(:warn).with(/Destroying machine that was originally created without device aliases.*/)
expect(ui).to receive(:warn).with(/Unexpected number of volumes detected/)
expect(ui).to receive(:warn).with(/box metadata not available to get volume list during destroy, assuming inferred list/)
domain_disks.each do |disk, name|
expect(disk).to receive(:name).and_return(name).at_least(:once)
# ignore box disks 2 and 3 and the last custom disk
next if domain_disks.last.first == disk
expect(disk).to receive(:destroy)
end
expect(domain).to receive(:destroy).with(destroy_volumes: false)
expect(subject.call(env)).to be_nil
end
context 'with box metadata' do
let(:box) { instance_double('::Vagrant::Box') }
before do
allow(env[:machine]).to receive(:box).and_return(box)
allow(box).to receive(:metadata).and_return(Hash[
'disks' => [
{:name => 'box-disk-1'},
{:name => 'box-disk-2'},
{:name => 'box-disk-3'},
]
])
end
it 'only destroys expected disks' do
expect(ui).to receive(:warn).with(/Destroying machine that was originally created without device aliases.*/)
expect(ui).to receive(:warn).with(/Unexpected number of volumes detected/)
domain_disks.each do |disk, name|
expect(disk).to receive(:name).and_return(name).at_least(:once)
# ignore box disks 2 and 3 and the last custom disk
next if domain_disks.last.first == disk
expect(disk).to receive(:destroy)
end
expect(domain).to receive(:destroy).with(destroy_volumes: false)
expect(subject.call(env)).to be_nil
end
end
end
end
EOF
end
let(:extra_disk) { double('libvirt_extra_disk') }
before do
allow(extra_disk).to receive(:name).and_return('test-vdb.qcow2')
end
it 'destroys disks individually' do
allow(libvirt_domain).to receive(:name).and_return('test')
allow(domain).to receive(:volumes).and_return([extra_disk], [root_disk])
expect(domain).to receive(:destroy).with(destroy_volumes: false)
expect(extra_disk).to receive(:destroy) # extra disk remove
expect(root_disk).to receive(:destroy) # root disk remove
expect(subject.call(env)).to be_nil
end
end
context 'when has CDROMs attached' do
let(:vagrantfile) do
let(:vagrantfile_providerconfig) do
<<-EOF
Vagrant.configure('2') do |config|
config.vm.define :test
config.vm.provider :libvirt do |libvirt|
libvirt.storage :file, :device => :cdrom
end
end
EOF
end
let(:domain_xml_file) { 'cdrom_domain.xml' }
it 'uses explicit removal of disks' do
allow(libvirt_domain).to receive(:name).and_return('test')
allow(domain).to receive(:volumes).and_return([root_disk, nil])
expect(domain).to receive(:volumes).and_return([root_disk, nil])
expect(libvirt_domain).to receive(:xml_desc).and_return(domain_xml)
expect(domain).to_not receive(:destroy).with(destroy_volumes: true)
expect(root_disk).to receive(:destroy) # root disk remove

View File

@@ -0,0 +1,47 @@
<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
<name>vagrant-test_default</name>
<title></title>
<description>Source: /rootpath/Vagrantfile</description>
<uuid></uuid>
<memory>524288</memory>
<vcpu>1</vcpu>
<cpu mode='host-model'>
<model fallback='allow'></model>
</cpu>
<os>
<type>hvm</type>
<kernel></kernel>
<initrd></initrd>
<cmdline></cmdline>
</os>
<features>
<acpi/>
<apic/>
<pae/>
</features>
<clock offset='utc'>
</clock>
<devices>
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2' cache='default'/>
<source file='/var/lib/libvirt/images/vagrant-test_default.img'/>
<target dev='vda' bus='virtio'/>
</disk>
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2' cache='default'/>
<source file='/var/lib/libvirt/images/vagrant-test_default-vdb.qcow2'/>
<target dev='vdb' bus='virtio'/>
</disk>
<serial type='pty'>
<target port='0'/>
</serial>
<console type='pty'>
<target port='0'/>
</console>
<input type='mouse' bus='ps2'/>
<graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' keymap='en-us'/>
<video>
<model type='cirrus' vram='9216' heads='1'/>
</video>
</devices>
</domain>

View File

@@ -0,0 +1,55 @@
<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
<name>vagrant-test_default</name>
<title></title>
<description>Source: /rootpath/Vagrantfile</description>
<uuid></uuid>
<memory>524288</memory>
<vcpu>1</vcpu>
<cpu mode='host-model'>
<model fallback='allow'></model>
</cpu>
<os>
<type>hvm</type>
<kernel></kernel>
<initrd></initrd>
<cmdline></cmdline>
</os>
<features>
<acpi/>
<apic/>
<pae/>
</features>
<clock offset='utc'>
</clock>
<devices>
<disk type='file' device='disk'>
<alias name='ua-box-volume-0'/>
<driver name='qemu' type='qcow2' cache='default'/>
<source file='/var/lib/libvirt/images/vagrant-test_default.img'/>
<target dev='vda' bus='virtio'/>
</disk>
<disk type='file' device='disk'>
<alias name='ua-box-volume-1'/>
<driver name='qemu' type='qcow2' cache='default'/>
<source file='/var/lib/libvirt/images/vagrant-test_default_1.img'/>
<target dev='vdb' bus='virtio'/>
</disk>
<disk type='file' device='disk'>
<alias name='ua-box-volume-2'/>
<driver name='qemu' type='qcow2' cache='default'/>
<source file='/var/lib/libvirt/images/vagrant-test_default_2.img'/>
<target dev='vdc' bus='virtio'/>
</disk>
<serial type='pty'>
<target port='0'/>
</serial>
<console type='pty'>
<target port='0'/>
</console>
<input type='mouse' bus='ps2'/>
<graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' keymap='en-us'/>
<video>
<model type='cirrus' vram='9216' heads='1'/>
</video>
</devices>
</domain>

View File

@@ -0,0 +1,72 @@
<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
<name>vagrant-test_default</name>
<title></title>
<description>Source: /rootpath/Vagrantfile</description>
<uuid></uuid>
<memory>524288</memory>
<vcpu>1</vcpu>
<cpu mode='host-model'>
<model fallback='allow'></model>
</cpu>
<os>
<type>hvm</type>
<kernel></kernel>
<initrd></initrd>
<cmdline></cmdline>
</os>
<features>
<acpi/>
<apic/>
<pae/>
</features>
<clock offset='utc'>
</clock>
<devices>
<disk type='file' device='disk'>
<alias name='ua-box-volume-0'/>
<driver name='qemu' type='qcow2' cache='default'/>
<source file='/var/lib/libvirt/images/vagrant-test_default.img'/>
<target dev='vda' bus='virtio'/>
</disk>
<disk type='file' device='disk'>
<alias name='ua-box-volume-1'/>
<driver name='qemu' type='qcow2' cache='default'/>
<source file='/var/lib/libvirt/images/vagrant-test_default_1.img'/>
<target dev='vdb' bus='virtio'/>
</disk>
<disk type='file' device='disk'>
<alias name='ua-box-volume-2'/>
<driver name='qemu' type='qcow2' cache='default'/>
<source file='/var/lib/libvirt/images/vagrant-test_default_2.img'/>
<target dev='vdc' bus='virtio'/>
</disk>
<disk type='file' device='disk'>
<alias name='ua-disk-volume-0'/>
<driver name='qemu' type='qcow2' cache='default'/>
<source file='/var/lib/libvirt/images/vagrant-test_default-vdd.qcow2'/>
<target dev='vdd' bus='virtio'/>
</disk>
<disk type='file' device='disk'>
<alias name='ua-disk-volume-1'/>
<driver name='qemu' type='qcow2' cache='default'/>
<source file='/var/lib/libvirt/images/vagrant-test_default-vde.qcow2'/>
<target dev='vde' bus='virtio'/>
</disk>
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2' cache='default'/>
<source file='/var/lib/libvirt/images/vagrant-test_default-vdf.qcow2'/>
<target dev='vdf' bus='virtio'/>
</disk>
<serial type='pty'>
<target port='0'/>
</serial>
<console type='pty'>
<target port='0'/>
</console>
<input type='mouse' bus='ps2'/>
<graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' keymap='en-us'/>
<video>
<model type='cirrus' vram='9216' heads='1'/>
</video>
</devices>
</domain>

View File

@@ -0,0 +1,67 @@
<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
<name>vagrant-test_default</name>
<title></title>
<description>Source: /rootpath/Vagrantfile</description>
<uuid></uuid>
<memory>524288</memory>
<vcpu>1</vcpu>
<cpu mode='host-model'>
<model fallback='allow'></model>
</cpu>
<os>
<type>hvm</type>
<kernel></kernel>
<initrd></initrd>
<cmdline></cmdline>
</os>
<features>
<acpi/>
<apic/>
<pae/>
</features>
<clock offset='utc'>
</clock>
<devices>
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2' cache='default'/>
<source file='/var/lib/libvirt/images/vagrant-test_default.img'/>
<target dev='vda' bus='virtio'/>
</disk>
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2' cache='default'/>
<source file='/var/lib/libvirt/images/vagrant-test_default_1.img'/>
<target dev='vdb' bus='virtio'/>
</disk>
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2' cache='default'/>
<source file='/var/lib/libvirt/images/vagrant-test_default_2.img'/>
<target dev='vdc' bus='virtio'/>
</disk>
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2' cache='default'/>
<source file='/var/lib/libvirt/images/vagrant-test_default-vdd.qcow2'/>
<target dev='vdd' bus='virtio'/>
</disk>
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2' cache='default'/>
<source file='/var/lib/libvirt/images/vagrant-test_default-vde.qcow2'/>
<target dev='vde' bus='virtio'/>
</disk>
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2' cache='default'/>
<source file='/var/lib/libvirt/images/vagrant-test_default-vdf.qcow2'/>
<target dev='vdf' bus='virtio'/>
</disk>
<serial type='pty'>
<target port='0'/>
</serial>
<console type='pty'>
<target port='0'/>
</console>
<input type='mouse' bus='ps2'/>
<graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' keymap='en-us'/>
<video>
<model type='cirrus' vram='9216' heads='1'/>
</video>
</devices>
</domain>

View File

@@ -0,0 +1,67 @@
<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
<name>vagrant-test_default</name>
<title></title>
<description>Source: /rootpath/Vagrantfile</description>
<uuid></uuid>
<memory>524288</memory>
<vcpu>1</vcpu>
<cpu mode='host-model'>
<model fallback='allow'></model>
</cpu>
<os>
<type>hvm</type>
<kernel></kernel>
<initrd></initrd>
<cmdline></cmdline>
</os>
<features>
<acpi/>
<apic/>
<pae/>
</features>
<clock offset='utc'>
</clock>
<devices>
<disk type='file' device='disk'>
<alias name='ua-box-volume-0'/>
<driver name='qemu' type='qcow2' cache='default'/>
<source file='/var/lib/libvirt/images/vagrant-test_default.img'/>
<target dev='vda' bus='virtio'/>
</disk>
<disk type='file' device='disk'>
<alias name='ua-box-volume-1'/>
<driver name='qemu' type='qcow2' cache='default'/>
<source file='/var/lib/libvirt/images/vagrant-test_default_1.img'/>
<target dev='vdb' bus='virtio'/>
</disk>
<disk type='file' device='disk'>
<alias name='ua-box-volume-2'/>
<driver name='qemu' type='qcow2' cache='default'/>
<source file='/var/lib/libvirt/images/vagrant-test_default_2.img'/>
<target dev='vdc' bus='virtio'/>
</disk>
<disk type='file' device='disk'>
<alias name='ua-disk-volume-0'/>
<driver name='qemu' type='qcow2' cache='default'/>
<source file='/var/lib/libvirt/images/vagrant-test_default-vdd.qcow2'/>
<target dev='vdd' bus='virtio'/>
</disk>
<disk type='file' device='disk'>
<alias name='ua-disk-volume-1'/>
<driver name='qemu' type='qcow2' cache='default'/>
<source file='/var/lib/libvirt/images/vagrant-test_default-vde.qcow2'/>
<target dev='vde' bus='virtio'/>
</disk>
<serial type='pty'>
<target port='0'/>
</serial>
<console type='pty'>
<target port='0'/>
</console>
<input type='mouse' bus='ps2'/>
<graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' keymap='en-us'/>
<video>
<model type='cirrus' vram='9216' heads='1'/>
</video>
</devices>
</domain>

View File

@@ -0,0 +1,48 @@
<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
<name>vagrant-test_default</name>
<title></title>
<description>Source: /rootpath/Vagrantfile</description>
<uuid></uuid>
<memory>524288</memory>
<vcpu>1</vcpu>
<cpu mode='host-model'>
<model fallback='allow'></model>
</cpu>
<os>
<type>hvm</type>
<kernel></kernel>
<initrd></initrd>
<cmdline></cmdline>
</os>
<features>
<acpi/>
<apic/>
<pae/>
</features>
<clock offset='utc'>
</clock>
<devices>
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2' cache='default'/>
<source file='/var/lib/libvirt/images/vagrant-test_default.img'/>
<target dev='vda' bus='virtio'/>
</disk>
<disk type='file' device='cdrom'>
<driver name='qemu' type='raw'/>
<source file='/home/test/images/os.iso'/>
<target dev='hdd' bus='ide'/>
<readonly/>
</disk>
<serial type='pty'>
<target port='0'/>
</serial>
<console type='pty'>
<target port='0'/>
</console>
<input type='mouse' bus='ps2'/>
<graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' keymap='en-us' />
<video>
<model type='cirrus' vram='9216' heads='1'/>
</video>
</devices>
</domain>