vagrant-kvm 0.1.7 → 0.1.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -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,