vagrant-libvirt 0.3.0 → 0.5.2

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.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +421 -50
  3. data/lib/vagrant-libvirt/action.rb +7 -1
  4. data/lib/vagrant-libvirt/action/clean_machine_folder.rb +30 -0
  5. data/lib/vagrant-libvirt/action/create_domain.rb +56 -18
  6. data/lib/vagrant-libvirt/action/create_domain_volume.rb +57 -55
  7. data/lib/vagrant-libvirt/action/create_network_interfaces.rb +0 -3
  8. data/lib/vagrant-libvirt/action/create_networks.rb +11 -4
  9. data/lib/vagrant-libvirt/action/destroy_domain.rb +1 -1
  10. data/lib/vagrant-libvirt/action/forward_ports.rb +37 -38
  11. data/lib/vagrant-libvirt/action/halt_domain.rb +25 -9
  12. data/lib/vagrant-libvirt/action/handle_box_image.rb +163 -74
  13. data/lib/vagrant-libvirt/action/is_running.rb +1 -3
  14. data/lib/vagrant-libvirt/action/is_suspended.rb +4 -4
  15. data/lib/vagrant-libvirt/action/package_domain.rb +2 -1
  16. data/lib/vagrant-libvirt/action/set_boot_order.rb +6 -2
  17. data/lib/vagrant-libvirt/action/start_domain.rb +86 -29
  18. data/lib/vagrant-libvirt/action/wait_till_up.rb +8 -52
  19. data/lib/vagrant-libvirt/cap/{mount_p9.rb → mount_9p.rb} +2 -2
  20. data/lib/vagrant-libvirt/cap/mount_virtiofs.rb +37 -0
  21. data/lib/vagrant-libvirt/cap/{synced_folder.rb → synced_folder_9p.rb} +4 -5
  22. data/lib/vagrant-libvirt/cap/synced_folder_virtiofs.rb +109 -0
  23. data/lib/vagrant-libvirt/config.rb +236 -43
  24. data/lib/vagrant-libvirt/driver.rb +49 -32
  25. data/lib/vagrant-libvirt/errors.rb +24 -1
  26. data/lib/vagrant-libvirt/plugin.rb +14 -5
  27. data/lib/vagrant-libvirt/provider.rb +2 -9
  28. data/lib/vagrant-libvirt/templates/domain.xml.erb +35 -10
  29. data/lib/vagrant-libvirt/templates/private_network.xml.erb +1 -1
  30. data/lib/vagrant-libvirt/util/network_util.rb +21 -3
  31. data/lib/vagrant-libvirt/version +1 -1
  32. data/lib/vagrant-libvirt/version.rb +57 -9
  33. data/locales/en.yml +12 -0
  34. data/spec/spec_helper.rb +37 -3
  35. data/spec/support/binding_proc.rb +24 -0
  36. data/spec/support/libvirt_context.rb +2 -0
  37. data/spec/support/matchers/have_file_content.rb +63 -0
  38. data/spec/support/sharedcontext.rb +4 -0
  39. data/spec/unit/action/clean_machine_folder_spec.rb +58 -0
  40. data/spec/unit/action/create_domain_spec.rb +121 -36
  41. data/spec/unit/action/create_domain_spec/additional_disks_domain.xml +54 -0
  42. data/spec/unit/action/create_domain_spec/default_domain.xml +49 -0
  43. data/spec/unit/action/create_domain_spec/{default_storage_pool.xml → default_system_storage_pool.xml} +0 -0
  44. data/spec/unit/action/create_domain_spec/default_user_storage_pool.xml +17 -0
  45. data/spec/unit/action/create_domain_volume_spec.rb +102 -0
  46. data/spec/unit/action/create_domain_volume_spec/one_disk_in_storage.xml +21 -0
  47. data/spec/unit/action/create_domain_volume_spec/three_disks_in_storage_disk_0.xml +21 -0
  48. data/spec/unit/action/create_domain_volume_spec/three_disks_in_storage_disk_1.xml +21 -0
  49. data/spec/unit/action/create_domain_volume_spec/three_disks_in_storage_disk_2.xml +21 -0
  50. data/spec/unit/action/destroy_domain_spec.rb +1 -1
  51. data/spec/unit/action/forward_ports_spec.rb +202 -0
  52. data/spec/unit/action/halt_domain_spec.rb +90 -0
  53. data/spec/unit/action/handle_box_image_spec.rb +363 -0
  54. data/spec/unit/action/start_domain_spec.rb +183 -1
  55. data/spec/unit/action/start_domain_spec/clock_timer_rtc.xml +50 -0
  56. data/spec/unit/action/start_domain_spec/default.xml +2 -2
  57. data/spec/unit/action/start_domain_spec/default_added_tpm_path.xml +48 -0
  58. data/spec/unit/action/start_domain_spec/default_added_tpm_version.xml +48 -0
  59. data/spec/unit/action/wait_till_up_spec.rb +22 -21
  60. data/spec/unit/config_spec.rb +395 -127
  61. data/spec/unit/templates/domain_all_settings.xml +14 -3
  62. data/spec/unit/templates/domain_custom_cpu_model.xml +2 -1
  63. data/spec/unit/templates/domain_defaults.xml +2 -1
  64. data/spec/unit/templates/domain_spec.rb +100 -3
  65. data/spec/unit/templates/tpm/version_1.2.xml +54 -0
  66. data/spec/unit/templates/tpm/version_2.0.xml +53 -0
  67. metadata +105 -19
data/locales/en.yml CHANGED
@@ -72,6 +72,14 @@ en:
72
72
  no_storage_pool: |-
73
73
  No usable storage pool found! Please check if storage pool is
74
74
  created and available.
75
+ box_format_duplicate_volume: |-
76
+ Encountered a duplicate volume name '%{volume}' generated for disk '%{new_disk}', due to already allocated for disk '%{orig_disk}'.
77
+ box_format_missing_attribute: |-
78
+ Invalid box metadata, missing expected attribute: '%{attribute}'
79
+ bad_box_image: |-
80
+ Received error when query the box image details from '%{image}'.
81
+ Stdout: %{out}
82
+ Stderr: %{err}
75
83
  no_box_volume: |-
76
84
  Volume for box image is missing in storage pools. Try to run vagrant
77
85
  again, or check if storage volume is accessible.
@@ -92,10 +100,14 @@ en:
92
100
  Error: %{stderr}
93
101
  no_box_virtual_size: |-
94
102
  No image virtual size specified for box.
103
+ no_disk_virtual_size: |-
104
+ No image virtual size specified for disk with index %{disk_index}.
95
105
  no_box_format: |-
96
106
  No image format specified for box.
97
107
  wrong_box_format: |-
98
108
  Wrong image format specified for box.
109
+ wrong_disk_format: |-
110
+ Wrong image format specified for disk with index %{disk_index}.
99
111
  fog_libvirt_connection_error: |-
100
112
  Error while connecting to Libvirt: %{error_message}
101
113
  fog_create_volume_error: |-
data/spec/spec_helper.rb CHANGED
@@ -1,9 +1,43 @@
1
- require 'coveralls'
2
- Coveralls.wear!
1
+ require 'simplecov'
2
+ require 'simplecov-lcov'
3
+
4
+ # patch simplecov configuration
5
+ if ! SimpleCov::Configuration.method_defined? :branch_coverage?
6
+ module SimpleCov
7
+ module Configuration
8
+ def branch_coverage?
9
+ return false
10
+ end
11
+ end
12
+ end
13
+ end
14
+
15
+ SimpleCov::Formatter::LcovFormatter.config do |config|
16
+ config.report_with_single_file = true
17
+ config.single_report_path = 'coverage/lcov.info'
18
+ end
19
+
20
+ SimpleCov.formatters = SimpleCov::Formatter::MultiFormatter.new(
21
+ [
22
+ SimpleCov::Formatter::HTMLFormatter,
23
+ SimpleCov::Formatter::LcovFormatter,
24
+ ]
25
+ )
26
+ SimpleCov.start do
27
+ add_filter 'spec/'
28
+ end
3
29
 
4
30
  require 'vagrant-libvirt'
5
31
  require 'support/environment_helper'
6
32
  require 'vagrant-spec/unit'
7
33
 
8
- RSpec.configure do |spec|
34
+ Dir[File.dirname(__FILE__) + '/support/**/*.rb'].each { |f| require f }
35
+
36
+ RSpec.configure do |config|
37
+ # ensure that setting of LIBVIRT_DEFAULT_URI in the environment is not picked
38
+ # up directly by tests, instead they must set as needed. Some build envs will
39
+ # may have it set to 'qemu:///session'.
40
+ config.before(:suite) do
41
+ ENV.delete('LIBVIRT_DEFAULT_URI')
42
+ end
9
43
  end
@@ -0,0 +1,24 @@
1
+ ##
2
+ # A simple extension of the Proc class that supports setting a custom binding
3
+ # and evaluates everything in the Proc using the new binding.
4
+
5
+ class ProcWithBinding < Proc
6
+ ##
7
+ # Set the binding for this instance
8
+
9
+ def apply_binding(bind, *args)
10
+ @binding = bind
11
+ instance_exec(*args, &self)
12
+ end
13
+
14
+ def method_missing(method, *args)
15
+ begin
16
+ method_from_binding = eval("method(#{method.inspect})", @binding)
17
+ return method_from_binding.call(*args)
18
+ rescue NameError
19
+ # fall through on purpose
20
+ end
21
+
22
+ super
23
+ end
24
+ end
@@ -7,6 +7,7 @@ shared_context 'libvirt' do
7
7
  let(:id) { 'dummy-vagrant_dummy' }
8
8
  let(:connection) { double('connection') }
9
9
  let(:domain) { double('domain') }
10
+ let(:logger) { double('logger') }
10
11
 
11
12
  def connection_result(options = {})
12
13
  result = options.fetch(:result, nil)
@@ -26,5 +27,6 @@ shared_context 'libvirt' do
26
27
  allow(domain).to receive(:mac).and_return('9C:D5:53:F1:5A:E7')
27
28
 
28
29
  allow(machine).to receive(:id).and_return(id)
30
+ allow(Log4r::Logger).to receive(:new).and_return(logger)
29
31
  end
30
32
  end
@@ -0,0 +1,63 @@
1
+ require "rspec/expectations/version"
2
+ #
3
+ # Taken from https://github.com/cucumber/aruba/blob/main/lib/aruba/matchers/file/have_file_content.rb
4
+ # with minor modifications
5
+ #
6
+ # @!method have_file_content(content)
7
+ # This matchers checks if <file> has content. `content` can be a string,
8
+ # regexp or an RSpec matcher.
9
+ #
10
+ # @param [String, Regexp, Matcher] content
11
+ # Specifies the content of the file
12
+ #
13
+ # @return [Boolean] The result
14
+ #
15
+ # false:
16
+ # * if file does not exist
17
+ # * if file content is not equal string
18
+ # * if file content does not include regexp
19
+ # * if file content does not match the content specification
20
+ #
21
+ # true:
22
+ # * if file content includes regexp
23
+ # * if file content is equal string
24
+ # * if file content matches the content specification
25
+ #
26
+ # @example Use matcher with string
27
+ #
28
+ # RSpec.describe do
29
+ # it { expect(file1).to have_file_content('a') }
30
+ # end
31
+ #
32
+ # @example Use matcher with regexp
33
+ #
34
+ # RSpec.describe do
35
+ # it { expect(file1).to have_file_content(/a/) }
36
+ # end
37
+ #
38
+ # @example Use matcher with an RSpec matcher
39
+ #
40
+ # RSpec.describe do
41
+ # it { expect(file1).to have_file_content(a_string_starting_with 'a') }
42
+ # it { expect(files1).to include a_file_having_content(a_string_starting_with 'a') }
43
+ # end
44
+ RSpec::Matchers.define :have_file_content do |expected|
45
+ match do |actual|
46
+ next false unless File.exists?(actual)
47
+
48
+ @actual = File.read(actual).chomp
49
+ @expected = if expected.is_a? String
50
+ expected.chomp
51
+ else
52
+ expected
53
+ end
54
+
55
+ values_match?(@expected, @actual)
56
+ end
57
+
58
+ diffable if expected.is_a? String
59
+
60
+ description { "have file content: #{description_of expected}" }
61
+ end
62
+
63
+ RSpec::Matchers.alias_matcher :a_file_having_content, :have_file_content
@@ -3,10 +3,14 @@ require 'spec_helper'
3
3
  shared_context 'unit' do
4
4
  include_context 'vagrant-unit'
5
5
 
6
+ let(:vagrantfile_providerconfig) { '' }
6
7
  let(:vagrantfile) do
7
8
  <<-EOF
8
9
  Vagrant.configure('2') do |config|
9
10
  config.vm.define :test
11
+ config.vm.provider :libvirt do |libvirt|
12
+ #{vagrantfile_providerconfig}
13
+ end
10
14
  end
11
15
  EOF
12
16
  end
@@ -0,0 +1,58 @@
1
+ require 'spec_helper'
2
+ require 'support/sharedcontext'
3
+
4
+ require 'vagrant-libvirt/action/clean_machine_folder'
5
+
6
+ describe VagrantPlugins::ProviderLibvirt::Action::CleanMachineFolder do
7
+ subject { described_class.new(app, env) }
8
+
9
+ include_context 'unit'
10
+
11
+ describe '#call' do
12
+ before do
13
+ FileUtils.touch(File.join(machine.data_dir, "box.meta"))
14
+ end
15
+
16
+ context 'with default options' do
17
+ it 'should verbosely remove the folder' do
18
+ expect(ui).to receive(:info).with('Deleting the machine folder')
19
+
20
+ expect(subject.call(env)).to be_nil
21
+
22
+ expect(File.exists?(machine.data_dir)).to eq(true)
23
+ expect(Dir.entries(machine.data_dir)).to match_array([".", ".."])
24
+ end
25
+ end
26
+
27
+ context 'when the data dir doesn\'t exist' do
28
+ before do
29
+ Dir.mktmpdir do |d|
30
+ # returns a temporary directory that has been already deleted when running
31
+ expect(machine).to receive(:data_dir).and_return(d.to_s).exactly(3).times
32
+ end
33
+ end
34
+
35
+ it 'should remove the folder' do
36
+ expect(ui).to receive(:info).with('Deleting the machine folder')
37
+
38
+ expect(subject.call(env)).to be_nil
39
+
40
+ expect(File.exists?(machine.data_dir)).to eq(true)
41
+ expect(Dir.entries(machine.data_dir)).to match_array([".", ".."])
42
+ end
43
+ end
44
+
45
+ context 'with quiet option enabled' do
46
+ subject { described_class.new(app, env, {:quiet => true}) }
47
+
48
+ it 'should quietly remove the folder' do
49
+ expect(ui).to_not receive(:info).with('Deleting the machine folder')
50
+
51
+ expect(subject.call(env)).to be_nil
52
+
53
+ expect(File.exists?(machine.data_dir)).to eq(true)
54
+ expect(Dir.entries(machine.data_dir)).to match_array([".", ".."])
55
+ end
56
+ end
57
+ end
58
+ end
@@ -15,7 +15,8 @@ describe VagrantPlugins::ProviderLibvirt::Action::CreateDomain do
15
15
  let(:servers) { double('servers') }
16
16
  let(:volumes) { double('volumes') }
17
17
 
18
- let(:storage_pool_xml) { File.read(File.join(File.dirname(__FILE__), File.basename(__FILE__, '.rb'), test_file)) }
18
+ let(:domain_xml) { File.read(File.join(File.dirname(__FILE__), File.basename(__FILE__, '.rb'), domain_xml_file)) }
19
+ let(:storage_pool_xml) { File.read(File.join(File.dirname(__FILE__), File.basename(__FILE__, '.rb'), storage_pool_xml_file)) }
19
20
  let(:libvirt_storage_pool) { double('storage_pool') }
20
21
 
21
22
  describe '#call' do
@@ -26,59 +27,143 @@ describe VagrantPlugins::ProviderLibvirt::Action::CreateDomain do
26
27
 
27
28
  allow(connection).to receive(:servers).and_return(servers)
28
29
  allow(connection).to receive(:volumes).and_return(volumes)
30
+
31
+ allow(logger).to receive(:info)
32
+
33
+ env[:domain_name] = "vagrant-test_default"
34
+
35
+ env[:box_volumes] = []
36
+ env[:box_volumes].push({
37
+ :path=>"/test/box.img",
38
+ :name=>"test_vagrant_box_image_1.1.1_0.img",
39
+ :virtual_size=>5
40
+ })
41
+ # should be ignored for system session and used for user session
42
+ allow(Process).to receive(:uid).and_return(9999)
43
+ allow(Process).to receive(:gid).and_return(9999)
29
44
  end
30
45
 
31
- context 'default pool' do
32
- let(:test_file) { 'default_storage_pool.xml' }
46
+ context 'connection => qemu:///system' do
47
+ context 'default pool' do
48
+ let(:domain_xml_file) { 'default_domain.xml' }
49
+ let(:storage_pool_xml_file) { 'default_system_storage_pool.xml' }
33
50
 
34
- it 'should execute correctly' do
35
- expect(libvirt_client).to receive(:lookup_storage_pool_by_name).and_return(libvirt_storage_pool)
36
- expect(libvirt_storage_pool).to receive(:xml_desc).and_return(storage_pool_xml)
37
- expect(servers).to receive(:create).and_return(machine)
51
+ it 'should execute correctly' do
52
+ expect(libvirt_client).to receive(:lookup_storage_pool_by_name).and_return(libvirt_storage_pool)
53
+ expect(libvirt_storage_pool).to receive(:xml_desc).and_return(storage_pool_xml)
54
+ expect(servers).to receive(:create).with(xml: domain_xml).and_return(machine)
55
+ expect(volumes).to_not receive(:create) # additional disks only
38
56
 
39
- expect(subject.call(env)).to be_nil
40
- end
57
+ expect(subject.call(env)).to be_nil
58
+ end
41
59
 
42
- context 'additional disks' do
43
- let(:vagrantfile) do
44
- <<-EOF
45
- Vagrant.configure('2') do |config|
46
- config.vm.define :test
47
- config.vm.provider :libvirt do |libvirt|
48
- libvirt.storage :file, :size => '20G'
60
+ context 'additional disks' do
61
+ let(:vagrantfile) do
62
+ <<-EOF
63
+ Vagrant.configure('2') do |config|
64
+ config.vm.define :test
65
+ config.vm.provider :libvirt do |libvirt|
66
+ libvirt.storage :file, :size => '20G'
67
+ end
49
68
  end
69
+ EOF
50
70
  end
51
- EOF
52
- end
53
71
 
54
- context 'volume create failed' do
55
- it 'should raise an exception' do
56
- expect(libvirt_client).to receive(:lookup_storage_pool_by_name).and_return(libvirt_storage_pool)
57
- expect(libvirt_storage_pool).to receive(:xml_desc).and_return(storage_pool_xml)
58
- expect(volumes).to receive(:create).and_raise(Libvirt::Error)
72
+ context 'volume create failed' do
73
+ it 'should raise an exception' do
74
+ expect(libvirt_client).to receive(:lookup_storage_pool_by_name).and_return(libvirt_storage_pool)
75
+ expect(libvirt_storage_pool).to receive(:xml_desc).and_return(storage_pool_xml)
76
+ expect(volumes).to receive(:create).and_raise(Libvirt::Error)
59
77
 
60
- expect{ subject.call(env) }.to raise_error(VagrantPlugins::ProviderLibvirt::Errors::FogCreateDomainVolumeError)
78
+ expect{ subject.call(env) }.to raise_error(VagrantPlugins::ProviderLibvirt::Errors::FogCreateDomainVolumeError)
79
+ end
80
+ end
81
+
82
+ context 'volume create succeeded' do
83
+ let(:domain_xml_file) { 'additional_disks_domain.xml' }
84
+
85
+ it 'should complete' do
86
+ expect(libvirt_client).to receive(:lookup_storage_pool_by_name).and_return(libvirt_storage_pool)
87
+ expect(libvirt_storage_pool).to receive(:xml_desc).and_return(storage_pool_xml)
88
+ expect(volumes).to receive(:create).with(
89
+ hash_including(
90
+ :path => "/var/lib/libvirt/images/vagrant-test_default-vdb.qcow2",
91
+ :owner => 0,
92
+ :group => 0,
93
+ :pool_name => "default",
94
+ )
95
+ )
96
+ expect(servers).to receive(:create).with(xml: domain_xml).and_return(machine)
97
+
98
+ expect(subject.call(env)).to be_nil
99
+ end
61
100
  end
62
101
  end
102
+ end
63
103
 
64
- context 'volume create succeeded' do
65
- it 'should complete' do
66
- expect(libvirt_client).to receive(:lookup_storage_pool_by_name).and_return(libvirt_storage_pool)
67
- expect(libvirt_storage_pool).to receive(:xml_desc).and_return(storage_pool_xml)
68
- expect(volumes).to receive(:create)
69
- expect(servers).to receive(:create).and_return(machine)
104
+ context 'no default pool' do
105
+ it 'should raise an exception' do
106
+ expect(libvirt_client).to receive(:lookup_storage_pool_by_name).and_return(nil)
70
107
 
71
- expect(subject.call(env)).to be_nil
72
- end
108
+ expect{ subject.call(env) }.to raise_error(VagrantPlugins::ProviderLibvirt::Errors::NoStoragePool)
73
109
  end
74
110
  end
75
111
  end
76
112
 
77
- context 'no default pool' do
78
- it 'should raise an exception' do
79
- expect(libvirt_client).to receive(:lookup_storage_pool_by_name).and_return(nil)
113
+ context 'connection => qemu:///session' do
114
+ let(:vagrantfile) do
115
+ <<-EOF
116
+ Vagrant.configure('2') do |config|
117
+ config.vm.define :test
118
+ config.vm.provider :libvirt do |libvirt|
119
+ libvirt.qemu_use_session = true
120
+ end
121
+ end
122
+ EOF
123
+ end
124
+
125
+ context 'default pool' do
126
+ let(:storage_pool_xml_file) { 'default_user_storage_pool.xml' }
127
+
128
+ it 'should execute correctly' do
129
+ expect(libvirt_client).to receive(:lookup_storage_pool_by_name).and_return(libvirt_storage_pool)
130
+ expect(libvirt_storage_pool).to receive(:xml_desc).and_return(storage_pool_xml)
131
+ expect(servers).to receive(:create).and_return(machine)
132
+
133
+ expect(subject.call(env)).to be_nil
134
+ end
80
135
 
81
- expect{ subject.call(env) }.to raise_error(VagrantPlugins::ProviderLibvirt::Errors::NoStoragePool)
136
+ context 'additional disks' do
137
+ let(:vagrantfile) do
138
+ <<-EOF
139
+ Vagrant.configure('2') do |config|
140
+ config.vm.define :test
141
+ config.vm.provider :libvirt do |libvirt|
142
+ libvirt.qemu_use_session = true
143
+ libvirt.storage :file, :size => '20G'
144
+ end
145
+ end
146
+ EOF
147
+ end
148
+
149
+ context 'volume create succeeded' do
150
+ it 'should complete' do
151
+ expect(libvirt_client).to receive(:lookup_storage_pool_by_name).and_return(libvirt_storage_pool)
152
+ expect(libvirt_storage_pool).to receive(:xml_desc).and_return(storage_pool_xml)
153
+ expect(volumes).to receive(:create).with(
154
+ hash_including(
155
+ :path => "/var/lib/libvirt/images/vagrant-test_default-vdb.qcow2",
156
+ :owner => 9999,
157
+ :group => 9999,
158
+ :pool_name => "default",
159
+ )
160
+ )
161
+ expect(servers).to receive(:create).and_return(machine)
162
+
163
+ expect(subject.call(env)).to be_nil
164
+ end
165
+ end
166
+ end
82
167
  end
83
168
  end
84
169
  end
@@ -0,0 +1,54 @@
1
+ <domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
2
+ <name>vagrant-test_default</name>
3
+ <title></title>
4
+ <description>Source: /rootpath/Vagrantfile</description>
5
+ <uuid></uuid>
6
+ <memory>524288</memory>
7
+ <vcpu>1</vcpu>
8
+
9
+
10
+ <cpu mode='host-model'>
11
+ <model fallback='allow'></model>
12
+ </cpu>
13
+
14
+
15
+ <os>
16
+ <type>hvm</type>
17
+ <kernel></kernel>
18
+ <initrd></initrd>
19
+ <cmdline></cmdline>
20
+ </os>
21
+ <features>
22
+ <acpi/>
23
+ <apic/>
24
+ <pae/>
25
+ </features>
26
+ <clock offset='utc'>
27
+ </clock>
28
+ <devices>
29
+ <disk type='file' device='disk'>
30
+ <driver name='qemu' type='qcow2' cache='default'/>
31
+ <source file='/var/lib/libvirt/images/vagrant-test_default-vdb.qcow2'/>
32
+ <target dev='vdb' bus='virtio'/>
33
+ </disk>
34
+
35
+
36
+ <serial type='pty'>
37
+ <target port='0'/>
38
+ </serial>
39
+ <console type='pty'>
40
+ <target port='0'/>
41
+ </console>
42
+
43
+
44
+ <input type='mouse' bus='ps2'/>
45
+
46
+ <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' keymap='en-us' />
47
+ <video>
48
+ <model type='cirrus' vram='9216' heads='1'/>
49
+ </video>
50
+
51
+
52
+ </devices>
53
+
54
+ </domain>