vagrant-kvm 0.1.7 → 0.1.8

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.
@@ -19,10 +19,6 @@ module VagrantPlugins
19
19
  error_key(:kvm_no_qemu_binary)
20
20
  end
21
21
 
22
- class KvmFailImageConversion < VagrantKVMError
23
- error_key(:kvm_fail_image_conversion)
24
- end
25
-
26
22
  class KvmBadBoxFormat < VagrantKVMError
27
23
  error_key(:kvm_bad_box_format)
28
24
  end
@@ -30,6 +26,10 @@ module VagrantPlugins
30
26
  class KvmFailedCommand < VagrantKVMError
31
27
  error_key(:kvm_failed_command)
32
28
  end
29
+
30
+ class KvmFailStoragePool < VagrantKVMError
31
+ error_key(:kvm_fail_storagepool)
32
+ end
33
33
  end
34
34
  end
35
35
  end
@@ -6,8 +6,8 @@ end
6
6
 
7
7
  # This is a sanity check to make sure no one is attempting to install
8
8
  # this into an early Vagrant version.
9
- if Vagrant::VERSION < "1.1.0"
10
- raise "The Vagrant KVM plugin is only compatible with Vagrant 1.1+"
9
+ if Vagrant::VERSION < "1.4.0"
10
+ raise "The Vagrant KVM plugin is only compatible with Vagrant 1.4+"
11
11
  end
12
12
 
13
13
  module VagrantPlugins
@@ -34,6 +34,16 @@ module VagrantPlugins
34
34
  Provider
35
35
  end
36
36
 
37
+ guest_capability("linux", "mount_p9_shared_folder") do
38
+ require_relative "cap/mount_p9"
39
+ Cap::MountP9
40
+ end
41
+
42
+ synced_folder("p9", 20) do
43
+ require_relative "synced_folder"
44
+ SyncedFolder
45
+ end
46
+
37
47
  # This initializes the internationalization strings.
38
48
  def self.setup_i18n
39
49
  I18n.load_path << File.expand_path("locales/en.yml", ProviderKvm.source_root)
@@ -47,30 +47,13 @@ module VagrantPlugins
47
47
  # we return nil.
48
48
  return nil if state == :not_created
49
49
 
50
- #ip_addr = @driver.read_ip(@machine.config.vm.base_mac)
50
+ ip_addr = @driver.read_machine_ip
51
51
  return {
52
- :host => read_machine_ip,
52
+ :host => ip_addr,
53
53
  :port => "22" # XXX should be somewhere in default config
54
54
  }
55
55
  end
56
56
 
57
- # XXX duplicated from prepare_nfs_settings
58
- # Returns the IP address of the guest by looking at the first
59
- # enabled host only network.
60
- #
61
- # @return [String]
62
- def read_machine_ip
63
- @machine.config.vm.networks.each do |type, options|
64
- if type == :private_network && options[:ip].is_a?(String)
65
- return options[:ip]
66
- end
67
- end
68
-
69
- # XXX duplicated with network.rb default
70
- # If no private network configuration, return default ip
71
- "192.168.123.10"
72
- end
73
-
74
57
  # Return the state of the VM
75
58
  #
76
59
  # @return [Symbol]
@@ -0,0 +1,57 @@
1
+ require 'digest/md5'
2
+
3
+ module VagrantPlugins
4
+ module ProviderKvm
5
+ class SyncedFolder < Vagrant.plugin("2", :synced_folder)
6
+ def usable?(machine)
7
+ # These synced folders only work if the provider if KVM
8
+ machine.provider_name == :kvm
9
+ end
10
+
11
+ def prepare(machine, folders, _opts)
12
+ defs = []
13
+ folders.each do |id, data|
14
+ # access_mode can be squash, mapped, or passthrough
15
+ accessmode = data.has_key?(:access_mode)? data[:access_mode] : 'squash'
16
+ accessmode = 'squash' unless accessmode == 'mapped' || accessmode == 'passthrough'
17
+ # tag maximum len is 31
18
+ tag = Digest::MD5.new.update(id).to_s[0,31]
19
+ defs << {
20
+ :mount_tag => tag,
21
+ :hostpath => data[:hostpath].to_s,
22
+ :accessmode => accessmode
23
+ }
24
+ end
25
+
26
+ driver(machine).share_folders(defs)
27
+ end
28
+
29
+ def enable(machine, folders, _opts)
30
+ # Go through each folder and mount
31
+ machine.ui.info("mounting p9 share in guest")
32
+ # Only mount folders that have a guest path specified.
33
+ mount_folders = {}
34
+ folders.each do |id, opts|
35
+ mount_folders[id] = opts.dup if opts[:guestpath]
36
+ end
37
+ common_opts = {
38
+ :version => '9p2000.L',
39
+ }
40
+ # Mount the actual folder
41
+ machine.guest.capability(
42
+ :mount_p9_shared_folder, mount_folders, common_opts)
43
+ end
44
+
45
+ def cleanup(machine, opts)
46
+ driver(machine).clear_shared_folders if machine.id && machine.id != ""
47
+ end
48
+
49
+ protected
50
+
51
+ # This is here so that we can stub it for tests
52
+ def driver(machine)
53
+ machine.provider.driver
54
+ end
55
+ end
56
+ end
57
+ end
@@ -13,11 +13,11 @@ module VagrantPlugins
13
13
  self.attributes = {
14
14
  :forward => "nat",
15
15
  :domain_name => "vagrant.local",
16
- :base_ip => "192.168.192.1",
16
+ :base_ip => "192.168.123.1",
17
17
  :netmask => "255.255.255.0",
18
18
  :range => {
19
- :start => "192.168.192.100",
20
- :end => "192.168.192.200",
19
+ :start => "192.168.123.100",
20
+ :end => "192.168.123.200",
21
21
  },
22
22
  :hosts => [],
23
23
  name: name,
@@ -60,6 +60,33 @@ module VagrantPlugins
60
60
  def as_xml
61
61
  KvmTemplateRenderer.render("libvirt_network", attributes.dup)
62
62
  end
63
+
64
+ # Provide host xml block to update definiton through libvirt(>= 0.5.0)
65
+ def as_host_xml
66
+ xml = ""
67
+ hosts.each do |host|
68
+ xml = xml + "<host mac='#{host[:mac]}' name='#{host[:name]}' ip='#{host[:ip]}' />"
69
+ end
70
+ xml
71
+ end
72
+
73
+ def hosts
74
+ get(:hosts)
75
+ end
76
+
77
+ def already_exist_host?(config)
78
+ hosts.each do |host|
79
+ return true if host[:mac]==config[:mac]
80
+ end
81
+ false
82
+ end
83
+
84
+ def already_exist_ip?(config)
85
+ hosts.each do |host|
86
+ return true if host[:ip]==config[:ip]
87
+ end
88
+ false
89
+ end
63
90
  end
64
91
  end
65
92
  end
@@ -33,11 +33,16 @@ module VagrantPlugins
33
33
  :gui => nil,
34
34
  :vnc_autoport => false,
35
35
  :vnc_password => nil,
36
- :network => 'default',
36
+ :network => 'vagrant',
37
37
  :network_model => 'virtio',
38
- :video_model => 'cirrus'
38
+ :video_model => 'cirrus',
39
+ :secmodel => nil,
40
+ :sound => nil,
41
+ :nics => [],
39
42
  }
40
43
  doc = REXML::Document.new definition
44
+
45
+ # Basic devices
41
46
  memory_unit = doc.elements["/domain/memory"].attributes["unit"]
42
47
  update({
43
48
  :name => doc.elements["/domain/name"].text,
@@ -48,23 +53,41 @@ module VagrantPlugins
48
53
  :machine_type => doc.elements["/domain/os/type"].attributes["machine"],
49
54
  :disk => doc.elements["//devices/disk/source"].attributes["file"],
50
55
  :network => doc.elements["//devices/interface/source"].attributes["network"],
51
- :network_model => :default,
52
- :mac => format_mac(doc.elements["//devices/interface/mac"].attributes["address"]),
56
+ :mac => doc.elements["//devices/interface/mac"].attributes["address"],
53
57
  :image_type => doc.elements["//devices/disk/driver"].attributes["type"],
54
58
  :qemu_bin => doc.elements["/domain/devices/emulator"].text,
55
59
  :video_model => doc.elements["/domain/devices/video/model"].attributes["type"],
56
60
  :disk_bus => doc.elements["//devices/disk/target"].attributes["bus"]
57
61
  })
58
- model_node = doc.elements["//devices/interface/model"]
59
- if model_node
60
- update({
61
- :model_node => model_node,
62
- :network_model => model_node.attributes["type"]
63
- })
62
+ # Security Model
63
+ doc.elements.each("/domain/seclabel") do |seclabel|
64
+ update({:secmodel => seclabel.attributes["model"]})
65
+ end
66
+ # NETWORK Interfaces
67
+ nics = []
68
+ doc.elements.each("//devices/interface") do |intf|
69
+ network = intf.elements["source"].attributes["network"]
70
+ mac = intf.elements["mac"].attributes["address"]
71
+ type = intf.attributes["type"]
72
+ model = intf.elements["model"].attributes["type"]
73
+ if network == 'vagrant' then
74
+ update({:network_model => model})
75
+ else
76
+ nics << {
77
+ :network => network,
78
+ :mac => format_mac(mac),
79
+ :type => type,
80
+ :model => model,
81
+ # XXX: fixme for supprting bridge
82
+ }
83
+ end
64
84
  end
85
+ update({ :nics => nics })
86
+ # UUID
65
87
  if doc.elements["/domain/uuid"]
66
88
  update({:uuid => doc.elements["/domain/uuid"].text})
67
89
  end
90
+ # VNC
68
91
  if doc.elements["//devices/graphics"]
69
92
  attrs = doc.elements["//devices/graphics"].attributes
70
93
  update({
@@ -74,6 +97,12 @@ module VagrantPlugins
74
97
  :vnc_password => attrs['passwd']
75
98
  })
76
99
  end
100
+ # SOUND
101
+ if doc.elements["//devices/sound"]
102
+ update({
103
+ :sound => true
104
+ })
105
+ end
77
106
  end
78
107
 
79
108
  def as_xml
@@ -99,7 +128,77 @@ module VagrantPlugins
99
128
  attributes.merge!(:memory_size => get_memory("KiB"),
100
129
  :memory_unit => "KiB")
101
130
  )
102
- xml
131
+ # not inject nics to definition when called for export
132
+ # FIXME: bad design
133
+ # export call here with (uuid = nil)
134
+ if get(:uuid)
135
+ inject_nics(xml)
136
+ else
137
+ xml
138
+ end
139
+ end
140
+
141
+ # inject nics into XML
142
+ #
143
+ # primary NIC is 0000:00:03.0
144
+ # and injected to 0000:01:01.0 ~ 0000:00:1f.0
145
+ #
146
+ def inject_nics(xml)
147
+ nics=get(:nics)
148
+ doc = REXML::Document.new xml
149
+ primary_nic = doc.elements["//interface"]
150
+ devid = 1
151
+ nics.each do |nic|
152
+ next if nic[:mac] == get(:mac)
153
+ #XXX: support maximum 31 additional NICs
154
+ # because of a PCI standard limitation.
155
+ break if devid > 31
156
+
157
+ nic[:type] = 'network' unless nic[:type]
158
+ nic[:model] = 'virtio' unless nic[:model]
159
+
160
+ e = REXML::Element.new('interface')
161
+ e.add_attributes({'type' => nic[:type]})
162
+ e.add_element('mac', {'address' => nic[:mac]})
163
+ e.add_element('source', {'network' => nic[:network]})
164
+ e.add_element('model', {'type' => nic[:model]})
165
+ e.add_element('address',{'type' => 'pci','domain' => '0x0000',
166
+ 'bus' => '0x01', # bus 0x01 is for NICs, 0x02 is for plan9fs
167
+ 'slot' => '0x%02x'% devid, 'function' => "0"})
168
+ primary_nic.next_sibling = e
169
+ devid = devid + 1
170
+ end
171
+ doc.to_s
172
+ end
173
+
174
+ # add_nic
175
+ #
176
+ # nic
177
+ # mac: mac address
178
+ # network: network name(vagrant-*, bridged)
179
+ # type: network/bridge
180
+ # model: virtio/ne2k_pci
181
+ #
182
+ def add_nic(new_nic)
183
+ mac = format_mac(new_nic[:mac])
184
+ nics = get(:nics)
185
+ unless nics == []
186
+ # if nic has already exist, update it
187
+ nics.each_with_index do |nic,i|
188
+ if nic[:mac] == mac
189
+ nics[i] = new_nic
190
+ return set(:nics, nics)
191
+ end
192
+ end
193
+ end
194
+ # add nic to nics
195
+ nics << {
196
+ :mac => mac,
197
+ :network => new_nic[:network],
198
+ :type => new_nic[:type],
199
+ :model => new_nic[:model]
200
+ }
201
+ set(:nics, nics)
103
202
  end
104
203
 
105
204
  def get_memory(unit="bytes")
@@ -1,5 +1,5 @@
1
1
  module VagrantPlugins
2
2
  module ProviderKvm
3
- VERSION = "0.1.7"
3
+ VERSION = "0.1.8"
4
4
  end
5
5
  end
data/locales/en.yml CHANGED
@@ -4,19 +4,21 @@ en:
4
4
  This is a test message.
5
5
  repair_permission: |-
6
6
  Change directory %{directory} permission from %{old_mode} to %{new_mode}.
7
+ kvm_spool_problem_inform: |-
8
+ Your vagrant-kvm environment should be fixed. see README.
7
9
  errors:
8
10
  kvm_no_connection: |-
9
11
  Cannot connect to KVM through Libvirt. Please check kernel module
10
12
  'kvm' and 'kvm-intel' or 'kvm-amd' are installed and your id is in
11
- group libvirt(in debian/ubuntu).
13
+ group libvirtd(in debian/ubuntu).
12
14
  kvm_invalid_version: |-
13
15
  Invalid Kvm version detected: %{actual}, but a version %{required} is
14
16
  required.
15
17
  kvm_no_qemu_binary: |-
16
18
  Executable binary of qemu could not be found. Please re-examine %{cause}.
17
- kvm_fail_image_conversion: |-
18
- Failed to convert image to specified format.
19
19
  kvm_failed_command: |-
20
20
  System command %{cmd} returned with error code %{res}.
21
21
  kvm_bad_box_format: |-
22
22
  Unsupported box format.
23
+ kvm_fail_storagepool: |-
24
+ Failed to activate storage pool.
data/locales/ja.yml CHANGED
@@ -2,13 +2,20 @@ en:
2
2
  vagrant_kvm:
3
3
  test_message: |-
4
4
  これはテストメッセージです。
5
+ kvm_spool_problem_inform: |-
6
+ このVagrant-kvm環境は修正の必要があります。READMEを確認してください。
5
7
  errors:
6
8
  kvm_no_connection: |-
7
9
  KVMにLibvirt経由で接続できません。カーネルモジュールの
8
- 'kvm' 及び、'kvm-intel'か'kvm-amd'が正しくインストールされ、(debian/ubuntuの場合)あなたのユーザIDが
9
- libvirtグループに属しているか、確認してください。
10
+ 'kvm' 及び、'kvm-intel'か'kvm-amd'が正しくインストールされ、
11
+ (debian/ubuntuの場合)あなたのユーザIDがlibvirtdグループに属しているか、
12
+ 確認してください。
10
13
  kvm_invalid_version: |-
11
- 不適切なKVMのバージョンが検出されました:バージョン %{actual} が検出されましたが、%{required}
12
- が必要です。
14
+ 不適切なKVMのバージョンが検出されました:バージョン %{actual}
15
+ 検出されましたが、%{required} が必要です。
13
16
  kvm_no_qemu_binary: |-
14
17
  Qemuの実行バイナリが見つかりません。%{cause}を確認してください。
18
+ kvm_failed_command: |-
19
+ システムコマンドの %{cmd} が、エラーコード %{res} を返しました。
20
+ kvm_bad_box_format: |-
21
+ サポートされないBOX形式です。
@@ -71,6 +71,12 @@ describe VagrantPlugins::ProviderKvm::Config do
71
71
  end
72
72
  end
73
73
 
74
+ describe "#disk_bus" do
75
+ it "defaults to nil" do
76
+ should_default(:disk_bus, nil)
77
+ end
78
+ end
79
+
74
80
  private
75
81
  def should_default(field, default_value)
76
82
  instance = described_class.new
@@ -10,6 +10,7 @@ module VagrantPlugins
10
10
  let(:box_path) { test_file "box-disk1.img" }
11
11
  let(:box_pool) { test_file "" }
12
12
  let(:capacity) { {:size=>256, :unit=>'KB'} }
13
+ let(:pool_path) { '/tmp/pool-storage' }
13
14
  let(:image_path) { '/tmp/pool-storage/box-disk1.img' }
14
15
  let(:image_type) { 'qcow2' }
15
16
  let(:uid) { 1000 }
@@ -21,7 +22,6 @@ module VagrantPlugins
21
22
  end
22
23
 
23
24
  describe "#import" do
24
-
25
25
  subject do
26
26
  described_class.new(nil)
27
27
  end
@@ -34,13 +34,14 @@ module VagrantPlugins
34
34
 
35
35
  it "does not raise execption" do
36
36
  expect do
37
- subject.init_storage("/tmp", uid, gid)
37
+ subject.init_storage_pool("vagrant", pool_path)
38
38
  end.to_not raise_exception
39
39
  end
40
40
 
41
41
  it "does not raise exception" do
42
42
  expect do
43
- subject.init_storage("/tmp", uid, gid)
43
+ subject.init_storage_pool("vagrant", pool_path)
44
+ subject.activate_storage_pool("vagrant")
44
45
  subject.create_volume(
45
46
  :disk_name => disk_name,
46
47
  :capacity => capacity,