vagrant-kvm 0.1.4 → 0.1.5

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 (58) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +2 -0
  3. data/.rspec +1 -0
  4. data/.travis.yml +14 -0
  5. data/CHANGELOG.md +29 -0
  6. data/DEVELOPMENT.md +87 -0
  7. data/Gemfile +1 -0
  8. data/INSTALL.md +229 -0
  9. data/LICENSE +2 -1
  10. data/README.md +154 -63
  11. data/Rakefile +24 -1
  12. data/example_box/README.md +8 -8
  13. data/lib/vagrant-kvm/action.rb +47 -5
  14. data/lib/vagrant-kvm/action/boot.rb +0 -4
  15. data/lib/vagrant-kvm/action/clear_forwarded_ports.rb +53 -0
  16. data/lib/vagrant-kvm/action/forward_ports.rb +104 -0
  17. data/lib/vagrant-kvm/action/import.rb +97 -18
  18. data/lib/vagrant-kvm/action/init_storage_pool.rb +3 -1
  19. data/lib/vagrant-kvm/action/message_not_running.rb +16 -0
  20. data/lib/vagrant-kvm/action/network.rb +12 -13
  21. data/lib/vagrant-kvm/action/package_vagrantfile.rb +3 -1
  22. data/lib/vagrant-kvm/action/prepare_gui.rb +20 -0
  23. data/lib/vagrant-kvm/action/prepare_nfs_settings.rb +8 -16
  24. data/lib/vagrant-kvm/action/prepare_nfs_valid_ids.rb +17 -0
  25. data/lib/vagrant-kvm/action/reset_image_permission.rb +23 -0
  26. data/lib/vagrant-kvm/action/resume_network.rb +28 -0
  27. data/lib/vagrant-kvm/action/share_folders.rb +6 -5
  28. data/lib/vagrant-kvm/action/suspend.rb +8 -1
  29. data/lib/vagrant-kvm/config.rb +103 -2
  30. data/lib/vagrant-kvm/driver/driver.rb +321 -99
  31. data/lib/vagrant-kvm/errors.rb +18 -0
  32. data/lib/vagrant-kvm/provider.rb +4 -1
  33. data/lib/vagrant-kvm/util.rb +3 -0
  34. data/lib/vagrant-kvm/util/commands.rb +23 -0
  35. data/lib/vagrant-kvm/util/definition_attributes.rb +33 -0
  36. data/lib/vagrant-kvm/util/disk_info.rb +48 -0
  37. data/lib/vagrant-kvm/util/network_definition.rb +44 -84
  38. data/lib/vagrant-kvm/util/vm_definition.rb +91 -103
  39. data/lib/vagrant-kvm/version.rb +1 -1
  40. data/locales/en.yml +8 -0
  41. data/locales/ja.yml +14 -0
  42. data/spec/acceptance/vagrant-kvm_spec.rb +80 -0
  43. data/spec/fedora/10.virt.rules +10 -0
  44. data/spec/fedora/50-vagrant-libvirt-access.pkla +6 -0
  45. data/spec/spec_helper.rb +30 -0
  46. data/spec/support/libvirt_helper.rb +37 -0
  47. data/spec/support/vagrant_kvm_helper.rb +39 -0
  48. data/spec/test_files/box.xml +74 -0
  49. data/spec/vagrant-kvm/config_spec.rb +56 -0
  50. data/spec/vagrant-kvm/driver/driver_spec.rb +36 -0
  51. data/spec/vagrant-kvm/errors_spec.rb +25 -0
  52. data/spec/vagrant-kvm/util/network_definition_spec.rb +60 -0
  53. data/spec/vagrant-kvm/util/vm_definition_spec.rb +76 -0
  54. data/templates/libvirt_domain.erb +34 -12
  55. data/templates/libvirt_network.erb +13 -0
  56. data/templates/package_Vagrantfile.erb +11 -0
  57. data/vagrant-kvm.gemspec +1 -2
  58. metadata +41 -42
@@ -1,5 +1,5 @@
1
1
  module VagrantPlugins
2
2
  module ProviderKvm
3
- VERSION = "0.1.4"
3
+ VERSION = "0.1.5"
4
4
  end
5
5
  end
@@ -10,3 +10,11 @@ en:
10
10
  kvm_invalid_version: |-
11
11
  Invalid Kvm version detected: %{actual}, but a version %{required} is
12
12
  required.
13
+ kvm_no_qemu_binary: |-
14
+ Executable binary of qemu could not be found. Please re-examine %{cause}.
15
+ kvm_fail_image_conversion: |-
16
+ Failed to convert image to specified format.
17
+ kvm_failed_command: |-
18
+ System command %{cmd} returned with error code %{res}.
19
+ kvm_bad_box_format: |-
20
+ Unsupported box format.
@@ -0,0 +1,14 @@
1
+ en:
2
+ vagrant_kvm:
3
+ test_message: |-
4
+ これはテストメッセージです。
5
+ errors:
6
+ kvm_no_connection: |-
7
+ KVMにLibvirt経由で接続できません。カーネルモジュールの
8
+ 'kvm' 及び、'kvm-intel'か'kvm-amd'が正しくインストールされ、(debian/ubuntuの場合)あなたのユーザIDが
9
+ libvirtグループに属しているか、確認してください。
10
+ kvm_invalid_version: |-
11
+ 不適切なKVMのバージョンが検出されました:バージョン %{actual} が検出されましたが、%{required}
12
+ が必要です。
13
+ kvm_no_qemu_binary: |-
14
+ Qemuの実行バイナリが見つかりません。%{cause}を確認してください。
@@ -0,0 +1,80 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'vagrant-kvm' do
4
+ before(:all) do
5
+ create_vagrantfile
6
+ end
7
+
8
+ before(:all) do
9
+ @old_domains = libvirt.domains.count
10
+ @old_pool_files = pool_files.count
11
+ end
12
+
13
+ describe 'up' do
14
+ before(:all) do
15
+ vagrant_up
16
+ end
17
+
18
+ after(:all) do
19
+ vagrant_destroy
20
+ end
21
+
22
+ it'creates new libvirt domain' do
23
+ (libvirt.domains.count - @old_domains).should == 1
24
+ end
25
+
26
+ it 'starts created libvirt domain' do
27
+ expect(libvirt.domain).to be_active
28
+ end
29
+
30
+ it 'creates disk image file' do
31
+ (pool_files.count - @old_pool_files).should == 1
32
+ end
33
+
34
+ it 'creates new pool' do
35
+ expect(libvirt.storage_pools).to include('vagrant')
36
+ end
37
+
38
+ it 'creates new network' do
39
+ expect(libvirt.networks).to include('vagrant')
40
+ end
41
+ end
42
+
43
+ describe 'down' do
44
+ before(:all) do
45
+ vagrant_up
46
+ vagrant_halt
47
+ end
48
+
49
+ after(:all) do
50
+ vagrant_destroy
51
+ end
52
+
53
+ it 'shutdowns domain' do
54
+ expect(libvirt.domain).not_to be_active
55
+ end
56
+ end
57
+
58
+ describe 'destroy' do
59
+ before(:all) do
60
+ vagrant_up
61
+ vagrant_destroy
62
+ end
63
+
64
+ it 'undefines domain' do
65
+ libvirt.domains.count.should == @old_domains
66
+ end
67
+
68
+ it 'removes disk image file' do
69
+ expect(pool_files).to be_empty
70
+ end
71
+
72
+ it 'does not undefine storage pool' do
73
+ expect(libvirt.storage_pools).to include('vagrant')
74
+ end
75
+
76
+ it 'does not undefine new network' do
77
+ expect(libvirt.networks).to include('vagrant')
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,10 @@
1
+ polkit.addRule(function(action, subject) {
2
+ polkit.log("action=" + action);
3
+ polkit.log("subject=" + subject);
4
+ var now = new Date();
5
+ polkit.log("now=" + now)
6
+ if ((action.id == "org.libvirt.unix.manage" || action.id == "org.libvirt.unix.monitor") && subject.isInGroup("virt")) {
7
+ return polkit.Result.YES;
8
+ }
9
+ return null;
10
+ });
@@ -0,0 +1,6 @@
1
+ [libvirt Management Access]
2
+ Identity=unix-group:virt
3
+ Action=org.libvirt.unix.manage;org.libvirt.unix.monitor
4
+ ResultAny=yes
5
+ ResultInactive=yes
6
+ ResultActive=yes
@@ -0,0 +1,30 @@
1
+ require 'vagrant-kvm'
2
+ require 'support/libvirt_helper'
3
+ require 'support/vagrant_kvm_helper'
4
+ require 'pry'
5
+
6
+ def libvirt
7
+ @libvirt ||= LibvirtHelper.new
8
+ end
9
+
10
+ RSpec.configure do |spec|
11
+ spec.include VagrantKvmHelper
12
+
13
+ spec.before(:all) do
14
+
15
+ # make sure everything is run in tmp
16
+ Dir.chdir '/tmp'
17
+ end
18
+
19
+ spec.after(:all) do
20
+ libvirt.connection.close
21
+ end
22
+
23
+ at_exit do
24
+ File.delete('Vagrantfile') if File.exists?('Vagrantfile')
25
+ end
26
+ end
27
+
28
+ def test_file(path)
29
+ File.join(File.dirname(__FILE__), "test_files", path)
30
+ end
@@ -0,0 +1,37 @@
1
+ require 'libvirt'
2
+
3
+ class LibvirtHelper
4
+
5
+ attr_reader :connection
6
+
7
+ def initialize
8
+ @connection = Libvirt.open('qemu:///system')
9
+ end
10
+
11
+ def domains
12
+ # list_domains returns IDs of active domains
13
+ # list_defined_domains returns names of inactive domains
14
+ @connection.list_domains + @connection.list_defined_domains
15
+ end
16
+
17
+ def domain
18
+ domain = domains.first
19
+ case domain
20
+ when Integer
21
+ @connection.lookup_domain_by_id(domain)
22
+ when String
23
+ @connection.lookup_domain_by_name(domain)
24
+ else
25
+ raise "Cannot find domain!"
26
+ end
27
+ end
28
+
29
+ def storage_pools
30
+ @connection.list_storage_pools
31
+ end
32
+
33
+ def networks
34
+ @connection.list_networks
35
+ end
36
+
37
+ end # LibvirtHelper
@@ -0,0 +1,39 @@
1
+ module VagrantKvmHelper
2
+
3
+ def create_vagrantfile
4
+ File.open('Vagrantfile', 'w') do |file|
5
+ file.write <<-RUBY
6
+ Vagrant.require_plugin 'vagrant-kvm'
7
+
8
+ Vagrant.configure('2') do |config|
9
+ config.vm.box = 'vagrant-kvm-specs'
10
+ config.vm.network :private_network, ip: '192.168.50.2'
11
+ end
12
+ RUBY
13
+ end
14
+ end
15
+
16
+ def vagrant_up
17
+ silent_exec('bundle exec vagrant up --provider=kvm')
18
+ end
19
+
20
+ def vagrant_halt
21
+ silent_exec('bundle exec vagrant halt')
22
+ end
23
+
24
+ def vagrant_destroy
25
+ silent_exec('bundle exec vagrant destroy -f')
26
+ end
27
+
28
+ def pool_files
29
+ Dir["/home/#{ENV['USER']}/.vagrant.d/tmp/storage-pool/*"]
30
+ end
31
+
32
+ private
33
+
34
+ def silent_exec(cmd)
35
+ cmd << ' 2>&1' unless !!ENV['DEBUG']
36
+ `#{cmd}`
37
+ end
38
+
39
+ end # VagrantKvmHelper
@@ -0,0 +1,74 @@
1
+ <domain type='kvm' id='37'>
2
+ <name>winxp_base</name>
3
+ <memory unit='KiB'>524288</memory>
4
+ <currentMemory unit='KiB'>524288</currentMemory>
5
+ <vcpu placement='static'>1</vcpu>
6
+ <os>
7
+ <type arch='x86_64' machine='pc-1.2'>hvm</type>
8
+ <boot dev='hd'/>
9
+ </os>
10
+ <features>
11
+ <acpi/>
12
+ <apic/>
13
+ <pae/>
14
+ </features>
15
+ <clock offset='utc'/>
16
+ <on_poweroff>destroy</on_poweroff>
17
+ <on_reboot>restart</on_reboot>
18
+ <on_crash>restart</on_crash>
19
+ <devices>
20
+ <emulator>/usr/bin/kvm</emulator>
21
+ <disk type='file' device='disk'>
22
+ <driver name='qemu' type='qcow2'/>
23
+ <source file='winxp.qcow2'/>
24
+ <target dev='vda' bus='virtio'/>
25
+ <alias name='virtio-disk0'/>
26
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>
27
+ </disk>
28
+ <controller type='usb' index='0'>
29
+ <alias name='usb0'/>
30
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
31
+ </controller>
32
+ <controller type='virtio-serial' index='0'>
33
+ <alias name='virtio-serial0'/>
34
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
35
+ </controller>
36
+ <interface type='network'>
37
+ <mac address='08:00:27:30:3b:ea'/>
38
+ <source network='vagrant'/>
39
+ <target dev='vnet0'/>
40
+ <model type='virtio'/>
41
+ <alias name='net0'/>
42
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
43
+ </interface>
44
+ <serial type='pty'>
45
+ <source path='/dev/pts/1'/>
46
+ <target port='0'/>
47
+ <alias name='serial0'/>
48
+ </serial>
49
+ <console type='pty' tty='/dev/pts/1'>
50
+ <source path='/dev/pts/1'/>
51
+ <target type='serial' port='0'/>
52
+ <alias name='serial0'/>
53
+ </console>
54
+ <input type='mouse' bus='ps2'/>
55
+ <graphics type='vnc' port='5900' autoport='no' listen='0.0.0.0'>
56
+ <listen type='address' address='0.0.0.0'/>
57
+ </graphics>
58
+ <sound model='ich6'>
59
+ <alias name='sound0'/>
60
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
61
+ </sound>
62
+ <video>
63
+ <model type='cirrus' vram='9216' heads='1'/>
64
+ <alias name='video0'/>
65
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
66
+ </video>
67
+ <memballoon model='virtio'>
68
+ <alias name='balloon0'/>
69
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/>
70
+ </memballoon>
71
+ </devices>
72
+ <seclabel type='none'/>
73
+ </domain>
74
+
@@ -0,0 +1,56 @@
1
+ require 'spec_helper'
2
+ require "vagrant-kvm/config"
3
+
4
+ describe VagrantPlugins::ProviderKvm::Config do
5
+ describe "#machine_type" do
6
+ it "defaults to pc-1.2" do
7
+ should_default(:machine_type, "pc-1.2")
8
+ end
9
+ end
10
+
11
+ describe "#vnc_port" do
12
+ it "defaults to -1" do
13
+ should_default(:vnc_port, -1)
14
+ end
15
+ end
16
+
17
+ describe "#vnc_password" do
18
+ it "defaults to nil" do
19
+ should_default(:vnc_password, nil)
20
+ end
21
+ end
22
+
23
+ describe "#network_model" do
24
+ it "defaults to 'virtio'" do
25
+ should_default(:network_model, 'virtio')
26
+ end
27
+ end
28
+
29
+ describe "#video_model" do
30
+ it "defaults to 'virtio'" do
31
+ should_default(:video_model, 'cirrus')
32
+ end
33
+ end
34
+
35
+ describe "#image_mode" do
36
+ it "sets image_backing to false if clone" do
37
+ subject.image_mode = 'clone'
38
+ subject.finalize!
39
+ subject.image_backing.should be_false
40
+ end
41
+
42
+ it "sets image_backing to true if cow" do
43
+ subject.image_mode = 'cow'
44
+ subject.finalize!
45
+ subject.image_backing.should be_true
46
+ end
47
+ end
48
+
49
+ private
50
+ def should_default(field, default_value)
51
+ instance = described_class.new
52
+ instance.send(field).should == described_class::UNSET_VALUE
53
+ instance.finalize!
54
+ instance.send(field).should == default_value
55
+ end
56
+ end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+
3
+ module VagrantPlugins
4
+ module ProviderKvm
5
+ module Driver
6
+ describe Driver do
7
+ let(:xml) { test_file "box.xml" }
8
+ let(:volume_name) { "" }
9
+
10
+ before do
11
+ described_class.any_instance.stub(:load_kvm_module!) { true }
12
+ end
13
+
14
+ describe "#import" do
15
+ # FIXME All of these required stubs are a symptom of bad design in the
16
+ # driver class.
17
+ let(:volume) { double(path: "foo") }
18
+ let(:pool) { double(refresh: nil, lookup_volume_by_name: volume) }
19
+ let(:domain) { double(uuid: "abc") }
20
+ let(:conn) { double(version: 1000000000,
21
+ lookup_storage_pool_by_name: pool,
22
+ define_domain_xml: domain) }
23
+ subject do
24
+ described_class.new(nil, conn)
25
+ end
26
+
27
+ it "does not raise exception" do
28
+ expect do
29
+ subject.import(xml, volume_name)
30
+ end.to_not raise_exception
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ module VagrantPlugins::ProviderKvm::Errors
4
+ describe VagrantPlugins::ProviderKvm::Errors do
5
+ it "has translations for all errors" do
6
+ # Load the translations
7
+ VagrantPlugins::ProviderKvm::Plugin.setup_i18n
8
+
9
+ descendants = ObjectSpace.each_object(Class).select { |klass| klass < VagrantKVMError }
10
+
11
+ all_interpolations = {
12
+ required: "",
13
+ cause: "",
14
+ actual: "",
15
+ cmd: "",
16
+ res: "",
17
+ }
18
+
19
+ descendants.each do |klass|
20
+ msg = klass.new(all_interpolations).message
21
+ msg.should_not include("translation missing")
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,60 @@
1
+ require 'spec_helper'
2
+
3
+ describe VagrantPlugins::ProviderKvm::Util::NetworkDefinition do
4
+ let(:name) { 'vagrant' }
5
+ let(:xml) do
6
+ <<-XML
7
+ <network connections='1'>
8
+ <name>vagrant</name>
9
+ <uuid>0b9deaff-7665-d129-02e9-0f0a74054f87</uuid>
10
+ <forward mode='nat'/>
11
+ <bridge name='virbr1' stp='on' delay='0' />
12
+ <mac address='52:54:00:DE:20:0C'/>
13
+ <domain name='vagrant.local'/>
14
+ <ip address='192.168.123.1' netmask='255.255.255.0'>
15
+ <dhcp>
16
+ <range start='192.168.123.100' end='192.168.123.200' />
17
+ <host mac='00:69:0d:c2:52:f7' name='default' ip='192.168.123.10' />
18
+ </dhcp>
19
+ </ip>
20
+ </network>
21
+ XML
22
+ end
23
+
24
+ let(:definition) { described_class.new(name, xml) }
25
+ subject { definition }
26
+
27
+ it "should set the attributes properly" do
28
+ subject.get(:forward).should == 'nat'
29
+ subject.get(:domain_name).should == 'vagrant.local'
30
+ subject.get(:base_ip).should == '192.168.123.1'
31
+ subject.get(:netmask).should == '255.255.255.0'
32
+ subject.get(:range).should == { :start => "192.168.123.100", :end => "192.168.123.200"}
33
+ subject.get(:hosts).should == [ {
34
+ :mac => '00:69:0d:c2:52:f7',
35
+ :name => 'default',
36
+ :ip => '192.168.123.10',
37
+ }]
38
+ end
39
+
40
+
41
+ describe "#==" do
42
+ it "returns true if and only if all attributes are equal" do
43
+ def1 = described_class.new(name, xml)
44
+ def2 = described_class.new(name, xml)
45
+
46
+ def1.should == def2
47
+
48
+ def2.set(:netmask, '255.255.0.0')
49
+ def1.should_not == def2
50
+ end
51
+ end
52
+
53
+ describe "#as_xml" do
54
+ it "should be symetrical" do
55
+ def1 = described_class.new(name, subject.as_xml)
56
+ subject.should == def1
57
+ subject.as_xml.should == def1.as_xml
58
+ end
59
+ end
60
+ end