vagrant-libvirt 0.0.41 → 0.0.42
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.coveralls.yml +1 -0
- data/.github/issue_template.md +37 -0
- data/.gitignore +21 -0
- data/.travis.yml +24 -0
- data/Gemfile +26 -0
- data/LICENSE +22 -0
- data/README.md +1380 -0
- data/Rakefile +8 -0
- data/example_box/README.md +29 -0
- data/example_box/Vagrantfile +60 -0
- data/example_box/metadata.json +5 -0
- data/lib/vagrant-libvirt.rb +29 -0
- data/lib/vagrant-libvirt/action.rb +370 -0
- data/lib/vagrant-libvirt/action/create_domain.rb +322 -0
- data/lib/vagrant-libvirt/action/create_domain_volume.rb +87 -0
- data/lib/vagrant-libvirt/action/create_network_interfaces.rb +302 -0
- data/lib/vagrant-libvirt/action/create_networks.rb +361 -0
- data/lib/vagrant-libvirt/action/destroy_domain.rb +83 -0
- data/lib/vagrant-libvirt/action/destroy_networks.rb +95 -0
- data/lib/vagrant-libvirt/action/forward_ports.rb +227 -0
- data/lib/vagrant-libvirt/action/halt_domain.rb +41 -0
- data/lib/vagrant-libvirt/action/handle_box_image.rb +156 -0
- data/lib/vagrant-libvirt/action/handle_storage_pool.rb +57 -0
- data/lib/vagrant-libvirt/action/is_created.rb +18 -0
- data/lib/vagrant-libvirt/action/is_running.rb +21 -0
- data/lib/vagrant-libvirt/action/is_suspended.rb +42 -0
- data/lib/vagrant-libvirt/action/message_already_created.rb +16 -0
- data/lib/vagrant-libvirt/action/message_not_created.rb +16 -0
- data/lib/vagrant-libvirt/action/message_not_running.rb +16 -0
- data/lib/vagrant-libvirt/action/message_not_suspended.rb +16 -0
- data/lib/vagrant-libvirt/action/message_will_not_destroy.rb +17 -0
- data/lib/vagrant-libvirt/action/package_domain.rb +105 -0
- data/lib/vagrant-libvirt/action/prepare_nfs_settings.rb +94 -0
- data/lib/vagrant-libvirt/action/prepare_nfs_valid_ids.rb +17 -0
- data/lib/vagrant-libvirt/action/prune_nfs_exports.rb +27 -0
- data/lib/vagrant-libvirt/action/read_mac_addresses.rb +40 -0
- data/lib/vagrant-libvirt/action/remove_libvirt_image.rb +20 -0
- data/lib/vagrant-libvirt/action/remove_stale_volume.rb +50 -0
- data/lib/vagrant-libvirt/action/resume_domain.rb +34 -0
- data/lib/vagrant-libvirt/action/set_boot_order.rb +109 -0
- data/lib/vagrant-libvirt/action/set_name_of_domain.rb +64 -0
- data/lib/vagrant-libvirt/action/share_folders.rb +71 -0
- data/lib/vagrant-libvirt/action/start_domain.rb +307 -0
- data/lib/vagrant-libvirt/action/suspend_domain.rb +40 -0
- data/lib/vagrant-libvirt/action/wait_till_up.rb +109 -0
- data/lib/vagrant-libvirt/cap/mount_p9.rb +42 -0
- data/lib/vagrant-libvirt/cap/nic_mac_addresses.rb +17 -0
- data/lib/vagrant-libvirt/cap/synced_folder.rb +113 -0
- data/lib/vagrant-libvirt/config.rb +746 -0
- data/lib/vagrant-libvirt/driver.rb +118 -0
- data/lib/vagrant-libvirt/errors.rb +153 -0
- data/lib/vagrant-libvirt/plugin.rb +92 -0
- data/lib/vagrant-libvirt/provider.rb +130 -0
- data/lib/vagrant-libvirt/templates/default_storage_pool.xml.erb +13 -0
- data/lib/vagrant-libvirt/templates/domain.xml.erb +244 -0
- data/lib/vagrant-libvirt/templates/private_network.xml.erb +42 -0
- data/lib/vagrant-libvirt/templates/public_interface.xml.erb +26 -0
- data/lib/vagrant-libvirt/util.rb +11 -0
- data/lib/vagrant-libvirt/util/collection.rb +19 -0
- data/lib/vagrant-libvirt/util/erb_template.rb +22 -0
- data/lib/vagrant-libvirt/util/error_codes.rb +100 -0
- data/lib/vagrant-libvirt/util/network_util.rb +151 -0
- data/lib/vagrant-libvirt/util/timer.rb +17 -0
- data/lib/vagrant-libvirt/version.rb +5 -0
- data/locales/en.yml +162 -0
- data/spec/spec_helper.rb +9 -0
- data/spec/support/environment_helper.rb +46 -0
- data/spec/support/libvirt_context.rb +30 -0
- data/spec/support/sharedcontext.rb +34 -0
- data/spec/unit/action/destroy_domain_spec.rb +97 -0
- data/spec/unit/action/set_name_of_domain_spec.rb +21 -0
- data/spec/unit/action/wait_till_up_spec.rb +127 -0
- data/spec/unit/config_spec.rb +113 -0
- data/spec/unit/templates/domain_all_settings.xml +137 -0
- data/spec/unit/templates/domain_defaults.xml +46 -0
- data/spec/unit/templates/domain_spec.rb +84 -0
- data/tools/create_box.sh +130 -0
- data/tools/prepare_redhat_for_box.sh +119 -0
- data/vagrant-libvirt.gemspec +54 -0
- metadata +93 -3
@@ -0,0 +1,97 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'support/sharedcontext'
|
3
|
+
require 'support/libvirt_context'
|
4
|
+
|
5
|
+
require 'vagrant-libvirt/action/destroy_domain'
|
6
|
+
|
7
|
+
describe VagrantPlugins::ProviderLibvirt::Action::DestroyDomain do
|
8
|
+
subject { described_class.new(app, env) }
|
9
|
+
|
10
|
+
include_context 'unit'
|
11
|
+
include_context 'libvirt'
|
12
|
+
|
13
|
+
let(:libvirt_domain) { double('libvirt_domain') }
|
14
|
+
let(:libvirt_client) { double('libvirt_client') }
|
15
|
+
let(:servers) { double('servers') }
|
16
|
+
|
17
|
+
describe '#call' do
|
18
|
+
before do
|
19
|
+
allow_any_instance_of(VagrantPlugins::ProviderLibvirt::Driver)
|
20
|
+
.to receive(:connection).and_return(connection)
|
21
|
+
allow(connection).to receive(:client).and_return(libvirt_client)
|
22
|
+
allow(libvirt_client).to receive(:lookup_domain_by_uuid)
|
23
|
+
.and_return(libvirt_domain)
|
24
|
+
allow(connection).to receive(:servers).and_return(servers)
|
25
|
+
allow(servers).to receive(:get).and_return(domain)
|
26
|
+
# always see this at the start of #call
|
27
|
+
expect(ui).to receive(:info).with('Removing domain...')
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'when no snapshots' do
|
31
|
+
let(:root_disk) { double('libvirt_root_disk') }
|
32
|
+
|
33
|
+
before do
|
34
|
+
allow(libvirt_domain).to receive(:list_snapshots).and_return([])
|
35
|
+
allow(libvirt_domain).to receive(:has_managed_save?).and_return(nil)
|
36
|
+
root_disk.stub(name: 'test.img')
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'when only has root disk' do
|
40
|
+
it 'calls fog to destroy volumes' do
|
41
|
+
expect(domain).to receive(:destroy).with(destroy_volumes: true)
|
42
|
+
expect(subject.call(env)).to be_nil
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context 'when has additional disks' do
|
47
|
+
let(:vagrantfile) do
|
48
|
+
<<-EOF
|
49
|
+
Vagrant.configure('2') do |config|
|
50
|
+
config.vm.define :test
|
51
|
+
config.vm.provider :libvirt do |libvirt|
|
52
|
+
libvirt.storage :file
|
53
|
+
end
|
54
|
+
end
|
55
|
+
EOF
|
56
|
+
end
|
57
|
+
|
58
|
+
let(:extra_disk) { double('libvirt_extra_disk') }
|
59
|
+
before do
|
60
|
+
extra_disk.stub(name: 'test-vdb.qcow2')
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'destroys disks individually' do
|
64
|
+
allow(libvirt_domain).to receive(:name).and_return('test')
|
65
|
+
allow(domain).to receive(:volumes).and_return([extra_disk], [root_disk])
|
66
|
+
|
67
|
+
expect(domain).to receive(:destroy).with(destroy_volumes: false)
|
68
|
+
expect(extra_disk).to receive(:destroy) # extra disk remove
|
69
|
+
expect(root_disk).to receive(:destroy) # root disk remove
|
70
|
+
expect(subject.call(env)).to be_nil
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
context 'when has CDROMs attached' do
|
75
|
+
let(:vagrantfile) do
|
76
|
+
<<-EOF
|
77
|
+
Vagrant.configure('2') do |config|
|
78
|
+
config.vm.define :test
|
79
|
+
config.vm.provider :libvirt do |libvirt|
|
80
|
+
libvirt.storage :file, :device => :cdrom
|
81
|
+
end
|
82
|
+
end
|
83
|
+
EOF
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'uses explicit removal of disks' do
|
87
|
+
allow(libvirt_domain).to receive(:name).and_return('test')
|
88
|
+
allow(domain).to receive(:volumes).and_return([root_disk])
|
89
|
+
|
90
|
+
expect(domain).to_not receive(:destroy).with(destroy_volumes: true)
|
91
|
+
expect(root_disk).to receive(:destroy) # root disk remove
|
92
|
+
expect(subject.call(env)).to be_nil
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe VagrantPlugins::ProviderLibvirt::Action::SetNameOfDomain do
|
4
|
+
before :each do
|
5
|
+
@env = EnvironmentHelper.new
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'builds unique domain name' do
|
9
|
+
@env.random_hostname = true
|
10
|
+
dmn = VagrantPlugins::ProviderLibvirt::Action::SetNameOfDomain.new(Object.new, @env)
|
11
|
+
first = dmn.build_domain_name(@env)
|
12
|
+
second = dmn.build_domain_name(@env)
|
13
|
+
first.should_not eq(second)
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'builds simple domain name' do
|
17
|
+
@env.default_prefix = 'pre'
|
18
|
+
dmn = VagrantPlugins::ProviderLibvirt::Action::SetNameOfDomain.new(Object.new, @env)
|
19
|
+
dmn.build_domain_name(@env).should eq('pre_')
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
require 'vagrant-libvirt/action/wait_till_up'
|
2
|
+
require 'vagrant-libvirt/errors'
|
3
|
+
|
4
|
+
require 'spec_helper'
|
5
|
+
require 'support/sharedcontext'
|
6
|
+
require 'support/libvirt_context'
|
7
|
+
|
8
|
+
describe VagrantPlugins::ProviderLibvirt::Action::WaitTillUp do
|
9
|
+
subject { described_class.new(app, env) }
|
10
|
+
|
11
|
+
include_context 'vagrant-unit'
|
12
|
+
include_context 'libvirt'
|
13
|
+
include_context 'unit'
|
14
|
+
|
15
|
+
describe '#call' do
|
16
|
+
before do
|
17
|
+
allow_any_instance_of(VagrantPlugins::ProviderLibvirt::Driver)
|
18
|
+
.to receive(:get_domain).and_return(domain)
|
19
|
+
allow_any_instance_of(VagrantPlugins::ProviderLibvirt::Driver).to receive(:state)
|
20
|
+
.and_return(:running)
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'when machine does not exist' do
|
24
|
+
before do
|
25
|
+
allow_any_instance_of(VagrantPlugins::ProviderLibvirt::Driver)
|
26
|
+
.to receive(:get_domain).and_return(nil)
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'raises exception' do
|
30
|
+
expect(app).to_not receive(:call)
|
31
|
+
expect { subject.call(env) }.to raise_error(::VagrantPlugins::ProviderLibvirt::Errors::NoDomainError,
|
32
|
+
/No domain found. Domain dummy-vagrant_dummy not found/)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'when machine is booting' do
|
37
|
+
context 'if interrupted looking for IP' do
|
38
|
+
before do
|
39
|
+
env[:interrupted] = true
|
40
|
+
end
|
41
|
+
it 'should exit' do
|
42
|
+
expect(app).to_not receive(:call)
|
43
|
+
expect(ui).to receive(:info).with('Waiting for domain to get an IP address...')
|
44
|
+
expect(subject.call(env)).to be_nil
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context 'if interrupted waiting for SSH' do
|
49
|
+
before do
|
50
|
+
allow(domain).to receive(:wait_for).and_return(true)
|
51
|
+
allow(env).to receive(:[]).and_call_original
|
52
|
+
allow(env).to receive(:[]).with(:interrupted).and_return(false, true, true)
|
53
|
+
allow(env).to receive(:[]).with(:ip_address).and_return('192.168.121.2')
|
54
|
+
end
|
55
|
+
it 'should exit after getting IP' do
|
56
|
+
expect(app).to_not receive(:call)
|
57
|
+
expect(ui).to receive(:info).with('Waiting for domain to get an IP address...')
|
58
|
+
expect(ui).to receive(:info).with('Waiting for SSH to become available...')
|
59
|
+
logger = subject.instance_variable_get(:@logger)
|
60
|
+
expect(logger).to receive(:debug).with(/Searching for IP for MAC address: .*/)
|
61
|
+
expect(logger).to receive(:info).with('Got IP address 192.168.121.2')
|
62
|
+
expect(logger).to receive(:info).with(/Time for getting IP: .*/)
|
63
|
+
expect(env[:machine].communicate).to_not receive(:ready?)
|
64
|
+
expect(subject.call(env)).to be_nil
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
context 'when machine boots and ssh available' do
|
70
|
+
before do
|
71
|
+
allow(domain).to receive(:wait_for).and_return(true)
|
72
|
+
allow(env).to receive(:[]).and_call_original
|
73
|
+
allow(env).to receive(:[]).with(:interrupted).and_return(false)
|
74
|
+
allow(env).to receive(:[]).with(:ip_address).and_return('192.168.121.2')
|
75
|
+
end
|
76
|
+
it 'should call the next hook' do
|
77
|
+
expect(app).to receive(:call)
|
78
|
+
expect(ui).to receive(:info).with('Waiting for domain to get an IP address...')
|
79
|
+
expect(ui).to receive(:info).with('Waiting for SSH to become available...')
|
80
|
+
expect(env[:machine].communicate).to receive(:ready?).and_return(true)
|
81
|
+
expect(subject.call(env)).to be_nil
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe '#recover' do
|
87
|
+
before do
|
88
|
+
allow_any_instance_of(VagrantPlugins::ProviderLibvirt::Driver).to receive(:get_domain).and_return(machine)
|
89
|
+
allow_any_instance_of(VagrantPlugins::ProviderLibvirt::Driver).to receive(:state)
|
90
|
+
.and_return(:not_created)
|
91
|
+
allow(env).to receive(:[]).and_call_original
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'should do nothing by default' do
|
95
|
+
expect(env).to_not receive(:[]).with(:action_runner) # cleanup
|
96
|
+
expect(subject.recover(env)).to be_nil
|
97
|
+
end
|
98
|
+
|
99
|
+
context 'with machine coming up' do
|
100
|
+
before do
|
101
|
+
allow_any_instance_of(VagrantPlugins::ProviderLibvirt::Driver).to receive(:state)
|
102
|
+
.and_return(:running)
|
103
|
+
env[:destroy_on_error] = true
|
104
|
+
end
|
105
|
+
|
106
|
+
context 'and user has disabled destroy on failure' do
|
107
|
+
before do
|
108
|
+
env[:destroy_on_error] = false
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'skips terminate on failure' do
|
112
|
+
expect(env).to_not receive(:[]).with(:action_runner) # cleanup
|
113
|
+
expect(subject.recover(env)).to be_nil
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
context 'and using default settings' do
|
118
|
+
let(:runner) { double('runner') }
|
119
|
+
it 'deletes VM on failure' do
|
120
|
+
expect(env).to receive(:[]).with(:action_runner).and_return(runner) # cleanup
|
121
|
+
expect(runner).to receive(:run)
|
122
|
+
expect(subject.recover(env)).to be_nil
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'support/sharedcontext'
|
3
|
+
|
4
|
+
require 'vagrant-libvirt/config'
|
5
|
+
|
6
|
+
describe VagrantPlugins::ProviderLibvirt::Config do
|
7
|
+
include_context 'unit'
|
8
|
+
|
9
|
+
def assert_invalid
|
10
|
+
errors = subject.validate(machine)
|
11
|
+
raise "No errors: #{errors.inspect}" if errors.values.all?(&:empty?)
|
12
|
+
end
|
13
|
+
|
14
|
+
def assert_valid
|
15
|
+
errors = subject.validate(machine)
|
16
|
+
raise "Errors: #{errors.inspect}" unless errors.values.all?(&:empty?)
|
17
|
+
end
|
18
|
+
|
19
|
+
describe '#validate' do
|
20
|
+
it 'is valid with defaults' do
|
21
|
+
assert_valid
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'with disks defined' do
|
25
|
+
before { expect(machine).to receive(:provider_config).and_return(subject).at_least(:once) }
|
26
|
+
|
27
|
+
it 'is valid if relative path used for disk' do
|
28
|
+
subject.storage :file, path: '../path/to/file.qcow2'
|
29
|
+
assert_valid
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should be invalid if absolute path used for disk' do
|
33
|
+
subject.storage :file, path: '/absolute/path/to/file.qcow2'
|
34
|
+
assert_invalid
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'with mac defined' do
|
39
|
+
let (:vm) { double('vm') }
|
40
|
+
before { expect(machine.config).to receive(:vm).and_return(vm) }
|
41
|
+
|
42
|
+
it 'is valid with valid mac' do
|
43
|
+
expect(vm).to receive(:networks).and_return([[:public, { mac: 'aa:bb:cc:dd:ee:ff' }]])
|
44
|
+
assert_valid
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'is valid with MAC containing no delimiters' do
|
48
|
+
network = [:public, { mac: 'aabbccddeeff' }]
|
49
|
+
expect(vm).to receive(:networks).and_return([network])
|
50
|
+
assert_valid
|
51
|
+
expect(network[1][:mac]).to eql('aa:bb:cc:dd:ee:ff')
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'should be invalid if MAC not formatted correctly' do
|
55
|
+
expect(vm).to receive(:networks).and_return([[:public, { mac: 'aa/bb/cc/dd/ee/ff' }]])
|
56
|
+
assert_invalid
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe '#merge' do
|
62
|
+
let(:one) { described_class.new }
|
63
|
+
let(:two) { described_class.new }
|
64
|
+
|
65
|
+
subject { one.merge(two) }
|
66
|
+
|
67
|
+
context 'storage' do
|
68
|
+
context 'with disks' do
|
69
|
+
context 'assigned specific devices' do
|
70
|
+
it 'should merge disks with specific devices' do
|
71
|
+
one.storage(:file, device: 'vdb')
|
72
|
+
two.storage(:file, device: 'vdc')
|
73
|
+
subject.finalize!
|
74
|
+
expect(subject.disks).to include(include(device: 'vdb'),
|
75
|
+
include(device: 'vdc'))
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context 'without devices given' do
|
80
|
+
it 'should merge disks with different devices assigned automatically' do
|
81
|
+
one.storage(:file)
|
82
|
+
two.storage(:file)
|
83
|
+
subject.finalize!
|
84
|
+
expect(subject.disks).to include(include(device: 'vdb'),
|
85
|
+
include(device: 'vdc'))
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
context 'with cdroms only' do
|
91
|
+
context 'assigned specific devs' do
|
92
|
+
it 'should merge disks with specific devices' do
|
93
|
+
one.storage(:file, device: :cdrom, dev: 'hda')
|
94
|
+
two.storage(:file, device: :cdrom, dev: 'hdb')
|
95
|
+
subject.finalize!
|
96
|
+
expect(subject.cdroms).to include(include(dev: 'hda'),
|
97
|
+
include(dev: 'hdb'))
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
context 'without devs given' do
|
102
|
+
it 'should merge cdroms with different devs assigned automatically' do
|
103
|
+
one.storage(:file, device: :cdrom)
|
104
|
+
two.storage(:file, device: :cdrom)
|
105
|
+
subject.finalize!
|
106
|
+
expect(subject.cdroms).to include(include(dev: 'hda'),
|
107
|
+
include(dev: 'hdb'))
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,137 @@
|
|
1
|
+
<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
|
2
|
+
<name></name>
|
3
|
+
<uuid></uuid>
|
4
|
+
<memory></memory>
|
5
|
+
<vcpu>1</vcpu>
|
6
|
+
|
7
|
+
|
8
|
+
<cpu mode='custom'>
|
9
|
+
<model fallback='allow'>qemu64</model>
|
10
|
+
<feature name='AAA' policy='required'/>
|
11
|
+
<topology sockets='1' cores='3' threads='2'/>
|
12
|
+
</cpu>
|
13
|
+
|
14
|
+
|
15
|
+
<os>
|
16
|
+
<type arch='x86_64' machine='pc-compatible'>hvm</type>
|
17
|
+
<loader readonly='yes' type='rom'>/efi/loader</loader>
|
18
|
+
<bootmenu enable='yes'/>
|
19
|
+
<kernel></kernel>
|
20
|
+
<initrd></initrd>
|
21
|
+
<cmdline></cmdline>
|
22
|
+
</os>
|
23
|
+
<features>
|
24
|
+
<acpi/>
|
25
|
+
<apic/>
|
26
|
+
<pae/>
|
27
|
+
</features>
|
28
|
+
<clock offset='utc'/>
|
29
|
+
<devices>
|
30
|
+
<emulator>/usr/bin/kvm-spice</emulator>
|
31
|
+
<disk type='file' device='disk'>
|
32
|
+
<driver name='qemu' type='qcow2' cache='unsafe'/>
|
33
|
+
<source file='/var/lib/libvirt/images/test.qcow2'/>
|
34
|
+
<target dev='vda' bus='ide'/>
|
35
|
+
</disk>
|
36
|
+
<disk type='file' device='disk'>
|
37
|
+
<driver name='qemu' type='qcow2' cache='default'/>
|
38
|
+
<source file='/var/lib/libvirt/images/test-disk1.qcow2'/>
|
39
|
+
<target dev='vdb' bus='virtio'/>
|
40
|
+
</disk>
|
41
|
+
<disk type='file' device='disk'>
|
42
|
+
<driver name='qemu' type='qcow2' cache='default'/>
|
43
|
+
<source file='/var/lib/libvirt/images/test-disk2.qcow2'/>
|
44
|
+
<target dev='vdc' bus='virtio'/>
|
45
|
+
</disk>
|
46
|
+
|
47
|
+
<disk type='file' device='cdrom'>
|
48
|
+
<source file=''/>
|
49
|
+
<target dev='hda' bus='ide'/>
|
50
|
+
<readonly/>
|
51
|
+
</disk>
|
52
|
+
<disk type='file' device='cdrom'>
|
53
|
+
<source file=''/>
|
54
|
+
<target dev='hdb' bus='ide'/>
|
55
|
+
<readonly/>
|
56
|
+
</disk>
|
57
|
+
|
58
|
+
<serial type='pty'>
|
59
|
+
<target port='0'/>
|
60
|
+
</serial>
|
61
|
+
<console type='pty'>
|
62
|
+
<target port='0'/>
|
63
|
+
</console>
|
64
|
+
|
65
|
+
<channel type='unix' >
|
66
|
+
<target type='virtio'
|
67
|
+
name="org.qemu.guest_agent.0"
|
68
|
+
/>
|
69
|
+
</channel>
|
70
|
+
<channel type='spicevmc' >
|
71
|
+
<target type='virtio'
|
72
|
+
name="com.redhat.spice.0"
|
73
|
+
/>
|
74
|
+
</channel>
|
75
|
+
<channel type='unix' >
|
76
|
+
<source
|
77
|
+
path="/tmp/foo"
|
78
|
+
/>
|
79
|
+
<target type='guestfwd'
|
80
|
+
address="192.0.2.42"
|
81
|
+
port="4242"
|
82
|
+
/>
|
83
|
+
</channel>
|
84
|
+
|
85
|
+
<input type='mouse' bus='ps2'/>
|
86
|
+
|
87
|
+
<graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' keymap='en-us' />
|
88
|
+
<video>
|
89
|
+
<model type='cirrus' vram='9216' heads='1'/>
|
90
|
+
</video>
|
91
|
+
<rng model='virtio'>
|
92
|
+
<backend model='random'>/dev/random</backend>
|
93
|
+
</rng>
|
94
|
+
<hostdev mode='subsystem' type='pci' managed='yes'>
|
95
|
+
<source>
|
96
|
+
<address domain='0x0000'
|
97
|
+
bus='0x06'
|
98
|
+
slot='0x12'
|
99
|
+
function='0x5'/>
|
100
|
+
</source>
|
101
|
+
</hostdev>
|
102
|
+
<hostdev mode='subsystem' type='pci' managed='yes'>
|
103
|
+
<source>
|
104
|
+
<address domain='0x0000'
|
105
|
+
bus='0x03'
|
106
|
+
slot='0x00'
|
107
|
+
function='0x0'/>
|
108
|
+
</source>
|
109
|
+
</hostdev>
|
110
|
+
<hostdev mode='subsystem' type='usb'>
|
111
|
+
<source startupPolicy='mandatory'>
|
112
|
+
<vendor id='0x1234'/>
|
113
|
+
<product id='0xabcd'/>
|
114
|
+
<address bus='1' device='2'/>
|
115
|
+
</source>
|
116
|
+
</hostdev>
|
117
|
+
<redirdev bus='usb' type='tcp'>
|
118
|
+
</redirdev>
|
119
|
+
<redirfilter>
|
120
|
+
<usbdev class='0x0b' vendor='0x0b' product='0x0b' version='0x0b' allow='yes'/>
|
121
|
+
</redirfilter>
|
122
|
+
<watchdog model='i6300esb' action='reset'/>
|
123
|
+
|
124
|
+
<smartcard mode='passthrough' type='spicevmc'/>
|
125
|
+
|
126
|
+
<tpm model='tpm-tis'>
|
127
|
+
<backend type='passthrough'>
|
128
|
+
<device path='/dev/tpm0'/>
|
129
|
+
</backend>
|
130
|
+
</tpm>
|
131
|
+
</devices>
|
132
|
+
|
133
|
+
<qemu:commandline>
|
134
|
+
<qemu:arg value='-device'/>
|
135
|
+
<qemu:arg value='dummy-device'/>
|
136
|
+
</qemu:commandline>
|
137
|
+
</domain>
|