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.
- checksums.yaml +4 -4
- data/.gitignore +5 -0
- data/CHANGELOG.md +0 -7
- data/DEVELOPMENT.md +69 -0
- data/INSTALL.md +1 -1
- data/README.md +61 -47
- data/bin/package.sh +83 -0
- data/install.rb +7 -0
- data/lib/vagrant-kvm/action.rb +23 -31
- data/lib/vagrant-kvm/action/customize.rb +44 -0
- data/lib/vagrant-kvm/action/import.rb +52 -23
- data/lib/vagrant-kvm/action/init_storage_pool.rb +5 -4
- data/lib/vagrant-kvm/action/network.rb +127 -30
- data/lib/vagrant-kvm/action/{prepare_gui.rb → prepare_kvmconfig.rb} +4 -1
- data/lib/vagrant-kvm/action/prepare_nfs_settings.rb +16 -23
- data/lib/vagrant-kvm/action/set_name.rb +27 -3
- data/lib/vagrant-kvm/action/share_folders.rb +4 -5
- data/lib/vagrant-kvm/cap/mount_p9.rb +40 -0
- data/lib/vagrant-kvm/config.rb +73 -1
- data/lib/vagrant-kvm/driver/driver.rb +303 -117
- data/lib/vagrant-kvm/errors.rb +4 -4
- data/lib/vagrant-kvm/plugin.rb +12 -2
- data/lib/vagrant-kvm/provider.rb +2 -19
- data/lib/vagrant-kvm/synced_folder.rb +57 -0
- data/lib/vagrant-kvm/util/network_definition.rb +30 -3
- data/lib/vagrant-kvm/util/vm_definition.rb +110 -11
- data/lib/vagrant-kvm/version.rb +1 -1
- data/locales/en.yml +5 -3
- data/locales/ja.yml +11 -4
- data/spec/vagrant-kvm/config_spec.rb +6 -0
- data/spec/vagrant-kvm/driver/driver_spec.rb +4 -3
- data/spec/vagrant-kvm/util/vm_definition_spec.rb +4 -8
- data/templates/libvirt_domain.erb +29 -3
- data/vagrant-kvm.gemspec +3 -3
- metadata +21 -9
- data/lib/vagrant-kvm/action/prune_nfs_exports.rb +0 -20
data/lib/vagrant-kvm/errors.rb
CHANGED
@@ -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
|
data/lib/vagrant-kvm/plugin.rb
CHANGED
@@ -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.
|
10
|
-
raise "The Vagrant KVM plugin is only compatible with Vagrant 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)
|
data/lib/vagrant-kvm/provider.rb
CHANGED
@@ -47,30 +47,13 @@ module VagrantPlugins
|
|
47
47
|
# we return nil.
|
48
48
|
return nil if state == :not_created
|
49
49
|
|
50
|
-
|
50
|
+
ip_addr = @driver.read_machine_ip
|
51
51
|
return {
|
52
|
-
:host =>
|
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.
|
16
|
+
:base_ip => "192.168.123.1",
|
17
17
|
:netmask => "255.255.255.0",
|
18
18
|
:range => {
|
19
|
-
:start => "192.168.
|
20
|
-
:end => "192.168.
|
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 => '
|
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
|
-
:
|
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
|
-
|
59
|
-
|
60
|
-
update({
|
61
|
-
|
62
|
-
|
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
|
-
|
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")
|
data/lib/vagrant-kvm/version.rb
CHANGED
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
|
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
|
-
|
9
|
-
|
10
|
+
'kvm' 及び、'kvm-intel'か'kvm-amd'が正しくインストールされ、
|
11
|
+
(debian/ubuntuの場合)あなたのユーザIDがlibvirtdグループに属しているか、
|
12
|
+
確認してください。
|
10
13
|
kvm_invalid_version: |-
|
11
|
-
不適切なKVMのバージョンが検出されました:バージョン %{actual}
|
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.
|
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.
|
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,
|